137045ce4SJed Brown /* Discretization tools */ 237045ce4SJed Brown 3a6fc04d9SSatish Balay #include <petscconf.h> 4a6fc04d9SSatish Balay #if defined(PETSC_HAVE_MATHIMF_H) 5a6fc04d9SSatish Balay #include <mathimf.h> /* this needs to be included before math.h */ 6a6fc04d9SSatish Balay #endif 7a6fc04d9SSatish Balay 83903c00fSMatthew G. Knepley #include <petscdt.h> /*I "petscdt.h" I*/ /*I "petscfe.h" I*/ 937045ce4SJed Brown #include <petscblaslapack.h> 10194825f6SJed Brown #include <petsc-private/petscimpl.h> 11665c2dedSJed Brown #include <petscviewer.h> 1259804f93SMatthew G. Knepley #include <petscdmplex.h> 1359804f93SMatthew G. Knepley #include <petscdmshell.h> 1437045ce4SJed Brown 1537045ce4SJed Brown #undef __FUNCT__ 16bfa639d9SMatthew G. Knepley #define __FUNCT__ "PetscQuadratureDestroy" 17bfa639d9SMatthew G. Knepley PetscErrorCode PetscQuadratureDestroy(PetscQuadrature *q) 18bfa639d9SMatthew G. Knepley { 19bfa639d9SMatthew G. Knepley PetscErrorCode ierr; 20bfa639d9SMatthew G. Knepley 21bfa639d9SMatthew G. Knepley PetscFunctionBegin; 22bfa639d9SMatthew G. Knepley ierr = PetscFree(q->quadPoints);CHKERRQ(ierr); 23bfa639d9SMatthew G. Knepley ierr = PetscFree(q->quadWeights);CHKERRQ(ierr); 24bfa639d9SMatthew G. Knepley PetscFunctionReturn(0); 25bfa639d9SMatthew G. Knepley } 26bfa639d9SMatthew G. Knepley 27bfa639d9SMatthew G. Knepley #undef __FUNCT__ 2837045ce4SJed Brown #define __FUNCT__ "PetscDTLegendreEval" 2937045ce4SJed Brown /*@ 3037045ce4SJed Brown PetscDTLegendreEval - evaluate Legendre polynomial at points 3137045ce4SJed Brown 3237045ce4SJed Brown Not Collective 3337045ce4SJed Brown 3437045ce4SJed Brown Input Arguments: 3537045ce4SJed Brown + npoints - number of spatial points to evaluate at 3637045ce4SJed Brown . points - array of locations to evaluate at 3737045ce4SJed Brown . ndegree - number of basis degrees to evaluate 3837045ce4SJed Brown - degrees - sorted array of degrees to evaluate 3937045ce4SJed Brown 4037045ce4SJed Brown Output Arguments: 410298fd71SBarry Smith + B - row-oriented basis evaluation matrix B[point*ndegree + degree] (dimension npoints*ndegrees, allocated by caller) (or NULL) 420298fd71SBarry Smith . D - row-oriented derivative evaluation matrix (or NULL) 430298fd71SBarry Smith - D2 - row-oriented second derivative evaluation matrix (or NULL) 4437045ce4SJed Brown 4537045ce4SJed Brown Level: intermediate 4637045ce4SJed Brown 4737045ce4SJed Brown .seealso: PetscDTGaussQuadrature() 4837045ce4SJed Brown @*/ 4937045ce4SJed Brown PetscErrorCode PetscDTLegendreEval(PetscInt npoints,const PetscReal *points,PetscInt ndegree,const PetscInt *degrees,PetscReal *B,PetscReal *D,PetscReal *D2) 5037045ce4SJed Brown { 5137045ce4SJed Brown PetscInt i,maxdegree; 5237045ce4SJed Brown 5337045ce4SJed Brown PetscFunctionBegin; 5437045ce4SJed Brown if (!npoints || !ndegree) PetscFunctionReturn(0); 5537045ce4SJed Brown maxdegree = degrees[ndegree-1]; 5637045ce4SJed Brown for (i=0; i<npoints; i++) { 5737045ce4SJed Brown PetscReal pm1,pm2,pd1,pd2,pdd1,pdd2,x; 5837045ce4SJed Brown PetscInt j,k; 5937045ce4SJed Brown x = points[i]; 6037045ce4SJed Brown pm2 = 0; 6137045ce4SJed Brown pm1 = 1; 6237045ce4SJed Brown pd2 = 0; 6337045ce4SJed Brown pd1 = 0; 6437045ce4SJed Brown pdd2 = 0; 6537045ce4SJed Brown pdd1 = 0; 6637045ce4SJed Brown k = 0; 6737045ce4SJed Brown if (degrees[k] == 0) { 6837045ce4SJed Brown if (B) B[i*ndegree+k] = pm1; 6937045ce4SJed Brown if (D) D[i*ndegree+k] = pd1; 7037045ce4SJed Brown if (D2) D2[i*ndegree+k] = pdd1; 7137045ce4SJed Brown k++; 7237045ce4SJed Brown } 7337045ce4SJed Brown for (j=1; j<=maxdegree; j++,k++) { 7437045ce4SJed Brown PetscReal p,d,dd; 7537045ce4SJed Brown p = ((2*j-1)*x*pm1 - (j-1)*pm2)/j; 7637045ce4SJed Brown d = pd2 + (2*j-1)*pm1; 7737045ce4SJed Brown dd = pdd2 + (2*j-1)*pd1; 7837045ce4SJed Brown pm2 = pm1; 7937045ce4SJed Brown pm1 = p; 8037045ce4SJed Brown pd2 = pd1; 8137045ce4SJed Brown pd1 = d; 8237045ce4SJed Brown pdd2 = pdd1; 8337045ce4SJed Brown pdd1 = dd; 8437045ce4SJed Brown if (degrees[k] == j) { 8537045ce4SJed Brown if (B) B[i*ndegree+k] = p; 8637045ce4SJed Brown if (D) D[i*ndegree+k] = d; 8737045ce4SJed Brown if (D2) D2[i*ndegree+k] = dd; 8837045ce4SJed Brown } 8937045ce4SJed Brown } 9037045ce4SJed Brown } 9137045ce4SJed Brown PetscFunctionReturn(0); 9237045ce4SJed Brown } 9337045ce4SJed Brown 9437045ce4SJed Brown #undef __FUNCT__ 9537045ce4SJed Brown #define __FUNCT__ "PetscDTGaussQuadrature" 9637045ce4SJed Brown /*@ 9737045ce4SJed Brown PetscDTGaussQuadrature - create Gauss quadrature 9837045ce4SJed Brown 9937045ce4SJed Brown Not Collective 10037045ce4SJed Brown 10137045ce4SJed Brown Input Arguments: 10237045ce4SJed Brown + npoints - number of points 10337045ce4SJed Brown . a - left end of interval (often-1) 10437045ce4SJed Brown - b - right end of interval (often +1) 10537045ce4SJed Brown 10637045ce4SJed Brown Output Arguments: 10737045ce4SJed Brown + x - quadrature points 10837045ce4SJed Brown - w - quadrature weights 10937045ce4SJed Brown 11037045ce4SJed Brown Level: intermediate 11137045ce4SJed Brown 11237045ce4SJed Brown References: 11337045ce4SJed Brown Golub and Welsch, Calculation of Quadrature Rules, Math. Comp. 23(106), 221--230, 1969. 11437045ce4SJed Brown 11537045ce4SJed Brown .seealso: PetscDTLegendreEval() 11637045ce4SJed Brown @*/ 11737045ce4SJed Brown PetscErrorCode PetscDTGaussQuadrature(PetscInt npoints,PetscReal a,PetscReal b,PetscReal *x,PetscReal *w) 11837045ce4SJed Brown { 11937045ce4SJed Brown PetscErrorCode ierr; 12037045ce4SJed Brown PetscInt i; 12137045ce4SJed Brown PetscReal *work; 12237045ce4SJed Brown PetscScalar *Z; 12337045ce4SJed Brown PetscBLASInt N,LDZ,info; 12437045ce4SJed Brown 12537045ce4SJed Brown PetscFunctionBegin; 12637045ce4SJed Brown /* Set up the Golub-Welsch system */ 12737045ce4SJed Brown for (i=0; i<npoints; i++) { 12837045ce4SJed Brown x[i] = 0; /* diagonal is 0 */ 12937045ce4SJed Brown if (i) w[i-1] = 0.5 / PetscSqrtReal(1 - 1./PetscSqr(2*i)); 13037045ce4SJed Brown } 13137045ce4SJed Brown ierr = PetscRealView(npoints-1,w,PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); 13237045ce4SJed Brown ierr = PetscMalloc2(npoints*npoints,PetscScalar,&Z,PetscMax(1,2*npoints-2),PetscReal,&work);CHKERRQ(ierr); 133c5df96a5SBarry Smith ierr = PetscBLASIntCast(npoints,&N);CHKERRQ(ierr); 13437045ce4SJed Brown LDZ = N; 13537045ce4SJed Brown ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 1368b83055fSJed Brown PetscStackCallBLAS("LAPACKsteqr",LAPACKsteqr_("I",&N,x,w,Z,&LDZ,work,&info)); 13737045ce4SJed Brown ierr = PetscFPTrapPop();CHKERRQ(ierr); 1381c3d6f74SJed Brown if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"xSTEQR error"); 13937045ce4SJed Brown 14037045ce4SJed Brown for (i=0; i<(npoints+1)/2; i++) { 14137045ce4SJed Brown PetscReal y = 0.5 * (-x[i] + x[npoints-i-1]); /* enforces symmetry */ 14237045ce4SJed Brown x[i] = (a+b)/2 - y*(b-a)/2; 14337045ce4SJed Brown x[npoints-i-1] = (a+b)/2 + y*(b-a)/2; 1440d644c17SKarl Rupp 14537045ce4SJed Brown w[i] = w[npoints-1-i] = (b-a)*PetscSqr(0.5*PetscAbsScalar(Z[i*npoints] + Z[(npoints-i-1)*npoints])); 14637045ce4SJed Brown } 14737045ce4SJed Brown ierr = PetscFree2(Z,work);CHKERRQ(ierr); 14837045ce4SJed Brown PetscFunctionReturn(0); 14937045ce4SJed Brown } 150194825f6SJed Brown 151194825f6SJed Brown #undef __FUNCT__ 152494e7359SMatthew G. Knepley #define __FUNCT__ "PetscDTFactorial_Internal" 153494e7359SMatthew G. Knepley /* Evaluates the nth jacobi polynomial with weight parameters a,b at a point x. 154494e7359SMatthew G. Knepley Recurrence relations implemented from the pseudocode given in Karniadakis and Sherwin, Appendix B */ 155494e7359SMatthew G. Knepley PETSC_STATIC_INLINE PetscErrorCode PetscDTFactorial_Internal(PetscInt n, PetscReal *factorial) 156494e7359SMatthew G. Knepley { 157494e7359SMatthew G. Knepley PetscReal f = 1.0; 158494e7359SMatthew G. Knepley PetscInt i; 159494e7359SMatthew G. Knepley 160494e7359SMatthew G. Knepley PetscFunctionBegin; 161494e7359SMatthew G. Knepley for (i = 1; i < n+1; ++i) f *= i; 162494e7359SMatthew G. Knepley *factorial = f; 163494e7359SMatthew G. Knepley PetscFunctionReturn(0); 164494e7359SMatthew G. Knepley } 165494e7359SMatthew G. Knepley 166494e7359SMatthew G. Knepley #undef __FUNCT__ 167494e7359SMatthew G. Knepley #define __FUNCT__ "PetscDTComputeJacobi" 168494e7359SMatthew G. Knepley /* Evaluates the nth jacobi polynomial with weight parameters a,b at a point x. 169494e7359SMatthew G. Knepley Recurrence relations implemented from the pseudocode given in Karniadakis and Sherwin, Appendix B */ 170494e7359SMatthew G. Knepley PETSC_STATIC_INLINE PetscErrorCode PetscDTComputeJacobi(PetscReal a, PetscReal b, PetscInt n, PetscReal x, PetscReal *P) 171494e7359SMatthew G. Knepley { 172494e7359SMatthew G. Knepley PetscReal apb, pn1, pn2; 173494e7359SMatthew G. Knepley PetscInt k; 174494e7359SMatthew G. Knepley 175494e7359SMatthew G. Knepley PetscFunctionBegin; 176494e7359SMatthew G. Knepley if (!n) {*P = 1.0; PetscFunctionReturn(0);} 177494e7359SMatthew G. Knepley if (n == 1) {*P = 0.5 * (a - b + (a + b + 2.0) * x); PetscFunctionReturn(0);} 178494e7359SMatthew G. Knepley apb = a + b; 179494e7359SMatthew G. Knepley pn2 = 1.0; 180494e7359SMatthew G. Knepley pn1 = 0.5 * (a - b + (apb + 2.0) * x); 181494e7359SMatthew G. Knepley *P = 0.0; 182494e7359SMatthew G. Knepley for (k = 2; k < n+1; ++k) { 183494e7359SMatthew G. Knepley PetscReal a1 = 2.0 * k * (k + apb) * (2.0*k + apb - 2.0); 184494e7359SMatthew G. Knepley PetscReal a2 = (2.0 * k + apb - 1.0) * (a*a - b*b); 185494e7359SMatthew G. Knepley PetscReal a3 = (2.0 * k + apb - 2.0) * (2.0 * k + apb - 1.0) * (2.0 * k + apb); 186494e7359SMatthew G. Knepley PetscReal a4 = 2.0 * (k + a - 1.0) * (k + b - 1.0) * (2.0 * k + apb); 187494e7359SMatthew G. Knepley 188494e7359SMatthew G. Knepley a2 = a2 / a1; 189494e7359SMatthew G. Knepley a3 = a3 / a1; 190494e7359SMatthew G. Knepley a4 = a4 / a1; 191494e7359SMatthew G. Knepley *P = (a2 + a3 * x) * pn1 - a4 * pn2; 192494e7359SMatthew G. Knepley pn2 = pn1; 193494e7359SMatthew G. Knepley pn1 = *P; 194494e7359SMatthew G. Knepley } 195494e7359SMatthew G. Knepley PetscFunctionReturn(0); 196494e7359SMatthew G. Knepley } 197494e7359SMatthew G. Knepley 198494e7359SMatthew G. Knepley #undef __FUNCT__ 199494e7359SMatthew G. Knepley #define __FUNCT__ "PetscDTComputeJacobiDerivative" 200494e7359SMatthew G. Knepley /* Evaluates the first derivative of P_{n}^{a,b} at a point x. */ 201494e7359SMatthew G. Knepley PETSC_STATIC_INLINE PetscErrorCode PetscDTComputeJacobiDerivative(PetscReal a, PetscReal b, PetscInt n, PetscReal x, PetscReal *P) 202494e7359SMatthew G. Knepley { 203494e7359SMatthew G. Knepley PetscReal nP; 204494e7359SMatthew G. Knepley PetscErrorCode ierr; 205494e7359SMatthew G. Knepley 206494e7359SMatthew G. Knepley PetscFunctionBegin; 207494e7359SMatthew G. Knepley if (!n) {*P = 0.0; PetscFunctionReturn(0);} 208494e7359SMatthew G. Knepley ierr = PetscDTComputeJacobi(a+1, b+1, n-1, x, &nP);CHKERRQ(ierr); 209494e7359SMatthew G. Knepley *P = 0.5 * (a + b + n + 1) * nP; 210494e7359SMatthew G. Knepley PetscFunctionReturn(0); 211494e7359SMatthew G. Knepley } 212494e7359SMatthew G. Knepley 213494e7359SMatthew G. Knepley #undef __FUNCT__ 214494e7359SMatthew G. Knepley #define __FUNCT__ "PetscDTMapSquareToTriangle_Internal" 215494e7359SMatthew G. Knepley /* Maps from [-1,1]^2 to the (-1,1) reference triangle */ 216494e7359SMatthew G. Knepley PETSC_STATIC_INLINE PetscErrorCode PetscDTMapSquareToTriangle_Internal(PetscReal x, PetscReal y, PetscReal *xi, PetscReal *eta) 217494e7359SMatthew G. Knepley { 218494e7359SMatthew G. Knepley PetscFunctionBegin; 219494e7359SMatthew G. Knepley *xi = 0.5 * (1.0 + x) * (1.0 - y) - 1.0; 220494e7359SMatthew G. Knepley *eta = y; 221494e7359SMatthew G. Knepley PetscFunctionReturn(0); 222494e7359SMatthew G. Knepley } 223494e7359SMatthew G. Knepley 224494e7359SMatthew G. Knepley #undef __FUNCT__ 225494e7359SMatthew G. Knepley #define __FUNCT__ "PetscDTMapCubeToTetrahedron_Internal" 226494e7359SMatthew G. Knepley /* Maps from [-1,1]^2 to the (-1,1) reference triangle */ 227494e7359SMatthew G. Knepley PETSC_STATIC_INLINE PetscErrorCode PetscDTMapCubeToTetrahedron_Internal(PetscReal x, PetscReal y, PetscReal z, PetscReal *xi, PetscReal *eta, PetscReal *zeta) 228494e7359SMatthew G. Knepley { 229494e7359SMatthew G. Knepley PetscFunctionBegin; 230494e7359SMatthew G. Knepley *xi = 0.25 * (1.0 + x) * (1.0 - y) * (1.0 - z) - 1.0; 231494e7359SMatthew G. Knepley *eta = 0.5 * (1.0 + y) * (1.0 - z) - 1.0; 232494e7359SMatthew G. Knepley *zeta = z; 233494e7359SMatthew G. Knepley PetscFunctionReturn(0); 234494e7359SMatthew G. Knepley } 235494e7359SMatthew G. Knepley 236494e7359SMatthew G. Knepley #undef __FUNCT__ 237494e7359SMatthew G. Knepley #define __FUNCT__ "PetscDTGaussJacobiQuadrature1D_Internal" 238494e7359SMatthew G. Knepley static PetscErrorCode PetscDTGaussJacobiQuadrature1D_Internal(PetscInt npoints, PetscReal a, PetscReal b, PetscReal *x, PetscReal *w) 239494e7359SMatthew G. Knepley { 240494e7359SMatthew G. Knepley PetscInt maxIter = 100; 241494e7359SMatthew G. Knepley PetscReal eps = 1.0e-8; 242a8291ba1SSatish Balay PetscReal a1, a2, a3, a4, a5, a6; 243494e7359SMatthew G. Knepley PetscInt k; 244494e7359SMatthew G. Knepley PetscErrorCode ierr; 245494e7359SMatthew G. Knepley 246494e7359SMatthew G. Knepley PetscFunctionBegin; 247a8291ba1SSatish Balay 248a8291ba1SSatish Balay a1 = pow(2, a+b+1); 249a8291ba1SSatish Balay #if defined(PETSC_HAVE_TGAMMA) 250a8291ba1SSatish Balay a2 = tgamma(a + npoints + 1); 251a8291ba1SSatish Balay a3 = tgamma(b + npoints + 1); 252a8291ba1SSatish Balay a4 = tgamma(a + b + npoints + 1); 253a8291ba1SSatish Balay #else 254a8291ba1SSatish Balay SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"tgamma() - math routine is unavailable."); 255a8291ba1SSatish Balay #endif 256a8291ba1SSatish Balay 257494e7359SMatthew G. Knepley ierr = PetscDTFactorial_Internal(npoints, &a5);CHKERRQ(ierr); 258494e7359SMatthew G. Knepley a6 = a1 * a2 * a3 / a4 / a5; 259494e7359SMatthew G. Knepley /* Computes the m roots of P_{m}^{a,b} on [-1,1] by Newton's method with Chebyshev points as initial guesses. 260494e7359SMatthew G. Knepley Algorithm implemented from the pseudocode given by Karniadakis and Sherwin and Python in FIAT */ 261494e7359SMatthew G. Knepley for (k = 0; k < npoints; ++k) { 2627f1c68b3SMatthew G. Knepley PetscReal r = -cos((2.0*k + 1.0) * PETSC_PI / (2.0 * npoints)), dP; 263494e7359SMatthew G. Knepley PetscInt j; 264494e7359SMatthew G. Knepley 265494e7359SMatthew G. Knepley if (k > 0) r = 0.5 * (r + x[k-1]); 266494e7359SMatthew G. Knepley for (j = 0; j < maxIter; ++j) { 267494e7359SMatthew G. Knepley PetscReal s = 0.0, delta, f, fp; 268494e7359SMatthew G. Knepley PetscInt i; 269494e7359SMatthew G. Knepley 270494e7359SMatthew G. Knepley for (i = 0; i < k; ++i) s = s + 1.0 / (r - x[i]); 271494e7359SMatthew G. Knepley ierr = PetscDTComputeJacobi(a, b, npoints, r, &f);CHKERRQ(ierr); 272494e7359SMatthew G. Knepley ierr = PetscDTComputeJacobiDerivative(a, b, npoints, r, &fp);CHKERRQ(ierr); 273494e7359SMatthew G. Knepley delta = f / (fp - f * s); 274494e7359SMatthew G. Knepley r = r - delta; 275494e7359SMatthew G. Knepley if (fabs(delta) < eps) break; 276494e7359SMatthew G. Knepley } 277494e7359SMatthew G. Knepley x[k] = r; 278494e7359SMatthew G. Knepley ierr = PetscDTComputeJacobiDerivative(a, b, npoints, x[k], &dP);CHKERRQ(ierr); 279494e7359SMatthew G. Knepley w[k] = a6 / (1.0 - PetscSqr(x[k])) / PetscSqr(dP); 280494e7359SMatthew G. Knepley } 281494e7359SMatthew G. Knepley PetscFunctionReturn(0); 282494e7359SMatthew G. Knepley } 283494e7359SMatthew G. Knepley 284494e7359SMatthew G. Knepley #undef __FUNCT__ 285494e7359SMatthew G. Knepley #define __FUNCT__ "PetscDTGaussJacobiQuadrature" 286fd9d31fbSMatthew G. Knepley /*@C 287494e7359SMatthew G. Knepley PetscDTGaussJacobiQuadrature - create Gauss-Jacobi quadrature for a simplex 288494e7359SMatthew G. Knepley 289494e7359SMatthew G. Knepley Not Collective 290494e7359SMatthew G. Knepley 291494e7359SMatthew G. Knepley Input Arguments: 292494e7359SMatthew G. Knepley + dim - The simplex dimension 293494e7359SMatthew G. Knepley . npoints - number of points 294494e7359SMatthew G. Knepley . a - left end of interval (often-1) 295494e7359SMatthew G. Knepley - b - right end of interval (often +1) 296494e7359SMatthew G. Knepley 297494e7359SMatthew G. Knepley Output Arguments: 298494e7359SMatthew G. Knepley + points - quadrature points 299494e7359SMatthew G. Knepley - weights - quadrature weights 300494e7359SMatthew G. Knepley 301494e7359SMatthew G. Knepley Level: intermediate 302494e7359SMatthew G. Knepley 303494e7359SMatthew G. Knepley References: 304494e7359SMatthew G. Knepley Karniadakis and Sherwin. 305494e7359SMatthew G. Knepley FIAT 306494e7359SMatthew G. Knepley 307494e7359SMatthew G. Knepley .seealso: PetscDTGaussQuadrature() 308494e7359SMatthew G. Knepley @*/ 309494e7359SMatthew G. Knepley PetscErrorCode PetscDTGaussJacobiQuadrature(PetscInt dim, PetscInt npoints, PetscReal a, PetscReal b, PetscReal *points[], PetscReal *weights[]) 310494e7359SMatthew G. Knepley { 311494e7359SMatthew G. Knepley PetscReal *px, *wx, *py, *wy, *pz, *wz, *x, *w; 312494e7359SMatthew G. Knepley PetscInt i, j, k; 313494e7359SMatthew G. Knepley PetscErrorCode ierr; 314494e7359SMatthew G. Knepley 315494e7359SMatthew G. Knepley PetscFunctionBegin; 316494e7359SMatthew G. Knepley if ((a != -1.0) || (b != 1.0)) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Must use default internal right now"); 317494e7359SMatthew G. Knepley switch (dim) { 318494e7359SMatthew G. Knepley case 1: 319494e7359SMatthew G. Knepley ierr = PetscMalloc(npoints * sizeof(PetscReal), &x);CHKERRQ(ierr); 320494e7359SMatthew G. Knepley ierr = PetscMalloc(npoints * sizeof(PetscReal), &w);CHKERRQ(ierr); 321494e7359SMatthew G. Knepley ierr = PetscDTGaussJacobiQuadrature1D_Internal(npoints, 0.0, 0.0, x, w);CHKERRQ(ierr); 322494e7359SMatthew G. Knepley break; 323494e7359SMatthew G. Knepley case 2: 324494e7359SMatthew G. Knepley ierr = PetscMalloc(npoints*npoints*2 * sizeof(PetscReal), &x);CHKERRQ(ierr); 325494e7359SMatthew G. Knepley ierr = PetscMalloc(npoints*npoints * sizeof(PetscReal), &w);CHKERRQ(ierr); 326494e7359SMatthew G. Knepley ierr = PetscMalloc4(npoints,PetscReal,&px,npoints,PetscReal,&wx,npoints,PetscReal,&py,npoints,PetscReal,&wy);CHKERRQ(ierr); 327494e7359SMatthew G. Knepley ierr = PetscDTGaussJacobiQuadrature1D_Internal(npoints, 0.0, 0.0, px, wx);CHKERRQ(ierr); 328494e7359SMatthew G. Knepley ierr = PetscDTGaussJacobiQuadrature1D_Internal(npoints, 1.0, 0.0, py, wy);CHKERRQ(ierr); 329494e7359SMatthew G. Knepley for (i = 0; i < npoints; ++i) { 330494e7359SMatthew G. Knepley for (j = 0; j < npoints; ++j) { 331494e7359SMatthew G. Knepley ierr = PetscDTMapSquareToTriangle_Internal(px[i], py[j], &x[(i*npoints+j)*2+0], &x[(i*npoints+j)*2+1]);CHKERRQ(ierr); 332494e7359SMatthew G. Knepley w[i*npoints+j] = 0.5 * wx[i] * wy[j]; 333494e7359SMatthew G. Knepley } 334494e7359SMatthew G. Knepley } 335494e7359SMatthew G. Knepley ierr = PetscFree4(px,wx,py,wy);CHKERRQ(ierr); 336494e7359SMatthew G. Knepley break; 337494e7359SMatthew G. Knepley case 3: 338494e7359SMatthew G. Knepley ierr = PetscMalloc(npoints*npoints*3 * sizeof(PetscReal), &x);CHKERRQ(ierr); 339494e7359SMatthew G. Knepley ierr = PetscMalloc(npoints*npoints * sizeof(PetscReal), &w);CHKERRQ(ierr); 340494e7359SMatthew G. Knepley ierr = PetscMalloc6(npoints,PetscReal,&px,npoints,PetscReal,&wx,npoints,PetscReal,&py,npoints,PetscReal,&wy,npoints,PetscReal,&pz,npoints,PetscReal,&wz);CHKERRQ(ierr); 341494e7359SMatthew G. Knepley ierr = PetscDTGaussJacobiQuadrature1D_Internal(npoints, 0.0, 0.0, px, wx);CHKERRQ(ierr); 342494e7359SMatthew G. Knepley ierr = PetscDTGaussJacobiQuadrature1D_Internal(npoints, 1.0, 0.0, py, wy);CHKERRQ(ierr); 343494e7359SMatthew G. Knepley ierr = PetscDTGaussJacobiQuadrature1D_Internal(npoints, 2.0, 0.0, pz, wz);CHKERRQ(ierr); 344494e7359SMatthew G. Knepley for (i = 0; i < npoints; ++i) { 345494e7359SMatthew G. Knepley for (j = 0; j < npoints; ++j) { 346494e7359SMatthew G. Knepley for (k = 0; k < npoints; ++k) { 347494e7359SMatthew G. Knepley ierr = PetscDTMapCubeToTetrahedron_Internal(px[i], py[j], pz[k], &x[((i*npoints+j)*npoints+k)*3+0], &x[((i*npoints+j)*npoints+k)*3+1], &x[((i*npoints+j)*npoints+k)*3+2]);CHKERRQ(ierr); 348494e7359SMatthew G. Knepley w[(i*npoints+j)*npoints+k] = 0.125 * wx[i] * wy[j] * wz[k]; 349494e7359SMatthew G. Knepley } 350494e7359SMatthew G. Knepley } 351494e7359SMatthew G. Knepley } 352494e7359SMatthew G. Knepley ierr = PetscFree6(px,wx,py,wy,pz,wz);CHKERRQ(ierr); 353494e7359SMatthew G. Knepley break; 354494e7359SMatthew G. Knepley default: 355494e7359SMatthew G. Knepley SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Cannot construct quadrature rule for dimension %d", dim); 356494e7359SMatthew G. Knepley } 357494e7359SMatthew G. Knepley if (points) *points = x; 358494e7359SMatthew G. Knepley if (weights) *weights = w; 359494e7359SMatthew G. Knepley PetscFunctionReturn(0); 360494e7359SMatthew G. Knepley } 361494e7359SMatthew G. Knepley 362494e7359SMatthew G. Knepley #undef __FUNCT__ 363194825f6SJed Brown #define __FUNCT__ "PetscDTPseudoInverseQR" 364194825f6SJed Brown /* Overwrites A. Can only handle full-rank problems with m>=n 365194825f6SJed Brown * A in column-major format 366194825f6SJed Brown * Ainv in row-major format 367194825f6SJed Brown * tau has length m 368194825f6SJed Brown * worksize must be >= max(1,n) 369194825f6SJed Brown */ 370194825f6SJed Brown static PetscErrorCode PetscDTPseudoInverseQR(PetscInt m,PetscInt mstride,PetscInt n,PetscReal *A_in,PetscReal *Ainv_out,PetscScalar *tau,PetscInt worksize,PetscScalar *work) 371194825f6SJed Brown { 372194825f6SJed Brown PetscErrorCode ierr; 373194825f6SJed Brown PetscBLASInt M,N,K,lda,ldb,ldwork,info; 374194825f6SJed Brown PetscScalar *A,*Ainv,*R,*Q,Alpha; 375194825f6SJed Brown 376194825f6SJed Brown PetscFunctionBegin; 377194825f6SJed Brown #if defined(PETSC_USE_COMPLEX) 378194825f6SJed Brown { 379194825f6SJed Brown PetscInt i,j; 380194825f6SJed Brown ierr = PetscMalloc2(m*n,PetscScalar,&A,m*n,PetscScalar,&Ainv);CHKERRQ(ierr); 381194825f6SJed Brown for (j=0; j<n; j++) { 382194825f6SJed Brown for (i=0; i<m; i++) A[i+m*j] = A_in[i+mstride*j]; 383194825f6SJed Brown } 384194825f6SJed Brown mstride = m; 385194825f6SJed Brown } 386194825f6SJed Brown #else 387194825f6SJed Brown A = A_in; 388194825f6SJed Brown Ainv = Ainv_out; 389194825f6SJed Brown #endif 390194825f6SJed Brown 391194825f6SJed Brown ierr = PetscBLASIntCast(m,&M);CHKERRQ(ierr); 392194825f6SJed Brown ierr = PetscBLASIntCast(n,&N);CHKERRQ(ierr); 393194825f6SJed Brown ierr = PetscBLASIntCast(mstride,&lda);CHKERRQ(ierr); 394194825f6SJed Brown ierr = PetscBLASIntCast(worksize,&ldwork);CHKERRQ(ierr); 395194825f6SJed Brown ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 396194825f6SJed Brown LAPACKgeqrf_(&M,&N,A,&lda,tau,work,&ldwork,&info); 397194825f6SJed Brown ierr = PetscFPTrapPop();CHKERRQ(ierr); 398194825f6SJed Brown if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"xGEQRF error"); 399194825f6SJed Brown R = A; /* Upper triangular part of A now contains R, the rest contains the elementary reflectors */ 400194825f6SJed Brown 401194825f6SJed Brown /* Extract an explicit representation of Q */ 402194825f6SJed Brown Q = Ainv; 403194825f6SJed Brown ierr = PetscMemcpy(Q,A,mstride*n*sizeof(PetscScalar));CHKERRQ(ierr); 404194825f6SJed Brown K = N; /* full rank */ 405194825f6SJed Brown LAPACKungqr_(&M,&N,&K,Q,&lda,tau,work,&ldwork,&info); 406194825f6SJed Brown if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"xORGQR/xUNGQR error"); 407194825f6SJed Brown 408194825f6SJed Brown /* Compute A^{-T} = (R^{-1} Q^T)^T = Q R^{-T} */ 409194825f6SJed Brown Alpha = 1.0; 410194825f6SJed Brown ldb = lda; 411194825f6SJed Brown BLAStrsm_("Right","Upper","ConjugateTranspose","NotUnitTriangular",&M,&N,&Alpha,R,&lda,Q,&ldb); 412194825f6SJed Brown /* Ainv is Q, overwritten with inverse */ 413194825f6SJed Brown 414194825f6SJed Brown #if defined(PETSC_USE_COMPLEX) 415194825f6SJed Brown { 416194825f6SJed Brown PetscInt i; 417194825f6SJed Brown for (i=0; i<m*n; i++) Ainv_out[i] = PetscRealPart(Ainv[i]); 418194825f6SJed Brown ierr = PetscFree2(A,Ainv);CHKERRQ(ierr); 419194825f6SJed Brown } 420194825f6SJed Brown #endif 421194825f6SJed Brown PetscFunctionReturn(0); 422194825f6SJed Brown } 423194825f6SJed Brown 424194825f6SJed Brown #undef __FUNCT__ 425194825f6SJed Brown #define __FUNCT__ "PetscDTLegendreIntegrate" 426194825f6SJed Brown /* Computes integral of L_p' over intervals {(x0,x1),(x1,x2),...} */ 427194825f6SJed Brown static PetscErrorCode PetscDTLegendreIntegrate(PetscInt ninterval,const PetscReal *x,PetscInt ndegree,const PetscInt *degrees,PetscBool Transpose,PetscReal *B) 428194825f6SJed Brown { 429194825f6SJed Brown PetscErrorCode ierr; 430194825f6SJed Brown PetscReal *Bv; 431194825f6SJed Brown PetscInt i,j; 432194825f6SJed Brown 433194825f6SJed Brown PetscFunctionBegin; 434194825f6SJed Brown ierr = PetscMalloc((ninterval+1)*ndegree*sizeof(PetscReal),&Bv);CHKERRQ(ierr); 435194825f6SJed Brown /* Point evaluation of L_p on all the source vertices */ 436194825f6SJed Brown ierr = PetscDTLegendreEval(ninterval+1,x,ndegree,degrees,Bv,NULL,NULL);CHKERRQ(ierr); 437194825f6SJed Brown /* Integral over each interval: \int_a^b L_p' = L_p(b)-L_p(a) */ 438194825f6SJed Brown for (i=0; i<ninterval; i++) { 439194825f6SJed Brown for (j=0; j<ndegree; j++) { 440194825f6SJed Brown if (Transpose) B[i+ninterval*j] = Bv[(i+1)*ndegree+j] - Bv[i*ndegree+j]; 441194825f6SJed Brown else B[i*ndegree+j] = Bv[(i+1)*ndegree+j] - Bv[i*ndegree+j]; 442194825f6SJed Brown } 443194825f6SJed Brown } 444194825f6SJed Brown ierr = PetscFree(Bv);CHKERRQ(ierr); 445194825f6SJed Brown PetscFunctionReturn(0); 446194825f6SJed Brown } 447194825f6SJed Brown 448194825f6SJed Brown #undef __FUNCT__ 449194825f6SJed Brown #define __FUNCT__ "PetscDTReconstructPoly" 450194825f6SJed Brown /*@ 451194825f6SJed Brown PetscDTReconstructPoly - create matrix representing polynomial reconstruction using cell intervals and evaluation at target intervals 452194825f6SJed Brown 453194825f6SJed Brown Not Collective 454194825f6SJed Brown 455194825f6SJed Brown Input Arguments: 456194825f6SJed Brown + degree - degree of reconstruction polynomial 457194825f6SJed Brown . nsource - number of source intervals 458194825f6SJed Brown . sourcex - sorted coordinates of source cell boundaries (length nsource+1) 459194825f6SJed Brown . ntarget - number of target intervals 460194825f6SJed Brown - targetx - sorted coordinates of target cell boundaries (length ntarget+1) 461194825f6SJed Brown 462194825f6SJed Brown Output Arguments: 463194825f6SJed Brown . R - reconstruction matrix, utarget = sum_s R[t*nsource+s] * usource[s] 464194825f6SJed Brown 465194825f6SJed Brown Level: advanced 466194825f6SJed Brown 467194825f6SJed Brown .seealso: PetscDTLegendreEval() 468194825f6SJed Brown @*/ 469194825f6SJed Brown PetscErrorCode PetscDTReconstructPoly(PetscInt degree,PetscInt nsource,const PetscReal *sourcex,PetscInt ntarget,const PetscReal *targetx,PetscReal *R) 470194825f6SJed Brown { 471194825f6SJed Brown PetscErrorCode ierr; 472194825f6SJed Brown PetscInt i,j,k,*bdegrees,worksize; 473194825f6SJed Brown PetscReal xmin,xmax,center,hscale,*sourcey,*targety,*Bsource,*Bsinv,*Btarget; 474194825f6SJed Brown PetscScalar *tau,*work; 475194825f6SJed Brown 476194825f6SJed Brown PetscFunctionBegin; 477194825f6SJed Brown PetscValidRealPointer(sourcex,3); 478194825f6SJed Brown PetscValidRealPointer(targetx,5); 479194825f6SJed Brown PetscValidRealPointer(R,6); 480194825f6SJed Brown if (degree >= nsource) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Reconstruction degree %D must be less than number of source intervals %D",degree,nsource); 481194825f6SJed Brown #if defined(PETSC_USE_DEBUG) 482194825f6SJed Brown for (i=0; i<nsource; i++) { 483194825f6SJed Brown if (sourcex[i] >= sourcex[i+1]) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"Source interval %D has negative orientation (%G,%G)",i,sourcex[i],sourcex[i+1]); 484194825f6SJed Brown } 485194825f6SJed Brown for (i=0; i<ntarget; i++) { 486194825f6SJed Brown if (targetx[i] >= targetx[i+1]) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"Target interval %D has negative orientation (%G,%G)",i,targetx[i],targetx[i+1]); 487194825f6SJed Brown } 488194825f6SJed Brown #endif 489194825f6SJed Brown xmin = PetscMin(sourcex[0],targetx[0]); 490194825f6SJed Brown xmax = PetscMax(sourcex[nsource],targetx[ntarget]); 491194825f6SJed Brown center = (xmin + xmax)/2; 492194825f6SJed Brown hscale = (xmax - xmin)/2; 493194825f6SJed Brown worksize = nsource; 494194825f6SJed Brown ierr = PetscMalloc4(degree+1,PetscInt,&bdegrees,nsource+1,PetscReal,&sourcey,nsource*(degree+1),PetscReal,&Bsource,worksize,PetscScalar,&work);CHKERRQ(ierr); 49582772646SJed Brown ierr = PetscMalloc4(nsource,PetscScalar,&tau,nsource*(degree+1),PetscReal,&Bsinv,ntarget+1,PetscReal,&targety,ntarget*(degree+1),PetscReal,&Btarget);CHKERRQ(ierr); 496194825f6SJed Brown for (i=0; i<=nsource; i++) sourcey[i] = (sourcex[i]-center)/hscale; 497194825f6SJed Brown for (i=0; i<=degree; i++) bdegrees[i] = i+1; 498194825f6SJed Brown ierr = PetscDTLegendreIntegrate(nsource,sourcey,degree+1,bdegrees,PETSC_TRUE,Bsource);CHKERRQ(ierr); 499194825f6SJed Brown ierr = PetscDTPseudoInverseQR(nsource,nsource,degree+1,Bsource,Bsinv,tau,nsource,work);CHKERRQ(ierr); 500194825f6SJed Brown for (i=0; i<=ntarget; i++) targety[i] = (targetx[i]-center)/hscale; 501194825f6SJed Brown ierr = PetscDTLegendreIntegrate(ntarget,targety,degree+1,bdegrees,PETSC_FALSE,Btarget);CHKERRQ(ierr); 502194825f6SJed Brown for (i=0; i<ntarget; i++) { 503194825f6SJed Brown PetscReal rowsum = 0; 504194825f6SJed Brown for (j=0; j<nsource; j++) { 505194825f6SJed Brown PetscReal sum = 0; 506194825f6SJed Brown for (k=0; k<degree+1; k++) { 507194825f6SJed Brown sum += Btarget[i*(degree+1)+k] * Bsinv[k*nsource+j]; 508194825f6SJed Brown } 509194825f6SJed Brown R[i*nsource+j] = sum; 510194825f6SJed Brown rowsum += sum; 511194825f6SJed Brown } 512194825f6SJed Brown for (j=0; j<nsource; j++) R[i*nsource+j] /= rowsum; /* normalize each row */ 513194825f6SJed Brown } 514194825f6SJed Brown ierr = PetscFree4(bdegrees,sourcey,Bsource,work);CHKERRQ(ierr); 515194825f6SJed Brown ierr = PetscFree4(tau,Bsinv,targety,Btarget);CHKERRQ(ierr); 516194825f6SJed Brown PetscFunctionReturn(0); 517194825f6SJed Brown } 51829d8e7bcSMatthew G. Knepley 51929d8e7bcSMatthew G. Knepley /* Basis Jet Tabulation 52029d8e7bcSMatthew G. Knepley 52129d8e7bcSMatthew G. Knepley We would like to tabulate the nodal basis functions and derivatives at a set of points, usually quadrature points. We 52229d8e7bcSMatthew G. Knepley follow here the derviation in http://www.math.ttu.edu/~kirby/papers/fiat-toms-2004.pdf. The nodal basis $\psi_i$ can 52329d8e7bcSMatthew G. Knepley be expressed in terms of a prime basis $\phi_i$ which can be stably evaluated. In PETSc, we will use the Legendre basis 52429d8e7bcSMatthew G. Knepley as a prime basis. 52529d8e7bcSMatthew G. Knepley 52629d8e7bcSMatthew G. Knepley \psi_i = \sum_k \alpha_{ki} \phi_k 52729d8e7bcSMatthew G. Knepley 52829d8e7bcSMatthew G. Knepley Our nodal basis is defined in terms of the dual basis $n_j$ 52929d8e7bcSMatthew G. Knepley 53029d8e7bcSMatthew G. Knepley n_j \cdot \psi_i = \delta_{ji} 53129d8e7bcSMatthew G. Knepley 53229d8e7bcSMatthew G. Knepley and we may act on the first equation to obtain 53329d8e7bcSMatthew G. Knepley 53429d8e7bcSMatthew G. Knepley n_j \cdot \psi_i = \sum_k \alpha_{ki} n_j \cdot \phi_k 53529d8e7bcSMatthew G. Knepley \delta_{ji} = \sum_k \alpha_{ki} V_{jk} 53629d8e7bcSMatthew G. Knepley I = V \alpha 53729d8e7bcSMatthew G. Knepley 53829d8e7bcSMatthew G. Knepley so the coefficients of the nodal basis in the prime basis are 53929d8e7bcSMatthew G. Knepley 54029d8e7bcSMatthew G. Knepley \alpha = V^{-1} 54129d8e7bcSMatthew G. Knepley 54229d8e7bcSMatthew G. Knepley We will define the dual basis vectors $n_j$ using a quadrature rule. 54329d8e7bcSMatthew G. Knepley 54429d8e7bcSMatthew G. Knepley Right now, we will just use the polynomial spaces P^k. I know some elements use the space of symmetric polynomials 54529d8e7bcSMatthew G. Knepley (I think Nedelec), but we will neglect this for now. Constraints in the space, e.g. Arnold-Winther elements, can 54629d8e7bcSMatthew G. Knepley be implemented exactly as in FIAT using functionals $L_j$. 54729d8e7bcSMatthew G. Knepley 54829d8e7bcSMatthew G. Knepley I will have to count the degrees correctly for the Legendre product when we are on simplices. 54929d8e7bcSMatthew G. Knepley 55029d8e7bcSMatthew G. Knepley We will have three objects: 55129d8e7bcSMatthew G. Knepley - Space, P: this just need point evaluation I think 55229d8e7bcSMatthew G. Knepley - Dual Space, P'+K: This looks like a set of functionals that can act on members of P, each n is defined by a Q 55329d8e7bcSMatthew G. Knepley - FEM: This keeps {P, P', Q} 55429d8e7bcSMatthew G. Knepley */ 55529d8e7bcSMatthew G. Knepley #include <petsc-private/petscfeimpl.h> 55629d8e7bcSMatthew G. Knepley 55729d8e7bcSMatthew G. Knepley PetscInt PETSCSPACE_CLASSID = 0; 55829d8e7bcSMatthew G. Knepley 55929d8e7bcSMatthew G. Knepley PetscFunctionList PetscSpaceList = NULL; 56029d8e7bcSMatthew G. Knepley PetscBool PetscSpaceRegisterAllCalled = PETSC_FALSE; 56129d8e7bcSMatthew G. Knepley 56229d8e7bcSMatthew G. Knepley #undef __FUNCT__ 56329d8e7bcSMatthew G. Knepley #define __FUNCT__ "PetscSpaceRegister" 56429d8e7bcSMatthew G. Knepley /*@C 56529d8e7bcSMatthew G. Knepley PetscSpaceRegister - Adds a new PetscSpace implementation 56629d8e7bcSMatthew G. Knepley 56729d8e7bcSMatthew G. Knepley Not Collective 56829d8e7bcSMatthew G. Knepley 56929d8e7bcSMatthew G. Knepley Input Parameters: 57029d8e7bcSMatthew G. Knepley + name - The name of a new user-defined creation routine 57129d8e7bcSMatthew G. Knepley - create_func - The creation routine itself 57229d8e7bcSMatthew G. Knepley 57329d8e7bcSMatthew G. Knepley Notes: 57429d8e7bcSMatthew G. Knepley PetscSpaceRegister() may be called multiple times to add several user-defined PetscSpaces 57529d8e7bcSMatthew G. Knepley 57629d8e7bcSMatthew G. Knepley Sample usage: 57729d8e7bcSMatthew G. Knepley .vb 57829d8e7bcSMatthew G. Knepley PetscSpaceRegister("my_space", MyPetscSpaceCreate); 57929d8e7bcSMatthew G. Knepley .ve 58029d8e7bcSMatthew G. Knepley 58129d8e7bcSMatthew G. Knepley Then, your PetscSpace type can be chosen with the procedural interface via 58229d8e7bcSMatthew G. Knepley .vb 58329d8e7bcSMatthew G. Knepley PetscSpaceCreate(MPI_Comm, PetscSpace *); 58429d8e7bcSMatthew G. Knepley PetscSpaceSetType(PetscSpace, "my_space"); 58529d8e7bcSMatthew G. Knepley .ve 58629d8e7bcSMatthew G. Knepley or at runtime via the option 58729d8e7bcSMatthew G. Knepley .vb 58829d8e7bcSMatthew G. Knepley -petscspace_type my_space 58929d8e7bcSMatthew G. Knepley .ve 59029d8e7bcSMatthew G. Knepley 59129d8e7bcSMatthew G. Knepley Level: advanced 59229d8e7bcSMatthew G. Knepley 59329d8e7bcSMatthew G. Knepley .keywords: PetscSpace, register 59429d8e7bcSMatthew G. Knepley .seealso: PetscSpaceRegisterAll(), PetscSpaceRegisterDestroy() 59529d8e7bcSMatthew G. Knepley 59629d8e7bcSMatthew G. Knepley @*/ 59729d8e7bcSMatthew G. Knepley PetscErrorCode PetscSpaceRegister(const char sname[], PetscErrorCode (*function)(PetscSpace)) 59829d8e7bcSMatthew G. Knepley { 59929d8e7bcSMatthew G. Knepley PetscErrorCode ierr; 60029d8e7bcSMatthew G. Knepley 60129d8e7bcSMatthew G. Knepley PetscFunctionBegin; 60229d8e7bcSMatthew G. Knepley ierr = PetscFunctionListAdd(&PetscSpaceList, sname, function);CHKERRQ(ierr); 60329d8e7bcSMatthew G. Knepley PetscFunctionReturn(0); 60429d8e7bcSMatthew G. Knepley } 60529d8e7bcSMatthew G. Knepley 60629d8e7bcSMatthew G. Knepley #undef __FUNCT__ 60729d8e7bcSMatthew G. Knepley #define __FUNCT__ "PetscSpaceSetType" 60829d8e7bcSMatthew G. Knepley /*@C 60929d8e7bcSMatthew G. Knepley PetscSpaceSetType - Builds a particular PetscSpace 61029d8e7bcSMatthew G. Knepley 61129d8e7bcSMatthew G. Knepley Collective on PetscSpace 61229d8e7bcSMatthew G. Knepley 61329d8e7bcSMatthew G. Knepley Input Parameters: 61429d8e7bcSMatthew G. Knepley + sp - The PetscSpace object 61529d8e7bcSMatthew G. Knepley - name - The kind of space 61629d8e7bcSMatthew G. Knepley 61729d8e7bcSMatthew G. Knepley Options Database Key: 61829d8e7bcSMatthew G. Knepley . -petscspace_type <type> - Sets the PetscSpace type; use -help for a list of available types 61929d8e7bcSMatthew G. Knepley 62029d8e7bcSMatthew G. Knepley Level: intermediate 62129d8e7bcSMatthew G. Knepley 62229d8e7bcSMatthew G. Knepley .keywords: PetscSpace, set, type 62329d8e7bcSMatthew G. Knepley .seealso: PetscSpaceGetType(), PetscSpaceCreate() 62429d8e7bcSMatthew G. Knepley @*/ 62529d8e7bcSMatthew G. Knepley PetscErrorCode PetscSpaceSetType(PetscSpace sp, PetscSpaceType name) 62629d8e7bcSMatthew G. Knepley { 62729d8e7bcSMatthew G. Knepley PetscErrorCode (*r)(PetscSpace); 62829d8e7bcSMatthew G. Knepley PetscBool match; 62929d8e7bcSMatthew G. Knepley PetscErrorCode ierr; 63029d8e7bcSMatthew G. Knepley 63129d8e7bcSMatthew G. Knepley PetscFunctionBegin; 63229d8e7bcSMatthew G. Knepley PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 63329d8e7bcSMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) sp, name, &match);CHKERRQ(ierr); 63429d8e7bcSMatthew G. Knepley if (match) PetscFunctionReturn(0); 63529d8e7bcSMatthew G. Knepley 63629d8e7bcSMatthew G. Knepley if (!PetscSpaceRegisterAllCalled) {ierr = PetscSpaceRegisterAll();CHKERRQ(ierr);} 63729d8e7bcSMatthew G. Knepley ierr = PetscFunctionListFind(PetscSpaceList, name, &r);CHKERRQ(ierr); 63829d8e7bcSMatthew G. Knepley if (!r) SETERRQ1(PetscObjectComm((PetscObject) sp), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown PetscSpace type: %s", name); 63929d8e7bcSMatthew G. Knepley 64029d8e7bcSMatthew G. Knepley if (sp->ops->destroy) { 64129d8e7bcSMatthew G. Knepley ierr = (*sp->ops->destroy)(sp);CHKERRQ(ierr); 64229d8e7bcSMatthew G. Knepley sp->ops->destroy = NULL; 64329d8e7bcSMatthew G. Knepley } 64429d8e7bcSMatthew G. Knepley ierr = (*r)(sp);CHKERRQ(ierr); 64529d8e7bcSMatthew G. Knepley ierr = PetscObjectChangeTypeName((PetscObject) sp, name);CHKERRQ(ierr); 64629d8e7bcSMatthew G. Knepley PetscFunctionReturn(0); 64729d8e7bcSMatthew G. Knepley } 64829d8e7bcSMatthew G. Knepley 64929d8e7bcSMatthew G. Knepley #undef __FUNCT__ 65029d8e7bcSMatthew G. Knepley #define __FUNCT__ "PetscSpaceGetType" 65129d8e7bcSMatthew G. Knepley /*@C 65229d8e7bcSMatthew G. Knepley PetscSpaceGetType - Gets the PetscSpace type name (as a string) from the object. 65329d8e7bcSMatthew G. Knepley 65429d8e7bcSMatthew G. Knepley Not Collective 65529d8e7bcSMatthew G. Knepley 65629d8e7bcSMatthew G. Knepley Input Parameter: 65729d8e7bcSMatthew G. Knepley . dm - The PetscSpace 65829d8e7bcSMatthew G. Knepley 65929d8e7bcSMatthew G. Knepley Output Parameter: 66029d8e7bcSMatthew G. Knepley . name - The PetscSpace type name 66129d8e7bcSMatthew G. Knepley 66229d8e7bcSMatthew G. Knepley Level: intermediate 66329d8e7bcSMatthew G. Knepley 66429d8e7bcSMatthew G. Knepley .keywords: PetscSpace, get, type, name 66529d8e7bcSMatthew G. Knepley .seealso: PetscSpaceSetType(), PetscSpaceCreate() 66629d8e7bcSMatthew G. Knepley @*/ 66729d8e7bcSMatthew G. Knepley PetscErrorCode PetscSpaceGetType(PetscSpace sp, PetscSpaceType *name) 66829d8e7bcSMatthew G. Knepley { 66929d8e7bcSMatthew G. Knepley PetscErrorCode ierr; 67029d8e7bcSMatthew G. Knepley 67129d8e7bcSMatthew G. Knepley PetscFunctionBegin; 67229d8e7bcSMatthew G. Knepley PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 67329d8e7bcSMatthew G. Knepley PetscValidCharPointer(name, 2); 67429d8e7bcSMatthew G. Knepley if (!PetscSpaceRegisterAllCalled) { 67529d8e7bcSMatthew G. Knepley ierr = PetscSpaceRegisterAll();CHKERRQ(ierr); 67629d8e7bcSMatthew G. Knepley } 67729d8e7bcSMatthew G. Knepley *name = ((PetscObject) sp)->type_name; 67829d8e7bcSMatthew G. Knepley PetscFunctionReturn(0); 67929d8e7bcSMatthew G. Knepley } 68029d8e7bcSMatthew G. Knepley 68129d8e7bcSMatthew G. Knepley #undef __FUNCT__ 68229d8e7bcSMatthew G. Knepley #define __FUNCT__ "PetscSpaceView" 68329d8e7bcSMatthew G. Knepley /*@C 68429d8e7bcSMatthew G. Knepley PetscSpaceView - Views a PetscSpace 68529d8e7bcSMatthew G. Knepley 68629d8e7bcSMatthew G. Knepley Collective on PetscSpace 68729d8e7bcSMatthew G. Knepley 68829d8e7bcSMatthew G. Knepley Input Parameter: 68929d8e7bcSMatthew G. Knepley + sp - the PetscSpace object to view 69029d8e7bcSMatthew G. Knepley - v - the viewer 69129d8e7bcSMatthew G. Knepley 69229d8e7bcSMatthew G. Knepley Level: developer 69329d8e7bcSMatthew G. Knepley 69429d8e7bcSMatthew G. Knepley .seealso PetscSpaceDestroy() 69529d8e7bcSMatthew G. Knepley @*/ 69629d8e7bcSMatthew G. Knepley PetscErrorCode PetscSpaceView(PetscSpace sp, PetscViewer v) 69729d8e7bcSMatthew G. Knepley { 69829d8e7bcSMatthew G. Knepley PetscErrorCode ierr; 69929d8e7bcSMatthew G. Knepley 70029d8e7bcSMatthew G. Knepley PetscFunctionBegin; 70129d8e7bcSMatthew G. Knepley PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 70229d8e7bcSMatthew G. Knepley if (!v) { 70329d8e7bcSMatthew G. Knepley ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject) sp), &v);CHKERRQ(ierr); 70429d8e7bcSMatthew G. Knepley } 70529d8e7bcSMatthew G. Knepley if (sp->ops->view) { 70629d8e7bcSMatthew G. Knepley ierr = (*sp->ops->view)(sp, v);CHKERRQ(ierr); 70729d8e7bcSMatthew G. Knepley } 70829d8e7bcSMatthew G. Knepley PetscFunctionReturn(0); 70929d8e7bcSMatthew G. Knepley } 71029d8e7bcSMatthew G. Knepley 71129d8e7bcSMatthew G. Knepley #undef __FUNCT__ 71229d8e7bcSMatthew G. Knepley #define __FUNCT__ "PetscSpaceViewFromOptions" 71329d8e7bcSMatthew G. Knepley /* 71429d8e7bcSMatthew G. Knepley PetscSpaceViewFromOptions - Processes command line options to determine if/how a PetscSpace is to be viewed. 71529d8e7bcSMatthew G. Knepley 71629d8e7bcSMatthew G. Knepley Collective on PetscSpace 71729d8e7bcSMatthew G. Knepley 71829d8e7bcSMatthew G. Knepley Input Parameters: 71929d8e7bcSMatthew G. Knepley + sp - the PetscSpace 72029d8e7bcSMatthew G. Knepley . prefix - prefix to use for viewing, or NULL to use prefix of 'rnd' 72129d8e7bcSMatthew G. Knepley - optionname - option to activate viewing 72229d8e7bcSMatthew G. Knepley 72329d8e7bcSMatthew G. Knepley Level: intermediate 72429d8e7bcSMatthew G. Knepley 72529d8e7bcSMatthew G. Knepley .keywords: PetscSpace, view, options, database 72629d8e7bcSMatthew G. Knepley .seealso: VecViewFromOptions(), MatViewFromOptions() 72729d8e7bcSMatthew G. Knepley */ 72829d8e7bcSMatthew G. Knepley PetscErrorCode PetscSpaceViewFromOptions(PetscSpace sp, const char prefix[], const char optionname[]) 72929d8e7bcSMatthew G. Knepley { 73029d8e7bcSMatthew G. Knepley PetscViewer viewer; 73129d8e7bcSMatthew G. Knepley PetscViewerFormat format; 73229d8e7bcSMatthew G. Knepley PetscBool flg; 73329d8e7bcSMatthew G. Knepley PetscErrorCode ierr; 73429d8e7bcSMatthew G. Knepley 73529d8e7bcSMatthew G. Knepley PetscFunctionBegin; 73629d8e7bcSMatthew G. Knepley if (prefix) { 73729d8e7bcSMatthew G. Knepley ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject) sp), prefix, optionname, &viewer, &format, &flg);CHKERRQ(ierr); 73829d8e7bcSMatthew G. Knepley } else { 73929d8e7bcSMatthew G. Knepley ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject) sp), ((PetscObject) sp)->prefix, optionname, &viewer, &format, &flg);CHKERRQ(ierr); 74029d8e7bcSMatthew G. Knepley } 74129d8e7bcSMatthew G. Knepley if (flg) { 74229d8e7bcSMatthew G. Knepley ierr = PetscViewerPushFormat(viewer, format);CHKERRQ(ierr); 74329d8e7bcSMatthew G. Knepley ierr = PetscSpaceView(sp, viewer);CHKERRQ(ierr); 74429d8e7bcSMatthew G. Knepley ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 74529d8e7bcSMatthew G. Knepley ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 74629d8e7bcSMatthew G. Knepley } 74729d8e7bcSMatthew G. Knepley PetscFunctionReturn(0); 74829d8e7bcSMatthew G. Knepley } 74929d8e7bcSMatthew G. Knepley 75029d8e7bcSMatthew G. Knepley #undef __FUNCT__ 75129d8e7bcSMatthew G. Knepley #define __FUNCT__ "PetscSpaceSetFromOptions" 75229d8e7bcSMatthew G. Knepley /*@ 75329d8e7bcSMatthew G. Knepley PetscSpaceSetFromOptions - sets parameters in a PetscSpace from the options database 75429d8e7bcSMatthew G. Knepley 75529d8e7bcSMatthew G. Knepley Collective on PetscSpace 75629d8e7bcSMatthew G. Knepley 75729d8e7bcSMatthew G. Knepley Input Parameter: 75829d8e7bcSMatthew G. Knepley . sp - the PetscSpace object to set options for 75929d8e7bcSMatthew G. Knepley 76029d8e7bcSMatthew G. Knepley Options Database: 76129d8e7bcSMatthew G. Knepley . -petscspace_order the approximation order of the space 76229d8e7bcSMatthew G. Knepley 76329d8e7bcSMatthew G. Knepley Level: developer 76429d8e7bcSMatthew G. Knepley 76529d8e7bcSMatthew G. Knepley .seealso PetscSpaceView() 76629d8e7bcSMatthew G. Knepley @*/ 76729d8e7bcSMatthew G. Knepley PetscErrorCode PetscSpaceSetFromOptions(PetscSpace sp) 76829d8e7bcSMatthew G. Knepley { 76929d8e7bcSMatthew G. Knepley const char *defaultType; 770*2025ba63SMatthew G. Knepley char name[256]; 77129d8e7bcSMatthew G. Knepley PetscBool flg; 77229d8e7bcSMatthew G. Knepley PetscErrorCode ierr; 77329d8e7bcSMatthew G. Knepley 77429d8e7bcSMatthew G. Knepley PetscFunctionBegin; 77529d8e7bcSMatthew G. Knepley PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 77629d8e7bcSMatthew G. Knepley if (!((PetscObject) sp)->type_name) { 77729d8e7bcSMatthew G. Knepley defaultType = PETSCSPACEPOLYNOMIAL; 77829d8e7bcSMatthew G. Knepley } else { 77929d8e7bcSMatthew G. Knepley defaultType = ((PetscObject) sp)->type_name; 78029d8e7bcSMatthew G. Knepley } 78129d8e7bcSMatthew G. Knepley if (!PetscSpaceRegisterAllCalled) {ierr = PetscSpaceRegisterAll();CHKERRQ(ierr);} 78229d8e7bcSMatthew G. Knepley 78329d8e7bcSMatthew G. Knepley ierr = PetscObjectOptionsBegin((PetscObject) sp);CHKERRQ(ierr); 784*2025ba63SMatthew G. Knepley ierr = PetscOptionsList("-petscspace_type", "Linear space", "PetscSpaceSetType", PetscSpaceList, defaultType, name, 256, &flg);CHKERRQ(ierr); 78529d8e7bcSMatthew G. Knepley if (flg) { 786*2025ba63SMatthew G. Knepley ierr = PetscSpaceSetType(sp, name);CHKERRQ(ierr); 78729d8e7bcSMatthew G. Knepley } else if (!((PetscObject) sp)->type_name) { 78829d8e7bcSMatthew G. Knepley ierr = PetscSpaceSetType(sp, defaultType);CHKERRQ(ierr); 78929d8e7bcSMatthew G. Knepley } 79029d8e7bcSMatthew G. Knepley ierr = PetscOptionsInt("-petscspace_order", "The approximation order", "PetscSpaceSetOrder", sp->order, &sp->order, NULL);CHKERRQ(ierr); 79129d8e7bcSMatthew G. Knepley if (sp->ops->setfromoptions) { 79229d8e7bcSMatthew G. Knepley ierr = (*sp->ops->setfromoptions)(sp);CHKERRQ(ierr); 79329d8e7bcSMatthew G. Knepley } 79429d8e7bcSMatthew G. Knepley /* process any options handlers added with PetscObjectAddOptionsHandler() */ 79529d8e7bcSMatthew G. Knepley ierr = PetscObjectProcessOptionsHandlers((PetscObject) sp);CHKERRQ(ierr); 79629d8e7bcSMatthew G. Knepley ierr = PetscOptionsEnd();CHKERRQ(ierr); 79729d8e7bcSMatthew G. Knepley ierr = PetscSpaceViewFromOptions(sp, NULL, "-petscspace_view");CHKERRQ(ierr); 79829d8e7bcSMatthew G. Knepley PetscFunctionReturn(0); 79929d8e7bcSMatthew G. Knepley } 80029d8e7bcSMatthew G. Knepley 80129d8e7bcSMatthew G. Knepley #undef __FUNCT__ 80229d8e7bcSMatthew G. Knepley #define __FUNCT__ "PetscSpaceSetUp" 80329d8e7bcSMatthew G. Knepley /*@C 80429d8e7bcSMatthew G. Knepley PetscSpaceSetUp - Construct data structures for the PetscSpace 80529d8e7bcSMatthew G. Knepley 80629d8e7bcSMatthew G. Knepley Collective on PetscSpace 80729d8e7bcSMatthew G. Knepley 80829d8e7bcSMatthew G. Knepley Input Parameter: 80929d8e7bcSMatthew G. Knepley . sp - the PetscSpace object to setup 81029d8e7bcSMatthew G. Knepley 81129d8e7bcSMatthew G. Knepley Level: developer 81229d8e7bcSMatthew G. Knepley 81329d8e7bcSMatthew G. Knepley .seealso PetscSpaceView(), PetscSpaceDestroy() 81429d8e7bcSMatthew G. Knepley @*/ 81529d8e7bcSMatthew G. Knepley PetscErrorCode PetscSpaceSetUp(PetscSpace sp) 81629d8e7bcSMatthew G. Knepley { 81729d8e7bcSMatthew G. Knepley PetscErrorCode ierr; 81829d8e7bcSMatthew G. Knepley 81929d8e7bcSMatthew G. Knepley PetscFunctionBegin; 82029d8e7bcSMatthew G. Knepley PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 82129d8e7bcSMatthew G. Knepley if (sp->ops->setup) {ierr = (*sp->ops->setup)(sp);CHKERRQ(ierr);} 82229d8e7bcSMatthew G. Knepley PetscFunctionReturn(0); 82329d8e7bcSMatthew G. Knepley } 82429d8e7bcSMatthew G. Knepley 82529d8e7bcSMatthew G. Knepley #undef __FUNCT__ 82629d8e7bcSMatthew G. Knepley #define __FUNCT__ "PetscSpaceDestroy" 82729d8e7bcSMatthew G. Knepley /*@ 82829d8e7bcSMatthew G. Knepley PetscSpaceDestroy - Destroys a PetscSpace object 82929d8e7bcSMatthew G. Knepley 83029d8e7bcSMatthew G. Knepley Collective on PetscSpace 83129d8e7bcSMatthew G. Knepley 83229d8e7bcSMatthew G. Knepley Input Parameter: 83329d8e7bcSMatthew G. Knepley . sp - the PetscSpace object to destroy 83429d8e7bcSMatthew G. Knepley 83529d8e7bcSMatthew G. Knepley Level: developer 83629d8e7bcSMatthew G. Knepley 83729d8e7bcSMatthew G. Knepley .seealso PetscSpaceView() 83829d8e7bcSMatthew G. Knepley @*/ 83929d8e7bcSMatthew G. Knepley PetscErrorCode PetscSpaceDestroy(PetscSpace *sp) 84029d8e7bcSMatthew G. Knepley { 84129d8e7bcSMatthew G. Knepley PetscErrorCode ierr; 84229d8e7bcSMatthew G. Knepley 84329d8e7bcSMatthew G. Knepley PetscFunctionBegin; 84429d8e7bcSMatthew G. Knepley if (!*sp) PetscFunctionReturn(0); 84529d8e7bcSMatthew G. Knepley PetscValidHeaderSpecific((*sp), PETSCSPACE_CLASSID, 1); 84629d8e7bcSMatthew G. Knepley 84729d8e7bcSMatthew G. Knepley if (--((PetscObject)(*sp))->refct > 0) {*sp = 0; PetscFunctionReturn(0);} 84829d8e7bcSMatthew G. Knepley ((PetscObject) (*sp))->refct = 0; 84929d8e7bcSMatthew G. Knepley /* if memory was published with AMS then destroy it */ 85029d8e7bcSMatthew G. Knepley ierr = PetscObjectAMSViewOff((PetscObject) *sp);CHKERRQ(ierr); 85129d8e7bcSMatthew G. Knepley 85229d8e7bcSMatthew G. Knepley ierr = DMDestroy(&(*sp)->dm);CHKERRQ(ierr); 85329d8e7bcSMatthew G. Knepley 85429d8e7bcSMatthew G. Knepley ierr = (*(*sp)->ops->destroy)(*sp);CHKERRQ(ierr); 85529d8e7bcSMatthew G. Knepley ierr = PetscHeaderDestroy(sp);CHKERRQ(ierr); 85629d8e7bcSMatthew G. Knepley PetscFunctionReturn(0); 85729d8e7bcSMatthew G. Knepley } 85829d8e7bcSMatthew G. Knepley 85929d8e7bcSMatthew G. Knepley #undef __FUNCT__ 86029d8e7bcSMatthew G. Knepley #define __FUNCT__ "PetscSpaceCreate" 86129d8e7bcSMatthew G. Knepley /*@ 86229d8e7bcSMatthew G. Knepley PetscSpaceCreate - Creates an empty PetscSpace object. The type can then be set with PetscSpaceSetType(). 86329d8e7bcSMatthew G. Knepley 86429d8e7bcSMatthew G. Knepley Collective on MPI_Comm 86529d8e7bcSMatthew G. Knepley 86629d8e7bcSMatthew G. Knepley Input Parameter: 86729d8e7bcSMatthew G. Knepley . comm - The communicator for the PetscSpace object 86829d8e7bcSMatthew G. Knepley 86929d8e7bcSMatthew G. Knepley Output Parameter: 87029d8e7bcSMatthew G. Knepley . sp - The PetscSpace object 87129d8e7bcSMatthew G. Knepley 87229d8e7bcSMatthew G. Knepley Level: beginner 87329d8e7bcSMatthew G. Knepley 87429d8e7bcSMatthew G. Knepley .seealso: PetscSpaceSetType(), PETSCSPACEPOLYNOMIAL 87529d8e7bcSMatthew G. Knepley @*/ 87629d8e7bcSMatthew G. Knepley PetscErrorCode PetscSpaceCreate(MPI_Comm comm, PetscSpace *sp) 87729d8e7bcSMatthew G. Knepley { 87829d8e7bcSMatthew G. Knepley PetscSpace s; 87929d8e7bcSMatthew G. Knepley PetscErrorCode ierr; 88029d8e7bcSMatthew G. Knepley 88129d8e7bcSMatthew G. Knepley PetscFunctionBegin; 88229d8e7bcSMatthew G. Knepley PetscValidPointer(sp, 2); 88329d8e7bcSMatthew G. Knepley *sp = NULL; 88429d8e7bcSMatthew G. Knepley #if !defined(PETSC_USE_DYNAMIC_LIBRARIES) 88529d8e7bcSMatthew G. Knepley ierr = PetscFEInitializePackage();CHKERRQ(ierr); 88629d8e7bcSMatthew G. Knepley #endif 88729d8e7bcSMatthew G. Knepley 88829d8e7bcSMatthew G. Knepley ierr = PetscHeaderCreate(s, _p_PetscSpace, struct _PetscSpaceOps, PETSCSPACE_CLASSID, "PetscSpace", "Linear Space", "PetscSpace", comm, PetscSpaceDestroy, PetscSpaceView);CHKERRQ(ierr); 88929d8e7bcSMatthew G. Knepley ierr = PetscMemzero(s->ops, sizeof(struct _PetscSpaceOps));CHKERRQ(ierr); 89029d8e7bcSMatthew G. Knepley 89129d8e7bcSMatthew G. Knepley s->order = 0; 89229d8e7bcSMatthew G. Knepley ierr = DMShellCreate(comm, &s->dm);CHKERRQ(ierr); 89329d8e7bcSMatthew G. Knepley 89429d8e7bcSMatthew G. Knepley *sp = s; 89529d8e7bcSMatthew G. Knepley PetscFunctionReturn(0); 89629d8e7bcSMatthew G. Knepley } 89729d8e7bcSMatthew G. Knepley 89829d8e7bcSMatthew G. Knepley #undef __FUNCT__ 89929d8e7bcSMatthew G. Knepley #define __FUNCT__ "PetscSpaceGetDimension" 90029d8e7bcSMatthew G. Knepley /* Dimension of the space, i.e. number of basis vectors */ 90129d8e7bcSMatthew G. Knepley PetscErrorCode PetscSpaceGetDimension(PetscSpace sp, PetscInt *dim) 90229d8e7bcSMatthew G. Knepley { 90329d8e7bcSMatthew G. Knepley PetscErrorCode ierr; 90429d8e7bcSMatthew G. Knepley 90529d8e7bcSMatthew G. Knepley PetscFunctionBegin; 90629d8e7bcSMatthew G. Knepley PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 90729d8e7bcSMatthew G. Knepley PetscValidPointer(dim, 2); 90829d8e7bcSMatthew G. Knepley *dim = 0; 90929d8e7bcSMatthew G. Knepley if (sp->ops->getdimension) {ierr = (*sp->ops->getdimension)(sp, dim);CHKERRQ(ierr);} 91029d8e7bcSMatthew G. Knepley PetscFunctionReturn(0); 91129d8e7bcSMatthew G. Knepley } 91229d8e7bcSMatthew G. Knepley 91329d8e7bcSMatthew G. Knepley #undef __FUNCT__ 91429d8e7bcSMatthew G. Knepley #define __FUNCT__ "PetscSpaceGetOrder" 91529d8e7bcSMatthew G. Knepley PetscErrorCode PetscSpaceGetOrder(PetscSpace sp, PetscInt *order) 91629d8e7bcSMatthew G. Knepley { 91729d8e7bcSMatthew G. Knepley PetscFunctionBegin; 91829d8e7bcSMatthew G. Knepley PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 91929d8e7bcSMatthew G. Knepley PetscValidPointer(order, 2); 92029d8e7bcSMatthew G. Knepley *order = sp->order; 92129d8e7bcSMatthew G. Knepley PetscFunctionReturn(0); 92229d8e7bcSMatthew G. Knepley } 92329d8e7bcSMatthew G. Knepley 92429d8e7bcSMatthew G. Knepley #undef __FUNCT__ 92529d8e7bcSMatthew G. Knepley #define __FUNCT__ "PetscSpaceSetOrder" 92629d8e7bcSMatthew G. Knepley PetscErrorCode PetscSpaceSetOrder(PetscSpace sp, PetscInt order) 92729d8e7bcSMatthew G. Knepley { 92829d8e7bcSMatthew G. Knepley PetscFunctionBegin; 92929d8e7bcSMatthew G. Knepley PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 93029d8e7bcSMatthew G. Knepley sp->order = order; 93129d8e7bcSMatthew G. Knepley PetscFunctionReturn(0); 93229d8e7bcSMatthew G. Knepley } 93329d8e7bcSMatthew G. Knepley 93429d8e7bcSMatthew G. Knepley #undef __FUNCT__ 93529d8e7bcSMatthew G. Knepley #define __FUNCT__ "PetscSpaceEvaluate" 93629d8e7bcSMatthew G. Knepley PetscErrorCode PetscSpaceEvaluate(PetscSpace sp, PetscInt npoints, const PetscReal points[], PetscReal B[], PetscReal D[], PetscReal H[]) 93729d8e7bcSMatthew G. Knepley { 93829d8e7bcSMatthew G. Knepley PetscErrorCode ierr; 93929d8e7bcSMatthew G. Knepley 94029d8e7bcSMatthew G. Knepley PetscFunctionBegin; 94129d8e7bcSMatthew G. Knepley PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 94229d8e7bcSMatthew G. Knepley PetscValidPointer(points, 3); 94329d8e7bcSMatthew G. Knepley if (B) PetscValidPointer(B, 4); 94429d8e7bcSMatthew G. Knepley if (D) PetscValidPointer(D, 5); 94529d8e7bcSMatthew G. Knepley if (H) PetscValidPointer(H, 6); 94629d8e7bcSMatthew G. Knepley if (sp->ops->evaluate) {ierr = (*sp->ops->evaluate)(sp, npoints, points, B, D, H);CHKERRQ(ierr);} 94729d8e7bcSMatthew G. Knepley PetscFunctionReturn(0); 94829d8e7bcSMatthew G. Knepley } 94929d8e7bcSMatthew G. Knepley 95029d8e7bcSMatthew G. Knepley #undef __FUNCT__ 95129d8e7bcSMatthew G. Knepley #define __FUNCT__ "PetscSpaceSetFromOptions_Polynomial" 95229d8e7bcSMatthew G. Knepley PetscErrorCode PetscSpaceSetFromOptions_Polynomial(PetscSpace sp) 95329d8e7bcSMatthew G. Knepley { 95429d8e7bcSMatthew G. Knepley PetscSpace_Poly *poly = (PetscSpace_Poly *) sp->data; 95529d8e7bcSMatthew G. Knepley PetscErrorCode ierr; 95629d8e7bcSMatthew G. Knepley 95729d8e7bcSMatthew G. Knepley PetscFunctionBegin; 95829d8e7bcSMatthew G. Knepley ierr = PetscObjectOptionsBegin((PetscObject) sp);CHKERRQ(ierr); 95929d8e7bcSMatthew G. Knepley ierr = PetscOptionsInt("-petscspace_num_variables", "The number of different variables, e.g. x and y", "PetscSpacePolynomialSetNumVariables", poly->numVariables, &poly->numVariables, NULL);CHKERRQ(ierr); 96029d8e7bcSMatthew G. Knepley ierr = PetscOptionsBool("-petscspace_poly_sym", "Use only symmetric polynomials", "PetscSpacePolynomialSetSymmetric", poly->symmetric, &poly->symmetric, NULL);CHKERRQ(ierr); 96129d8e7bcSMatthew G. Knepley ierr = PetscOptionsEnd();CHKERRQ(ierr); 96229d8e7bcSMatthew G. Knepley PetscFunctionReturn(0); 96329d8e7bcSMatthew G. Knepley } 96429d8e7bcSMatthew G. Knepley 96529d8e7bcSMatthew G. Knepley #undef __FUNCT__ 96629d8e7bcSMatthew G. Knepley #define __FUNCT__ "PetscSpacePolynomialView_Ascii" 96729d8e7bcSMatthew G. Knepley PetscErrorCode PetscSpacePolynomialView_Ascii(PetscSpace sp, PetscViewer viewer) 96829d8e7bcSMatthew G. Knepley { 96929d8e7bcSMatthew G. Knepley PetscSpace_Poly *poly = (PetscSpace_Poly *) sp->data; 97029d8e7bcSMatthew G. Knepley PetscViewerFormat format; 97129d8e7bcSMatthew G. Knepley PetscErrorCode ierr; 97229d8e7bcSMatthew G. Knepley 97329d8e7bcSMatthew G. Knepley PetscFunctionBegin; 97429d8e7bcSMatthew G. Knepley ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 97529d8e7bcSMatthew G. Knepley if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 97629d8e7bcSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "Polynomial space in %d variables of order %d", poly->numVariables, sp->order);CHKERRQ(ierr); 97729d8e7bcSMatthew G. Knepley } else { 97829d8e7bcSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "Polynomial space in %d variables of order %d", poly->numVariables, sp->order);CHKERRQ(ierr); 97929d8e7bcSMatthew G. Knepley } 98029d8e7bcSMatthew G. Knepley PetscFunctionReturn(0); 98129d8e7bcSMatthew G. Knepley } 98229d8e7bcSMatthew G. Knepley 98329d8e7bcSMatthew G. Knepley #undef __FUNCT__ 98429d8e7bcSMatthew G. Knepley #define __FUNCT__ "PetscSpaceView_Polynomial" 98529d8e7bcSMatthew G. Knepley PetscErrorCode PetscSpaceView_Polynomial(PetscSpace sp, PetscViewer viewer) 98629d8e7bcSMatthew G. Knepley { 98729d8e7bcSMatthew G. Knepley PetscBool iascii; 98829d8e7bcSMatthew G. Knepley PetscErrorCode ierr; 98929d8e7bcSMatthew G. Knepley 99029d8e7bcSMatthew G. Knepley PetscFunctionBegin; 99129d8e7bcSMatthew G. Knepley PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 99229d8e7bcSMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 99329d8e7bcSMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr); 99429d8e7bcSMatthew G. Knepley if (iascii) {ierr = PetscSpacePolynomialView_Ascii(sp, viewer);CHKERRQ(ierr);} 99529d8e7bcSMatthew G. Knepley PetscFunctionReturn(0); 99629d8e7bcSMatthew G. Knepley } 99729d8e7bcSMatthew G. Knepley 99829d8e7bcSMatthew G. Knepley #undef __FUNCT__ 99929d8e7bcSMatthew G. Knepley #define __FUNCT__ "PetscSpaceSetUp_Polynomial" 100029d8e7bcSMatthew G. Knepley PetscErrorCode PetscSpaceSetUp_Polynomial(PetscSpace sp) 100129d8e7bcSMatthew G. Knepley { 100229d8e7bcSMatthew G. Knepley PetscSpace_Poly *poly = (PetscSpace_Poly *) sp->data; 100329d8e7bcSMatthew G. Knepley PetscInt ndegree = sp->order+1; 100405d1e344SMatthew G. Knepley PetscInt deg; 100529d8e7bcSMatthew G. Knepley PetscErrorCode ierr; 100629d8e7bcSMatthew G. Knepley 100729d8e7bcSMatthew G. Knepley PetscFunctionBegin; 100829d8e7bcSMatthew G. Knepley ierr = PetscMalloc(ndegree * sizeof(PetscInt), &poly->degrees);CHKERRQ(ierr); 100929d8e7bcSMatthew G. Knepley for (deg = 0; deg < ndegree; ++deg) poly->degrees[deg] = deg; 101029d8e7bcSMatthew G. Knepley PetscFunctionReturn(0); 101129d8e7bcSMatthew G. Knepley } 101229d8e7bcSMatthew G. Knepley 101329d8e7bcSMatthew G. Knepley #undef __FUNCT__ 101429d8e7bcSMatthew G. Knepley #define __FUNCT__ "PetscSpaceDestroy_Polynomial" 101529d8e7bcSMatthew G. Knepley PetscErrorCode PetscSpaceDestroy_Polynomial(PetscSpace sp) 101629d8e7bcSMatthew G. Knepley { 101729d8e7bcSMatthew G. Knepley PetscSpace_Poly *poly = (PetscSpace_Poly *) sp->data; 101829d8e7bcSMatthew G. Knepley PetscErrorCode ierr; 101929d8e7bcSMatthew G. Knepley 102029d8e7bcSMatthew G. Knepley PetscFunctionBegin; 102129d8e7bcSMatthew G. Knepley ierr = PetscFree(poly->degrees);CHKERRQ(ierr); 102229d8e7bcSMatthew G. Knepley ierr = PetscFree(poly);CHKERRQ(ierr); 102329d8e7bcSMatthew G. Knepley PetscFunctionReturn(0); 102429d8e7bcSMatthew G. Knepley } 102529d8e7bcSMatthew G. Knepley 102629d8e7bcSMatthew G. Knepley #undef __FUNCT__ 102729d8e7bcSMatthew G. Knepley #define __FUNCT__ "PetscSpaceGetDimension_Polynomial" 102829d8e7bcSMatthew G. Knepley PetscErrorCode PetscSpaceGetDimension_Polynomial(PetscSpace sp, PetscInt *dim) 102929d8e7bcSMatthew G. Knepley { 103029d8e7bcSMatthew G. Knepley PetscSpace_Poly *poly = (PetscSpace_Poly *) sp->data; 103129d8e7bcSMatthew G. Knepley PetscInt deg = sp->order; 103229d8e7bcSMatthew G. Knepley PetscInt n = poly->numVariables, i; 103329d8e7bcSMatthew G. Knepley PetscReal D = 1.0; 103429d8e7bcSMatthew G. Knepley 103529d8e7bcSMatthew G. Knepley PetscFunctionBegin; 103629d8e7bcSMatthew G. Knepley for (i = 1; i <= n; ++i) { 103729d8e7bcSMatthew G. Knepley D *= ((PetscReal) (deg+i))/i; 103829d8e7bcSMatthew G. Knepley } 103929d8e7bcSMatthew G. Knepley *dim = (PetscInt) (D + 0.5); 104029d8e7bcSMatthew G. Knepley PetscFunctionReturn(0); 104129d8e7bcSMatthew G. Knepley } 104229d8e7bcSMatthew G. Knepley 104329d8e7bcSMatthew G. Knepley #undef __FUNCT__ 10443dc9baa2SMatthew G. Knepley #define __FUNCT__ "LatticePoint_Internal" 10453dc9baa2SMatthew G. Knepley /* 10463dc9baa2SMatthew G. Knepley LatticePoint_Internal - Returns all tuples of size 'len' with nonnegative integers that sum up to 'sum'. 10473dc9baa2SMatthew G. Knepley 10483dc9baa2SMatthew G. Knepley Input Parameters: 10493dc9baa2SMatthew G. Knepley + len - The length of the tuple 10503dc9baa2SMatthew G. Knepley . sum - The sum of all entries in the tuple 10513dc9baa2SMatthew G. Knepley - ind - The current multi-index of the tuple, initialized to the 0 tuple 10523dc9baa2SMatthew G. Knepley 10533dc9baa2SMatthew G. Knepley Output Parameter: 10543dc9baa2SMatthew G. Knepley + ind - The multi-index of the tuple, -1 indicates the iteration has terminated 10553dc9baa2SMatthew G. Knepley . tup - A tuple of len integers addig to sum 10563dc9baa2SMatthew G. Knepley 10573dc9baa2SMatthew G. Knepley Level: developer 10583dc9baa2SMatthew G. Knepley 10593dc9baa2SMatthew G. Knepley .seealso: 10603dc9baa2SMatthew G. Knepley */ 10613dc9baa2SMatthew G. Knepley static PetscErrorCode LatticePoint_Internal(PetscInt len, PetscInt sum, PetscInt ind[], PetscInt tup[]) 10623dc9baa2SMatthew G. Knepley { 10633dc9baa2SMatthew G. Knepley PetscInt i; 10643dc9baa2SMatthew G. Knepley PetscErrorCode ierr; 10653dc9baa2SMatthew G. Knepley 10663dc9baa2SMatthew G. Knepley PetscFunctionBegin; 10673dc9baa2SMatthew G. Knepley if (len == 1) { 10683dc9baa2SMatthew G. Knepley ind[0] = -1; 10693dc9baa2SMatthew G. Knepley tup[0] = sum; 10703dc9baa2SMatthew G. Knepley } else if (sum == 0) { 10713dc9baa2SMatthew G. Knepley for (i = 0; i < len; ++i) {ind[0] = -1; tup[i] = 0;} 10723dc9baa2SMatthew G. Knepley } else { 10733dc9baa2SMatthew G. Knepley tup[0] = sum - ind[0]; 10743dc9baa2SMatthew G. Knepley ierr = LatticePoint_Internal(len-1, ind[0], &ind[1], &tup[1]);CHKERRQ(ierr); 10753dc9baa2SMatthew G. Knepley if (ind[1] < 0) { 10763dc9baa2SMatthew G. Knepley if (ind[0] == sum) {ind[0] = -1;} 10773dc9baa2SMatthew G. Knepley else {ind[1] = 0; ++ind[0];} 10783dc9baa2SMatthew G. Knepley } 10793dc9baa2SMatthew G. Knepley } 10803dc9baa2SMatthew G. Knepley PetscFunctionReturn(0); 10813dc9baa2SMatthew G. Knepley } 10823dc9baa2SMatthew G. Knepley 10833dc9baa2SMatthew G. Knepley #undef __FUNCT__ 108429d8e7bcSMatthew G. Knepley #define __FUNCT__ "PetscSpaceEvaluate_Polynomial" 108529d8e7bcSMatthew G. Knepley PetscErrorCode PetscSpaceEvaluate_Polynomial(PetscSpace sp, PetscInt npoints, const PetscReal points[], PetscReal B[], PetscReal D[], PetscReal H[]) 108629d8e7bcSMatthew G. Knepley { 108729d8e7bcSMatthew G. Knepley PetscSpace_Poly *poly = (PetscSpace_Poly *) sp->data; 108829d8e7bcSMatthew G. Knepley DM dm = sp->dm; 108929d8e7bcSMatthew G. Knepley PetscInt ndegree = sp->order+1; 109029d8e7bcSMatthew G. Knepley PetscInt *degrees = poly->degrees; 109129d8e7bcSMatthew G. Knepley PetscInt dim = poly->numVariables; 109229d8e7bcSMatthew G. Knepley PetscReal *lpoints, *tmp, *LB, *LD, *LH; 10933dc9baa2SMatthew G. Knepley PetscInt *ind, *tup; 109407d6ad7fSMatthew G. Knepley PetscInt pdim, d, der, i, p, deg, o; 109529d8e7bcSMatthew G. Knepley PetscErrorCode ierr; 109629d8e7bcSMatthew G. Knepley 109729d8e7bcSMatthew G. Knepley PetscFunctionBegin; 109829d8e7bcSMatthew G. Knepley ierr = PetscSpaceGetDimension(sp, &pdim);CHKERRQ(ierr); 109929d8e7bcSMatthew G. Knepley ierr = DMGetWorkArray(dm, npoints, PETSC_REAL, &lpoints);CHKERRQ(ierr); 110029d8e7bcSMatthew G. Knepley ierr = DMGetWorkArray(dm, npoints*ndegree*3, PETSC_REAL, &tmp);CHKERRQ(ierr); 110129d8e7bcSMatthew G. Knepley if (B) {ierr = DMGetWorkArray(dm, npoints*dim*ndegree, PETSC_REAL, &LB);CHKERRQ(ierr);} 110229d8e7bcSMatthew G. Knepley if (D) {ierr = DMGetWorkArray(dm, npoints*dim*ndegree, PETSC_REAL, &LD);CHKERRQ(ierr);} 110329d8e7bcSMatthew G. Knepley if (H) {ierr = DMGetWorkArray(dm, npoints*dim*ndegree, PETSC_REAL, &LH);CHKERRQ(ierr);} 110429d8e7bcSMatthew G. Knepley for (d = 0; d < dim; ++d) { 110529d8e7bcSMatthew G. Knepley for (p = 0; p < npoints; ++p) { 110629d8e7bcSMatthew G. Knepley lpoints[p] = points[p*dim+d]; 110729d8e7bcSMatthew G. Knepley } 110829d8e7bcSMatthew G. Knepley ierr = PetscDTLegendreEval(npoints, lpoints, ndegree, degrees, tmp, &tmp[1*npoints*ndegree], &tmp[2*npoints*ndegree]);CHKERRQ(ierr); 110929d8e7bcSMatthew G. Knepley /* LB, LD, LH (ndegree * dim x npoints) */ 111029d8e7bcSMatthew G. Knepley for (deg = 0; deg < ndegree; ++deg) { 111129d8e7bcSMatthew G. Knepley for (p = 0; p < npoints; ++p) { 111229d8e7bcSMatthew G. Knepley if (B) LB[(deg*dim + d)*npoints + p] = tmp[(0*npoints + p)*ndegree+deg]; 111329d8e7bcSMatthew G. Knepley if (D) LD[(deg*dim + d)*npoints + p] = tmp[(1*npoints + p)*ndegree+deg]; 111429d8e7bcSMatthew G. Knepley if (H) LH[(deg*dim + d)*npoints + p] = tmp[(2*npoints + p)*ndegree+deg]; 111529d8e7bcSMatthew G. Knepley } 111629d8e7bcSMatthew G. Knepley } 111729d8e7bcSMatthew G. Knepley } 111829d8e7bcSMatthew G. Knepley /* Multiply by A (pdim x ndegree * dim) */ 11193dc9baa2SMatthew G. Knepley ierr = PetscMalloc2(dim,PetscInt,&ind,dim,PetscInt,&tup);CHKERRQ(ierr); 112029d8e7bcSMatthew G. Knepley if (B) { 11213dc9baa2SMatthew G. Knepley /* B (npoints x pdim) */ 11223dc9baa2SMatthew G. Knepley i = 0; 11233dc9baa2SMatthew G. Knepley for (o = 0; o <= sp->order; ++o) { 11243dc9baa2SMatthew G. Knepley ierr = PetscMemzero(ind, dim * sizeof(PetscInt));CHKERRQ(ierr); 11253dc9baa2SMatthew G. Knepley while (ind[0] >= 0) { 11263dc9baa2SMatthew G. Knepley ierr = LatticePoint_Internal(dim, o, ind, tup);CHKERRQ(ierr); 112729d8e7bcSMatthew G. Knepley for (p = 0; p < npoints; ++p) { 11283dc9baa2SMatthew G. Knepley B[p*pdim + i] = 1.0; 112929d8e7bcSMatthew G. Knepley for (d = 0; d < dim; ++d) { 11303dc9baa2SMatthew G. Knepley B[p*pdim + i] *= LB[(tup[d]*dim + d)*npoints + p]; 11313dc9baa2SMatthew G. Knepley } 11323dc9baa2SMatthew G. Knepley } 11333dc9baa2SMatthew G. Knepley ++i; 113429d8e7bcSMatthew G. Knepley } 113529d8e7bcSMatthew G. Knepley } 113629d8e7bcSMatthew G. Knepley } 113707d6ad7fSMatthew G. Knepley if (D) { 113807d6ad7fSMatthew G. Knepley /* D (npoints x pdim x dim) */ 113907d6ad7fSMatthew G. Knepley i = 0; 114007d6ad7fSMatthew G. Knepley for (o = 0; o <= sp->order; ++o) { 114107d6ad7fSMatthew G. Knepley ierr = PetscMemzero(ind, dim * sizeof(PetscInt));CHKERRQ(ierr); 114207d6ad7fSMatthew G. Knepley while (ind[0] >= 0) { 114307d6ad7fSMatthew G. Knepley ierr = LatticePoint_Internal(dim, o, ind, tup);CHKERRQ(ierr); 114407d6ad7fSMatthew G. Knepley for (p = 0; p < npoints; ++p) { 114507d6ad7fSMatthew G. Knepley for (der = 0; der < dim; ++der) { 114607d6ad7fSMatthew G. Knepley D[(p*pdim + i)*dim + der] = 1.0; 114707d6ad7fSMatthew G. Knepley for (d = 0; d < dim; ++d) { 114807d6ad7fSMatthew G. Knepley if (d == der) { 114907d6ad7fSMatthew G. Knepley D[(p*pdim + i)*dim + der] *= LD[(tup[d]*dim + d)*npoints + p]; 115007d6ad7fSMatthew G. Knepley } else { 115107d6ad7fSMatthew G. Knepley D[(p*pdim + i)*dim + der] *= LB[(tup[d]*dim + d)*npoints + p]; 115207d6ad7fSMatthew G. Knepley } 115307d6ad7fSMatthew G. Knepley } 115407d6ad7fSMatthew G. Knepley } 115507d6ad7fSMatthew G. Knepley } 115607d6ad7fSMatthew G. Knepley ++i; 115707d6ad7fSMatthew G. Knepley } 115807d6ad7fSMatthew G. Knepley } 115907d6ad7fSMatthew G. Knepley } 116029d8e7bcSMatthew G. Knepley if (H) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Too lazy to code second derivatives"); 116107d6ad7fSMatthew G. Knepley ierr = PetscFree2(ind,tup);CHKERRQ(ierr); 116229d8e7bcSMatthew G. Knepley if (B) {ierr = DMRestoreWorkArray(dm, npoints*dim*ndegree, PETSC_REAL, &LB);CHKERRQ(ierr);} 116329d8e7bcSMatthew G. Knepley if (D) {ierr = DMRestoreWorkArray(dm, npoints*dim*ndegree, PETSC_REAL, &LD);CHKERRQ(ierr);} 116429d8e7bcSMatthew G. Knepley if (H) {ierr = DMRestoreWorkArray(dm, npoints*dim*ndegree, PETSC_REAL, &LH);CHKERRQ(ierr);} 116529d8e7bcSMatthew G. Knepley ierr = DMRestoreWorkArray(dm, npoints*ndegree*3, PETSC_REAL, &tmp);CHKERRQ(ierr); 116629d8e7bcSMatthew G. Knepley ierr = DMRestoreWorkArray(dm, npoints, PETSC_REAL, &lpoints);CHKERRQ(ierr); 116729d8e7bcSMatthew G. Knepley PetscFunctionReturn(0); 116829d8e7bcSMatthew G. Knepley } 116929d8e7bcSMatthew G. Knepley 117029d8e7bcSMatthew G. Knepley #undef __FUNCT__ 117129d8e7bcSMatthew G. Knepley #define __FUNCT__ "PetscSpaceInitialize_Polynomial" 117229d8e7bcSMatthew G. Knepley PetscErrorCode PetscSpaceInitialize_Polynomial(PetscSpace sp) 117329d8e7bcSMatthew G. Knepley { 117429d8e7bcSMatthew G. Knepley PetscFunctionBegin; 117529d8e7bcSMatthew G. Knepley sp->ops->setfromoptions = PetscSpaceSetFromOptions_Polynomial; 117629d8e7bcSMatthew G. Knepley sp->ops->setup = PetscSpaceSetUp_Polynomial; 117729d8e7bcSMatthew G. Knepley sp->ops->view = PetscSpaceView_Polynomial; 117829d8e7bcSMatthew G. Knepley sp->ops->destroy = PetscSpaceDestroy_Polynomial; 117929d8e7bcSMatthew G. Knepley sp->ops->getdimension = PetscSpaceGetDimension_Polynomial; 118029d8e7bcSMatthew G. Knepley sp->ops->evaluate = PetscSpaceEvaluate_Polynomial; 118129d8e7bcSMatthew G. Knepley PetscFunctionReturn(0); 118229d8e7bcSMatthew G. Knepley } 118329d8e7bcSMatthew G. Knepley 118429d8e7bcSMatthew G. Knepley /*MC 118529d8e7bcSMatthew G. Knepley PETSCSPACEPOLYNOMIAL = "poly" - A PetscSpace object that encapsulates a polynomial space, e.g. P1 is the space of linear polynomials. 118629d8e7bcSMatthew G. Knepley 118729d8e7bcSMatthew G. Knepley Level: intermediate 118829d8e7bcSMatthew G. Knepley 118929d8e7bcSMatthew G. Knepley .seealso: PetscSpaceType, PetscSpaceCreate(), PetscSpaceSetType() 119029d8e7bcSMatthew G. Knepley M*/ 119129d8e7bcSMatthew G. Knepley 119229d8e7bcSMatthew G. Knepley #undef __FUNCT__ 119329d8e7bcSMatthew G. Knepley #define __FUNCT__ "PetscSpaceCreate_Polynomial" 119429d8e7bcSMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscSpaceCreate_Polynomial(PetscSpace sp) 119529d8e7bcSMatthew G. Knepley { 119629d8e7bcSMatthew G. Knepley PetscSpace_Poly *poly; 119729d8e7bcSMatthew G. Knepley PetscErrorCode ierr; 119829d8e7bcSMatthew G. Knepley 119929d8e7bcSMatthew G. Knepley PetscFunctionBegin; 120029d8e7bcSMatthew G. Knepley PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 120129d8e7bcSMatthew G. Knepley ierr = PetscNewLog(sp, PetscSpace_Poly, &poly);CHKERRQ(ierr); 120229d8e7bcSMatthew G. Knepley sp->data = poly; 120329d8e7bcSMatthew G. Knepley 120429d8e7bcSMatthew G. Knepley poly->numVariables = 0; 120529d8e7bcSMatthew G. Knepley poly->symmetric = PETSC_FALSE; 120629d8e7bcSMatthew G. Knepley poly->degrees = NULL; 120729d8e7bcSMatthew G. Knepley 120829d8e7bcSMatthew G. Knepley ierr = PetscSpaceInitialize_Polynomial(sp);CHKERRQ(ierr); 120929d8e7bcSMatthew G. Knepley PetscFunctionReturn(0); 121029d8e7bcSMatthew G. Knepley } 121129d8e7bcSMatthew G. Knepley 121229d8e7bcSMatthew G. Knepley #undef __FUNCT__ 121329d8e7bcSMatthew G. Knepley #define __FUNCT__ "PetscSpacePolynomialSetSymmetric" 121429d8e7bcSMatthew G. Knepley PetscErrorCode PetscSpacePolynomialSetSymmetric(PetscSpace sp, PetscBool sym) 121529d8e7bcSMatthew G. Knepley { 121629d8e7bcSMatthew G. Knepley PetscSpace_Poly *poly = (PetscSpace_Poly *) sp->data; 121729d8e7bcSMatthew G. Knepley 121829d8e7bcSMatthew G. Knepley PetscFunctionBegin; 121929d8e7bcSMatthew G. Knepley PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 122029d8e7bcSMatthew G. Knepley poly->symmetric = sym; 122129d8e7bcSMatthew G. Knepley PetscFunctionReturn(0); 122229d8e7bcSMatthew G. Knepley } 122329d8e7bcSMatthew G. Knepley 122429d8e7bcSMatthew G. Knepley #undef __FUNCT__ 122529d8e7bcSMatthew G. Knepley #define __FUNCT__ "PetscSpacePolynomialGetSymmetric" 122629d8e7bcSMatthew G. Knepley PetscErrorCode PetscSpacePolynomialGetSymmetric(PetscSpace sp, PetscBool *sym) 122729d8e7bcSMatthew G. Knepley { 122829d8e7bcSMatthew G. Knepley PetscSpace_Poly *poly = (PetscSpace_Poly *) sp->data; 122929d8e7bcSMatthew G. Knepley 123029d8e7bcSMatthew G. Knepley PetscFunctionBegin; 123129d8e7bcSMatthew G. Knepley PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 123229d8e7bcSMatthew G. Knepley PetscValidPointer(sym, 2); 123329d8e7bcSMatthew G. Knepley *sym = poly->symmetric; 123429d8e7bcSMatthew G. Knepley PetscFunctionReturn(0); 123529d8e7bcSMatthew G. Knepley } 123629d8e7bcSMatthew G. Knepley 123729d8e7bcSMatthew G. Knepley #undef __FUNCT__ 123829d8e7bcSMatthew G. Knepley #define __FUNCT__ "PetscSpacePolynomialSetNumVariables" 123929d8e7bcSMatthew G. Knepley PetscErrorCode PetscSpacePolynomialSetNumVariables(PetscSpace sp, PetscInt n) 124029d8e7bcSMatthew G. Knepley { 124129d8e7bcSMatthew G. Knepley PetscSpace_Poly *poly = (PetscSpace_Poly *) sp->data; 124229d8e7bcSMatthew G. Knepley 124329d8e7bcSMatthew G. Knepley PetscFunctionBegin; 124429d8e7bcSMatthew G. Knepley PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 124529d8e7bcSMatthew G. Knepley poly->numVariables = n; 124629d8e7bcSMatthew G. Knepley PetscFunctionReturn(0); 124729d8e7bcSMatthew G. Knepley } 124829d8e7bcSMatthew G. Knepley 124929d8e7bcSMatthew G. Knepley #undef __FUNCT__ 125029d8e7bcSMatthew G. Knepley #define __FUNCT__ "PetscSpacePolynomialGetNumVariables" 125129d8e7bcSMatthew G. Knepley PetscErrorCode PetscSpacePolynomialGetNumVariables(PetscSpace sp, PetscInt *n) 125229d8e7bcSMatthew G. Knepley { 125329d8e7bcSMatthew G. Knepley PetscSpace_Poly *poly = (PetscSpace_Poly *) sp->data; 125429d8e7bcSMatthew G. Knepley 125529d8e7bcSMatthew G. Knepley PetscFunctionBegin; 125629d8e7bcSMatthew G. Knepley PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 125729d8e7bcSMatthew G. Knepley PetscValidPointer(n, 2); 125829d8e7bcSMatthew G. Knepley *n = poly->numVariables; 125929d8e7bcSMatthew G. Knepley PetscFunctionReturn(0); 126029d8e7bcSMatthew G. Knepley } 126129d8e7bcSMatthew G. Knepley 126229d8e7bcSMatthew G. Knepley 126329d8e7bcSMatthew G. Knepley PetscInt PETSCDUALSPACE_CLASSID = 0; 126429d8e7bcSMatthew G. Knepley 126529d8e7bcSMatthew G. Knepley PetscFunctionList PetscDualSpaceList = NULL; 126629d8e7bcSMatthew G. Knepley PetscBool PetscDualSpaceRegisterAllCalled = PETSC_FALSE; 126729d8e7bcSMatthew G. Knepley 126829d8e7bcSMatthew G. Knepley #undef __FUNCT__ 126929d8e7bcSMatthew G. Knepley #define __FUNCT__ "PetscDualSpaceRegister" 127029d8e7bcSMatthew G. Knepley /*@C 127129d8e7bcSMatthew G. Knepley PetscDualSpaceRegister - Adds a new PetscDualSpace implementation 127229d8e7bcSMatthew G. Knepley 127329d8e7bcSMatthew G. Knepley Not Collective 127429d8e7bcSMatthew G. Knepley 127529d8e7bcSMatthew G. Knepley Input Parameters: 127629d8e7bcSMatthew G. Knepley + name - The name of a new user-defined creation routine 127729d8e7bcSMatthew G. Knepley - create_func - The creation routine itself 127829d8e7bcSMatthew G. Knepley 127929d8e7bcSMatthew G. Knepley Notes: 128029d8e7bcSMatthew G. Knepley PetscDualSpaceRegister() may be called multiple times to add several user-defined PetscDualSpaces 128129d8e7bcSMatthew G. Knepley 128229d8e7bcSMatthew G. Knepley Sample usage: 128329d8e7bcSMatthew G. Knepley .vb 128429d8e7bcSMatthew G. Knepley PetscDualSpaceRegister("my_space", MyPetscDualSpaceCreate); 128529d8e7bcSMatthew G. Knepley .ve 128629d8e7bcSMatthew G. Knepley 128729d8e7bcSMatthew G. Knepley Then, your PetscDualSpace type can be chosen with the procedural interface via 128829d8e7bcSMatthew G. Knepley .vb 128929d8e7bcSMatthew G. Knepley PetscDualSpaceCreate(MPI_Comm, PetscDualSpace *); 129029d8e7bcSMatthew G. Knepley PetscDualSpaceSetType(PetscDualSpace, "my_dual_space"); 129129d8e7bcSMatthew G. Knepley .ve 129229d8e7bcSMatthew G. Knepley or at runtime via the option 129329d8e7bcSMatthew G. Knepley .vb 129429d8e7bcSMatthew G. Knepley -petscdualspace_type my_dual_space 129529d8e7bcSMatthew G. Knepley .ve 129629d8e7bcSMatthew G. Knepley 129729d8e7bcSMatthew G. Knepley Level: advanced 129829d8e7bcSMatthew G. Knepley 129929d8e7bcSMatthew G. Knepley .keywords: PetscDualSpace, register 130029d8e7bcSMatthew G. Knepley .seealso: PetscDualSpaceRegisterAll(), PetscDualSpaceRegisterDestroy() 130129d8e7bcSMatthew G. Knepley 130229d8e7bcSMatthew G. Knepley @*/ 130329d8e7bcSMatthew G. Knepley PetscErrorCode PetscDualSpaceRegister(const char sname[], PetscErrorCode (*function)(PetscDualSpace)) 130429d8e7bcSMatthew G. Knepley { 130529d8e7bcSMatthew G. Knepley PetscErrorCode ierr; 130629d8e7bcSMatthew G. Knepley 130729d8e7bcSMatthew G. Knepley PetscFunctionBegin; 130829d8e7bcSMatthew G. Knepley ierr = PetscFunctionListAdd(&PetscDualSpaceList, sname, function);CHKERRQ(ierr); 130929d8e7bcSMatthew G. Knepley PetscFunctionReturn(0); 131029d8e7bcSMatthew G. Knepley } 131129d8e7bcSMatthew G. Knepley 131229d8e7bcSMatthew G. Knepley #undef __FUNCT__ 131329d8e7bcSMatthew G. Knepley #define __FUNCT__ "PetscDualSpaceSetType" 131429d8e7bcSMatthew G. Knepley /*@C 131529d8e7bcSMatthew G. Knepley PetscDualSpaceSetType - Builds a particular PetscDualSpace 131629d8e7bcSMatthew G. Knepley 131729d8e7bcSMatthew G. Knepley Collective on PetscDualSpace 131829d8e7bcSMatthew G. Knepley 131929d8e7bcSMatthew G. Knepley Input Parameters: 132029d8e7bcSMatthew G. Knepley + sp - The PetscDualSpace object 132129d8e7bcSMatthew G. Knepley - name - The kind of space 132229d8e7bcSMatthew G. Knepley 132329d8e7bcSMatthew G. Knepley Options Database Key: 132429d8e7bcSMatthew G. Knepley . -petscdualspace_type <type> - Sets the PetscDualSpace type; use -help for a list of available types 132529d8e7bcSMatthew G. Knepley 132629d8e7bcSMatthew G. Knepley Level: intermediate 132729d8e7bcSMatthew G. Knepley 132829d8e7bcSMatthew G. Knepley .keywords: PetscDualSpace, set, type 132929d8e7bcSMatthew G. Knepley .seealso: PetscDualSpaceGetType(), PetscDualSpaceCreate() 133029d8e7bcSMatthew G. Knepley @*/ 133129d8e7bcSMatthew G. Knepley PetscErrorCode PetscDualSpaceSetType(PetscDualSpace sp, PetscDualSpaceType name) 133229d8e7bcSMatthew G. Knepley { 133329d8e7bcSMatthew G. Knepley PetscErrorCode (*r)(PetscDualSpace); 133429d8e7bcSMatthew G. Knepley PetscBool match; 133529d8e7bcSMatthew G. Knepley PetscErrorCode ierr; 133629d8e7bcSMatthew G. Knepley 133729d8e7bcSMatthew G. Knepley PetscFunctionBegin; 133829d8e7bcSMatthew G. Knepley PetscValidHeaderSpecific(sp, PETSCDUALSPACE_CLASSID, 1); 133929d8e7bcSMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) sp, name, &match);CHKERRQ(ierr); 134029d8e7bcSMatthew G. Knepley if (match) PetscFunctionReturn(0); 134129d8e7bcSMatthew G. Knepley 134229d8e7bcSMatthew G. Knepley if (!PetscDualSpaceRegisterAllCalled) {ierr = PetscDualSpaceRegisterAll();CHKERRQ(ierr);} 134329d8e7bcSMatthew G. Knepley ierr = PetscFunctionListFind(PetscDualSpaceList, name, &r);CHKERRQ(ierr); 134429d8e7bcSMatthew G. Knepley if (!r) SETERRQ1(PetscObjectComm((PetscObject) sp), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown PetscDualSpace type: %s", name); 134529d8e7bcSMatthew G. Knepley 134629d8e7bcSMatthew G. Knepley if (sp->ops->destroy) { 134729d8e7bcSMatthew G. Knepley ierr = (*sp->ops->destroy)(sp);CHKERRQ(ierr); 134829d8e7bcSMatthew G. Knepley sp->ops->destroy = NULL; 134929d8e7bcSMatthew G. Knepley } 135029d8e7bcSMatthew G. Knepley ierr = (*r)(sp);CHKERRQ(ierr); 135129d8e7bcSMatthew G. Knepley ierr = PetscObjectChangeTypeName((PetscObject) sp, name);CHKERRQ(ierr); 135229d8e7bcSMatthew G. Knepley PetscFunctionReturn(0); 135329d8e7bcSMatthew G. Knepley } 135429d8e7bcSMatthew G. Knepley 135529d8e7bcSMatthew G. Knepley #undef __FUNCT__ 135629d8e7bcSMatthew G. Knepley #define __FUNCT__ "PetscDualSpaceGetType" 135729d8e7bcSMatthew G. Knepley /*@C 135829d8e7bcSMatthew G. Knepley PetscDualSpaceGetType - Gets the PetscDualSpace type name (as a string) from the object. 135929d8e7bcSMatthew G. Knepley 136029d8e7bcSMatthew G. Knepley Not Collective 136129d8e7bcSMatthew G. Knepley 136229d8e7bcSMatthew G. Knepley Input Parameter: 136329d8e7bcSMatthew G. Knepley . dm - The PetscDualSpace 136429d8e7bcSMatthew G. Knepley 136529d8e7bcSMatthew G. Knepley Output Parameter: 136629d8e7bcSMatthew G. Knepley . name - The PetscDualSpace type name 136729d8e7bcSMatthew G. Knepley 136829d8e7bcSMatthew G. Knepley Level: intermediate 136929d8e7bcSMatthew G. Knepley 137029d8e7bcSMatthew G. Knepley .keywords: PetscDualSpace, get, type, name 137129d8e7bcSMatthew G. Knepley .seealso: PetscDualSpaceSetType(), PetscDualSpaceCreate() 137229d8e7bcSMatthew G. Knepley @*/ 137329d8e7bcSMatthew G. Knepley PetscErrorCode PetscDualSpaceGetType(PetscDualSpace sp, PetscDualSpaceType *name) 137429d8e7bcSMatthew G. Knepley { 137529d8e7bcSMatthew G. Knepley PetscErrorCode ierr; 137629d8e7bcSMatthew G. Knepley 137729d8e7bcSMatthew G. Knepley PetscFunctionBegin; 137829d8e7bcSMatthew G. Knepley PetscValidHeaderSpecific(sp, PETSCDUALSPACE_CLASSID, 1); 137929d8e7bcSMatthew G. Knepley PetscValidCharPointer(name, 2); 138029d8e7bcSMatthew G. Knepley if (!PetscDualSpaceRegisterAllCalled) { 138129d8e7bcSMatthew G. Knepley ierr = PetscDualSpaceRegisterAll();CHKERRQ(ierr); 138229d8e7bcSMatthew G. Knepley } 138329d8e7bcSMatthew G. Knepley *name = ((PetscObject) sp)->type_name; 138429d8e7bcSMatthew G. Knepley PetscFunctionReturn(0); 138529d8e7bcSMatthew G. Knepley } 138629d8e7bcSMatthew G. Knepley 138729d8e7bcSMatthew G. Knepley #undef __FUNCT__ 138829d8e7bcSMatthew G. Knepley #define __FUNCT__ "PetscDualSpaceView" 138929d8e7bcSMatthew G. Knepley /*@C 139029d8e7bcSMatthew G. Knepley PetscDualSpaceView - Views a PetscDualSpace 139129d8e7bcSMatthew G. Knepley 139229d8e7bcSMatthew G. Knepley Collective on PetscDualSpace 139329d8e7bcSMatthew G. Knepley 139429d8e7bcSMatthew G. Knepley Input Parameter: 139529d8e7bcSMatthew G. Knepley + sp - the PetscDualSpace object to view 139629d8e7bcSMatthew G. Knepley - v - the viewer 139729d8e7bcSMatthew G. Knepley 139829d8e7bcSMatthew G. Knepley Level: developer 139929d8e7bcSMatthew G. Knepley 140029d8e7bcSMatthew G. Knepley .seealso PetscDualSpaceDestroy() 140129d8e7bcSMatthew G. Knepley @*/ 140229d8e7bcSMatthew G. Knepley PetscErrorCode PetscDualSpaceView(PetscDualSpace sp, PetscViewer v) 140329d8e7bcSMatthew G. Knepley { 140429d8e7bcSMatthew G. Knepley PetscErrorCode ierr; 140529d8e7bcSMatthew G. Knepley 140629d8e7bcSMatthew G. Knepley PetscFunctionBegin; 140729d8e7bcSMatthew G. Knepley PetscValidHeaderSpecific(sp, PETSCDUALSPACE_CLASSID, 1); 140829d8e7bcSMatthew G. Knepley if (!v) { 140929d8e7bcSMatthew G. Knepley ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject) sp), &v);CHKERRQ(ierr); 141029d8e7bcSMatthew G. Knepley } 141129d8e7bcSMatthew G. Knepley if (sp->ops->view) { 141229d8e7bcSMatthew G. Knepley ierr = (*sp->ops->view)(sp, v);CHKERRQ(ierr); 141329d8e7bcSMatthew G. Knepley } 141429d8e7bcSMatthew G. Knepley PetscFunctionReturn(0); 141529d8e7bcSMatthew G. Knepley } 141629d8e7bcSMatthew G. Knepley 141729d8e7bcSMatthew G. Knepley #undef __FUNCT__ 141829d8e7bcSMatthew G. Knepley #define __FUNCT__ "PetscDualSpaceViewFromOptions" 141929d8e7bcSMatthew G. Knepley /* 142029d8e7bcSMatthew G. Knepley PetscDualSpaceViewFromOptions - Processes command line options to determine if/how a PetscDualSpace is to be viewed. 142129d8e7bcSMatthew G. Knepley 142229d8e7bcSMatthew G. Knepley Collective on PetscDualSpace 142329d8e7bcSMatthew G. Knepley 142429d8e7bcSMatthew G. Knepley Input Parameters: 142529d8e7bcSMatthew G. Knepley + sp - the PetscDualSpace 142629d8e7bcSMatthew G. Knepley . prefix - prefix to use for viewing, or NULL to use prefix of 'rnd' 142729d8e7bcSMatthew G. Knepley - optionname - option to activate viewing 142829d8e7bcSMatthew G. Knepley 142929d8e7bcSMatthew G. Knepley Level: intermediate 143029d8e7bcSMatthew G. Knepley 143129d8e7bcSMatthew G. Knepley .keywords: PetscDualSpace, view, options, database 143229d8e7bcSMatthew G. Knepley .seealso: VecViewFromOptions(), MatViewFromOptions() 143329d8e7bcSMatthew G. Knepley */ 143429d8e7bcSMatthew G. Knepley PetscErrorCode PetscDualSpaceViewFromOptions(PetscDualSpace sp, const char prefix[], const char optionname[]) 143529d8e7bcSMatthew G. Knepley { 143629d8e7bcSMatthew G. Knepley PetscViewer viewer; 143729d8e7bcSMatthew G. Knepley PetscViewerFormat format; 143829d8e7bcSMatthew G. Knepley PetscBool flg; 143929d8e7bcSMatthew G. Knepley PetscErrorCode ierr; 144029d8e7bcSMatthew G. Knepley 144129d8e7bcSMatthew G. Knepley PetscFunctionBegin; 144229d8e7bcSMatthew G. Knepley if (prefix) { 144329d8e7bcSMatthew G. Knepley ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject) sp), prefix, optionname, &viewer, &format, &flg);CHKERRQ(ierr); 144429d8e7bcSMatthew G. Knepley } else { 144529d8e7bcSMatthew G. Knepley ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject) sp), ((PetscObject) sp)->prefix, optionname, &viewer, &format, &flg);CHKERRQ(ierr); 144629d8e7bcSMatthew G. Knepley } 144729d8e7bcSMatthew G. Knepley if (flg) { 144829d8e7bcSMatthew G. Knepley ierr = PetscViewerPushFormat(viewer, format);CHKERRQ(ierr); 144929d8e7bcSMatthew G. Knepley ierr = PetscDualSpaceView(sp, viewer);CHKERRQ(ierr); 145029d8e7bcSMatthew G. Knepley ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 145129d8e7bcSMatthew G. Knepley ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 145229d8e7bcSMatthew G. Knepley } 145329d8e7bcSMatthew G. Knepley PetscFunctionReturn(0); 145429d8e7bcSMatthew G. Knepley } 145529d8e7bcSMatthew G. Knepley 145629d8e7bcSMatthew G. Knepley #undef __FUNCT__ 145729d8e7bcSMatthew G. Knepley #define __FUNCT__ "PetscDualSpaceSetFromOptions" 145829d8e7bcSMatthew G. Knepley /*@ 145929d8e7bcSMatthew G. Knepley PetscDualSpaceSetFromOptions - sets parameters in a PetscDualSpace from the options database 146029d8e7bcSMatthew G. Knepley 146129d8e7bcSMatthew G. Knepley Collective on PetscDualSpace 146229d8e7bcSMatthew G. Knepley 146329d8e7bcSMatthew G. Knepley Input Parameter: 146429d8e7bcSMatthew G. Knepley . sp - the PetscDualSpace object to set options for 146529d8e7bcSMatthew G. Knepley 146629d8e7bcSMatthew G. Knepley Options Database: 146729d8e7bcSMatthew G. Knepley . -petscspace_order the approximation order of the space 146829d8e7bcSMatthew G. Knepley 146929d8e7bcSMatthew G. Knepley Level: developer 147029d8e7bcSMatthew G. Knepley 147129d8e7bcSMatthew G. Knepley .seealso PetscDualSpaceView() 147229d8e7bcSMatthew G. Knepley @*/ 147329d8e7bcSMatthew G. Knepley PetscErrorCode PetscDualSpaceSetFromOptions(PetscDualSpace sp) 147429d8e7bcSMatthew G. Knepley { 147529d8e7bcSMatthew G. Knepley const char *defaultType; 1476*2025ba63SMatthew G. Knepley char name[256]; 147729d8e7bcSMatthew G. Knepley PetscBool flg; 147829d8e7bcSMatthew G. Knepley PetscErrorCode ierr; 147929d8e7bcSMatthew G. Knepley 148029d8e7bcSMatthew G. Knepley PetscFunctionBegin; 148129d8e7bcSMatthew G. Knepley PetscValidHeaderSpecific(sp, PETSCDUALSPACE_CLASSID, 1); 148229d8e7bcSMatthew G. Knepley if (!((PetscObject) sp)->type_name) { 148329d8e7bcSMatthew G. Knepley defaultType = PETSCDUALSPACELAGRANGE; 148429d8e7bcSMatthew G. Knepley } else { 148529d8e7bcSMatthew G. Knepley defaultType = ((PetscObject) sp)->type_name; 148629d8e7bcSMatthew G. Knepley } 148729d8e7bcSMatthew G. Knepley if (!PetscSpaceRegisterAllCalled) {ierr = PetscSpaceRegisterAll();CHKERRQ(ierr);} 148829d8e7bcSMatthew G. Knepley 148929d8e7bcSMatthew G. Knepley ierr = PetscObjectOptionsBegin((PetscObject) sp);CHKERRQ(ierr); 1490*2025ba63SMatthew G. Knepley ierr = PetscOptionsList("-petscdualspace_type", "Dual space", "PetscDualSpaceSetType", PetscDualSpaceList, defaultType, name, 256, &flg);CHKERRQ(ierr); 149129d8e7bcSMatthew G. Knepley if (flg) { 1492*2025ba63SMatthew G. Knepley ierr = PetscDualSpaceSetType(sp, name);CHKERRQ(ierr); 149329d8e7bcSMatthew G. Knepley } else if (!((PetscObject) sp)->type_name) { 149429d8e7bcSMatthew G. Knepley ierr = PetscDualSpaceSetType(sp, defaultType);CHKERRQ(ierr); 149529d8e7bcSMatthew G. Knepley } 149629d8e7bcSMatthew G. Knepley ierr = PetscOptionsInt("-petscdualspace_order", "The approximation order", "PetscDualSpaceSetOrder", sp->order, &sp->order, NULL);CHKERRQ(ierr); 149729d8e7bcSMatthew G. Knepley if (sp->ops->setfromoptions) { 149829d8e7bcSMatthew G. Knepley ierr = (*sp->ops->setfromoptions)(sp);CHKERRQ(ierr); 149929d8e7bcSMatthew G. Knepley } 150029d8e7bcSMatthew G. Knepley /* process any options handlers added with PetscObjectAddOptionsHandler() */ 150129d8e7bcSMatthew G. Knepley ierr = PetscObjectProcessOptionsHandlers((PetscObject) sp);CHKERRQ(ierr); 150229d8e7bcSMatthew G. Knepley ierr = PetscOptionsEnd();CHKERRQ(ierr); 150329d8e7bcSMatthew G. Knepley ierr = PetscDualSpaceViewFromOptions(sp, NULL, "-petscdualspace_view");CHKERRQ(ierr); 150429d8e7bcSMatthew G. Knepley PetscFunctionReturn(0); 150529d8e7bcSMatthew G. Knepley } 150629d8e7bcSMatthew G. Knepley 150729d8e7bcSMatthew G. Knepley #undef __FUNCT__ 150829d8e7bcSMatthew G. Knepley #define __FUNCT__ "PetscDualSpaceSetUp" 150929d8e7bcSMatthew G. Knepley /*@C 151029d8e7bcSMatthew G. Knepley PetscDualSpaceSetUp - Construct a basis for the PetscDualSpace 151129d8e7bcSMatthew G. Knepley 151229d8e7bcSMatthew G. Knepley Collective on PetscDualSpace 151329d8e7bcSMatthew G. Knepley 151429d8e7bcSMatthew G. Knepley Input Parameter: 151529d8e7bcSMatthew G. Knepley . sp - the PetscDualSpace object to setup 151629d8e7bcSMatthew G. Knepley 151729d8e7bcSMatthew G. Knepley Level: developer 151829d8e7bcSMatthew G. Knepley 151929d8e7bcSMatthew G. Knepley .seealso PetscDualSpaceView(), PetscDualSpaceDestroy() 152029d8e7bcSMatthew G. Knepley @*/ 152129d8e7bcSMatthew G. Knepley PetscErrorCode PetscDualSpaceSetUp(PetscDualSpace sp) 152229d8e7bcSMatthew G. Knepley { 152329d8e7bcSMatthew G. Knepley PetscErrorCode ierr; 152429d8e7bcSMatthew G. Knepley 152529d8e7bcSMatthew G. Knepley PetscFunctionBegin; 152629d8e7bcSMatthew G. Knepley PetscValidHeaderSpecific(sp, PETSCDUALSPACE_CLASSID, 1); 152729d8e7bcSMatthew G. Knepley if (sp->ops->setup) {ierr = (*sp->ops->setup)(sp);CHKERRQ(ierr);} 152829d8e7bcSMatthew G. Knepley PetscFunctionReturn(0); 152929d8e7bcSMatthew G. Knepley } 153029d8e7bcSMatthew G. Knepley 153129d8e7bcSMatthew G. Knepley #undef __FUNCT__ 153229d8e7bcSMatthew G. Knepley #define __FUNCT__ "PetscDualSpaceDestroy" 153329d8e7bcSMatthew G. Knepley /*@ 153429d8e7bcSMatthew G. Knepley PetscDualSpaceDestroy - Destroys a PetscDualSpace object 153529d8e7bcSMatthew G. Knepley 153629d8e7bcSMatthew G. Knepley Collective on PetscDualSpace 153729d8e7bcSMatthew G. Knepley 153829d8e7bcSMatthew G. Knepley Input Parameter: 153929d8e7bcSMatthew G. Knepley . sp - the PetscDualSpace object to destroy 154029d8e7bcSMatthew G. Knepley 154129d8e7bcSMatthew G. Knepley Level: developer 154229d8e7bcSMatthew G. Knepley 154329d8e7bcSMatthew G. Knepley .seealso PetscDualSpaceView() 154429d8e7bcSMatthew G. Knepley @*/ 154529d8e7bcSMatthew G. Knepley PetscErrorCode PetscDualSpaceDestroy(PetscDualSpace *sp) 154629d8e7bcSMatthew G. Knepley { 154729d8e7bcSMatthew G. Knepley PetscInt dim, f; 154829d8e7bcSMatthew G. Knepley PetscErrorCode ierr; 154929d8e7bcSMatthew G. Knepley 155029d8e7bcSMatthew G. Knepley PetscFunctionBegin; 155129d8e7bcSMatthew G. Knepley if (!*sp) PetscFunctionReturn(0); 155229d8e7bcSMatthew G. Knepley PetscValidHeaderSpecific((*sp), PETSCDUALSPACE_CLASSID, 1); 155329d8e7bcSMatthew G. Knepley 155429d8e7bcSMatthew G. Knepley if (--((PetscObject)(*sp))->refct > 0) {*sp = 0; PetscFunctionReturn(0);} 155529d8e7bcSMatthew G. Knepley ((PetscObject) (*sp))->refct = 0; 155629d8e7bcSMatthew G. Knepley /* if memory was published with AMS then destroy it */ 155729d8e7bcSMatthew G. Knepley ierr = PetscObjectAMSViewOff((PetscObject) *sp);CHKERRQ(ierr); 155829d8e7bcSMatthew G. Knepley 155929d8e7bcSMatthew G. Knepley ierr = PetscDualSpaceGetDimension(*sp, &dim);CHKERRQ(ierr); 156029d8e7bcSMatthew G. Knepley for (f = 0; f < dim; ++f) { 1561bfa639d9SMatthew G. Knepley ierr = PetscQuadratureDestroy(&(*sp)->functional[f]);CHKERRQ(ierr); 156229d8e7bcSMatthew G. Knepley } 156329d8e7bcSMatthew G. Knepley ierr = PetscFree((*sp)->functional);CHKERRQ(ierr); 1564bfa639d9SMatthew G. Knepley ierr = DMDestroy(&(*sp)->dm);CHKERRQ(ierr); 156529d8e7bcSMatthew G. Knepley 1566bfa639d9SMatthew G. Knepley if ((*sp)->ops->destroy) {ierr = (*(*sp)->ops->destroy)(*sp);CHKERRQ(ierr);} 156729d8e7bcSMatthew G. Knepley ierr = PetscHeaderDestroy(sp);CHKERRQ(ierr); 156829d8e7bcSMatthew G. Knepley PetscFunctionReturn(0); 156929d8e7bcSMatthew G. Knepley } 157029d8e7bcSMatthew G. Knepley 157129d8e7bcSMatthew G. Knepley #undef __FUNCT__ 157229d8e7bcSMatthew G. Knepley #define __FUNCT__ "PetscDualSpaceCreate" 157329d8e7bcSMatthew G. Knepley /*@ 157429d8e7bcSMatthew G. Knepley PetscDualSpaceCreate - Creates an empty PetscDualSpace object. The type can then be set with PetscDualSpaceSetType(). 157529d8e7bcSMatthew G. Knepley 157629d8e7bcSMatthew G. Knepley Collective on MPI_Comm 157729d8e7bcSMatthew G. Knepley 157829d8e7bcSMatthew G. Knepley Input Parameter: 157929d8e7bcSMatthew G. Knepley . comm - The communicator for the PetscDualSpace object 158029d8e7bcSMatthew G. Knepley 158129d8e7bcSMatthew G. Knepley Output Parameter: 158229d8e7bcSMatthew G. Knepley . sp - The PetscDualSpace object 158329d8e7bcSMatthew G. Knepley 158429d8e7bcSMatthew G. Knepley Level: beginner 158529d8e7bcSMatthew G. Knepley 158629d8e7bcSMatthew G. Knepley .seealso: PetscDualSpaceSetType(), PETSCDUALSPACELAGRANGE 158729d8e7bcSMatthew G. Knepley @*/ 158829d8e7bcSMatthew G. Knepley PetscErrorCode PetscDualSpaceCreate(MPI_Comm comm, PetscDualSpace *sp) 158929d8e7bcSMatthew G. Knepley { 159029d8e7bcSMatthew G. Knepley PetscDualSpace s; 159129d8e7bcSMatthew G. Knepley PetscErrorCode ierr; 159229d8e7bcSMatthew G. Knepley 159329d8e7bcSMatthew G. Knepley PetscFunctionBegin; 159429d8e7bcSMatthew G. Knepley PetscValidPointer(sp, 2); 159529d8e7bcSMatthew G. Knepley *sp = NULL; 159629d8e7bcSMatthew G. Knepley #if !defined(PETSC_USE_DYNAMIC_LIBRARIES) 159729d8e7bcSMatthew G. Knepley ierr = PetscFEInitializePackage();CHKERRQ(ierr); 159829d8e7bcSMatthew G. Knepley #endif 159929d8e7bcSMatthew G. Knepley 160029d8e7bcSMatthew G. Knepley ierr = PetscHeaderCreate(s, _p_PetscDualSpace, struct _PetscDualSpaceOps, PETSCDUALSPACE_CLASSID, "PetscDualSpace", "Dual Space", "PetscDualSpace", comm, PetscDualSpaceDestroy, PetscDualSpaceView);CHKERRQ(ierr); 160129d8e7bcSMatthew G. Knepley ierr = PetscMemzero(s->ops, sizeof(struct _PetscDualSpaceOps));CHKERRQ(ierr); 160229d8e7bcSMatthew G. Knepley 160329d8e7bcSMatthew G. Knepley s->order = 0; 160429d8e7bcSMatthew G. Knepley 160529d8e7bcSMatthew G. Knepley *sp = s; 160629d8e7bcSMatthew G. Knepley PetscFunctionReturn(0); 160729d8e7bcSMatthew G. Knepley } 160829d8e7bcSMatthew G. Knepley 160929d8e7bcSMatthew G. Knepley #undef __FUNCT__ 161029d8e7bcSMatthew G. Knepley #define __FUNCT__ "PetscDualSpaceGetDM" 161129d8e7bcSMatthew G. Knepley PetscErrorCode PetscDualSpaceGetDM(PetscDualSpace sp, DM *dm) 161229d8e7bcSMatthew G. Knepley { 161329d8e7bcSMatthew G. Knepley PetscFunctionBegin; 161429d8e7bcSMatthew G. Knepley PetscValidHeaderSpecific(sp, PETSCDUALSPACE_CLASSID, 1); 161529d8e7bcSMatthew G. Knepley PetscValidPointer(dm, 2); 161629d8e7bcSMatthew G. Knepley *dm = sp->dm; 161729d8e7bcSMatthew G. Knepley PetscFunctionReturn(0); 161829d8e7bcSMatthew G. Knepley } 161929d8e7bcSMatthew G. Knepley 162029d8e7bcSMatthew G. Knepley #undef __FUNCT__ 162129d8e7bcSMatthew G. Knepley #define __FUNCT__ "PetscDualSpaceSetDM" 162229d8e7bcSMatthew G. Knepley PetscErrorCode PetscDualSpaceSetDM(PetscDualSpace sp, DM dm) 162329d8e7bcSMatthew G. Knepley { 162454da605fSMatthew G. Knepley PetscErrorCode ierr; 162554da605fSMatthew G. Knepley 162629d8e7bcSMatthew G. Knepley PetscFunctionBegin; 162729d8e7bcSMatthew G. Knepley PetscValidHeaderSpecific(sp, PETSCDUALSPACE_CLASSID, 1); 162829d8e7bcSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 2); 162954da605fSMatthew G. Knepley ierr = DMDestroy(&sp->dm);CHKERRQ(ierr); 163054da605fSMatthew G. Knepley ierr = PetscObjectReference((PetscObject) dm);CHKERRQ(ierr); 163129d8e7bcSMatthew G. Knepley sp->dm = dm; 163229d8e7bcSMatthew G. Knepley PetscFunctionReturn(0); 163329d8e7bcSMatthew G. Knepley } 163429d8e7bcSMatthew G. Knepley 163529d8e7bcSMatthew G. Knepley #undef __FUNCT__ 163629d8e7bcSMatthew G. Knepley #define __FUNCT__ "PetscDualSpaceGetOrder" 163729d8e7bcSMatthew G. Knepley PetscErrorCode PetscDualSpaceGetOrder(PetscDualSpace sp, PetscInt *order) 163829d8e7bcSMatthew G. Knepley { 163929d8e7bcSMatthew G. Knepley PetscFunctionBegin; 164029d8e7bcSMatthew G. Knepley PetscValidHeaderSpecific(sp, PETSCDUALSPACE_CLASSID, 1); 164129d8e7bcSMatthew G. Knepley PetscValidPointer(order, 2); 164229d8e7bcSMatthew G. Knepley *order = sp->order; 164329d8e7bcSMatthew G. Knepley PetscFunctionReturn(0); 164429d8e7bcSMatthew G. Knepley } 164529d8e7bcSMatthew G. Knepley 164629d8e7bcSMatthew G. Knepley #undef __FUNCT__ 164729d8e7bcSMatthew G. Knepley #define __FUNCT__ "PetscDualSpaceSetOrder" 164829d8e7bcSMatthew G. Knepley PetscErrorCode PetscDualSpaceSetOrder(PetscDualSpace sp, PetscInt order) 164929d8e7bcSMatthew G. Knepley { 165029d8e7bcSMatthew G. Knepley PetscFunctionBegin; 165129d8e7bcSMatthew G. Knepley PetscValidHeaderSpecific(sp, PETSCDUALSPACE_CLASSID, 1); 165229d8e7bcSMatthew G. Knepley sp->order = order; 165329d8e7bcSMatthew G. Knepley PetscFunctionReturn(0); 165429d8e7bcSMatthew G. Knepley } 165529d8e7bcSMatthew G. Knepley 165629d8e7bcSMatthew G. Knepley #undef __FUNCT__ 165729d8e7bcSMatthew G. Knepley #define __FUNCT__ "PetscDualSpaceGetFunctional" 165829d8e7bcSMatthew G. Knepley PetscErrorCode PetscDualSpaceGetFunctional(PetscDualSpace sp, PetscInt i, PetscQuadrature *functional) 165929d8e7bcSMatthew G. Knepley { 166029d8e7bcSMatthew G. Knepley PetscInt dim; 166129d8e7bcSMatthew G. Knepley PetscErrorCode ierr; 166229d8e7bcSMatthew G. Knepley 166329d8e7bcSMatthew G. Knepley PetscFunctionBegin; 166429d8e7bcSMatthew G. Knepley PetscValidHeaderSpecific(sp, PETSCDUALSPACE_CLASSID, 1); 166529d8e7bcSMatthew G. Knepley PetscValidPointer(functional, 3); 166629d8e7bcSMatthew G. Knepley ierr = PetscDualSpaceGetDimension(sp, &dim);CHKERRQ(ierr); 166729d8e7bcSMatthew G. Knepley if ((i < 0) || (i >= dim)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Functional index %d must be in [0, %d)", i, dim); 166829d8e7bcSMatthew G. Knepley *functional = sp->functional[i]; 166929d8e7bcSMatthew G. Knepley PetscFunctionReturn(0); 167029d8e7bcSMatthew G. Knepley } 167129d8e7bcSMatthew G. Knepley 167229d8e7bcSMatthew G. Knepley #undef __FUNCT__ 167329d8e7bcSMatthew G. Knepley #define __FUNCT__ "PetscDualSpaceGetDimension" 167429d8e7bcSMatthew G. Knepley /* Dimension of the space, i.e. number of basis vectors */ 167529d8e7bcSMatthew G. Knepley PetscErrorCode PetscDualSpaceGetDimension(PetscDualSpace sp, PetscInt *dim) 167629d8e7bcSMatthew G. Knepley { 167729d8e7bcSMatthew G. Knepley PetscErrorCode ierr; 167829d8e7bcSMatthew G. Knepley 167929d8e7bcSMatthew G. Knepley PetscFunctionBegin; 168029d8e7bcSMatthew G. Knepley PetscValidHeaderSpecific(sp, PETSCDUALSPACE_CLASSID, 1); 168129d8e7bcSMatthew G. Knepley PetscValidPointer(dim, 2); 168229d8e7bcSMatthew G. Knepley *dim = 0; 168329d8e7bcSMatthew G. Knepley if (sp->ops->getdimension) {ierr = (*sp->ops->getdimension)(sp, dim);CHKERRQ(ierr);} 168429d8e7bcSMatthew G. Knepley PetscFunctionReturn(0); 168529d8e7bcSMatthew G. Knepley } 168629d8e7bcSMatthew G. Knepley 168729d8e7bcSMatthew G. Knepley #undef __FUNCT__ 16880ddb9b0bSMatthew G. Knepley #define __FUNCT__ "PetscDualSpaceGetNumDof" 16890ddb9b0bSMatthew G. Knepley PetscErrorCode PetscDualSpaceGetNumDof(PetscDualSpace sp, const PetscInt **numDof) 16900ddb9b0bSMatthew G. Knepley { 16910ddb9b0bSMatthew G. Knepley PetscErrorCode ierr; 16920ddb9b0bSMatthew G. Knepley 16930ddb9b0bSMatthew G. Knepley PetscFunctionBegin; 16940ddb9b0bSMatthew G. Knepley PetscValidHeaderSpecific(sp, PETSCDUALSPACE_CLASSID, 1); 16950ddb9b0bSMatthew G. Knepley PetscValidPointer(numDof, 2); 16960ddb9b0bSMatthew G. Knepley *numDof = NULL; 16970ddb9b0bSMatthew G. Knepley if (sp->ops->getnumdof) {ierr = (*sp->ops->getnumdof)(sp, numDof);CHKERRQ(ierr);} 16980ddb9b0bSMatthew G. Knepley PetscFunctionReturn(0); 16990ddb9b0bSMatthew G. Knepley } 17000ddb9b0bSMatthew G. Knepley 17010ddb9b0bSMatthew G. Knepley #undef __FUNCT__ 17020ddb9b0bSMatthew G. Knepley #define __FUNCT__ "PetscDualSpaceCreateReferenceCell" 17030ddb9b0bSMatthew G. Knepley PetscErrorCode PetscDualSpaceCreateReferenceCell(PetscDualSpace sp, PetscInt dim, PetscBool simplex, DM *refdm) 17040ddb9b0bSMatthew G. Knepley { 17050ddb9b0bSMatthew G. Knepley DM rdm; 17060ddb9b0bSMatthew G. Knepley PetscErrorCode ierr; 17070ddb9b0bSMatthew G. Knepley 17080ddb9b0bSMatthew G. Knepley PetscFunctionBeginUser; 17090ddb9b0bSMatthew G. Knepley ierr = DMCreate(PetscObjectComm((PetscObject) sp), &rdm);CHKERRQ(ierr); 17100ddb9b0bSMatthew G. Knepley ierr = DMSetType(rdm, DMPLEX);CHKERRQ(ierr); 17110ddb9b0bSMatthew G. Knepley ierr = DMPlexSetDimension(rdm, dim);CHKERRQ(ierr); 17120ddb9b0bSMatthew G. Knepley switch (dim) { 17130ddb9b0bSMatthew G. Knepley case 2: 17140ddb9b0bSMatthew G. Knepley { 17150ddb9b0bSMatthew G. Knepley PetscInt numPoints[2] = {3, 1}; 17160ddb9b0bSMatthew G. Knepley PetscInt coneSize[4] = {3, 0, 0, 0}; 17170ddb9b0bSMatthew G. Knepley PetscInt cones[3] = {1, 2, 3}; 17180ddb9b0bSMatthew G. Knepley PetscInt coneOrientations[3] = {0, 0, 0}; 17190ddb9b0bSMatthew G. Knepley PetscScalar vertexCoords[6] = {-1.0, -1.0, 1.0, -1.0, -1.0, 1.0}; 17200ddb9b0bSMatthew G. Knepley 17210ddb9b0bSMatthew G. Knepley ierr = DMPlexCreateFromDAG(rdm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 17220ddb9b0bSMatthew G. Knepley } 17230ddb9b0bSMatthew G. Knepley break; 17240ddb9b0bSMatthew G. Knepley case 3: 17250ddb9b0bSMatthew G. Knepley { 17260ddb9b0bSMatthew G. Knepley PetscInt numPoints[2] = {4, 1}; 17270ddb9b0bSMatthew G. Knepley PetscInt coneSize[5] = {4, 0, 0, 0, 0}; 17280ddb9b0bSMatthew G. Knepley PetscInt cones[4] = {1, 2, 3, 4}; 17290ddb9b0bSMatthew G. Knepley PetscInt coneOrientations[4] = {0, 0, 0, 0}; 17300ddb9b0bSMatthew G. Knepley PetscScalar vertexCoords[12] = {-1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0}; 17310ddb9b0bSMatthew G. Knepley 17320ddb9b0bSMatthew G. Knepley ierr = DMPlexCreateFromDAG(rdm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); 17330ddb9b0bSMatthew G. Knepley } 17340ddb9b0bSMatthew G. Knepley break; 17350ddb9b0bSMatthew G. Knepley default: 17360ddb9b0bSMatthew G. Knepley SETERRQ1(PetscObjectComm((PetscObject) sp), PETSC_ERR_ARG_WRONG, "Cannot create reference cell for dimension %d", dim); 17370ddb9b0bSMatthew G. Knepley } 17380ddb9b0bSMatthew G. Knepley ierr = DMPlexInterpolate(rdm, refdm);CHKERRQ(ierr); 17390ddb9b0bSMatthew G. Knepley ierr = DMPlexCopyCoordinates(rdm, *refdm);CHKERRQ(ierr); 17400ddb9b0bSMatthew G. Knepley ierr = DMDestroy(&rdm);CHKERRQ(ierr); 17410ddb9b0bSMatthew G. Knepley PetscFunctionReturn(0); 17420ddb9b0bSMatthew G. Knepley } 17430ddb9b0bSMatthew G. Knepley 17440ddb9b0bSMatthew G. Knepley #undef __FUNCT__ 174529d8e7bcSMatthew G. Knepley #define __FUNCT__ "PetscDualSpaceSetUp_Lagrange" 174629d8e7bcSMatthew G. Knepley PetscErrorCode PetscDualSpaceSetUp_Lagrange(PetscDualSpace sp) 174729d8e7bcSMatthew G. Knepley { 17480ddb9b0bSMatthew G. Knepley PetscDualSpace_Lag *lag = (PetscDualSpace_Lag *) sp->data; 174929d8e7bcSMatthew G. Knepley DM dm = sp->dm; 175029d8e7bcSMatthew G. Knepley PetscInt order = sp->order; 175129d8e7bcSMatthew G. Knepley PetscSection csection; 175229d8e7bcSMatthew G. Knepley Vec coordinates; 175359804f93SMatthew G. Knepley PetscReal *qpoints, *qweights; 175459804f93SMatthew G. Knepley PetscInt depth, dim, pdim, *pStart, *pEnd, coneSize, d, n, f = 0; 175529d8e7bcSMatthew G. Knepley PetscErrorCode ierr; 175629d8e7bcSMatthew G. Knepley 175729d8e7bcSMatthew G. Knepley PetscFunctionBegin; 175829d8e7bcSMatthew G. Knepley ierr = PetscDualSpaceGetDimension(sp, &pdim);CHKERRQ(ierr); 175929d8e7bcSMatthew G. Knepley ierr = PetscMalloc(pdim * sizeof(PetscQuadrature), &sp->functional);CHKERRQ(ierr); 176029d8e7bcSMatthew G. Knepley /* Classify element type */ 176129d8e7bcSMatthew G. Knepley ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr); 176259804f93SMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 17630ddb9b0bSMatthew G. Knepley ierr = PetscMalloc((dim+1) * sizeof(PetscInt), &lag->numDof);CHKERRQ(ierr); 17640ddb9b0bSMatthew G. Knepley ierr = PetscMemzero(lag->numDof, (dim+1) * sizeof(PetscInt));CHKERRQ(ierr); 176559804f93SMatthew G. Knepley ierr = PetscMalloc2(depth+1,PetscInt,&pStart,depth+1,PetscInt,&pEnd);CHKERRQ(ierr); 176659804f93SMatthew G. Knepley for (d = 0; d < depth; ++d) { 176759804f93SMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, d, &pStart[d], &pEnd[d]);CHKERRQ(ierr); 176859804f93SMatthew G. Knepley } 176959804f93SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, pStart[depth], &coneSize);CHKERRQ(ierr); 177029d8e7bcSMatthew G. Knepley ierr = DMPlexGetCoordinateSection(dm, &csection);CHKERRQ(ierr); 177129d8e7bcSMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 177229d8e7bcSMatthew G. Knepley if (coneSize == dim+1) { 177329d8e7bcSMatthew G. Knepley PetscInt *closure = NULL, closureSize, c; 177429d8e7bcSMatthew G. Knepley 177529d8e7bcSMatthew G. Knepley /* Simplex */ 177659804f93SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, pStart[depth], PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 177729d8e7bcSMatthew G. Knepley for (c = 0; c < closureSize*2; c += 2) { 177829d8e7bcSMatthew G. Knepley const PetscInt p = closure[c]; 177959804f93SMatthew G. Knepley 178059804f93SMatthew G. Knepley if ((p >= pStart[0]) && (p < pEnd[0])) { 178129d8e7bcSMatthew G. Knepley /* Vertices */ 1782d9dbb98eSMatthew G. Knepley const PetscScalar *coords; 178329d8e7bcSMatthew G. Knepley PetscInt dof, off, d; 178429d8e7bcSMatthew G. Knepley 178559804f93SMatthew G. Knepley if (order < 1) continue; 178629d8e7bcSMatthew G. Knepley sp->functional[f].numQuadPoints = 1; 178729d8e7bcSMatthew G. Knepley ierr = PetscMalloc(sp->functional[f].numQuadPoints*dim * sizeof(PetscReal), &qpoints);CHKERRQ(ierr); 178829d8e7bcSMatthew G. Knepley ierr = PetscMalloc(sp->functional[f].numQuadPoints * sizeof(PetscReal), &qweights);CHKERRQ(ierr); 178959804f93SMatthew G. Knepley ierr = VecGetArrayRead(coordinates, &coords);CHKERRQ(ierr); 179029d8e7bcSMatthew G. Knepley ierr = PetscSectionGetDof(csection, p, &dof);CHKERRQ(ierr); 179129d8e7bcSMatthew G. Knepley ierr = PetscSectionGetOffset(csection, p, &off);CHKERRQ(ierr); 179229d8e7bcSMatthew G. Knepley if (dof != dim) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of coordinates %d does not match spatial dimension %d", dof, dim); 179329d8e7bcSMatthew G. Knepley for (d = 0; d < dof; ++d) {qpoints[d] = coords[off+d];} 179429d8e7bcSMatthew G. Knepley qweights[0] = 1.0; 179529d8e7bcSMatthew G. Knepley sp->functional[f].quadPoints = qpoints; 179629d8e7bcSMatthew G. Knepley sp->functional[f].quadWeights = qweights; 179729d8e7bcSMatthew G. Knepley ++f; 179859804f93SMatthew G. Knepley ierr = VecRestoreArrayRead(coordinates, &coords);CHKERRQ(ierr); 17990ddb9b0bSMatthew G. Knepley lag->numDof[0] = 1; 180059804f93SMatthew G. Knepley } else if ((p >= pStart[1]) && (p < pEnd[1])) { 180159804f93SMatthew G. Knepley /* Edges */ 1802d9dbb98eSMatthew G. Knepley PetscScalar *coords; 180359804f93SMatthew G. Knepley PetscInt k; 180459804f93SMatthew G. Knepley 180559804f93SMatthew G. Knepley if (order < 2) continue; 180659804f93SMatthew G. Knepley coords = NULL; 180759804f93SMatthew G. Knepley ierr = DMPlexVecGetClosure(dm, csection, coordinates, p, &n, &coords);CHKERRQ(ierr); 180859804f93SMatthew G. Knepley if (n != dim*2) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Point %d has %d coordinate values instead of %d", p, n, dim*2); 180959804f93SMatthew G. Knepley for (k = 1; k < order; ++k) { 181059804f93SMatthew G. Knepley sp->functional[f].numQuadPoints = 1; 181159804f93SMatthew G. Knepley ierr = PetscMalloc(sp->functional[f].numQuadPoints*dim * sizeof(PetscReal), &qpoints);CHKERRQ(ierr); 181259804f93SMatthew G. Knepley ierr = PetscMalloc(sp->functional[f].numQuadPoints * sizeof(PetscReal), &qweights);CHKERRQ(ierr); 181359804f93SMatthew G. Knepley for (d = 0; d < dim; ++d) {qpoints[d] = k*(coords[1*dim+d] - coords[0*dim+d])/order + coords[0*dim+d];} 181459804f93SMatthew G. Knepley qweights[0] = 1.0; 181559804f93SMatthew G. Knepley sp->functional[f].quadPoints = qpoints; 181659804f93SMatthew G. Knepley sp->functional[f].quadWeights = qweights; 181759804f93SMatthew G. Knepley ++f; 181859804f93SMatthew G. Knepley } 181959804f93SMatthew G. Knepley ierr = DMPlexVecRestoreClosure(dm, csection, coordinates, p, &n, &coords);CHKERRQ(ierr); 18200ddb9b0bSMatthew G. Knepley lag->numDof[1] = order-1; 182159804f93SMatthew G. Knepley } else if ((p >= pStart[depth-1]) && (p < pEnd[depth-1])) { 182259804f93SMatthew G. Knepley /* Faces */ 182359804f93SMatthew G. Knepley 182459804f93SMatthew G. Knepley if (order < 3) continue; 18250ddb9b0bSMatthew G. Knepley lag->numDof[depth-1] = 0; 182659804f93SMatthew G. Knepley SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Too lazy to implement faces"); 182759804f93SMatthew G. Knepley } else if ((p >= pStart[depth]) && (p < pEnd[depth])) { 182859804f93SMatthew G. Knepley /* Cells */ 182959804f93SMatthew G. Knepley 183059804f93SMatthew G. Knepley if ((order > 0) && (order < 3)) continue; 18310ddb9b0bSMatthew G. Knepley lag->numDof[depth] = 0; 183259804f93SMatthew G. Knepley SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Too lazy to implement cells"); 183329d8e7bcSMatthew G. Knepley } 183429d8e7bcSMatthew G. Knepley } 183559804f93SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, pStart[depth], PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 183629d8e7bcSMatthew G. Knepley } else SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Cannot handle cells with cone size %d", coneSize); 183759804f93SMatthew G. Knepley ierr = PetscFree2(pStart,pEnd);CHKERRQ(ierr); 183859804f93SMatthew G. Knepley if (f != pdim) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Number of dual basis vector %d not equal to dimension %d", f, pdim); 183929d8e7bcSMatthew G. Knepley PetscFunctionReturn(0); 184029d8e7bcSMatthew G. Knepley } 184129d8e7bcSMatthew G. Knepley 184229d8e7bcSMatthew G. Knepley #undef __FUNCT__ 184355db0949SMatthew G. Knepley #define __FUNCT__ "PetscDualSpaceDestroy_Lagrange" 184455db0949SMatthew G. Knepley PetscErrorCode PetscDualSpaceDestroy_Lagrange(PetscDualSpace sp) 184555db0949SMatthew G. Knepley { 184655db0949SMatthew G. Knepley PetscDualSpace_Lag *lag = (PetscDualSpace_Lag *) sp->data; 184755db0949SMatthew G. Knepley PetscErrorCode ierr; 184855db0949SMatthew G. Knepley 184955db0949SMatthew G. Knepley PetscFunctionBegin; 18500ddb9b0bSMatthew G. Knepley ierr = PetscFree(lag->numDof);CHKERRQ(ierr); 185155db0949SMatthew G. Knepley ierr = PetscFree(lag);CHKERRQ(ierr); 185255db0949SMatthew G. Knepley PetscFunctionReturn(0); 185355db0949SMatthew G. Knepley } 185455db0949SMatthew G. Knepley 185555db0949SMatthew G. Knepley #undef __FUNCT__ 185629d8e7bcSMatthew G. Knepley #define __FUNCT__ "PetscDualSpaceGetDimension_Lagrange" 185729d8e7bcSMatthew G. Knepley PetscErrorCode PetscDualSpaceGetDimension_Lagrange(PetscDualSpace sp, PetscInt *dim) 185829d8e7bcSMatthew G. Knepley { 185929d8e7bcSMatthew G. Knepley PetscInt deg = sp->order; 186029d8e7bcSMatthew G. Knepley PetscReal D = 1.0; 186129d8e7bcSMatthew G. Knepley PetscInt n, i; 186229d8e7bcSMatthew G. Knepley PetscErrorCode ierr; 186329d8e7bcSMatthew G. Knepley 186429d8e7bcSMatthew G. Knepley PetscFunctionBegin; 186529d8e7bcSMatthew G. Knepley /* TODO: Assumes simplices */ 186629d8e7bcSMatthew G. Knepley ierr = DMPlexGetDimension(sp->dm, &n);CHKERRQ(ierr); 186729d8e7bcSMatthew G. Knepley for (i = 1; i <= n; ++i) { 186829d8e7bcSMatthew G. Knepley D *= ((PetscReal) (deg+i))/i; 186929d8e7bcSMatthew G. Knepley } 187029d8e7bcSMatthew G. Knepley *dim = (PetscInt) (D + 0.5); 187129d8e7bcSMatthew G. Knepley PetscFunctionReturn(0); 187229d8e7bcSMatthew G. Knepley } 187329d8e7bcSMatthew G. Knepley 187429d8e7bcSMatthew G. Knepley #undef __FUNCT__ 18750ddb9b0bSMatthew G. Knepley #define __FUNCT__ "PetscDualSpaceGetNumDof_Lagrange" 18760ddb9b0bSMatthew G. Knepley PetscErrorCode PetscDualSpaceGetNumDof_Lagrange(PetscDualSpace sp, const PetscInt **numDof) 18770ddb9b0bSMatthew G. Knepley { 18780ddb9b0bSMatthew G. Knepley PetscDualSpace_Lag *lag = (PetscDualSpace_Lag *) sp->data; 18790ddb9b0bSMatthew G. Knepley 18800ddb9b0bSMatthew G. Knepley PetscFunctionBegin; 18810ddb9b0bSMatthew G. Knepley *numDof = lag->numDof; 18820ddb9b0bSMatthew G. Knepley PetscFunctionReturn(0); 18830ddb9b0bSMatthew G. Knepley } 18840ddb9b0bSMatthew G. Knepley 18850ddb9b0bSMatthew G. Knepley #undef __FUNCT__ 188629d8e7bcSMatthew G. Knepley #define __FUNCT__ "PetscDualSpaceInitialize_Lagrange" 188729d8e7bcSMatthew G. Knepley PetscErrorCode PetscDualSpaceInitialize_Lagrange(PetscDualSpace sp) 188829d8e7bcSMatthew G. Knepley { 188929d8e7bcSMatthew G. Knepley PetscFunctionBegin; 189029d8e7bcSMatthew G. Knepley sp->ops->setfromoptions = NULL; 189129d8e7bcSMatthew G. Knepley sp->ops->setup = PetscDualSpaceSetUp_Lagrange; 189229d8e7bcSMatthew G. Knepley sp->ops->view = NULL; 189355db0949SMatthew G. Knepley sp->ops->destroy = PetscDualSpaceDestroy_Lagrange; 189429d8e7bcSMatthew G. Knepley sp->ops->getdimension = PetscDualSpaceGetDimension_Lagrange; 18950ddb9b0bSMatthew G. Knepley sp->ops->getnumdof = PetscDualSpaceGetNumDof_Lagrange; 189629d8e7bcSMatthew G. Knepley PetscFunctionReturn(0); 189729d8e7bcSMatthew G. Knepley } 189829d8e7bcSMatthew G. Knepley 189929d8e7bcSMatthew G. Knepley /*MC 190029d8e7bcSMatthew G. Knepley PETSCDUALSPACELAGRANGE = "lagrange" - A PetscDualSpace object that encapsulates a dual space of pointwise evaluation functionals 190129d8e7bcSMatthew G. Knepley 190229d8e7bcSMatthew G. Knepley Level: intermediate 190329d8e7bcSMatthew G. Knepley 190429d8e7bcSMatthew G. Knepley .seealso: PetscDualSpaceType, PetscDualSpaceCreate(), PetscDualSpaceSetType() 190529d8e7bcSMatthew G. Knepley M*/ 190629d8e7bcSMatthew G. Knepley 190729d8e7bcSMatthew G. Knepley #undef __FUNCT__ 190829d8e7bcSMatthew G. Knepley #define __FUNCT__ "PetscDualSpaceCreate_Lagrange" 190929d8e7bcSMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscDualSpaceCreate_Lagrange(PetscDualSpace sp) 191029d8e7bcSMatthew G. Knepley { 191129d8e7bcSMatthew G. Knepley PetscDualSpace_Lag *lag; 191229d8e7bcSMatthew G. Knepley PetscErrorCode ierr; 191329d8e7bcSMatthew G. Knepley 191429d8e7bcSMatthew G. Knepley PetscFunctionBegin; 191529d8e7bcSMatthew G. Knepley PetscValidHeaderSpecific(sp, PETSCDUALSPACE_CLASSID, 1); 191629d8e7bcSMatthew G. Knepley ierr = PetscNewLog(sp, PetscDualSpace_Lag, &lag);CHKERRQ(ierr); 191729d8e7bcSMatthew G. Knepley sp->data = lag; 191829d8e7bcSMatthew G. Knepley 19190ddb9b0bSMatthew G. Knepley lag->numDof = NULL; 192029d8e7bcSMatthew G. Knepley 192129d8e7bcSMatthew G. Knepley ierr = PetscDualSpaceInitialize_Lagrange(sp);CHKERRQ(ierr); 192229d8e7bcSMatthew G. Knepley PetscFunctionReturn(0); 192329d8e7bcSMatthew G. Knepley } 192429d8e7bcSMatthew G. Knepley 192529d8e7bcSMatthew G. Knepley 192629d8e7bcSMatthew G. Knepley PetscInt PETSCFE_CLASSID = 0; 192729d8e7bcSMatthew G. Knepley 192829d8e7bcSMatthew G. Knepley #undef __FUNCT__ 192929d8e7bcSMatthew G. Knepley #define __FUNCT__ "PetscFEView" 193029d8e7bcSMatthew G. Knepley /*@C 193129d8e7bcSMatthew G. Knepley PetscFEView - Views a PetscFE 193229d8e7bcSMatthew G. Knepley 193329d8e7bcSMatthew G. Knepley Collective on PetscFE 193429d8e7bcSMatthew G. Knepley 193529d8e7bcSMatthew G. Knepley Input Parameter: 193629d8e7bcSMatthew G. Knepley + sp - the PetscFE object to view 193729d8e7bcSMatthew G. Knepley - v - the viewer 193829d8e7bcSMatthew G. Knepley 193929d8e7bcSMatthew G. Knepley Level: developer 194029d8e7bcSMatthew G. Knepley 194129d8e7bcSMatthew G. Knepley .seealso PetscFEDestroy() 194229d8e7bcSMatthew G. Knepley @*/ 194329d8e7bcSMatthew G. Knepley PetscErrorCode PetscFEView(PetscFE fem, PetscViewer v) 194429d8e7bcSMatthew G. Knepley { 194529d8e7bcSMatthew G. Knepley PetscErrorCode ierr; 194629d8e7bcSMatthew G. Knepley 194729d8e7bcSMatthew G. Knepley PetscFunctionBegin; 194829d8e7bcSMatthew G. Knepley PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 194929d8e7bcSMatthew G. Knepley if (!v) { 195029d8e7bcSMatthew G. Knepley ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject) fem), &v);CHKERRQ(ierr); 195129d8e7bcSMatthew G. Knepley } 195229d8e7bcSMatthew G. Knepley if (fem->ops->view) { 195329d8e7bcSMatthew G. Knepley ierr = (*fem->ops->view)(fem, v);CHKERRQ(ierr); 195429d8e7bcSMatthew G. Knepley } 195529d8e7bcSMatthew G. Knepley PetscFunctionReturn(0); 195629d8e7bcSMatthew G. Knepley } 195729d8e7bcSMatthew G. Knepley 195829d8e7bcSMatthew G. Knepley #undef __FUNCT__ 195929d8e7bcSMatthew G. Knepley #define __FUNCT__ "PetscFEDestroy" 196029d8e7bcSMatthew G. Knepley /*@ 196129d8e7bcSMatthew G. Knepley PetscFEDestroy - Destroys a PetscFE object 196229d8e7bcSMatthew G. Knepley 196329d8e7bcSMatthew G. Knepley Collective on PetscFE 196429d8e7bcSMatthew G. Knepley 196529d8e7bcSMatthew G. Knepley Input Parameter: 196629d8e7bcSMatthew G. Knepley . fem - the PetscFE object to destroy 196729d8e7bcSMatthew G. Knepley 196829d8e7bcSMatthew G. Knepley Level: developer 196929d8e7bcSMatthew G. Knepley 197029d8e7bcSMatthew G. Knepley .seealso PetscFEView() 197129d8e7bcSMatthew G. Knepley @*/ 197229d8e7bcSMatthew G. Knepley PetscErrorCode PetscFEDestroy(PetscFE *fem) 197329d8e7bcSMatthew G. Knepley { 197429d8e7bcSMatthew G. Knepley PetscErrorCode ierr; 197529d8e7bcSMatthew G. Knepley 197629d8e7bcSMatthew G. Knepley PetscFunctionBegin; 197729d8e7bcSMatthew G. Knepley if (!*fem) PetscFunctionReturn(0); 197829d8e7bcSMatthew G. Knepley PetscValidHeaderSpecific((*fem), PETSCFE_CLASSID, 1); 197929d8e7bcSMatthew G. Knepley 198029d8e7bcSMatthew G. Knepley if (--((PetscObject)(*fem))->refct > 0) {*fem = 0; PetscFunctionReturn(0);} 198129d8e7bcSMatthew G. Knepley ((PetscObject) (*fem))->refct = 0; 198229d8e7bcSMatthew G. Knepley /* if memory was published with AMS then destroy it */ 198329d8e7bcSMatthew G. Knepley ierr = PetscObjectAMSViewOff((PetscObject) *fem);CHKERRQ(ierr); 198429d8e7bcSMatthew G. Knepley 1985bfa639d9SMatthew G. Knepley ierr = PetscSpaceDestroy(&(*fem)->basisSpace);CHKERRQ(ierr); 1986bfa639d9SMatthew G. Knepley ierr = PetscDualSpaceDestroy(&(*fem)->dualSpace);CHKERRQ(ierr); 1987bfa639d9SMatthew G. Knepley ierr = PetscQuadratureDestroy(&(*fem)->quadrature);CHKERRQ(ierr); 19880ddb9b0bSMatthew G. Knepley ierr = PetscFree((*fem)->numDof);CHKERRQ(ierr); 1989bfa639d9SMatthew G. Knepley 1990bfa639d9SMatthew G. Knepley if ((*fem)->ops->destroy) {ierr = (*(*fem)->ops->destroy)(*fem);CHKERRQ(ierr);} 199129d8e7bcSMatthew G. Knepley ierr = PetscHeaderDestroy(fem);CHKERRQ(ierr); 199229d8e7bcSMatthew G. Knepley PetscFunctionReturn(0); 199329d8e7bcSMatthew G. Knepley } 199429d8e7bcSMatthew G. Knepley 199529d8e7bcSMatthew G. Knepley #undef __FUNCT__ 199629d8e7bcSMatthew G. Knepley #define __FUNCT__ "PetscFECreate" 199729d8e7bcSMatthew G. Knepley /*@ 199829d8e7bcSMatthew G. Knepley PetscFECreate - Creates an empty PetscFE object. The type can then be set with PetscFESetType(). 199929d8e7bcSMatthew G. Knepley 200029d8e7bcSMatthew G. Knepley Collective on MPI_Comm 200129d8e7bcSMatthew G. Knepley 200229d8e7bcSMatthew G. Knepley Input Parameter: 200329d8e7bcSMatthew G. Knepley . comm - The communicator for the PetscFE object 200429d8e7bcSMatthew G. Knepley 200529d8e7bcSMatthew G. Knepley Output Parameter: 200629d8e7bcSMatthew G. Knepley . fem - The PetscFE object 200729d8e7bcSMatthew G. Knepley 200829d8e7bcSMatthew G. Knepley Level: beginner 200929d8e7bcSMatthew G. Knepley 201029d8e7bcSMatthew G. Knepley .seealso: PetscFESetType(), PETSCFEGALERKIN 201129d8e7bcSMatthew G. Knepley @*/ 201229d8e7bcSMatthew G. Knepley PetscErrorCode PetscFECreate(MPI_Comm comm, PetscFE *fem) 201329d8e7bcSMatthew G. Knepley { 201429d8e7bcSMatthew G. Knepley PetscFE f; 201529d8e7bcSMatthew G. Knepley PetscErrorCode ierr; 201629d8e7bcSMatthew G. Knepley 201729d8e7bcSMatthew G. Knepley PetscFunctionBegin; 201829d8e7bcSMatthew G. Knepley PetscValidPointer(fem, 2); 201929d8e7bcSMatthew G. Knepley *fem = NULL; 202029d8e7bcSMatthew G. Knepley #if !defined(PETSC_USE_DYNAMIC_LIBRARIES) 202129d8e7bcSMatthew G. Knepley ierr = PetscFEInitializePackage();CHKERRQ(ierr); 202229d8e7bcSMatthew G. Knepley #endif 202329d8e7bcSMatthew G. Knepley 202429d8e7bcSMatthew G. Knepley ierr = PetscHeaderCreate(f, _p_PetscFE, struct _PetscFEOps, PETSCFE_CLASSID, "PetscFE", "Finite Element", "PetscFE", comm, PetscFEDestroy, PetscFEView);CHKERRQ(ierr); 202529d8e7bcSMatthew G. Knepley ierr = PetscMemzero(f->ops, sizeof(struct _PetscFEOps));CHKERRQ(ierr); 202629d8e7bcSMatthew G. Knepley 202729d8e7bcSMatthew G. Knepley f->basisSpace = NULL; 202829d8e7bcSMatthew G. Knepley f->dualSpace = NULL; 2029d9dbb98eSMatthew G. Knepley f->numComponents = 1; 20300ddb9b0bSMatthew G. Knepley f->numDof = NULL; 2031bfa639d9SMatthew G. Knepley ierr = PetscMemzero(&f->quadrature, sizeof(PetscQuadrature));CHKERRQ(ierr); 203229d8e7bcSMatthew G. Knepley 203329d8e7bcSMatthew G. Knepley *fem = f; 203429d8e7bcSMatthew G. Knepley PetscFunctionReturn(0); 203529d8e7bcSMatthew G. Knepley } 203629d8e7bcSMatthew G. Knepley 203729d8e7bcSMatthew G. Knepley #undef __FUNCT__ 203829d8e7bcSMatthew G. Knepley #define __FUNCT__ "PetscFEGetDimension" 203929d8e7bcSMatthew G. Knepley PetscErrorCode PetscFEGetDimension(PetscFE fem, PetscInt *dim) 204029d8e7bcSMatthew G. Knepley { 204129d8e7bcSMatthew G. Knepley PetscErrorCode ierr; 204229d8e7bcSMatthew G. Knepley 204329d8e7bcSMatthew G. Knepley PetscFunctionBegin; 204429d8e7bcSMatthew G. Knepley PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 204529d8e7bcSMatthew G. Knepley PetscValidPointer(dim, 2); 204629d8e7bcSMatthew G. Knepley ierr = PetscSpaceGetDimension(fem->basisSpace, dim);CHKERRQ(ierr); 204729d8e7bcSMatthew G. Knepley PetscFunctionReturn(0); 204829d8e7bcSMatthew G. Knepley } 204929d8e7bcSMatthew G. Knepley 205029d8e7bcSMatthew G. Knepley #undef __FUNCT__ 20510ddb9b0bSMatthew G. Knepley #define __FUNCT__ "PetscFEGetSpatialDimension" 20520ddb9b0bSMatthew G. Knepley PetscErrorCode PetscFEGetSpatialDimension(PetscFE fem, PetscInt *dim) 20530ddb9b0bSMatthew G. Knepley { 20540ddb9b0bSMatthew G. Knepley DM dm; 20550ddb9b0bSMatthew G. Knepley PetscErrorCode ierr; 20560ddb9b0bSMatthew G. Knepley 20570ddb9b0bSMatthew G. Knepley PetscFunctionBegin; 20580ddb9b0bSMatthew G. Knepley PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 20590ddb9b0bSMatthew G. Knepley PetscValidPointer(dim, 2); 20600ddb9b0bSMatthew G. Knepley ierr = PetscDualSpaceGetDM(fem->dualSpace, &dm);CHKERRQ(ierr); 20610ddb9b0bSMatthew G. Knepley ierr = DMPlexGetDimension(dm, dim);CHKERRQ(ierr); 20620ddb9b0bSMatthew G. Knepley PetscFunctionReturn(0); 20630ddb9b0bSMatthew G. Knepley } 20640ddb9b0bSMatthew G. Knepley 20650ddb9b0bSMatthew G. Knepley #undef __FUNCT__ 2066d9dbb98eSMatthew G. Knepley #define __FUNCT__ "PetscFESetNumComponents" 2067d9dbb98eSMatthew G. Knepley PetscErrorCode PetscFESetNumComponents(PetscFE fem, PetscInt comp) 2068d9dbb98eSMatthew G. Knepley { 2069d9dbb98eSMatthew G. Knepley PetscFunctionBegin; 2070d9dbb98eSMatthew G. Knepley PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 2071d9dbb98eSMatthew G. Knepley fem->numComponents = comp; 2072d9dbb98eSMatthew G. Knepley PetscFunctionReturn(0); 2073d9dbb98eSMatthew G. Knepley } 2074d9dbb98eSMatthew G. Knepley 2075d9dbb98eSMatthew G. Knepley #undef __FUNCT__ 207629d8e7bcSMatthew G. Knepley #define __FUNCT__ "PetscFEGetNumComponents" 207729d8e7bcSMatthew G. Knepley PetscErrorCode PetscFEGetNumComponents(PetscFE fem, PetscInt *comp) 207829d8e7bcSMatthew G. Knepley { 207929d8e7bcSMatthew G. Knepley PetscFunctionBegin; 208029d8e7bcSMatthew G. Knepley PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 208129d8e7bcSMatthew G. Knepley PetscValidPointer(comp, 2); 2082d9dbb98eSMatthew G. Knepley *comp = fem->numComponents; 208329d8e7bcSMatthew G. Knepley PetscFunctionReturn(0); 208429d8e7bcSMatthew G. Knepley } 208529d8e7bcSMatthew G. Knepley 208629d8e7bcSMatthew G. Knepley #undef __FUNCT__ 208729d8e7bcSMatthew G. Knepley #define __FUNCT__ "PetscFEGetBasisSpace" 208829d8e7bcSMatthew G. Knepley PetscErrorCode PetscFEGetBasisSpace(PetscFE fem, PetscSpace *sp) 208929d8e7bcSMatthew G. Knepley { 209029d8e7bcSMatthew G. Knepley PetscFunctionBegin; 209129d8e7bcSMatthew G. Knepley PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 209229d8e7bcSMatthew G. Knepley PetscValidPointer(sp, 2); 209329d8e7bcSMatthew G. Knepley *sp = fem->basisSpace; 209429d8e7bcSMatthew G. Knepley PetscFunctionReturn(0); 209529d8e7bcSMatthew G. Knepley } 209629d8e7bcSMatthew G. Knepley 209729d8e7bcSMatthew G. Knepley #undef __FUNCT__ 209829d8e7bcSMatthew G. Knepley #define __FUNCT__ "PetscFESetBasisSpace" 209929d8e7bcSMatthew G. Knepley PetscErrorCode PetscFESetBasisSpace(PetscFE fem, PetscSpace sp) 210029d8e7bcSMatthew G. Knepley { 2101bfa639d9SMatthew G. Knepley PetscErrorCode ierr; 2102bfa639d9SMatthew G. Knepley 210329d8e7bcSMatthew G. Knepley PetscFunctionBegin; 210429d8e7bcSMatthew G. Knepley PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 210529d8e7bcSMatthew G. Knepley PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 2); 2106bfa639d9SMatthew G. Knepley ierr = PetscSpaceDestroy(&fem->basisSpace);CHKERRQ(ierr); 210729d8e7bcSMatthew G. Knepley fem->basisSpace = sp; 2108bfa639d9SMatthew G. Knepley ierr = PetscObjectReference((PetscObject) fem->basisSpace);CHKERRQ(ierr); 210929d8e7bcSMatthew G. Knepley PetscFunctionReturn(0); 211029d8e7bcSMatthew G. Knepley } 211129d8e7bcSMatthew G. Knepley 211229d8e7bcSMatthew G. Knepley #undef __FUNCT__ 211329d8e7bcSMatthew G. Knepley #define __FUNCT__ "PetscFEGetDualSpace" 211429d8e7bcSMatthew G. Knepley PetscErrorCode PetscFEGetDualSpace(PetscFE fem, PetscDualSpace *sp) 211529d8e7bcSMatthew G. Knepley { 211629d8e7bcSMatthew G. Knepley PetscFunctionBegin; 211729d8e7bcSMatthew G. Knepley PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 211829d8e7bcSMatthew G. Knepley PetscValidPointer(sp, 2); 211929d8e7bcSMatthew G. Knepley *sp = fem->dualSpace; 212029d8e7bcSMatthew G. Knepley PetscFunctionReturn(0); 212129d8e7bcSMatthew G. Knepley } 212229d8e7bcSMatthew G. Knepley 212329d8e7bcSMatthew G. Knepley #undef __FUNCT__ 212429d8e7bcSMatthew G. Knepley #define __FUNCT__ "PetscFESetDualSpace" 212529d8e7bcSMatthew G. Knepley PetscErrorCode PetscFESetDualSpace(PetscFE fem, PetscDualSpace sp) 212629d8e7bcSMatthew G. Knepley { 2127bfa639d9SMatthew G. Knepley PetscErrorCode ierr; 2128bfa639d9SMatthew G. Knepley 212929d8e7bcSMatthew G. Knepley PetscFunctionBegin; 213029d8e7bcSMatthew G. Knepley PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 213129d8e7bcSMatthew G. Knepley PetscValidHeaderSpecific(sp, PETSCDUALSPACE_CLASSID, 2); 2132bfa639d9SMatthew G. Knepley ierr = PetscDualSpaceDestroy(&fem->dualSpace);CHKERRQ(ierr); 213329d8e7bcSMatthew G. Knepley fem->dualSpace = sp; 2134bfa639d9SMatthew G. Knepley ierr = PetscObjectReference((PetscObject) fem->dualSpace);CHKERRQ(ierr); 2135bfa639d9SMatthew G. Knepley PetscFunctionReturn(0); 2136bfa639d9SMatthew G. Knepley } 2137bfa639d9SMatthew G. Knepley 2138bfa639d9SMatthew G. Knepley #undef __FUNCT__ 2139bfa639d9SMatthew G. Knepley #define __FUNCT__ "PetscFEGetQuadrature" 2140bfa639d9SMatthew G. Knepley PetscErrorCode PetscFEGetQuadrature(PetscFE fem, PetscQuadrature *q) 2141bfa639d9SMatthew G. Knepley { 2142bfa639d9SMatthew G. Knepley PetscFunctionBegin; 2143bfa639d9SMatthew G. Knepley PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 2144bfa639d9SMatthew G. Knepley PetscValidPointer(q, 2); 2145bfa639d9SMatthew G. Knepley *q = fem->quadrature; 2146bfa639d9SMatthew G. Knepley PetscFunctionReturn(0); 2147bfa639d9SMatthew G. Knepley } 2148bfa639d9SMatthew G. Knepley 2149bfa639d9SMatthew G. Knepley #undef __FUNCT__ 2150bfa639d9SMatthew G. Knepley #define __FUNCT__ "PetscFESetQuadrature" 2151bfa639d9SMatthew G. Knepley PetscErrorCode PetscFESetQuadrature(PetscFE fem, PetscQuadrature q) 2152bfa639d9SMatthew G. Knepley { 2153bfa639d9SMatthew G. Knepley PetscErrorCode ierr; 2154bfa639d9SMatthew G. Knepley 2155bfa639d9SMatthew G. Knepley PetscFunctionBegin; 2156bfa639d9SMatthew G. Knepley PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 2157bfa639d9SMatthew G. Knepley ierr = PetscQuadratureDestroy(&fem->quadrature);CHKERRQ(ierr); 2158bfa639d9SMatthew G. Knepley fem->quadrature = q; 215929d8e7bcSMatthew G. Knepley PetscFunctionReturn(0); 216029d8e7bcSMatthew G. Knepley } 216129d8e7bcSMatthew G. Knepley 216229d8e7bcSMatthew G. Knepley #undef __FUNCT__ 21630ddb9b0bSMatthew G. Knepley #define __FUNCT__ "PetscFEGetNumDof" 21640ddb9b0bSMatthew G. Knepley PetscErrorCode PetscFEGetNumDof(PetscFE fem, const PetscInt **numDof) 21650ddb9b0bSMatthew G. Knepley { 21660ddb9b0bSMatthew G. Knepley const PetscInt *numDofDual; 21670ddb9b0bSMatthew G. Knepley PetscErrorCode ierr; 21680ddb9b0bSMatthew G. Knepley 21690ddb9b0bSMatthew G. Knepley PetscFunctionBegin; 21700ddb9b0bSMatthew G. Knepley PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 21710ddb9b0bSMatthew G. Knepley PetscValidPointer(numDof, 2); 21720ddb9b0bSMatthew G. Knepley ierr = PetscDualSpaceGetNumDof(fem->dualSpace, &numDofDual);CHKERRQ(ierr); 21730ddb9b0bSMatthew G. Knepley if (!fem->numDof) { 21740ddb9b0bSMatthew G. Knepley DM dm; 21750ddb9b0bSMatthew G. Knepley PetscInt dim, d; 21760ddb9b0bSMatthew G. Knepley 21770ddb9b0bSMatthew G. Knepley ierr = PetscDualSpaceGetDM(fem->dualSpace, &dm);CHKERRQ(ierr); 21780ddb9b0bSMatthew G. Knepley ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr); 21790ddb9b0bSMatthew G. Knepley ierr = PetscMalloc((dim+1) * sizeof(PetscInt), &fem->numDof);CHKERRQ(ierr); 21800ddb9b0bSMatthew G. Knepley for (d = 0; d <= dim; ++d) { 21810ddb9b0bSMatthew G. Knepley fem->numDof[d] = fem->numComponents*numDofDual[d]; 21820ddb9b0bSMatthew G. Knepley } 21830ddb9b0bSMatthew G. Knepley } 21840ddb9b0bSMatthew G. Knepley *numDof = fem->numDof; 21850ddb9b0bSMatthew G. Knepley PetscFunctionReturn(0); 21860ddb9b0bSMatthew G. Knepley } 21870ddb9b0bSMatthew G. Knepley 21880ddb9b0bSMatthew G. Knepley #undef __FUNCT__ 218929d8e7bcSMatthew G. Knepley #define __FUNCT__ "PetscFEGetTabulation" 2190bfa639d9SMatthew G. Knepley PetscErrorCode PetscFEGetTabulation(PetscFE fem, PetscReal **B, PetscReal **D, PetscReal **H) 219129d8e7bcSMatthew G. Knepley { 219229d8e7bcSMatthew G. Knepley DM dm; 219329d8e7bcSMatthew G. Knepley PetscInt pdim; /* Dimension of FE space P */ 219429d8e7bcSMatthew G. Knepley PetscInt dim; /* Spatial dimension */ 2195d9dbb98eSMatthew G. Knepley PetscInt comp; /* Field components */ 2196bfa639d9SMatthew G. Knepley PetscInt npoints = fem->quadrature.numQuadPoints; 219707d6ad7fSMatthew G. Knepley const PetscReal *points = fem->quadrature.quadPoints; 219807d6ad7fSMatthew G. Knepley PetscReal *tmpB, *tmpD, *invV; 219907d6ad7fSMatthew G. Knepley PetscInt p, d, j, k; 220029d8e7bcSMatthew G. Knepley PetscErrorCode ierr; 220129d8e7bcSMatthew G. Knepley 220229d8e7bcSMatthew G. Knepley PetscFunctionBegin; 220329d8e7bcSMatthew G. Knepley PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 220429d8e7bcSMatthew G. Knepley PetscValidPointer(points, 3); 220529d8e7bcSMatthew G. Knepley if (B) PetscValidPointer(B, 4); 220629d8e7bcSMatthew G. Knepley if (D) PetscValidPointer(D, 5); 220729d8e7bcSMatthew G. Knepley if (H) PetscValidPointer(H, 6); 220829d8e7bcSMatthew G. Knepley ierr = PetscDualSpaceGetDM(fem->dualSpace, &dm);CHKERRQ(ierr); 220929d8e7bcSMatthew G. Knepley 221029d8e7bcSMatthew G. Knepley ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr); 221129d8e7bcSMatthew G. Knepley ierr = PetscSpaceGetDimension(fem->basisSpace, &pdim);CHKERRQ(ierr); 2212d9dbb98eSMatthew G. Knepley ierr = PetscFEGetNumComponents(fem, &comp);CHKERRQ(ierr); 221329d8e7bcSMatthew G. Knepley /* if (nvalues%dim) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "The number of coordinate values %d must be divisible by the spatial dimension %d", nvalues, dim); */ 221429d8e7bcSMatthew G. Knepley 221529d8e7bcSMatthew G. Knepley if (B) { 2216d9dbb98eSMatthew G. Knepley ierr = DMGetWorkArray(dm, npoints*pdim*comp, PETSC_REAL, B);CHKERRQ(ierr); 221729d8e7bcSMatthew G. Knepley ierr = DMGetWorkArray(dm, npoints*pdim, PETSC_REAL, &tmpB);CHKERRQ(ierr); 221829d8e7bcSMatthew G. Knepley } 221907d6ad7fSMatthew G. Knepley if (D) { 222007d6ad7fSMatthew G. Knepley ierr = DMGetWorkArray(dm, npoints*pdim*comp*dim, PETSC_REAL, D);CHKERRQ(ierr); 222107d6ad7fSMatthew G. Knepley ierr = DMGetWorkArray(dm, npoints*pdim*dim, PETSC_REAL, &tmpD);CHKERRQ(ierr); 222207d6ad7fSMatthew G. Knepley } 222329d8e7bcSMatthew G. Knepley if (H) {ierr = DMGetWorkArray(dm, npoints*pdim*dim*dim, PETSC_REAL, H);CHKERRQ(ierr);} 222407d6ad7fSMatthew G. Knepley ierr = PetscSpaceEvaluate(fem->basisSpace, npoints, points, B ? tmpB : NULL, D ? tmpD : NULL, H ? *H : NULL);CHKERRQ(ierr); 222529d8e7bcSMatthew G. Knepley 222629d8e7bcSMatthew G. Knepley ierr = DMGetWorkArray(dm, pdim*pdim, PETSC_REAL, &invV);CHKERRQ(ierr); 222729d8e7bcSMatthew G. Knepley for (j = 0; j < pdim; ++j) { 222829d8e7bcSMatthew G. Knepley PetscReal *Bf; 222929d8e7bcSMatthew G. Knepley PetscQuadrature f; 223029d8e7bcSMatthew G. Knepley PetscInt q; 223129d8e7bcSMatthew G. Knepley 223229d8e7bcSMatthew G. Knepley ierr = PetscDualSpaceGetFunctional(fem->dualSpace, j, &f); 223329d8e7bcSMatthew G. Knepley ierr = DMGetWorkArray(dm, f.numQuadPoints*pdim, PETSC_REAL, &Bf);CHKERRQ(ierr); 223429d8e7bcSMatthew G. Knepley ierr = PetscSpaceEvaluate(fem->basisSpace, f.numQuadPoints, f.quadPoints, Bf, NULL, NULL);CHKERRQ(ierr); 223529d8e7bcSMatthew G. Knepley for (k = 0; k < pdim; ++k) { 223629d8e7bcSMatthew G. Knepley /* n_j \cdot \phi_k */ 223729d8e7bcSMatthew G. Knepley invV[j*pdim+k] = 0.0; 223829d8e7bcSMatthew G. Knepley for (q = 0; q < f.numQuadPoints; ++q) { 223929d8e7bcSMatthew G. Knepley invV[j*pdim+k] += Bf[q*pdim+k]*f.quadWeights[q]; 224029d8e7bcSMatthew G. Knepley } 224129d8e7bcSMatthew G. Knepley } 224229d8e7bcSMatthew G. Knepley ierr = DMRestoreWorkArray(dm, f.numQuadPoints*pdim, PETSC_REAL, &Bf);CHKERRQ(ierr); 224329d8e7bcSMatthew G. Knepley } 224429d8e7bcSMatthew G. Knepley { 224529d8e7bcSMatthew G. Knepley PetscReal *work; 224629d8e7bcSMatthew G. Knepley PetscBLASInt *pivots; 224729d8e7bcSMatthew G. Knepley PetscBLASInt n = pdim, info; 224829d8e7bcSMatthew G. Knepley 224929d8e7bcSMatthew G. Knepley ierr = DMGetWorkArray(dm, pdim, PETSC_INT, &pivots);CHKERRQ(ierr); 225029d8e7bcSMatthew G. Knepley ierr = DMGetWorkArray(dm, pdim, PETSC_REAL, &work);CHKERRQ(ierr); 225129d8e7bcSMatthew G. Knepley PetscStackCallBLAS("LAPACKgetrf", LAPACKgetrf_(&n, &n, invV, &n, pivots, &info)); 225229d8e7bcSMatthew G. Knepley PetscStackCallBLAS("LAPACKgetri", LAPACKgetri_(&n, invV, &n, pivots, work, &n, &info)); 225329d8e7bcSMatthew G. Knepley ierr = DMRestoreWorkArray(dm, pdim, PETSC_INT, &pivots);CHKERRQ(ierr); 225429d8e7bcSMatthew G. Knepley ierr = DMRestoreWorkArray(dm, pdim, PETSC_REAL, &work);CHKERRQ(ierr); 225529d8e7bcSMatthew G. Knepley } 225629d8e7bcSMatthew G. Knepley for (p = 0; p < npoints; ++p) { 225729d8e7bcSMatthew G. Knepley if (B) { 225829d8e7bcSMatthew G. Knepley /* Multiply by V^{-1} (pdim x pdim) */ 225929d8e7bcSMatthew G. Knepley for (j = 0; j < pdim; ++j) { 2260d9dbb98eSMatthew G. Knepley const PetscInt i = (p*pdim + j)*comp; 2261d9dbb98eSMatthew G. Knepley PetscInt c; 226229d8e7bcSMatthew G. Knepley 226329d8e7bcSMatthew G. Knepley (*B)[i] = 0.0; 226429d8e7bcSMatthew G. Knepley for (k = 0; k < pdim; ++k) { 226529d8e7bcSMatthew G. Knepley (*B)[i] += invV[k*pdim+j] * tmpB[p*pdim + k]; 226629d8e7bcSMatthew G. Knepley } 2267d9dbb98eSMatthew G. Knepley for (c = 1; c < comp; ++c) { 2268d9dbb98eSMatthew G. Knepley (*B)[i+c] = (*B)[i]; 2269d9dbb98eSMatthew G. Knepley } 227029d8e7bcSMatthew G. Knepley } 227129d8e7bcSMatthew G. Knepley } 227207d6ad7fSMatthew G. Knepley if (D) { 227307d6ad7fSMatthew G. Knepley /* Multiply by V^{-1} (pdim x pdim) */ 227407d6ad7fSMatthew G. Knepley for (j = 0; j < pdim; ++j) { 227507d6ad7fSMatthew G. Knepley for (d = 0; d < dim; ++d) { 227607d6ad7fSMatthew G. Knepley const PetscInt i = ((p*pdim + j)*comp + 0)*dim + d; 227707d6ad7fSMatthew G. Knepley PetscInt c; 227807d6ad7fSMatthew G. Knepley 227907d6ad7fSMatthew G. Knepley (*D)[i] = 0.0; 228007d6ad7fSMatthew G. Knepley for (k = 0; k < pdim; ++k) { 228107d6ad7fSMatthew G. Knepley (*D)[i] += invV[k*pdim+j] * tmpD[(p*pdim + k)*dim + d]; 228207d6ad7fSMatthew G. Knepley } 228307d6ad7fSMatthew G. Knepley for (c = 1; c < comp; ++c) { 228407d6ad7fSMatthew G. Knepley (*D)[((p*pdim + j)*comp + c)*dim + d] = (*D)[i]; 228507d6ad7fSMatthew G. Knepley } 228607d6ad7fSMatthew G. Knepley } 228707d6ad7fSMatthew G. Knepley } 228807d6ad7fSMatthew G. Knepley } 228929d8e7bcSMatthew G. Knepley } 229029d8e7bcSMatthew G. Knepley ierr = DMRestoreWorkArray(dm, pdim*pdim, PETSC_REAL, &invV);CHKERRQ(ierr); 229107d6ad7fSMatthew G. Knepley if (B) {ierr = DMRestoreWorkArray(dm, npoints*pdim, PETSC_REAL, &tmpB);CHKERRQ(ierr);} 229207d6ad7fSMatthew G. Knepley if (D) {ierr = DMRestoreWorkArray(dm, npoints*pdim*dim, PETSC_REAL, &tmpD);CHKERRQ(ierr);} 229329d8e7bcSMatthew G. Knepley PetscFunctionReturn(0); 229429d8e7bcSMatthew G. Knepley } 229529d8e7bcSMatthew G. Knepley 229629d8e7bcSMatthew G. Knepley #undef __FUNCT__ 229729d8e7bcSMatthew G. Knepley #define __FUNCT__ "PetscFERestoreTabulation" 229807d6ad7fSMatthew G. Knepley PetscErrorCode PetscFERestoreTabulation(PetscFE fem, PetscReal **B, PetscReal **D, PetscReal **H) 229929d8e7bcSMatthew G. Knepley { 230029d8e7bcSMatthew G. Knepley DM dm; 230129d8e7bcSMatthew G. Knepley PetscErrorCode ierr; 230229d8e7bcSMatthew G. Knepley 230329d8e7bcSMatthew G. Knepley PetscFunctionBegin; 230429d8e7bcSMatthew G. Knepley PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 230529d8e7bcSMatthew G. Knepley ierr = PetscDualSpaceGetDM(fem->dualSpace, &dm);CHKERRQ(ierr); 230629d8e7bcSMatthew G. Knepley if (B) {ierr = DMRestoreWorkArray(dm, 0, PETSC_REAL, B);CHKERRQ(ierr);} 230729d8e7bcSMatthew G. Knepley if (D) {ierr = DMRestoreWorkArray(dm, 0, PETSC_REAL, D);CHKERRQ(ierr);} 230807d6ad7fSMatthew G. Knepley if (H) {ierr = DMRestoreWorkArray(dm, 0, PETSC_REAL, H);CHKERRQ(ierr);} 230929d8e7bcSMatthew G. Knepley PetscFunctionReturn(0); 231029d8e7bcSMatthew G. Knepley } 2311