120cf1dd8SToby Isaac /* Basis Jet Tabulation 220cf1dd8SToby Isaac 320cf1dd8SToby Isaac We would like to tabulate the nodal basis functions and derivatives at a set of points, usually quadrature points. We 420cf1dd8SToby Isaac follow here the derviation in http://www.math.ttu.edu/~kirby/papers/fiat-toms-2004.pdf. The nodal basis $\psi_i$ can 520cf1dd8SToby Isaac be expressed in terms of a prime basis $\phi_i$ which can be stably evaluated. In PETSc, we will use the Legendre basis 620cf1dd8SToby Isaac as a prime basis. 720cf1dd8SToby Isaac 820cf1dd8SToby Isaac \psi_i = \sum_k \alpha_{ki} \phi_k 920cf1dd8SToby Isaac 1020cf1dd8SToby Isaac Our nodal basis is defined in terms of the dual basis $n_j$ 1120cf1dd8SToby Isaac 1220cf1dd8SToby Isaac n_j \cdot \psi_i = \delta_{ji} 1320cf1dd8SToby Isaac 1420cf1dd8SToby Isaac and we may act on the first equation to obtain 1520cf1dd8SToby Isaac 1620cf1dd8SToby Isaac n_j \cdot \psi_i = \sum_k \alpha_{ki} n_j \cdot \phi_k 1720cf1dd8SToby Isaac \delta_{ji} = \sum_k \alpha_{ki} V_{jk} 1820cf1dd8SToby Isaac I = V \alpha 1920cf1dd8SToby Isaac 2020cf1dd8SToby Isaac so the coefficients of the nodal basis in the prime basis are 2120cf1dd8SToby Isaac 2220cf1dd8SToby Isaac \alpha = V^{-1} 2320cf1dd8SToby Isaac 2420cf1dd8SToby Isaac We will define the dual basis vectors $n_j$ using a quadrature rule. 2520cf1dd8SToby Isaac 2620cf1dd8SToby Isaac Right now, we will just use the polynomial spaces P^k. I know some elements use the space of symmetric polynomials 2720cf1dd8SToby Isaac (I think Nedelec), but we will neglect this for now. Constraints in the space, e.g. Arnold-Winther elements, can 2820cf1dd8SToby Isaac be implemented exactly as in FIAT using functionals $L_j$. 2920cf1dd8SToby Isaac 3020cf1dd8SToby Isaac I will have to count the degrees correctly for the Legendre product when we are on simplices. 3120cf1dd8SToby Isaac 3220cf1dd8SToby Isaac We will have three objects: 3320cf1dd8SToby Isaac - Space, P: this just need point evaluation I think 3420cf1dd8SToby Isaac - 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 3520cf1dd8SToby Isaac - FEM: This keeps {P, P', Q} 3620cf1dd8SToby Isaac */ 3720cf1dd8SToby Isaac #include <petsc/private/petscfeimpl.h> /*I "petscfe.h" I*/ 3820cf1dd8SToby Isaac #include <petscdmplex.h> 3920cf1dd8SToby Isaac 4020cf1dd8SToby Isaac PetscBool FEcite = PETSC_FALSE; 4120cf1dd8SToby Isaac const char FECitation[] = "@article{kirby2004,\n" 4220cf1dd8SToby Isaac " title = {Algorithm 839: FIAT, a New Paradigm for Computing Finite Element Basis Functions},\n" 4320cf1dd8SToby Isaac " journal = {ACM Transactions on Mathematical Software},\n" 4420cf1dd8SToby Isaac " author = {Robert C. Kirby},\n" 4520cf1dd8SToby Isaac " volume = {30},\n" 4620cf1dd8SToby Isaac " number = {4},\n" 4720cf1dd8SToby Isaac " pages = {502--516},\n" 4820cf1dd8SToby Isaac " doi = {10.1145/1039813.1039820},\n" 4920cf1dd8SToby Isaac " year = {2004}\n}\n"; 5020cf1dd8SToby Isaac 5120cf1dd8SToby Isaac PetscClassId PETSCFE_CLASSID = 0; 5220cf1dd8SToby Isaac 53ead873ccSMatthew G. Knepley PetscLogEvent PETSCFE_SetUp; 54ead873ccSMatthew G. Knepley 5520cf1dd8SToby Isaac PetscFunctionList PetscFEList = NULL; 5620cf1dd8SToby Isaac PetscBool PetscFERegisterAllCalled = PETSC_FALSE; 5720cf1dd8SToby Isaac 5820cf1dd8SToby Isaac /*@C 5920cf1dd8SToby Isaac PetscFERegister - Adds a new PetscFE implementation 6020cf1dd8SToby Isaac 6120cf1dd8SToby Isaac Not Collective 6220cf1dd8SToby Isaac 6320cf1dd8SToby Isaac Input Parameters: 6420cf1dd8SToby Isaac + name - The name of a new user-defined creation routine 6520cf1dd8SToby Isaac - create_func - The creation routine itself 6620cf1dd8SToby Isaac 6720cf1dd8SToby Isaac Notes: 6820cf1dd8SToby Isaac PetscFERegister() may be called multiple times to add several user-defined PetscFEs 6920cf1dd8SToby Isaac 7020cf1dd8SToby Isaac Sample usage: 7120cf1dd8SToby Isaac .vb 7220cf1dd8SToby Isaac PetscFERegister("my_fe", MyPetscFECreate); 7320cf1dd8SToby Isaac .ve 7420cf1dd8SToby Isaac 7520cf1dd8SToby Isaac Then, your PetscFE type can be chosen with the procedural interface via 7620cf1dd8SToby Isaac .vb 7720cf1dd8SToby Isaac PetscFECreate(MPI_Comm, PetscFE *); 7820cf1dd8SToby Isaac PetscFESetType(PetscFE, "my_fe"); 7920cf1dd8SToby Isaac .ve 8020cf1dd8SToby Isaac or at runtime via the option 8120cf1dd8SToby Isaac .vb 8220cf1dd8SToby Isaac -petscfe_type my_fe 8320cf1dd8SToby Isaac .ve 8420cf1dd8SToby Isaac 8520cf1dd8SToby Isaac Level: advanced 8620cf1dd8SToby Isaac 87db781477SPatrick Sanan .seealso: `PetscFERegisterAll()`, `PetscFERegisterDestroy()` 8820cf1dd8SToby Isaac 8920cf1dd8SToby Isaac @*/ 909371c9d4SSatish Balay PetscErrorCode PetscFERegister(const char sname[], PetscErrorCode (*function)(PetscFE)) { 9120cf1dd8SToby Isaac PetscFunctionBegin; 929566063dSJacob Faibussowitsch PetscCall(PetscFunctionListAdd(&PetscFEList, sname, function)); 9320cf1dd8SToby Isaac PetscFunctionReturn(0); 9420cf1dd8SToby Isaac } 9520cf1dd8SToby Isaac 9620cf1dd8SToby Isaac /*@C 9720cf1dd8SToby Isaac PetscFESetType - Builds a particular PetscFE 9820cf1dd8SToby Isaac 99d083f849SBarry Smith Collective on fem 10020cf1dd8SToby Isaac 10120cf1dd8SToby Isaac Input Parameters: 10220cf1dd8SToby Isaac + fem - The PetscFE object 10320cf1dd8SToby Isaac - name - The kind of FEM space 10420cf1dd8SToby Isaac 10520cf1dd8SToby Isaac Options Database Key: 10620cf1dd8SToby Isaac . -petscfe_type <type> - Sets the PetscFE type; use -help for a list of available types 10720cf1dd8SToby Isaac 10820cf1dd8SToby Isaac Level: intermediate 10920cf1dd8SToby Isaac 110db781477SPatrick Sanan .seealso: `PetscFEGetType()`, `PetscFECreate()` 11120cf1dd8SToby Isaac @*/ 1129371c9d4SSatish Balay PetscErrorCode PetscFESetType(PetscFE fem, PetscFEType name) { 11320cf1dd8SToby Isaac PetscErrorCode (*r)(PetscFE); 11420cf1dd8SToby Isaac PetscBool match; 11520cf1dd8SToby Isaac 11620cf1dd8SToby Isaac PetscFunctionBegin; 11720cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 1189566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)fem, name, &match)); 11920cf1dd8SToby Isaac if (match) PetscFunctionReturn(0); 12020cf1dd8SToby Isaac 1219566063dSJacob Faibussowitsch if (!PetscFERegisterAllCalled) PetscCall(PetscFERegisterAll()); 1229566063dSJacob Faibussowitsch PetscCall(PetscFunctionListFind(PetscFEList, name, &r)); 12328b400f6SJacob Faibussowitsch PetscCheck(r, PetscObjectComm((PetscObject)fem), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown PetscFE type: %s", name); 12420cf1dd8SToby Isaac 125dbbe0bcdSBarry Smith PetscTryTypeMethod(fem, destroy); 12620cf1dd8SToby Isaac fem->ops->destroy = NULL; 127dbbe0bcdSBarry Smith 1289566063dSJacob Faibussowitsch PetscCall((*r)(fem)); 1299566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)fem, name)); 13020cf1dd8SToby Isaac PetscFunctionReturn(0); 13120cf1dd8SToby Isaac } 13220cf1dd8SToby Isaac 13320cf1dd8SToby Isaac /*@C 13420cf1dd8SToby Isaac PetscFEGetType - Gets the PetscFE type name (as a string) from the object. 13520cf1dd8SToby Isaac 13620cf1dd8SToby Isaac Not Collective 13720cf1dd8SToby Isaac 13820cf1dd8SToby Isaac Input Parameter: 13920cf1dd8SToby Isaac . fem - The PetscFE 14020cf1dd8SToby Isaac 14120cf1dd8SToby Isaac Output Parameter: 14220cf1dd8SToby Isaac . name - The PetscFE type name 14320cf1dd8SToby Isaac 14420cf1dd8SToby Isaac Level: intermediate 14520cf1dd8SToby Isaac 146db781477SPatrick Sanan .seealso: `PetscFESetType()`, `PetscFECreate()` 14720cf1dd8SToby Isaac @*/ 1489371c9d4SSatish Balay PetscErrorCode PetscFEGetType(PetscFE fem, PetscFEType *name) { 14920cf1dd8SToby Isaac PetscFunctionBegin; 15020cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 15120cf1dd8SToby Isaac PetscValidPointer(name, 2); 152*48a46eb9SPierre Jolivet if (!PetscFERegisterAllCalled) PetscCall(PetscFERegisterAll()); 15320cf1dd8SToby Isaac *name = ((PetscObject)fem)->type_name; 15420cf1dd8SToby Isaac PetscFunctionReturn(0); 15520cf1dd8SToby Isaac } 15620cf1dd8SToby Isaac 15720cf1dd8SToby Isaac /*@C 158fe2efc57SMark PetscFEViewFromOptions - View from Options 159fe2efc57SMark 160fe2efc57SMark Collective on PetscFE 161fe2efc57SMark 162fe2efc57SMark Input Parameters: 163fe2efc57SMark + A - the PetscFE object 164fe2efc57SMark . obj - Optional object 165fe2efc57SMark - name - command line option 166fe2efc57SMark 167fe2efc57SMark Level: intermediate 168db781477SPatrick Sanan .seealso: `PetscFE()`, `PetscFEView()`, `PetscObjectViewFromOptions()`, `PetscFECreate()` 169fe2efc57SMark @*/ 1709371c9d4SSatish Balay PetscErrorCode PetscFEViewFromOptions(PetscFE A, PetscObject obj, const char name[]) { 171fe2efc57SMark PetscFunctionBegin; 172fe2efc57SMark PetscValidHeaderSpecific(A, PETSCFE_CLASSID, 1); 1739566063dSJacob Faibussowitsch PetscCall(PetscObjectViewFromOptions((PetscObject)A, obj, name)); 174fe2efc57SMark PetscFunctionReturn(0); 175fe2efc57SMark } 176fe2efc57SMark 177fe2efc57SMark /*@C 17820cf1dd8SToby Isaac PetscFEView - Views a PetscFE 17920cf1dd8SToby Isaac 180d083f849SBarry Smith Collective on fem 18120cf1dd8SToby Isaac 182d8d19677SJose E. Roman Input Parameters: 18320cf1dd8SToby Isaac + fem - the PetscFE object to view 184d9bac1caSLisandro Dalcin - viewer - the viewer 18520cf1dd8SToby Isaac 1862b99622eSMatthew G. Knepley Level: beginner 18720cf1dd8SToby Isaac 188db781477SPatrick Sanan .seealso `PetscFEDestroy()` 18920cf1dd8SToby Isaac @*/ 1909371c9d4SSatish Balay PetscErrorCode PetscFEView(PetscFE fem, PetscViewer viewer) { 191d9bac1caSLisandro Dalcin PetscBool iascii; 19220cf1dd8SToby Isaac 19320cf1dd8SToby Isaac PetscFunctionBegin; 19420cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 195d9bac1caSLisandro Dalcin if (viewer) PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 1969566063dSJacob Faibussowitsch if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)fem), &viewer)); 1979566063dSJacob Faibussowitsch PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)fem, viewer)); 1989566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 199dbbe0bcdSBarry Smith PetscTryTypeMethod(fem, view, viewer); 20020cf1dd8SToby Isaac PetscFunctionReturn(0); 20120cf1dd8SToby Isaac } 20220cf1dd8SToby Isaac 20320cf1dd8SToby Isaac /*@ 20420cf1dd8SToby Isaac PetscFESetFromOptions - sets parameters in a PetscFE from the options database 20520cf1dd8SToby Isaac 206d083f849SBarry Smith Collective on fem 20720cf1dd8SToby Isaac 20820cf1dd8SToby Isaac Input Parameter: 20920cf1dd8SToby Isaac . fem - the PetscFE object to set options for 21020cf1dd8SToby Isaac 21120cf1dd8SToby Isaac Options Database: 212a2b725a8SWilliam Gropp + -petscfe_num_blocks - the number of cell blocks to integrate concurrently 213a2b725a8SWilliam Gropp - -petscfe_num_batches - the number of cell batches to integrate serially 21420cf1dd8SToby Isaac 2152b99622eSMatthew G. Knepley Level: intermediate 21620cf1dd8SToby Isaac 217db781477SPatrick Sanan .seealso `PetscFEView()` 21820cf1dd8SToby Isaac @*/ 2199371c9d4SSatish Balay PetscErrorCode PetscFESetFromOptions(PetscFE fem) { 22020cf1dd8SToby Isaac const char *defaultType; 22120cf1dd8SToby Isaac char name[256]; 22220cf1dd8SToby Isaac PetscBool flg; 22320cf1dd8SToby Isaac 22420cf1dd8SToby Isaac PetscFunctionBegin; 22520cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 22620cf1dd8SToby Isaac if (!((PetscObject)fem)->type_name) { 22720cf1dd8SToby Isaac defaultType = PETSCFEBASIC; 22820cf1dd8SToby Isaac } else { 22920cf1dd8SToby Isaac defaultType = ((PetscObject)fem)->type_name; 23020cf1dd8SToby Isaac } 2319566063dSJacob Faibussowitsch if (!PetscFERegisterAllCalled) PetscCall(PetscFERegisterAll()); 23220cf1dd8SToby Isaac 233d0609cedSBarry Smith PetscObjectOptionsBegin((PetscObject)fem); 2349566063dSJacob Faibussowitsch PetscCall(PetscOptionsFList("-petscfe_type", "Finite element space", "PetscFESetType", PetscFEList, defaultType, name, 256, &flg)); 23520cf1dd8SToby Isaac if (flg) { 2369566063dSJacob Faibussowitsch PetscCall(PetscFESetType(fem, name)); 23720cf1dd8SToby Isaac } else if (!((PetscObject)fem)->type_name) { 2389566063dSJacob Faibussowitsch PetscCall(PetscFESetType(fem, defaultType)); 23920cf1dd8SToby Isaac } 2409566063dSJacob Faibussowitsch PetscCall(PetscOptionsBoundedInt("-petscfe_num_blocks", "The number of cell blocks to integrate concurrently", "PetscSpaceSetTileSizes", fem->numBlocks, &fem->numBlocks, NULL, 1)); 2419566063dSJacob Faibussowitsch PetscCall(PetscOptionsBoundedInt("-petscfe_num_batches", "The number of cell batches to integrate serially", "PetscSpaceSetTileSizes", fem->numBatches, &fem->numBatches, NULL, 1)); 242dbbe0bcdSBarry Smith PetscTryTypeMethod(fem, setfromoptions, PetscOptionsObject); 24320cf1dd8SToby Isaac /* process any options handlers added with PetscObjectAddOptionsHandler() */ 244dbbe0bcdSBarry Smith PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)fem, PetscOptionsObject)); 245d0609cedSBarry Smith PetscOptionsEnd(); 2469566063dSJacob Faibussowitsch PetscCall(PetscFEViewFromOptions(fem, NULL, "-petscfe_view")); 24720cf1dd8SToby Isaac PetscFunctionReturn(0); 24820cf1dd8SToby Isaac } 24920cf1dd8SToby Isaac 25020cf1dd8SToby Isaac /*@C 25120cf1dd8SToby Isaac PetscFESetUp - Construct data structures for the PetscFE 25220cf1dd8SToby Isaac 253d083f849SBarry Smith Collective on fem 25420cf1dd8SToby Isaac 25520cf1dd8SToby Isaac Input Parameter: 25620cf1dd8SToby Isaac . fem - the PetscFE object to setup 25720cf1dd8SToby Isaac 2582b99622eSMatthew G. Knepley Level: intermediate 25920cf1dd8SToby Isaac 260db781477SPatrick Sanan .seealso `PetscFEView()`, `PetscFEDestroy()` 26120cf1dd8SToby Isaac @*/ 2629371c9d4SSatish Balay PetscErrorCode PetscFESetUp(PetscFE fem) { 26320cf1dd8SToby Isaac PetscFunctionBegin; 26420cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 26520cf1dd8SToby Isaac if (fem->setupcalled) PetscFunctionReturn(0); 2669566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(PETSCFE_SetUp, fem, 0, 0, 0)); 26720cf1dd8SToby Isaac fem->setupcalled = PETSC_TRUE; 268dbbe0bcdSBarry Smith PetscTryTypeMethod(fem, setup); 2699566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(PETSCFE_SetUp, fem, 0, 0, 0)); 27020cf1dd8SToby Isaac PetscFunctionReturn(0); 27120cf1dd8SToby Isaac } 27220cf1dd8SToby Isaac 27320cf1dd8SToby Isaac /*@ 27420cf1dd8SToby Isaac PetscFEDestroy - Destroys a PetscFE object 27520cf1dd8SToby Isaac 276d083f849SBarry Smith Collective on fem 27720cf1dd8SToby Isaac 27820cf1dd8SToby Isaac Input Parameter: 27920cf1dd8SToby Isaac . fem - the PetscFE object to destroy 28020cf1dd8SToby Isaac 2812b99622eSMatthew G. Knepley Level: beginner 28220cf1dd8SToby Isaac 283db781477SPatrick Sanan .seealso `PetscFEView()` 28420cf1dd8SToby Isaac @*/ 2859371c9d4SSatish Balay PetscErrorCode PetscFEDestroy(PetscFE *fem) { 28620cf1dd8SToby Isaac PetscFunctionBegin; 28720cf1dd8SToby Isaac if (!*fem) PetscFunctionReturn(0); 28820cf1dd8SToby Isaac PetscValidHeaderSpecific((*fem), PETSCFE_CLASSID, 1); 28920cf1dd8SToby Isaac 2909371c9d4SSatish Balay if (--((PetscObject)(*fem))->refct > 0) { 2919371c9d4SSatish Balay *fem = NULL; 2929371c9d4SSatish Balay PetscFunctionReturn(0); 2939371c9d4SSatish Balay } 29420cf1dd8SToby Isaac ((PetscObject)(*fem))->refct = 0; 29520cf1dd8SToby Isaac 29620cf1dd8SToby Isaac if ((*fem)->subspaces) { 29720cf1dd8SToby Isaac PetscInt dim, d; 29820cf1dd8SToby Isaac 2999566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetDimension((*fem)->dualSpace, &dim)); 3009566063dSJacob Faibussowitsch for (d = 0; d < dim; ++d) PetscCall(PetscFEDestroy(&(*fem)->subspaces[d])); 30120cf1dd8SToby Isaac } 3029566063dSJacob Faibussowitsch PetscCall(PetscFree((*fem)->subspaces)); 3039566063dSJacob Faibussowitsch PetscCall(PetscFree((*fem)->invV)); 3049566063dSJacob Faibussowitsch PetscCall(PetscTabulationDestroy(&(*fem)->T)); 3059566063dSJacob Faibussowitsch PetscCall(PetscTabulationDestroy(&(*fem)->Tf)); 3069566063dSJacob Faibussowitsch PetscCall(PetscTabulationDestroy(&(*fem)->Tc)); 3079566063dSJacob Faibussowitsch PetscCall(PetscSpaceDestroy(&(*fem)->basisSpace)); 3089566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceDestroy(&(*fem)->dualSpace)); 3099566063dSJacob Faibussowitsch PetscCall(PetscQuadratureDestroy(&(*fem)->quadrature)); 3109566063dSJacob Faibussowitsch PetscCall(PetscQuadratureDestroy(&(*fem)->faceQuadrature)); 311f918ec44SMatthew G. Knepley #ifdef PETSC_HAVE_LIBCEED 3129566063dSJacob Faibussowitsch PetscCallCEED(CeedBasisDestroy(&(*fem)->ceedBasis)); 3139566063dSJacob Faibussowitsch PetscCallCEED(CeedDestroy(&(*fem)->ceed)); 314f918ec44SMatthew G. Knepley #endif 31520cf1dd8SToby Isaac 316dbbe0bcdSBarry Smith PetscTryTypeMethod((*fem), destroy); 3179566063dSJacob Faibussowitsch PetscCall(PetscHeaderDestroy(fem)); 31820cf1dd8SToby Isaac PetscFunctionReturn(0); 31920cf1dd8SToby Isaac } 32020cf1dd8SToby Isaac 32120cf1dd8SToby Isaac /*@ 32220cf1dd8SToby Isaac PetscFECreate - Creates an empty PetscFE object. The type can then be set with PetscFESetType(). 32320cf1dd8SToby Isaac 324d083f849SBarry Smith Collective 32520cf1dd8SToby Isaac 32620cf1dd8SToby Isaac Input Parameter: 32720cf1dd8SToby Isaac . comm - The communicator for the PetscFE object 32820cf1dd8SToby Isaac 32920cf1dd8SToby Isaac Output Parameter: 33020cf1dd8SToby Isaac . fem - The PetscFE object 33120cf1dd8SToby Isaac 33220cf1dd8SToby Isaac Level: beginner 33320cf1dd8SToby Isaac 334db781477SPatrick Sanan .seealso: `PetscFESetType()`, `PETSCFEGALERKIN` 33520cf1dd8SToby Isaac @*/ 3369371c9d4SSatish Balay PetscErrorCode PetscFECreate(MPI_Comm comm, PetscFE *fem) { 33720cf1dd8SToby Isaac PetscFE f; 33820cf1dd8SToby Isaac 33920cf1dd8SToby Isaac PetscFunctionBegin; 34020cf1dd8SToby Isaac PetscValidPointer(fem, 2); 3419566063dSJacob Faibussowitsch PetscCall(PetscCitationsRegister(FECitation, &FEcite)); 34220cf1dd8SToby Isaac *fem = NULL; 3439566063dSJacob Faibussowitsch PetscCall(PetscFEInitializePackage()); 34420cf1dd8SToby Isaac 3459566063dSJacob Faibussowitsch PetscCall(PetscHeaderCreate(f, PETSCFE_CLASSID, "PetscFE", "Finite Element", "PetscFE", comm, PetscFEDestroy, PetscFEView)); 34620cf1dd8SToby Isaac 34720cf1dd8SToby Isaac f->basisSpace = NULL; 34820cf1dd8SToby Isaac f->dualSpace = NULL; 34920cf1dd8SToby Isaac f->numComponents = 1; 35020cf1dd8SToby Isaac f->subspaces = NULL; 35120cf1dd8SToby Isaac f->invV = NULL; 352ef0bb6c7SMatthew G. Knepley f->T = NULL; 353ef0bb6c7SMatthew G. Knepley f->Tf = NULL; 354ef0bb6c7SMatthew G. Knepley f->Tc = NULL; 3559566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(&f->quadrature, 1)); 3569566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(&f->faceQuadrature, 1)); 35720cf1dd8SToby Isaac f->blockSize = 0; 35820cf1dd8SToby Isaac f->numBlocks = 1; 35920cf1dd8SToby Isaac f->batchSize = 0; 36020cf1dd8SToby Isaac f->numBatches = 1; 36120cf1dd8SToby Isaac 36220cf1dd8SToby Isaac *fem = f; 36320cf1dd8SToby Isaac PetscFunctionReturn(0); 36420cf1dd8SToby Isaac } 36520cf1dd8SToby Isaac 36620cf1dd8SToby Isaac /*@ 36720cf1dd8SToby Isaac PetscFEGetSpatialDimension - Returns the spatial dimension of the element 36820cf1dd8SToby Isaac 36920cf1dd8SToby Isaac Not collective 37020cf1dd8SToby Isaac 37120cf1dd8SToby Isaac Input Parameter: 37220cf1dd8SToby Isaac . fem - The PetscFE object 37320cf1dd8SToby Isaac 37420cf1dd8SToby Isaac Output Parameter: 37520cf1dd8SToby Isaac . dim - The spatial dimension 37620cf1dd8SToby Isaac 37720cf1dd8SToby Isaac Level: intermediate 37820cf1dd8SToby Isaac 379db781477SPatrick Sanan .seealso: `PetscFECreate()` 38020cf1dd8SToby Isaac @*/ 3819371c9d4SSatish Balay PetscErrorCode PetscFEGetSpatialDimension(PetscFE fem, PetscInt *dim) { 38220cf1dd8SToby Isaac DM dm; 38320cf1dd8SToby Isaac 38420cf1dd8SToby Isaac PetscFunctionBegin; 38520cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 386dadcf809SJacob Faibussowitsch PetscValidIntPointer(dim, 2); 3879566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetDM(fem->dualSpace, &dm)); 3889566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, dim)); 38920cf1dd8SToby Isaac PetscFunctionReturn(0); 39020cf1dd8SToby Isaac } 39120cf1dd8SToby Isaac 39220cf1dd8SToby Isaac /*@ 39320cf1dd8SToby Isaac PetscFESetNumComponents - Sets the number of components in the element 39420cf1dd8SToby Isaac 39520cf1dd8SToby Isaac Not collective 39620cf1dd8SToby Isaac 39720cf1dd8SToby Isaac Input Parameters: 39820cf1dd8SToby Isaac + fem - The PetscFE object 39920cf1dd8SToby Isaac - comp - The number of field components 40020cf1dd8SToby Isaac 40120cf1dd8SToby Isaac Level: intermediate 40220cf1dd8SToby Isaac 403db781477SPatrick Sanan .seealso: `PetscFECreate()` 40420cf1dd8SToby Isaac @*/ 4059371c9d4SSatish Balay PetscErrorCode PetscFESetNumComponents(PetscFE fem, PetscInt comp) { 40620cf1dd8SToby Isaac PetscFunctionBegin; 40720cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 40820cf1dd8SToby Isaac fem->numComponents = comp; 40920cf1dd8SToby Isaac PetscFunctionReturn(0); 41020cf1dd8SToby Isaac } 41120cf1dd8SToby Isaac 41220cf1dd8SToby Isaac /*@ 41320cf1dd8SToby Isaac PetscFEGetNumComponents - Returns the number of components in the element 41420cf1dd8SToby Isaac 41520cf1dd8SToby Isaac Not collective 41620cf1dd8SToby Isaac 41720cf1dd8SToby Isaac Input Parameter: 41820cf1dd8SToby Isaac . fem - The PetscFE object 41920cf1dd8SToby Isaac 42020cf1dd8SToby Isaac Output Parameter: 42120cf1dd8SToby Isaac . comp - The number of field components 42220cf1dd8SToby Isaac 42320cf1dd8SToby Isaac Level: intermediate 42420cf1dd8SToby Isaac 425db781477SPatrick Sanan .seealso: `PetscFECreate()` 42620cf1dd8SToby Isaac @*/ 4279371c9d4SSatish Balay PetscErrorCode PetscFEGetNumComponents(PetscFE fem, PetscInt *comp) { 42820cf1dd8SToby Isaac PetscFunctionBegin; 42920cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 430dadcf809SJacob Faibussowitsch PetscValidIntPointer(comp, 2); 43120cf1dd8SToby Isaac *comp = fem->numComponents; 43220cf1dd8SToby Isaac PetscFunctionReturn(0); 43320cf1dd8SToby Isaac } 43420cf1dd8SToby Isaac 43520cf1dd8SToby Isaac /*@ 43620cf1dd8SToby Isaac PetscFESetTileSizes - Sets the tile sizes for evaluation 43720cf1dd8SToby Isaac 43820cf1dd8SToby Isaac Not collective 43920cf1dd8SToby Isaac 44020cf1dd8SToby Isaac Input Parameters: 44120cf1dd8SToby Isaac + fem - The PetscFE object 44220cf1dd8SToby Isaac . blockSize - The number of elements in a block 44320cf1dd8SToby Isaac . numBlocks - The number of blocks in a batch 44420cf1dd8SToby Isaac . batchSize - The number of elements in a batch 44520cf1dd8SToby Isaac - numBatches - The number of batches in a chunk 44620cf1dd8SToby Isaac 44720cf1dd8SToby Isaac Level: intermediate 44820cf1dd8SToby Isaac 449db781477SPatrick Sanan .seealso: `PetscFECreate()` 45020cf1dd8SToby Isaac @*/ 4519371c9d4SSatish Balay PetscErrorCode PetscFESetTileSizes(PetscFE fem, PetscInt blockSize, PetscInt numBlocks, PetscInt batchSize, PetscInt numBatches) { 45220cf1dd8SToby Isaac PetscFunctionBegin; 45320cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 45420cf1dd8SToby Isaac fem->blockSize = blockSize; 45520cf1dd8SToby Isaac fem->numBlocks = numBlocks; 45620cf1dd8SToby Isaac fem->batchSize = batchSize; 45720cf1dd8SToby Isaac fem->numBatches = numBatches; 45820cf1dd8SToby Isaac PetscFunctionReturn(0); 45920cf1dd8SToby Isaac } 46020cf1dd8SToby Isaac 46120cf1dd8SToby Isaac /*@ 46220cf1dd8SToby Isaac PetscFEGetTileSizes - Returns the tile sizes for evaluation 46320cf1dd8SToby Isaac 46420cf1dd8SToby Isaac Not collective 46520cf1dd8SToby Isaac 46620cf1dd8SToby Isaac Input Parameter: 46720cf1dd8SToby Isaac . fem - The PetscFE object 46820cf1dd8SToby Isaac 46920cf1dd8SToby Isaac Output Parameters: 47020cf1dd8SToby Isaac + blockSize - The number of elements in a block 47120cf1dd8SToby Isaac . numBlocks - The number of blocks in a batch 47220cf1dd8SToby Isaac . batchSize - The number of elements in a batch 47320cf1dd8SToby Isaac - numBatches - The number of batches in a chunk 47420cf1dd8SToby Isaac 47520cf1dd8SToby Isaac Level: intermediate 47620cf1dd8SToby Isaac 477db781477SPatrick Sanan .seealso: `PetscFECreate()` 47820cf1dd8SToby Isaac @*/ 4799371c9d4SSatish Balay PetscErrorCode PetscFEGetTileSizes(PetscFE fem, PetscInt *blockSize, PetscInt *numBlocks, PetscInt *batchSize, PetscInt *numBatches) { 48020cf1dd8SToby Isaac PetscFunctionBegin; 48120cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 482dadcf809SJacob Faibussowitsch if (blockSize) PetscValidIntPointer(blockSize, 2); 483dadcf809SJacob Faibussowitsch if (numBlocks) PetscValidIntPointer(numBlocks, 3); 484dadcf809SJacob Faibussowitsch if (batchSize) PetscValidIntPointer(batchSize, 4); 485dadcf809SJacob Faibussowitsch if (numBatches) PetscValidIntPointer(numBatches, 5); 48620cf1dd8SToby Isaac if (blockSize) *blockSize = fem->blockSize; 48720cf1dd8SToby Isaac if (numBlocks) *numBlocks = fem->numBlocks; 48820cf1dd8SToby Isaac if (batchSize) *batchSize = fem->batchSize; 48920cf1dd8SToby Isaac if (numBatches) *numBatches = fem->numBatches; 49020cf1dd8SToby Isaac PetscFunctionReturn(0); 49120cf1dd8SToby Isaac } 49220cf1dd8SToby Isaac 49320cf1dd8SToby Isaac /*@ 49420cf1dd8SToby Isaac PetscFEGetBasisSpace - Returns the PetscSpace used for approximation of the solution 49520cf1dd8SToby Isaac 49620cf1dd8SToby Isaac Not collective 49720cf1dd8SToby Isaac 49820cf1dd8SToby Isaac Input Parameter: 49920cf1dd8SToby Isaac . fem - The PetscFE object 50020cf1dd8SToby Isaac 50120cf1dd8SToby Isaac Output Parameter: 50220cf1dd8SToby Isaac . sp - The PetscSpace object 50320cf1dd8SToby Isaac 50420cf1dd8SToby Isaac Level: intermediate 50520cf1dd8SToby Isaac 506db781477SPatrick Sanan .seealso: `PetscFECreate()` 50720cf1dd8SToby Isaac @*/ 5089371c9d4SSatish Balay PetscErrorCode PetscFEGetBasisSpace(PetscFE fem, PetscSpace *sp) { 50920cf1dd8SToby Isaac PetscFunctionBegin; 51020cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 51120cf1dd8SToby Isaac PetscValidPointer(sp, 2); 51220cf1dd8SToby Isaac *sp = fem->basisSpace; 51320cf1dd8SToby Isaac PetscFunctionReturn(0); 51420cf1dd8SToby Isaac } 51520cf1dd8SToby Isaac 51620cf1dd8SToby Isaac /*@ 51720cf1dd8SToby Isaac PetscFESetBasisSpace - Sets the PetscSpace used for approximation of the solution 51820cf1dd8SToby Isaac 51920cf1dd8SToby Isaac Not collective 52020cf1dd8SToby Isaac 52120cf1dd8SToby Isaac Input Parameters: 52220cf1dd8SToby Isaac + fem - The PetscFE object 52320cf1dd8SToby Isaac - sp - The PetscSpace object 52420cf1dd8SToby Isaac 52520cf1dd8SToby Isaac Level: intermediate 52620cf1dd8SToby Isaac 527db781477SPatrick Sanan .seealso: `PetscFECreate()` 52820cf1dd8SToby Isaac @*/ 5299371c9d4SSatish Balay PetscErrorCode PetscFESetBasisSpace(PetscFE fem, PetscSpace sp) { 53020cf1dd8SToby Isaac PetscFunctionBegin; 53120cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 53220cf1dd8SToby Isaac PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 2); 5339566063dSJacob Faibussowitsch PetscCall(PetscSpaceDestroy(&fem->basisSpace)); 53420cf1dd8SToby Isaac fem->basisSpace = sp; 5359566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)fem->basisSpace)); 53620cf1dd8SToby Isaac PetscFunctionReturn(0); 53720cf1dd8SToby Isaac } 53820cf1dd8SToby Isaac 53920cf1dd8SToby Isaac /*@ 54020cf1dd8SToby Isaac PetscFEGetDualSpace - Returns the PetscDualSpace used to define the inner product 54120cf1dd8SToby Isaac 54220cf1dd8SToby Isaac Not collective 54320cf1dd8SToby Isaac 54420cf1dd8SToby Isaac Input Parameter: 54520cf1dd8SToby Isaac . fem - The PetscFE object 54620cf1dd8SToby Isaac 54720cf1dd8SToby Isaac Output Parameter: 54820cf1dd8SToby Isaac . sp - The PetscDualSpace object 54920cf1dd8SToby Isaac 55020cf1dd8SToby Isaac Level: intermediate 55120cf1dd8SToby Isaac 552db781477SPatrick Sanan .seealso: `PetscFECreate()` 55320cf1dd8SToby Isaac @*/ 5549371c9d4SSatish Balay PetscErrorCode PetscFEGetDualSpace(PetscFE fem, PetscDualSpace *sp) { 55520cf1dd8SToby Isaac PetscFunctionBegin; 55620cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 55720cf1dd8SToby Isaac PetscValidPointer(sp, 2); 55820cf1dd8SToby Isaac *sp = fem->dualSpace; 55920cf1dd8SToby Isaac PetscFunctionReturn(0); 56020cf1dd8SToby Isaac } 56120cf1dd8SToby Isaac 56220cf1dd8SToby Isaac /*@ 56320cf1dd8SToby Isaac PetscFESetDualSpace - Sets the PetscDualSpace used to define the inner product 56420cf1dd8SToby Isaac 56520cf1dd8SToby Isaac Not collective 56620cf1dd8SToby Isaac 56720cf1dd8SToby Isaac Input Parameters: 56820cf1dd8SToby Isaac + fem - The PetscFE object 56920cf1dd8SToby Isaac - sp - The PetscDualSpace object 57020cf1dd8SToby Isaac 57120cf1dd8SToby Isaac Level: intermediate 57220cf1dd8SToby Isaac 573db781477SPatrick Sanan .seealso: `PetscFECreate()` 57420cf1dd8SToby Isaac @*/ 5759371c9d4SSatish Balay PetscErrorCode PetscFESetDualSpace(PetscFE fem, PetscDualSpace sp) { 57620cf1dd8SToby Isaac PetscFunctionBegin; 57720cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 57820cf1dd8SToby Isaac PetscValidHeaderSpecific(sp, PETSCDUALSPACE_CLASSID, 2); 5799566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceDestroy(&fem->dualSpace)); 58020cf1dd8SToby Isaac fem->dualSpace = sp; 5819566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)fem->dualSpace)); 58220cf1dd8SToby Isaac PetscFunctionReturn(0); 58320cf1dd8SToby Isaac } 58420cf1dd8SToby Isaac 58520cf1dd8SToby Isaac /*@ 58620cf1dd8SToby Isaac PetscFEGetQuadrature - Returns the PetscQuadrature used to calculate inner products 58720cf1dd8SToby Isaac 58820cf1dd8SToby Isaac Not collective 58920cf1dd8SToby Isaac 59020cf1dd8SToby Isaac Input Parameter: 59120cf1dd8SToby Isaac . fem - The PetscFE object 59220cf1dd8SToby Isaac 59320cf1dd8SToby Isaac Output Parameter: 59420cf1dd8SToby Isaac . q - The PetscQuadrature object 59520cf1dd8SToby Isaac 59620cf1dd8SToby Isaac Level: intermediate 59720cf1dd8SToby Isaac 598db781477SPatrick Sanan .seealso: `PetscFECreate()` 59920cf1dd8SToby Isaac @*/ 6009371c9d4SSatish Balay PetscErrorCode PetscFEGetQuadrature(PetscFE fem, PetscQuadrature *q) { 60120cf1dd8SToby Isaac PetscFunctionBegin; 60220cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 60320cf1dd8SToby Isaac PetscValidPointer(q, 2); 60420cf1dd8SToby Isaac *q = fem->quadrature; 60520cf1dd8SToby Isaac PetscFunctionReturn(0); 60620cf1dd8SToby Isaac } 60720cf1dd8SToby Isaac 60820cf1dd8SToby Isaac /*@ 60920cf1dd8SToby Isaac PetscFESetQuadrature - Sets the PetscQuadrature used to calculate inner products 61020cf1dd8SToby Isaac 61120cf1dd8SToby Isaac Not collective 61220cf1dd8SToby Isaac 61320cf1dd8SToby Isaac Input Parameters: 61420cf1dd8SToby Isaac + fem - The PetscFE object 61520cf1dd8SToby Isaac - q - The PetscQuadrature object 61620cf1dd8SToby Isaac 61720cf1dd8SToby Isaac Level: intermediate 61820cf1dd8SToby Isaac 619db781477SPatrick Sanan .seealso: `PetscFECreate()` 62020cf1dd8SToby Isaac @*/ 6219371c9d4SSatish Balay PetscErrorCode PetscFESetQuadrature(PetscFE fem, PetscQuadrature q) { 62220cf1dd8SToby Isaac PetscInt Nc, qNc; 62320cf1dd8SToby Isaac 62420cf1dd8SToby Isaac PetscFunctionBegin; 62520cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 626fd2fdbddSMatthew G. Knepley if (q == fem->quadrature) PetscFunctionReturn(0); 6279566063dSJacob Faibussowitsch PetscCall(PetscFEGetNumComponents(fem, &Nc)); 6289566063dSJacob Faibussowitsch PetscCall(PetscQuadratureGetNumComponents(q, &qNc)); 62963a3b9bcSJacob Faibussowitsch PetscCheck(!(qNc != 1) || !(Nc != qNc), PetscObjectComm((PetscObject)fem), PETSC_ERR_ARG_SIZ, "FE components %" PetscInt_FMT " != Quadrature components %" PetscInt_FMT " and non-scalar quadrature", Nc, qNc); 6309566063dSJacob Faibussowitsch PetscCall(PetscTabulationDestroy(&fem->T)); 6319566063dSJacob Faibussowitsch PetscCall(PetscTabulationDestroy(&fem->Tc)); 6329566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)q)); 6339566063dSJacob Faibussowitsch PetscCall(PetscQuadratureDestroy(&fem->quadrature)); 63420cf1dd8SToby Isaac fem->quadrature = q; 63520cf1dd8SToby Isaac PetscFunctionReturn(0); 63620cf1dd8SToby Isaac } 63720cf1dd8SToby Isaac 63820cf1dd8SToby Isaac /*@ 63920cf1dd8SToby Isaac PetscFEGetFaceQuadrature - Returns the PetscQuadrature used to calculate inner products on faces 64020cf1dd8SToby Isaac 64120cf1dd8SToby Isaac Not collective 64220cf1dd8SToby Isaac 64320cf1dd8SToby Isaac Input Parameter: 64420cf1dd8SToby Isaac . fem - The PetscFE object 64520cf1dd8SToby Isaac 64620cf1dd8SToby Isaac Output Parameter: 64720cf1dd8SToby Isaac . q - The PetscQuadrature object 64820cf1dd8SToby Isaac 64920cf1dd8SToby Isaac Level: intermediate 65020cf1dd8SToby Isaac 651db781477SPatrick Sanan .seealso: `PetscFECreate()` 65220cf1dd8SToby Isaac @*/ 6539371c9d4SSatish Balay PetscErrorCode PetscFEGetFaceQuadrature(PetscFE fem, PetscQuadrature *q) { 65420cf1dd8SToby Isaac PetscFunctionBegin; 65520cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 65620cf1dd8SToby Isaac PetscValidPointer(q, 2); 65720cf1dd8SToby Isaac *q = fem->faceQuadrature; 65820cf1dd8SToby Isaac PetscFunctionReturn(0); 65920cf1dd8SToby Isaac } 66020cf1dd8SToby Isaac 66120cf1dd8SToby Isaac /*@ 66220cf1dd8SToby Isaac PetscFESetFaceQuadrature - Sets the PetscQuadrature used to calculate inner products on faces 66320cf1dd8SToby Isaac 66420cf1dd8SToby Isaac Not collective 66520cf1dd8SToby Isaac 66620cf1dd8SToby Isaac Input Parameters: 66720cf1dd8SToby Isaac + fem - The PetscFE object 66820cf1dd8SToby Isaac - q - The PetscQuadrature object 66920cf1dd8SToby Isaac 67020cf1dd8SToby Isaac Level: intermediate 67120cf1dd8SToby Isaac 672db781477SPatrick Sanan .seealso: `PetscFECreate()` 67320cf1dd8SToby Isaac @*/ 6749371c9d4SSatish Balay PetscErrorCode PetscFESetFaceQuadrature(PetscFE fem, PetscQuadrature q) { 675ef0bb6c7SMatthew G. Knepley PetscInt Nc, qNc; 67620cf1dd8SToby Isaac 67720cf1dd8SToby Isaac PetscFunctionBegin; 67820cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 6799566063dSJacob Faibussowitsch PetscCall(PetscFEGetNumComponents(fem, &Nc)); 6809566063dSJacob Faibussowitsch PetscCall(PetscQuadratureGetNumComponents(q, &qNc)); 68163a3b9bcSJacob Faibussowitsch PetscCheck(!(qNc != 1) || !(Nc != qNc), PetscObjectComm((PetscObject)fem), PETSC_ERR_ARG_SIZ, "FE components %" PetscInt_FMT " != Quadrature components %" PetscInt_FMT " and non-scalar quadrature", Nc, qNc); 6829566063dSJacob Faibussowitsch PetscCall(PetscTabulationDestroy(&fem->Tf)); 6839566063dSJacob Faibussowitsch PetscCall(PetscQuadratureDestroy(&fem->faceQuadrature)); 68420cf1dd8SToby Isaac fem->faceQuadrature = q; 6859566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)q)); 68620cf1dd8SToby Isaac PetscFunctionReturn(0); 68720cf1dd8SToby Isaac } 68820cf1dd8SToby Isaac 6895dc5c000SMatthew G. Knepley /*@ 6905dc5c000SMatthew G. Knepley PetscFECopyQuadrature - Copy both volumetric and surface quadrature 6915dc5c000SMatthew G. Knepley 6925dc5c000SMatthew G. Knepley Not collective 6935dc5c000SMatthew G. Knepley 6945dc5c000SMatthew G. Knepley Input Parameters: 6955dc5c000SMatthew G. Knepley + sfe - The PetscFE source for the quadratures 6965dc5c000SMatthew G. Knepley - tfe - The PetscFE target for the quadratures 6975dc5c000SMatthew G. Knepley 6985dc5c000SMatthew G. Knepley Level: intermediate 6995dc5c000SMatthew G. Knepley 700db781477SPatrick Sanan .seealso: `PetscFECreate()`, `PetscFESetQuadrature()`, `PetscFESetFaceQuadrature()` 7015dc5c000SMatthew G. Knepley @*/ 7029371c9d4SSatish Balay PetscErrorCode PetscFECopyQuadrature(PetscFE sfe, PetscFE tfe) { 7035dc5c000SMatthew G. Knepley PetscQuadrature q; 7045dc5c000SMatthew G. Knepley 7055dc5c000SMatthew G. Knepley PetscFunctionBegin; 7065dc5c000SMatthew G. Knepley PetscValidHeaderSpecific(sfe, PETSCFE_CLASSID, 1); 7075dc5c000SMatthew G. Knepley PetscValidHeaderSpecific(tfe, PETSCFE_CLASSID, 2); 7089566063dSJacob Faibussowitsch PetscCall(PetscFEGetQuadrature(sfe, &q)); 7099566063dSJacob Faibussowitsch PetscCall(PetscFESetQuadrature(tfe, q)); 7109566063dSJacob Faibussowitsch PetscCall(PetscFEGetFaceQuadrature(sfe, &q)); 7119566063dSJacob Faibussowitsch PetscCall(PetscFESetFaceQuadrature(tfe, q)); 7125dc5c000SMatthew G. Knepley PetscFunctionReturn(0); 7135dc5c000SMatthew G. Knepley } 7145dc5c000SMatthew G. Knepley 71520cf1dd8SToby Isaac /*@C 71620cf1dd8SToby Isaac PetscFEGetNumDof - Returns the number of dofs (dual basis vectors) associated to mesh points on the reference cell of a given dimension 71720cf1dd8SToby Isaac 71820cf1dd8SToby Isaac Not collective 71920cf1dd8SToby Isaac 72020cf1dd8SToby Isaac Input Parameter: 72120cf1dd8SToby Isaac . fem - The PetscFE object 72220cf1dd8SToby Isaac 72320cf1dd8SToby Isaac Output Parameter: 72420cf1dd8SToby Isaac . numDof - Array with the number of dofs per dimension 72520cf1dd8SToby Isaac 72620cf1dd8SToby Isaac Level: intermediate 72720cf1dd8SToby Isaac 728db781477SPatrick Sanan .seealso: `PetscFECreate()` 72920cf1dd8SToby Isaac @*/ 7309371c9d4SSatish Balay PetscErrorCode PetscFEGetNumDof(PetscFE fem, const PetscInt **numDof) { 73120cf1dd8SToby Isaac PetscFunctionBegin; 73220cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 73320cf1dd8SToby Isaac PetscValidPointer(numDof, 2); 7349566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetNumDof(fem->dualSpace, numDof)); 73520cf1dd8SToby Isaac PetscFunctionReturn(0); 73620cf1dd8SToby Isaac } 73720cf1dd8SToby Isaac 73820cf1dd8SToby Isaac /*@C 739ef0bb6c7SMatthew G. Knepley PetscFEGetCellTabulation - Returns the tabulation of the basis functions at the quadrature points on the reference cell 74020cf1dd8SToby Isaac 74120cf1dd8SToby Isaac Not collective 74220cf1dd8SToby Isaac 743d8d19677SJose E. Roman Input Parameters: 744f9244615SMatthew G. Knepley + fem - The PetscFE object 745f9244615SMatthew G. Knepley - k - The highest derivative we need to tabulate, very often 1 74620cf1dd8SToby Isaac 747ef0bb6c7SMatthew G. Knepley Output Parameter: 748ef0bb6c7SMatthew G. Knepley . T - The basis function values and derivatives at quadrature points 74920cf1dd8SToby Isaac 75020cf1dd8SToby Isaac Note: 751ef0bb6c7SMatthew G. Knepley $ T->T[0] = B[(p*pdim + i)*Nc + c] is the value at point p for basis function i and component c 752ef0bb6c7SMatthew G. Knepley $ T->T[1] = D[((p*pdim + i)*Nc + c)*dim + d] is the derivative value at point p for basis function i, component c, in direction d 753ef0bb6c7SMatthew G. Knepley $ T->T[2] = H[(((p*pdim + i)*Nc + c)*dim + d)*dim + e] is the value at point p for basis function i, component c, in directions d and e 75420cf1dd8SToby Isaac 75520cf1dd8SToby Isaac Level: intermediate 75620cf1dd8SToby Isaac 757db781477SPatrick Sanan .seealso: `PetscFECreateTabulation()`, `PetscTabulationDestroy()` 75820cf1dd8SToby Isaac @*/ 7599371c9d4SSatish Balay PetscErrorCode PetscFEGetCellTabulation(PetscFE fem, PetscInt k, PetscTabulation *T) { 76020cf1dd8SToby Isaac PetscInt npoints; 76120cf1dd8SToby Isaac const PetscReal *points; 76220cf1dd8SToby Isaac 76320cf1dd8SToby Isaac PetscFunctionBegin; 76420cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 765064a246eSJacob Faibussowitsch PetscValidPointer(T, 3); 7669566063dSJacob Faibussowitsch PetscCall(PetscQuadratureGetData(fem->quadrature, NULL, NULL, &npoints, &points, NULL)); 7679566063dSJacob Faibussowitsch if (!fem->T) PetscCall(PetscFECreateTabulation(fem, 1, npoints, points, k, &fem->T)); 7681dca8a05SBarry Smith PetscCheck(!fem->T || k <= fem->T->K, PetscObjectComm((PetscObject)fem), PETSC_ERR_ARG_OUTOFRANGE, "Requested %" PetscInt_FMT " derivatives, but only tabulated %" PetscInt_FMT, k, fem->T->K); 769ef0bb6c7SMatthew G. Knepley *T = fem->T; 77020cf1dd8SToby Isaac PetscFunctionReturn(0); 77120cf1dd8SToby Isaac } 77220cf1dd8SToby Isaac 7732b99622eSMatthew G. Knepley /*@C 774ef0bb6c7SMatthew G. Knepley PetscFEGetFaceTabulation - Returns the tabulation of the basis functions at the face quadrature points for each face of the reference cell 7752b99622eSMatthew G. Knepley 7762b99622eSMatthew G. Knepley Not collective 7772b99622eSMatthew G. Knepley 778d8d19677SJose E. Roman Input Parameters: 779f9244615SMatthew G. Knepley + fem - The PetscFE object 780f9244615SMatthew G. Knepley - k - The highest derivative we need to tabulate, very often 1 7812b99622eSMatthew G. Knepley 7822b99622eSMatthew G. Knepley Output Parameters: 783a5b23f4aSJose E. Roman . Tf - The basis function values and derivatives at face quadrature points 7842b99622eSMatthew G. Knepley 7852b99622eSMatthew G. Knepley Note: 786ef0bb6c7SMatthew G. Knepley $ T->T[0] = Bf[((f*Nq + q)*pdim + i)*Nc + c] is the value at point f,q for basis function i and component c 787ef0bb6c7SMatthew G. Knepley $ T->T[1] = Df[(((f*Nq + q)*pdim + i)*Nc + c)*dim + d] is the derivative value at point f,q for basis function i, component c, in direction d 788ef0bb6c7SMatthew G. Knepley $ T->T[2] = Hf[((((f*Nq + q)*pdim + i)*Nc + c)*dim + d)*dim + e] is the value at point f,q for basis function i, component c, in directions d and e 7892b99622eSMatthew G. Knepley 7902b99622eSMatthew G. Knepley Level: intermediate 7912b99622eSMatthew G. Knepley 792db781477SPatrick Sanan .seealso: `PetscFEGetCellTabulation()`, `PetscFECreateTabulation()`, `PetscTabulationDestroy()` 7932b99622eSMatthew G. Knepley @*/ 7949371c9d4SSatish Balay PetscErrorCode PetscFEGetFaceTabulation(PetscFE fem, PetscInt k, PetscTabulation *Tf) { 79520cf1dd8SToby Isaac PetscFunctionBegin; 79620cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 797064a246eSJacob Faibussowitsch PetscValidPointer(Tf, 3); 798ef0bb6c7SMatthew G. Knepley if (!fem->Tf) { 79920cf1dd8SToby Isaac const PetscReal xi0[3] = {-1., -1., -1.}; 80020cf1dd8SToby Isaac PetscReal v0[3], J[9], detJ; 80120cf1dd8SToby Isaac PetscQuadrature fq; 80220cf1dd8SToby Isaac PetscDualSpace sp; 80320cf1dd8SToby Isaac DM dm; 80420cf1dd8SToby Isaac const PetscInt *faces; 80520cf1dd8SToby Isaac PetscInt dim, numFaces, f, npoints, q; 80620cf1dd8SToby Isaac const PetscReal *points; 80720cf1dd8SToby Isaac PetscReal *facePoints; 80820cf1dd8SToby Isaac 8099566063dSJacob Faibussowitsch PetscCall(PetscFEGetDualSpace(fem, &sp)); 8109566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetDM(sp, &dm)); 8119566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &dim)); 8129566063dSJacob Faibussowitsch PetscCall(DMPlexGetConeSize(dm, 0, &numFaces)); 8139566063dSJacob Faibussowitsch PetscCall(DMPlexGetCone(dm, 0, &faces)); 8149566063dSJacob Faibussowitsch PetscCall(PetscFEGetFaceQuadrature(fem, &fq)); 81520cf1dd8SToby Isaac if (fq) { 8169566063dSJacob Faibussowitsch PetscCall(PetscQuadratureGetData(fq, NULL, NULL, &npoints, &points, NULL)); 8179566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(numFaces * npoints * dim, &facePoints)); 81820cf1dd8SToby Isaac for (f = 0; f < numFaces; ++f) { 8199566063dSJacob Faibussowitsch PetscCall(DMPlexComputeCellGeometryFEM(dm, faces[f], NULL, v0, J, NULL, &detJ)); 82020cf1dd8SToby Isaac for (q = 0; q < npoints; ++q) CoordinatesRefToReal(dim, dim - 1, xi0, v0, J, &points[q * (dim - 1)], &facePoints[(f * npoints + q) * dim]); 82120cf1dd8SToby Isaac } 8229566063dSJacob Faibussowitsch PetscCall(PetscFECreateTabulation(fem, numFaces, npoints, facePoints, k, &fem->Tf)); 8239566063dSJacob Faibussowitsch PetscCall(PetscFree(facePoints)); 82420cf1dd8SToby Isaac } 82520cf1dd8SToby Isaac } 8261dca8a05SBarry Smith PetscCheck(!fem->Tf || k <= fem->Tf->K, PetscObjectComm((PetscObject)fem), PETSC_ERR_ARG_OUTOFRANGE, "Requested %" PetscInt_FMT " derivatives, but only tabulated %" PetscInt_FMT, k, fem->Tf->K); 827ef0bb6c7SMatthew G. Knepley *Tf = fem->Tf; 82820cf1dd8SToby Isaac PetscFunctionReturn(0); 82920cf1dd8SToby Isaac } 83020cf1dd8SToby Isaac 8312b99622eSMatthew G. Knepley /*@C 832ef0bb6c7SMatthew G. Knepley PetscFEGetFaceCentroidTabulation - Returns the tabulation of the basis functions at the face centroid points 8332b99622eSMatthew G. Knepley 8342b99622eSMatthew G. Knepley Not collective 8352b99622eSMatthew G. Knepley 8362b99622eSMatthew G. Knepley Input Parameter: 8372b99622eSMatthew G. Knepley . fem - The PetscFE object 8382b99622eSMatthew G. Knepley 8392b99622eSMatthew G. Knepley Output Parameters: 840ef0bb6c7SMatthew G. Knepley . Tc - The basis function values at face centroid points 8412b99622eSMatthew G. Knepley 8422b99622eSMatthew G. Knepley Note: 843ef0bb6c7SMatthew G. Knepley $ T->T[0] = Bf[(f*pdim + i)*Nc + c] is the value at point f for basis function i and component c 8442b99622eSMatthew G. Knepley 8452b99622eSMatthew G. Knepley Level: intermediate 8462b99622eSMatthew G. Knepley 847db781477SPatrick Sanan .seealso: `PetscFEGetFaceTabulation()`, `PetscFEGetCellTabulation()`, `PetscFECreateTabulation()`, `PetscTabulationDestroy()` 8482b99622eSMatthew G. Knepley @*/ 8499371c9d4SSatish Balay PetscErrorCode PetscFEGetFaceCentroidTabulation(PetscFE fem, PetscTabulation *Tc) { 85020cf1dd8SToby Isaac PetscFunctionBegin; 85120cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 852ef0bb6c7SMatthew G. Knepley PetscValidPointer(Tc, 2); 853ef0bb6c7SMatthew G. Knepley if (!fem->Tc) { 85420cf1dd8SToby Isaac PetscDualSpace sp; 85520cf1dd8SToby Isaac DM dm; 85620cf1dd8SToby Isaac const PetscInt *cone; 85720cf1dd8SToby Isaac PetscReal *centroids; 85820cf1dd8SToby Isaac PetscInt dim, numFaces, f; 85920cf1dd8SToby Isaac 8609566063dSJacob Faibussowitsch PetscCall(PetscFEGetDualSpace(fem, &sp)); 8619566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetDM(sp, &dm)); 8629566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &dim)); 8639566063dSJacob Faibussowitsch PetscCall(DMPlexGetConeSize(dm, 0, &numFaces)); 8649566063dSJacob Faibussowitsch PetscCall(DMPlexGetCone(dm, 0, &cone)); 8659566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(numFaces * dim, ¢roids)); 8669566063dSJacob Faibussowitsch for (f = 0; f < numFaces; ++f) PetscCall(DMPlexComputeCellGeometryFVM(dm, cone[f], NULL, ¢roids[f * dim], NULL)); 8679566063dSJacob Faibussowitsch PetscCall(PetscFECreateTabulation(fem, 1, numFaces, centroids, 0, &fem->Tc)); 8689566063dSJacob Faibussowitsch PetscCall(PetscFree(centroids)); 86920cf1dd8SToby Isaac } 870ef0bb6c7SMatthew G. Knepley *Tc = fem->Tc; 87120cf1dd8SToby Isaac PetscFunctionReturn(0); 87220cf1dd8SToby Isaac } 87320cf1dd8SToby Isaac 87420cf1dd8SToby Isaac /*@C 875ef0bb6c7SMatthew G. Knepley PetscFECreateTabulation - Tabulates the basis functions, and perhaps derivatives, at the points provided. 87620cf1dd8SToby Isaac 87720cf1dd8SToby Isaac Not collective 87820cf1dd8SToby Isaac 87920cf1dd8SToby Isaac Input Parameters: 88020cf1dd8SToby Isaac + fem - The PetscFE object 881ef0bb6c7SMatthew G. Knepley . nrepl - The number of replicas 882ef0bb6c7SMatthew G. Knepley . npoints - The number of tabulation points in a replica 883ef0bb6c7SMatthew G. Knepley . points - The tabulation point coordinates 884ef0bb6c7SMatthew G. Knepley - K - The number of derivatives calculated 88520cf1dd8SToby Isaac 886ef0bb6c7SMatthew G. Knepley Output Parameter: 887ef0bb6c7SMatthew G. Knepley . T - The basis function values and derivatives at tabulation points 88820cf1dd8SToby Isaac 88920cf1dd8SToby Isaac Note: 890ef0bb6c7SMatthew G. Knepley $ T->T[0] = B[(p*pdim + i)*Nc + c] is the value at point p for basis function i and component c 891ef0bb6c7SMatthew G. Knepley $ T->T[1] = D[((p*pdim + i)*Nc + c)*dim + d] is the derivative value at point p for basis function i, component c, in direction d 892ef0bb6c7SMatthew G. Knepley $ T->T[2] = H[(((p*pdim + i)*Nc + c)*dim + d)*dim + e] is the value at point p for basis function i, component c, in directions d and e 89320cf1dd8SToby Isaac 89420cf1dd8SToby Isaac Level: intermediate 89520cf1dd8SToby Isaac 896db781477SPatrick Sanan .seealso: `PetscFEGetCellTabulation()`, `PetscTabulationDestroy()` 89720cf1dd8SToby Isaac @*/ 8989371c9d4SSatish Balay PetscErrorCode PetscFECreateTabulation(PetscFE fem, PetscInt nrepl, PetscInt npoints, const PetscReal points[], PetscInt K, PetscTabulation *T) { 89920cf1dd8SToby Isaac DM dm; 900ef0bb6c7SMatthew G. Knepley PetscDualSpace Q; 901ef0bb6c7SMatthew G. Knepley PetscInt Nb; /* Dimension of FE space P */ 902ef0bb6c7SMatthew G. Knepley PetscInt Nc; /* Field components */ 903ef0bb6c7SMatthew G. Knepley PetscInt cdim; /* Reference coordinate dimension */ 904ef0bb6c7SMatthew G. Knepley PetscInt k; 90520cf1dd8SToby Isaac 90620cf1dd8SToby Isaac PetscFunctionBegin; 907ef0bb6c7SMatthew G. Knepley if (!npoints || !fem->dualSpace || K < 0) { 908ef0bb6c7SMatthew G. Knepley *T = NULL; 90920cf1dd8SToby Isaac PetscFunctionReturn(0); 91020cf1dd8SToby Isaac } 91120cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 912dadcf809SJacob Faibussowitsch PetscValidRealPointer(points, 4); 91340a2aa30SMatthew G. Knepley PetscValidPointer(T, 6); 9149566063dSJacob Faibussowitsch PetscCall(PetscFEGetDualSpace(fem, &Q)); 9159566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetDM(Q, &dm)); 9169566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &cdim)); 9179566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetDimension(Q, &Nb)); 9189566063dSJacob Faibussowitsch PetscCall(PetscFEGetNumComponents(fem, &Nc)); 9199566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(1, T)); 920ef0bb6c7SMatthew G. Knepley (*T)->K = !cdim ? 0 : K; 921ef0bb6c7SMatthew G. Knepley (*T)->Nr = nrepl; 922ef0bb6c7SMatthew G. Knepley (*T)->Np = npoints; 923ef0bb6c7SMatthew G. Knepley (*T)->Nb = Nb; 924ef0bb6c7SMatthew G. Knepley (*T)->Nc = Nc; 925ef0bb6c7SMatthew G. Knepley (*T)->cdim = cdim; 9269566063dSJacob Faibussowitsch PetscCall(PetscMalloc1((*T)->K + 1, &(*T)->T)); 927*48a46eb9SPierre Jolivet for (k = 0; k <= (*T)->K; ++k) PetscCall(PetscMalloc1(nrepl * npoints * Nb * Nc * PetscPowInt(cdim, k), &(*T)->T[k])); 928dbbe0bcdSBarry Smith PetscUseTypeMethod(fem, createtabulation, nrepl * npoints, points, K, *T); 92920cf1dd8SToby Isaac PetscFunctionReturn(0); 93020cf1dd8SToby Isaac } 93120cf1dd8SToby Isaac 9322b99622eSMatthew G. Knepley /*@C 933ef0bb6c7SMatthew G. Knepley PetscFEComputeTabulation - Tabulates the basis functions, and perhaps derivatives, at the points provided. 9342b99622eSMatthew G. Knepley 9352b99622eSMatthew G. Knepley Not collective 9362b99622eSMatthew G. Knepley 9372b99622eSMatthew G. Knepley Input Parameters: 9382b99622eSMatthew G. Knepley + fem - The PetscFE object 9392b99622eSMatthew G. Knepley . npoints - The number of tabulation points 9402b99622eSMatthew G. Knepley . points - The tabulation point coordinates 941ef0bb6c7SMatthew G. Knepley . K - The number of derivatives calculated 942ef0bb6c7SMatthew G. Knepley - T - An existing tabulation object with enough allocated space 943ef0bb6c7SMatthew G. Knepley 944ef0bb6c7SMatthew G. Knepley Output Parameter: 945ef0bb6c7SMatthew G. Knepley . T - The basis function values and derivatives at tabulation points 9462b99622eSMatthew G. Knepley 9472b99622eSMatthew G. Knepley Note: 948ef0bb6c7SMatthew G. Knepley $ T->T[0] = B[(p*pdim + i)*Nc + c] is the value at point p for basis function i and component c 949ef0bb6c7SMatthew G. Knepley $ T->T[1] = D[((p*pdim + i)*Nc + c)*dim + d] is the derivative value at point p for basis function i, component c, in direction d 950ef0bb6c7SMatthew G. Knepley $ T->T[2] = H[(((p*pdim + i)*Nc + c)*dim + d)*dim + e] is the value at point p for basis function i, component c, in directions d and e 9512b99622eSMatthew G. Knepley 9522b99622eSMatthew G. Knepley Level: intermediate 9532b99622eSMatthew G. Knepley 954db781477SPatrick Sanan .seealso: `PetscFEGetCellTabulation()`, `PetscTabulationDestroy()` 9552b99622eSMatthew G. Knepley @*/ 9569371c9d4SSatish Balay PetscErrorCode PetscFEComputeTabulation(PetscFE fem, PetscInt npoints, const PetscReal points[], PetscInt K, PetscTabulation T) { 957ef0bb6c7SMatthew G. Knepley PetscFunctionBeginHot; 958ef0bb6c7SMatthew G. Knepley if (!npoints || !fem->dualSpace || K < 0) PetscFunctionReturn(0); 959ef0bb6c7SMatthew G. Knepley PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 960dadcf809SJacob Faibussowitsch PetscValidRealPointer(points, 3); 961ef0bb6c7SMatthew G. Knepley PetscValidPointer(T, 5); 96276bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 96320cf1dd8SToby Isaac DM dm; 964ef0bb6c7SMatthew G. Knepley PetscDualSpace Q; 965ef0bb6c7SMatthew G. Knepley PetscInt Nb; /* Dimension of FE space P */ 966ef0bb6c7SMatthew G. Knepley PetscInt Nc; /* Field components */ 967ef0bb6c7SMatthew G. Knepley PetscInt cdim; /* Reference coordinate dimension */ 968ef0bb6c7SMatthew G. Knepley 9699566063dSJacob Faibussowitsch PetscCall(PetscFEGetDualSpace(fem, &Q)); 9709566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetDM(Q, &dm)); 9719566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &cdim)); 9729566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetDimension(Q, &Nb)); 9739566063dSJacob Faibussowitsch PetscCall(PetscFEGetNumComponents(fem, &Nc)); 97463a3b9bcSJacob Faibussowitsch PetscCheck(T->K == (!cdim ? 0 : K), PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Tabulation K %" PetscInt_FMT " must match requested K %" PetscInt_FMT, T->K, !cdim ? 0 : K); 97563a3b9bcSJacob Faibussowitsch PetscCheck(T->Nb == Nb, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Tabulation Nb %" PetscInt_FMT " must match requested Nb %" PetscInt_FMT, T->Nb, Nb); 97663a3b9bcSJacob Faibussowitsch PetscCheck(T->Nc == Nc, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Tabulation Nc %" PetscInt_FMT " must match requested Nc %" PetscInt_FMT, T->Nc, Nc); 97763a3b9bcSJacob Faibussowitsch PetscCheck(T->cdim == cdim, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Tabulation cdim %" PetscInt_FMT " must match requested cdim %" PetscInt_FMT, T->cdim, cdim); 978ef0bb6c7SMatthew G. Knepley } 979ef0bb6c7SMatthew G. Knepley T->Nr = 1; 980ef0bb6c7SMatthew G. Knepley T->Np = npoints; 981dbbe0bcdSBarry Smith PetscUseTypeMethod(fem, createtabulation, npoints, points, K, T); 982ef0bb6c7SMatthew G. Knepley PetscFunctionReturn(0); 983ef0bb6c7SMatthew G. Knepley } 984ef0bb6c7SMatthew G. Knepley 985ef0bb6c7SMatthew G. Knepley /*@C 986ef0bb6c7SMatthew G. Knepley PetscTabulationDestroy - Frees memory from the associated tabulation. 987ef0bb6c7SMatthew G. Knepley 988ef0bb6c7SMatthew G. Knepley Not collective 989ef0bb6c7SMatthew G. Knepley 990ef0bb6c7SMatthew G. Knepley Input Parameter: 991ef0bb6c7SMatthew G. Knepley . T - The tabulation 992ef0bb6c7SMatthew G. Knepley 993ef0bb6c7SMatthew G. Knepley Level: intermediate 994ef0bb6c7SMatthew G. Knepley 995db781477SPatrick Sanan .seealso: `PetscFECreateTabulation()`, `PetscFEGetCellTabulation()` 996ef0bb6c7SMatthew G. Knepley @*/ 9979371c9d4SSatish Balay PetscErrorCode PetscTabulationDestroy(PetscTabulation *T) { 998ef0bb6c7SMatthew G. Knepley PetscInt k; 99920cf1dd8SToby Isaac 100020cf1dd8SToby Isaac PetscFunctionBegin; 1001ef0bb6c7SMatthew G. Knepley PetscValidPointer(T, 1); 1002ef0bb6c7SMatthew G. Knepley if (!T || !(*T)) PetscFunctionReturn(0); 10039566063dSJacob Faibussowitsch for (k = 0; k <= (*T)->K; ++k) PetscCall(PetscFree((*T)->T[k])); 10049566063dSJacob Faibussowitsch PetscCall(PetscFree((*T)->T)); 10059566063dSJacob Faibussowitsch PetscCall(PetscFree(*T)); 1006ef0bb6c7SMatthew G. Knepley *T = NULL; 100720cf1dd8SToby Isaac PetscFunctionReturn(0); 100820cf1dd8SToby Isaac } 100920cf1dd8SToby Isaac 10109371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode PetscFECreatePointTrace(PetscFE fe, PetscInt refPoint, PetscFE *trFE) { 101120cf1dd8SToby Isaac PetscSpace bsp, bsubsp; 101220cf1dd8SToby Isaac PetscDualSpace dsp, dsubsp; 101320cf1dd8SToby Isaac PetscInt dim, depth, numComp, i, j, coneSize, order; 101420cf1dd8SToby Isaac PetscFEType type; 101520cf1dd8SToby Isaac DM dm; 101620cf1dd8SToby Isaac DMLabel label; 101720cf1dd8SToby Isaac PetscReal *xi, *v, *J, detJ; 1018db11e2ebSMatthew G. Knepley const char *name; 101920cf1dd8SToby Isaac PetscQuadrature origin, fullQuad, subQuad; 102020cf1dd8SToby Isaac 102120cf1dd8SToby Isaac PetscFunctionBegin; 102220cf1dd8SToby Isaac PetscValidHeaderSpecific(fe, PETSCFE_CLASSID, 1); 102320cf1dd8SToby Isaac PetscValidPointer(trFE, 3); 10249566063dSJacob Faibussowitsch PetscCall(PetscFEGetBasisSpace(fe, &bsp)); 10259566063dSJacob Faibussowitsch PetscCall(PetscFEGetDualSpace(fe, &dsp)); 10269566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetDM(dsp, &dm)); 10279566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &dim)); 10289566063dSJacob Faibussowitsch PetscCall(DMPlexGetDepthLabel(dm, &label)); 10299566063dSJacob Faibussowitsch PetscCall(DMLabelGetValue(label, refPoint, &depth)); 10309566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(depth, &xi)); 10319566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(dim, &v)); 10329566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(dim * dim, &J)); 103320cf1dd8SToby Isaac for (i = 0; i < depth; i++) xi[i] = 0.; 10349566063dSJacob Faibussowitsch PetscCall(PetscQuadratureCreate(PETSC_COMM_SELF, &origin)); 10359566063dSJacob Faibussowitsch PetscCall(PetscQuadratureSetData(origin, depth, 0, 1, xi, NULL)); 10369566063dSJacob Faibussowitsch PetscCall(DMPlexComputeCellGeometryFEM(dm, refPoint, origin, v, J, NULL, &detJ)); 103720cf1dd8SToby Isaac /* CellGeometryFEM computes the expanded Jacobian, we want the true jacobian */ 103820cf1dd8SToby Isaac for (i = 1; i < dim; i++) { 10399371c9d4SSatish Balay for (j = 0; j < depth; j++) { J[i * depth + j] = J[i * dim + j]; } 104020cf1dd8SToby Isaac } 10419566063dSJacob Faibussowitsch PetscCall(PetscQuadratureDestroy(&origin)); 10429566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetPointSubspace(dsp, refPoint, &dsubsp)); 10439566063dSJacob Faibussowitsch PetscCall(PetscSpaceCreateSubspace(bsp, dsubsp, v, J, NULL, NULL, PETSC_OWN_POINTER, &bsubsp)); 10449566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetUp(bsubsp)); 10459566063dSJacob Faibussowitsch PetscCall(PetscFECreate(PetscObjectComm((PetscObject)fe), trFE)); 10469566063dSJacob Faibussowitsch PetscCall(PetscFEGetType(fe, &type)); 10479566063dSJacob Faibussowitsch PetscCall(PetscFESetType(*trFE, type)); 10489566063dSJacob Faibussowitsch PetscCall(PetscFEGetNumComponents(fe, &numComp)); 10499566063dSJacob Faibussowitsch PetscCall(PetscFESetNumComponents(*trFE, numComp)); 10509566063dSJacob Faibussowitsch PetscCall(PetscFESetBasisSpace(*trFE, bsubsp)); 10519566063dSJacob Faibussowitsch PetscCall(PetscFESetDualSpace(*trFE, dsubsp)); 10529566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)fe, &name)); 10539566063dSJacob Faibussowitsch if (name) PetscCall(PetscFESetName(*trFE, name)); 10549566063dSJacob Faibussowitsch PetscCall(PetscFEGetQuadrature(fe, &fullQuad)); 10559566063dSJacob Faibussowitsch PetscCall(PetscQuadratureGetOrder(fullQuad, &order)); 10569566063dSJacob Faibussowitsch PetscCall(DMPlexGetConeSize(dm, refPoint, &coneSize)); 10571baa6e33SBarry Smith if (coneSize == 2 * depth) PetscCall(PetscDTGaussTensorQuadrature(depth, 1, (order + 1) / 2, -1., 1., &subQuad)); 10581baa6e33SBarry Smith else PetscCall(PetscDTStroudConicalQuadrature(depth, 1, (order + 1) / 2, -1., 1., &subQuad)); 10599566063dSJacob Faibussowitsch PetscCall(PetscFESetQuadrature(*trFE, subQuad)); 10609566063dSJacob Faibussowitsch PetscCall(PetscFESetUp(*trFE)); 10619566063dSJacob Faibussowitsch PetscCall(PetscQuadratureDestroy(&subQuad)); 10629566063dSJacob Faibussowitsch PetscCall(PetscSpaceDestroy(&bsubsp)); 106320cf1dd8SToby Isaac PetscFunctionReturn(0); 106420cf1dd8SToby Isaac } 106520cf1dd8SToby Isaac 10669371c9d4SSatish Balay PetscErrorCode PetscFECreateHeightTrace(PetscFE fe, PetscInt height, PetscFE *trFE) { 106720cf1dd8SToby Isaac PetscInt hStart, hEnd; 106820cf1dd8SToby Isaac PetscDualSpace dsp; 106920cf1dd8SToby Isaac DM dm; 107020cf1dd8SToby Isaac 107120cf1dd8SToby Isaac PetscFunctionBegin; 107220cf1dd8SToby Isaac PetscValidHeaderSpecific(fe, PETSCFE_CLASSID, 1); 107320cf1dd8SToby Isaac PetscValidPointer(trFE, 3); 107420cf1dd8SToby Isaac *trFE = NULL; 10759566063dSJacob Faibussowitsch PetscCall(PetscFEGetDualSpace(fe, &dsp)); 10769566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetDM(dsp, &dm)); 10779566063dSJacob Faibussowitsch PetscCall(DMPlexGetHeightStratum(dm, height, &hStart, &hEnd)); 107820cf1dd8SToby Isaac if (hEnd <= hStart) PetscFunctionReturn(0); 10799566063dSJacob Faibussowitsch PetscCall(PetscFECreatePointTrace(fe, hStart, trFE)); 108020cf1dd8SToby Isaac PetscFunctionReturn(0); 108120cf1dd8SToby Isaac } 108220cf1dd8SToby Isaac 108320cf1dd8SToby Isaac /*@ 108420cf1dd8SToby Isaac PetscFEGetDimension - Get the dimension of the finite element space on a cell 108520cf1dd8SToby Isaac 108620cf1dd8SToby Isaac Not collective 108720cf1dd8SToby Isaac 108820cf1dd8SToby Isaac Input Parameter: 108920cf1dd8SToby Isaac . fe - The PetscFE 109020cf1dd8SToby Isaac 109120cf1dd8SToby Isaac Output Parameter: 109220cf1dd8SToby Isaac . dim - The dimension 109320cf1dd8SToby Isaac 109420cf1dd8SToby Isaac Level: intermediate 109520cf1dd8SToby Isaac 1096db781477SPatrick Sanan .seealso: `PetscFECreate()`, `PetscSpaceGetDimension()`, `PetscDualSpaceGetDimension()` 109720cf1dd8SToby Isaac @*/ 10989371c9d4SSatish Balay PetscErrorCode PetscFEGetDimension(PetscFE fem, PetscInt *dim) { 109920cf1dd8SToby Isaac PetscFunctionBegin; 110020cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 1101dadcf809SJacob Faibussowitsch PetscValidIntPointer(dim, 2); 1102dbbe0bcdSBarry Smith PetscTryTypeMethod(fem, getdimension, dim); 110320cf1dd8SToby Isaac PetscFunctionReturn(0); 110420cf1dd8SToby Isaac } 110520cf1dd8SToby Isaac 11064bee2e38SMatthew G. Knepley /*@C 11074bee2e38SMatthew G. Knepley PetscFEPushforward - Map the reference element function to real space 11084bee2e38SMatthew G. Knepley 11094bee2e38SMatthew G. Knepley Input Parameters: 11104bee2e38SMatthew G. Knepley + fe - The PetscFE 11114bee2e38SMatthew G. Knepley . fegeom - The cell geometry 11124bee2e38SMatthew G. Knepley . Nv - The number of function values 11134bee2e38SMatthew G. Knepley - vals - The function values 11144bee2e38SMatthew G. Knepley 11154bee2e38SMatthew G. Knepley Output Parameter: 11164bee2e38SMatthew G. Knepley . vals - The transformed function values 11174bee2e38SMatthew G. Knepley 11184bee2e38SMatthew G. Knepley Level: advanced 11194bee2e38SMatthew G. Knepley 11204bee2e38SMatthew G. Knepley Note: This just forwards the call onto PetscDualSpacePushforward(). 11214bee2e38SMatthew G. Knepley 1122f9244615SMatthew G. Knepley Note: This only handles transformations when the embedding dimension of the geometry in fegeom is the same as the reference dimension. 11232edcad52SToby Isaac 1124db781477SPatrick Sanan .seealso: `PetscDualSpacePushforward()` 11254bee2e38SMatthew G. Knepley @*/ 11269371c9d4SSatish Balay PetscErrorCode PetscFEPushforward(PetscFE fe, PetscFEGeom *fegeom, PetscInt Nv, PetscScalar vals[]) { 11272ae266adSMatthew G. Knepley PetscFunctionBeginHot; 11289566063dSJacob Faibussowitsch PetscCall(PetscDualSpacePushforward(fe->dualSpace, fegeom, Nv, fe->numComponents, vals)); 11294bee2e38SMatthew G. Knepley PetscFunctionReturn(0); 11304bee2e38SMatthew G. Knepley } 11314bee2e38SMatthew G. Knepley 11324bee2e38SMatthew G. Knepley /*@C 11334bee2e38SMatthew G. Knepley PetscFEPushforwardGradient - Map the reference element function gradient to real space 11344bee2e38SMatthew G. Knepley 11354bee2e38SMatthew G. Knepley Input Parameters: 11364bee2e38SMatthew G. Knepley + fe - The PetscFE 11374bee2e38SMatthew G. Knepley . fegeom - The cell geometry 11384bee2e38SMatthew G. Knepley . Nv - The number of function gradient values 11394bee2e38SMatthew G. Knepley - vals - The function gradient values 11404bee2e38SMatthew G. Knepley 11414bee2e38SMatthew G. Knepley Output Parameter: 11424bee2e38SMatthew G. Knepley . vals - The transformed function gradient values 11434bee2e38SMatthew G. Knepley 11444bee2e38SMatthew G. Knepley Level: advanced 11454bee2e38SMatthew G. Knepley 11464bee2e38SMatthew G. Knepley Note: This just forwards the call onto PetscDualSpacePushforwardGradient(). 11474bee2e38SMatthew G. Knepley 1148f9244615SMatthew G. Knepley Note: This only handles transformations when the embedding dimension of the geometry in fegeom is the same as the reference dimension. 11492edcad52SToby Isaac 1150db781477SPatrick Sanan .seealso: `PetscFEPushforward()`, `PetscDualSpacePushforwardGradient()`, `PetscDualSpacePushforward()` 11514bee2e38SMatthew G. Knepley @*/ 11529371c9d4SSatish Balay PetscErrorCode PetscFEPushforwardGradient(PetscFE fe, PetscFEGeom *fegeom, PetscInt Nv, PetscScalar vals[]) { 11532ae266adSMatthew G. Knepley PetscFunctionBeginHot; 11549566063dSJacob Faibussowitsch PetscCall(PetscDualSpacePushforwardGradient(fe->dualSpace, fegeom, Nv, fe->numComponents, vals)); 11554bee2e38SMatthew G. Knepley PetscFunctionReturn(0); 11564bee2e38SMatthew G. Knepley } 11574bee2e38SMatthew G. Knepley 1158f9244615SMatthew G. Knepley /*@C 1159f9244615SMatthew G. Knepley PetscFEPushforwardHessian - Map the reference element function Hessian to real space 1160f9244615SMatthew G. Knepley 1161f9244615SMatthew G. Knepley Input Parameters: 1162f9244615SMatthew G. Knepley + fe - The PetscFE 1163f9244615SMatthew G. Knepley . fegeom - The cell geometry 1164f9244615SMatthew G. Knepley . Nv - The number of function Hessian values 1165f9244615SMatthew G. Knepley - vals - The function Hessian values 1166f9244615SMatthew G. Knepley 1167f9244615SMatthew G. Knepley Output Parameter: 1168f9244615SMatthew G. Knepley . vals - The transformed function Hessian values 1169f9244615SMatthew G. Knepley 1170f9244615SMatthew G. Knepley Level: advanced 1171f9244615SMatthew G. Knepley 1172f9244615SMatthew G. Knepley Note: This just forwards the call onto PetscDualSpacePushforwardHessian(). 1173f9244615SMatthew G. Knepley 1174f9244615SMatthew G. Knepley Note: This only handles transformations when the embedding dimension of the geometry in fegeom is the same as the reference dimension. 1175f9244615SMatthew G. Knepley 1176db781477SPatrick Sanan .seealso: `PetscFEPushforward()`, `PetscDualSpacePushforwardHessian()`, `PetscDualSpacePushforward()` 1177f9244615SMatthew G. Knepley @*/ 11789371c9d4SSatish Balay PetscErrorCode PetscFEPushforwardHessian(PetscFE fe, PetscFEGeom *fegeom, PetscInt Nv, PetscScalar vals[]) { 1179f9244615SMatthew G. Knepley PetscFunctionBeginHot; 11809566063dSJacob Faibussowitsch PetscCall(PetscDualSpacePushforwardHessian(fe->dualSpace, fegeom, Nv, fe->numComponents, vals)); 1181f9244615SMatthew G. Knepley PetscFunctionReturn(0); 1182f9244615SMatthew G. Knepley } 1183f9244615SMatthew G. Knepley 118420cf1dd8SToby Isaac /* 118520cf1dd8SToby Isaac Purpose: Compute element vector for chunk of elements 118620cf1dd8SToby Isaac 118720cf1dd8SToby Isaac Input: 118820cf1dd8SToby Isaac Sizes: 118920cf1dd8SToby Isaac Ne: number of elements 119020cf1dd8SToby Isaac Nf: number of fields 119120cf1dd8SToby Isaac PetscFE 119220cf1dd8SToby Isaac dim: spatial dimension 119320cf1dd8SToby Isaac Nb: number of basis functions 119420cf1dd8SToby Isaac Nc: number of field components 119520cf1dd8SToby Isaac PetscQuadrature 119620cf1dd8SToby Isaac Nq: number of quadrature points 119720cf1dd8SToby Isaac 119820cf1dd8SToby Isaac Geometry: 119920cf1dd8SToby Isaac PetscFEGeom[Ne] possibly *Nq 120020cf1dd8SToby Isaac PetscReal v0s[dim] 120120cf1dd8SToby Isaac PetscReal n[dim] 120220cf1dd8SToby Isaac PetscReal jacobians[dim*dim] 120320cf1dd8SToby Isaac PetscReal jacobianInverses[dim*dim] 120420cf1dd8SToby Isaac PetscReal jacobianDeterminants 120520cf1dd8SToby Isaac FEM: 120620cf1dd8SToby Isaac PetscFE 120720cf1dd8SToby Isaac PetscQuadrature 120820cf1dd8SToby Isaac PetscReal quadPoints[Nq*dim] 120920cf1dd8SToby Isaac PetscReal quadWeights[Nq] 121020cf1dd8SToby Isaac PetscReal basis[Nq*Nb*Nc] 121120cf1dd8SToby Isaac PetscReal basisDer[Nq*Nb*Nc*dim] 121220cf1dd8SToby Isaac PetscScalar coefficients[Ne*Nb*Nc] 121320cf1dd8SToby Isaac PetscScalar elemVec[Ne*Nb*Nc] 121420cf1dd8SToby Isaac 121520cf1dd8SToby Isaac Problem: 121620cf1dd8SToby Isaac PetscInt f: the active field 121720cf1dd8SToby Isaac f0, f1 121820cf1dd8SToby Isaac 121920cf1dd8SToby Isaac Work Space: 122020cf1dd8SToby Isaac PetscFE 122120cf1dd8SToby Isaac PetscScalar f0[Nq*dim]; 122220cf1dd8SToby Isaac PetscScalar f1[Nq*dim*dim]; 122320cf1dd8SToby Isaac PetscScalar u[Nc]; 122420cf1dd8SToby Isaac PetscScalar gradU[Nc*dim]; 122520cf1dd8SToby Isaac PetscReal x[dim]; 122620cf1dd8SToby Isaac PetscScalar realSpaceDer[dim]; 122720cf1dd8SToby Isaac 122820cf1dd8SToby Isaac Purpose: Compute element vector for N_cb batches of elements 122920cf1dd8SToby Isaac 123020cf1dd8SToby Isaac Input: 123120cf1dd8SToby Isaac Sizes: 123220cf1dd8SToby Isaac N_cb: Number of serial cell batches 123320cf1dd8SToby Isaac 123420cf1dd8SToby Isaac Geometry: 123520cf1dd8SToby Isaac PetscReal v0s[Ne*dim] 123620cf1dd8SToby Isaac PetscReal jacobians[Ne*dim*dim] possibly *Nq 123720cf1dd8SToby Isaac PetscReal jacobianInverses[Ne*dim*dim] possibly *Nq 123820cf1dd8SToby Isaac PetscReal jacobianDeterminants[Ne] possibly *Nq 123920cf1dd8SToby Isaac FEM: 124020cf1dd8SToby Isaac static PetscReal quadPoints[Nq*dim] 124120cf1dd8SToby Isaac static PetscReal quadWeights[Nq] 124220cf1dd8SToby Isaac static PetscReal basis[Nq*Nb*Nc] 124320cf1dd8SToby Isaac static PetscReal basisDer[Nq*Nb*Nc*dim] 124420cf1dd8SToby Isaac PetscScalar coefficients[Ne*Nb*Nc] 124520cf1dd8SToby Isaac PetscScalar elemVec[Ne*Nb*Nc] 124620cf1dd8SToby Isaac 124720cf1dd8SToby Isaac ex62.c: 124820cf1dd8SToby Isaac PetscErrorCode PetscFEIntegrateResidualBatch(PetscInt Ne, PetscInt numFields, PetscInt field, PetscQuadrature quad[], const PetscScalar coefficients[], 124920cf1dd8SToby Isaac const PetscReal v0s[], const PetscReal jacobians[], const PetscReal jacobianInverses[], const PetscReal jacobianDeterminants[], 125020cf1dd8SToby Isaac void (*f0_func)(const PetscScalar u[], const PetscScalar gradU[], const PetscReal x[], PetscScalar f0[]), 125120cf1dd8SToby Isaac void (*f1_func)(const PetscScalar u[], const PetscScalar gradU[], const PetscReal x[], PetscScalar f1[]), PetscScalar elemVec[]) 125220cf1dd8SToby Isaac 125320cf1dd8SToby Isaac ex52.c: 125420cf1dd8SToby Isaac PetscErrorCode IntegrateLaplacianBatchCPU(PetscInt Ne, PetscInt Nb, const PetscScalar coefficients[], const PetscReal jacobianInverses[], const PetscReal jacobianDeterminants[], PetscInt Nq, const PetscReal quadPoints[], const PetscReal quadWeights[], const PetscReal basisTabulation[], const PetscReal basisDerTabulation[], PetscScalar elemVec[], AppCtx *user) 125520cf1dd8SToby Isaac PetscErrorCode IntegrateElasticityBatchCPU(PetscInt Ne, PetscInt Nb, PetscInt Ncomp, const PetscScalar coefficients[], const PetscReal jacobianInverses[], const PetscReal jacobianDeterminants[], PetscInt Nq, const PetscReal quadPoints[], const PetscReal quadWeights[], const PetscReal basisTabulation[], const PetscReal basisDerTabulation[], PetscScalar elemVec[], AppCtx *user) 125620cf1dd8SToby Isaac 125720cf1dd8SToby Isaac ex52_integrateElement.cu 125820cf1dd8SToby Isaac __global__ void integrateElementQuadrature(int N_cb, realType *coefficients, realType *jacobianInverses, realType *jacobianDeterminants, realType *elemVec) 125920cf1dd8SToby Isaac 126020cf1dd8SToby Isaac PETSC_EXTERN PetscErrorCode IntegrateElementBatchGPU(PetscInt spatial_dim, PetscInt Ne, PetscInt Ncb, PetscInt Nbc, PetscInt Nbl, const PetscScalar coefficients[], 126120cf1dd8SToby Isaac const PetscReal jacobianInverses[], const PetscReal jacobianDeterminants[], PetscScalar elemVec[], 126220cf1dd8SToby Isaac PetscLogEvent event, PetscInt debug, PetscInt pde_op) 126320cf1dd8SToby Isaac 126420cf1dd8SToby Isaac ex52_integrateElementOpenCL.c: 126520cf1dd8SToby Isaac PETSC_EXTERN PetscErrorCode IntegrateElementBatchGPU(PetscInt spatial_dim, PetscInt Ne, PetscInt Ncb, PetscInt Nbc, PetscInt N_bl, const PetscScalar coefficients[], 126620cf1dd8SToby Isaac const PetscReal jacobianInverses[], const PetscReal jacobianDeterminants[], PetscScalar elemVec[], 126720cf1dd8SToby Isaac PetscLogEvent event, PetscInt debug, PetscInt pde_op) 126820cf1dd8SToby Isaac 126920cf1dd8SToby Isaac __kernel void integrateElementQuadrature(int N_cb, __global float *coefficients, __global float *jacobianInverses, __global float *jacobianDeterminants, __global float *elemVec) 127020cf1dd8SToby Isaac */ 127120cf1dd8SToby Isaac 127220cf1dd8SToby Isaac /*@C 127320cf1dd8SToby Isaac PetscFEIntegrate - Produce the integral for the given field for a chunk of elements by quadrature integration 127420cf1dd8SToby Isaac 127520cf1dd8SToby Isaac Not collective 127620cf1dd8SToby Isaac 127720cf1dd8SToby Isaac Input Parameters: 1278360cf244SMatthew G. Knepley + prob - The PetscDS specifying the discretizations and continuum functions 127920cf1dd8SToby Isaac . field - The field being integrated 128020cf1dd8SToby Isaac . Ne - The number of elements in the chunk 128120cf1dd8SToby Isaac . cgeom - The cell geometry for each cell in the chunk 128220cf1dd8SToby Isaac . coefficients - The array of FEM basis coefficients for the elements 128320cf1dd8SToby Isaac . probAux - The PetscDS specifying the auxiliary discretizations 128420cf1dd8SToby Isaac - coefficientsAux - The array of FEM auxiliary basis coefficients for the elements 128520cf1dd8SToby Isaac 12867a7aea1fSJed Brown Output Parameter: 128720cf1dd8SToby Isaac . integral - the integral for this field 128820cf1dd8SToby Isaac 12892b99622eSMatthew G. Knepley Level: intermediate 129020cf1dd8SToby Isaac 1291db781477SPatrick Sanan .seealso: `PetscFEIntegrateResidual()` 129220cf1dd8SToby Isaac @*/ 12939371c9d4SSatish Balay PetscErrorCode PetscFEIntegrate(PetscDS prob, PetscInt field, PetscInt Ne, PetscFEGeom *cgeom, const PetscScalar coefficients[], PetscDS probAux, const PetscScalar coefficientsAux[], PetscScalar integral[]) { 12944bee2e38SMatthew G. Knepley PetscFE fe; 129520cf1dd8SToby Isaac 129620cf1dd8SToby Isaac PetscFunctionBegin; 12974bee2e38SMatthew G. Knepley PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 12989566063dSJacob Faibussowitsch PetscCall(PetscDSGetDiscretization(prob, field, (PetscObject *)&fe)); 12999566063dSJacob Faibussowitsch if (fe->ops->integrate) PetscCall((*fe->ops->integrate)(prob, field, Ne, cgeom, coefficients, probAux, coefficientsAux, integral)); 130020cf1dd8SToby Isaac PetscFunctionReturn(0); 130120cf1dd8SToby Isaac } 130220cf1dd8SToby Isaac 130320cf1dd8SToby Isaac /*@C 1304afe6d6adSToby Isaac PetscFEIntegrateBd - Produce the integral for the given field for a chunk of elements by quadrature integration 1305afe6d6adSToby Isaac 1306afe6d6adSToby Isaac Not collective 1307afe6d6adSToby Isaac 1308afe6d6adSToby Isaac Input Parameters: 1309360cf244SMatthew G. Knepley + prob - The PetscDS specifying the discretizations and continuum functions 1310afe6d6adSToby Isaac . field - The field being integrated 1311afe6d6adSToby Isaac . obj_func - The function to be integrated 1312afe6d6adSToby Isaac . Ne - The number of elements in the chunk 1313afe6d6adSToby Isaac . fgeom - The face geometry for each face in the chunk 1314afe6d6adSToby Isaac . coefficients - The array of FEM basis coefficients for the elements 1315afe6d6adSToby Isaac . probAux - The PetscDS specifying the auxiliary discretizations 1316afe6d6adSToby Isaac - coefficientsAux - The array of FEM auxiliary basis coefficients for the elements 1317afe6d6adSToby Isaac 13187a7aea1fSJed Brown Output Parameter: 1319afe6d6adSToby Isaac . integral - the integral for this field 1320afe6d6adSToby Isaac 13212b99622eSMatthew G. Knepley Level: intermediate 1322afe6d6adSToby Isaac 1323db781477SPatrick Sanan .seealso: `PetscFEIntegrateResidual()` 1324afe6d6adSToby Isaac @*/ 13259371c9d4SSatish Balay PetscErrorCode PetscFEIntegrateBd(PetscDS prob, PetscInt field, void (*obj_func)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), PetscInt Ne, PetscFEGeom *geom, const PetscScalar coefficients[], PetscDS probAux, const PetscScalar coefficientsAux[], PetscScalar integral[]) { 13264bee2e38SMatthew G. Knepley PetscFE fe; 1327afe6d6adSToby Isaac 1328afe6d6adSToby Isaac PetscFunctionBegin; 13294bee2e38SMatthew G. Knepley PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 13309566063dSJacob Faibussowitsch PetscCall(PetscDSGetDiscretization(prob, field, (PetscObject *)&fe)); 13319566063dSJacob Faibussowitsch if (fe->ops->integratebd) PetscCall((*fe->ops->integratebd)(prob, field, obj_func, Ne, geom, coefficients, probAux, coefficientsAux, integral)); 1332afe6d6adSToby Isaac PetscFunctionReturn(0); 1333afe6d6adSToby Isaac } 1334afe6d6adSToby Isaac 1335afe6d6adSToby Isaac /*@C 133620cf1dd8SToby Isaac PetscFEIntegrateResidual - Produce the element residual vector for a chunk of elements by quadrature integration 133720cf1dd8SToby Isaac 133820cf1dd8SToby Isaac Not collective 133920cf1dd8SToby Isaac 134020cf1dd8SToby Isaac Input Parameters: 13416528b96dSMatthew G. Knepley + ds - The PetscDS specifying the discretizations and continuum functions 13426528b96dSMatthew G. Knepley . key - The (label+value, field) being integrated 134320cf1dd8SToby Isaac . Ne - The number of elements in the chunk 134420cf1dd8SToby Isaac . cgeom - The cell geometry for each cell in the chunk 134520cf1dd8SToby Isaac . coefficients - The array of FEM basis coefficients for the elements 134620cf1dd8SToby Isaac . coefficients_t - The array of FEM basis time derivative coefficients for the elements 134720cf1dd8SToby Isaac . probAux - The PetscDS specifying the auxiliary discretizations 134820cf1dd8SToby Isaac . coefficientsAux - The array of FEM auxiliary basis coefficients for the elements 134920cf1dd8SToby Isaac - t - The time 135020cf1dd8SToby Isaac 13517a7aea1fSJed Brown Output Parameter: 135220cf1dd8SToby Isaac . elemVec - the element residual vectors from each element 135320cf1dd8SToby Isaac 135420cf1dd8SToby Isaac Note: 135520cf1dd8SToby Isaac $ Loop over batch of elements (e): 135620cf1dd8SToby Isaac $ Loop over quadrature points (q): 135720cf1dd8SToby Isaac $ Make u_q and gradU_q (loops over fields,Nb,Ncomp) and x_q 135820cf1dd8SToby Isaac $ Call f_0 and f_1 135920cf1dd8SToby Isaac $ Loop over element vector entries (f,fc --> i): 136020cf1dd8SToby Isaac $ elemVec[i] += \psi^{fc}_f(q) f0_{fc}(u, \nabla u) + \nabla\psi^{fc}_f(q) \cdot f1_{fc,df}(u, \nabla u) 136120cf1dd8SToby Isaac 13622b99622eSMatthew G. Knepley Level: intermediate 136320cf1dd8SToby Isaac 1364db781477SPatrick Sanan .seealso: `PetscFEIntegrateResidual()` 136520cf1dd8SToby Isaac @*/ 13669371c9d4SSatish Balay PetscErrorCode PetscFEIntegrateResidual(PetscDS ds, PetscFormKey key, PetscInt Ne, PetscFEGeom *cgeom, const PetscScalar coefficients[], const PetscScalar coefficients_t[], PetscDS probAux, const PetscScalar coefficientsAux[], PetscReal t, PetscScalar elemVec[]) { 13674bee2e38SMatthew G. Knepley PetscFE fe; 136820cf1dd8SToby Isaac 13696528b96dSMatthew G. Knepley PetscFunctionBeginHot; 13706528b96dSMatthew G. Knepley PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1); 13719566063dSJacob Faibussowitsch PetscCall(PetscDSGetDiscretization(ds, key.field, (PetscObject *)&fe)); 13729566063dSJacob Faibussowitsch if (fe->ops->integrateresidual) PetscCall((*fe->ops->integrateresidual)(ds, key, Ne, cgeom, coefficients, coefficients_t, probAux, coefficientsAux, t, elemVec)); 137320cf1dd8SToby Isaac PetscFunctionReturn(0); 137420cf1dd8SToby Isaac } 137520cf1dd8SToby Isaac 137620cf1dd8SToby Isaac /*@C 137720cf1dd8SToby Isaac PetscFEIntegrateBdResidual - Produce the element residual vector for a chunk of elements by quadrature integration over a boundary 137820cf1dd8SToby Isaac 137920cf1dd8SToby Isaac Not collective 138020cf1dd8SToby Isaac 138120cf1dd8SToby Isaac Input Parameters: 138206d8a0d3SMatthew G. Knepley + ds - The PetscDS specifying the discretizations and continuum functions 138345480ffeSMatthew G. Knepley . wf - The PetscWeakForm object holding the pointwise functions 138406d8a0d3SMatthew G. Knepley . key - The (label+value, field) being integrated 138520cf1dd8SToby Isaac . Ne - The number of elements in the chunk 138620cf1dd8SToby Isaac . fgeom - The face geometry for each cell in the chunk 138720cf1dd8SToby Isaac . coefficients - The array of FEM basis coefficients for the elements 138820cf1dd8SToby Isaac . coefficients_t - The array of FEM basis time derivative coefficients for the elements 138920cf1dd8SToby Isaac . probAux - The PetscDS specifying the auxiliary discretizations 139020cf1dd8SToby Isaac . coefficientsAux - The array of FEM auxiliary basis coefficients for the elements 139120cf1dd8SToby Isaac - t - The time 139220cf1dd8SToby Isaac 13937a7aea1fSJed Brown Output Parameter: 139420cf1dd8SToby Isaac . elemVec - the element residual vectors from each element 139520cf1dd8SToby Isaac 13962b99622eSMatthew G. Knepley Level: intermediate 139720cf1dd8SToby Isaac 1398db781477SPatrick Sanan .seealso: `PetscFEIntegrateResidual()` 139920cf1dd8SToby Isaac @*/ 14009371c9d4SSatish Balay PetscErrorCode PetscFEIntegrateBdResidual(PetscDS ds, PetscWeakForm wf, PetscFormKey key, PetscInt Ne, PetscFEGeom *fgeom, const PetscScalar coefficients[], const PetscScalar coefficients_t[], PetscDS probAux, const PetscScalar coefficientsAux[], PetscReal t, PetscScalar elemVec[]) { 14014bee2e38SMatthew G. Knepley PetscFE fe; 140220cf1dd8SToby Isaac 140320cf1dd8SToby Isaac PetscFunctionBegin; 140406d8a0d3SMatthew G. Knepley PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1); 14059566063dSJacob Faibussowitsch PetscCall(PetscDSGetDiscretization(ds, key.field, (PetscObject *)&fe)); 14069566063dSJacob Faibussowitsch if (fe->ops->integratebdresidual) PetscCall((*fe->ops->integratebdresidual)(ds, wf, key, Ne, fgeom, coefficients, coefficients_t, probAux, coefficientsAux, t, elemVec)); 140720cf1dd8SToby Isaac PetscFunctionReturn(0); 140820cf1dd8SToby Isaac } 140920cf1dd8SToby Isaac 141020cf1dd8SToby Isaac /*@C 141127f02ce8SMatthew G. Knepley PetscFEIntegrateHybridResidual - Produce the element residual vector for a chunk of hybrid element faces by quadrature integration 141227f02ce8SMatthew G. Knepley 141327f02ce8SMatthew G. Knepley Not collective 141427f02ce8SMatthew G. Knepley 141527f02ce8SMatthew G. Knepley Input Parameters: 141627f02ce8SMatthew G. Knepley + prob - The PetscDS specifying the discretizations and continuum functions 14176528b96dSMatthew G. Knepley . key - The (label+value, field) being integrated 1418c2b7495fSMatthew G. Knepley . s - The side of the cell being integrated, 0 for negative and 1 for positive 141927f02ce8SMatthew G. Knepley . Ne - The number of elements in the chunk 142027f02ce8SMatthew G. Knepley . fgeom - The face geometry for each cell in the chunk 142127f02ce8SMatthew G. Knepley . coefficients - The array of FEM basis coefficients for the elements 142227f02ce8SMatthew G. Knepley . coefficients_t - The array of FEM basis time derivative coefficients for the elements 142327f02ce8SMatthew G. Knepley . probAux - The PetscDS specifying the auxiliary discretizations 142427f02ce8SMatthew G. Knepley . coefficientsAux - The array of FEM auxiliary basis coefficients for the elements 142527f02ce8SMatthew G. Knepley - t - The time 142627f02ce8SMatthew G. Knepley 142727f02ce8SMatthew G. Knepley Output Parameter 142827f02ce8SMatthew G. Knepley . elemVec - the element residual vectors from each element 142927f02ce8SMatthew G. Knepley 143027f02ce8SMatthew G. Knepley Level: developer 143127f02ce8SMatthew G. Knepley 1432db781477SPatrick Sanan .seealso: `PetscFEIntegrateResidual()` 143327f02ce8SMatthew G. Knepley @*/ 14349371c9d4SSatish Balay PetscErrorCode PetscFEIntegrateHybridResidual(PetscDS prob, PetscFormKey key, PetscInt s, PetscInt Ne, PetscFEGeom *fgeom, const PetscScalar coefficients[], const PetscScalar coefficients_t[], PetscDS probAux, const PetscScalar coefficientsAux[], PetscReal t, PetscScalar elemVec[]) { 143527f02ce8SMatthew G. Knepley PetscFE fe; 143627f02ce8SMatthew G. Knepley 143727f02ce8SMatthew G. Knepley PetscFunctionBegin; 143827f02ce8SMatthew G. Knepley PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 14399566063dSJacob Faibussowitsch PetscCall(PetscDSGetDiscretization(prob, key.field, (PetscObject *)&fe)); 14409566063dSJacob Faibussowitsch if (fe->ops->integratehybridresidual) PetscCall((*fe->ops->integratehybridresidual)(prob, key, s, Ne, fgeom, coefficients, coefficients_t, probAux, coefficientsAux, t, elemVec)); 144127f02ce8SMatthew G. Knepley PetscFunctionReturn(0); 144227f02ce8SMatthew G. Knepley } 144327f02ce8SMatthew G. Knepley 144427f02ce8SMatthew G. Knepley /*@C 144520cf1dd8SToby Isaac PetscFEIntegrateJacobian - Produce the element Jacobian for a chunk of elements by quadrature integration 144620cf1dd8SToby Isaac 144720cf1dd8SToby Isaac Not collective 144820cf1dd8SToby Isaac 144920cf1dd8SToby Isaac Input Parameters: 14506528b96dSMatthew G. Knepley + ds - The PetscDS specifying the discretizations and continuum functions 145120cf1dd8SToby Isaac . jtype - The type of matrix pointwise functions that should be used 14526528b96dSMatthew G. Knepley . key - The (label+value, fieldI*Nf + fieldJ) being integrated 14535fedec97SMatthew G. Knepley . s - The side of the cell being integrated, 0 for negative and 1 for positive 145420cf1dd8SToby Isaac . Ne - The number of elements in the chunk 145520cf1dd8SToby Isaac . cgeom - The cell geometry for each cell in the chunk 145620cf1dd8SToby Isaac . coefficients - The array of FEM basis coefficients for the elements for the Jacobian evaluation point 145720cf1dd8SToby Isaac . coefficients_t - The array of FEM basis time derivative coefficients for the elements 145820cf1dd8SToby Isaac . probAux - The PetscDS specifying the auxiliary discretizations 145920cf1dd8SToby Isaac . coefficientsAux - The array of FEM auxiliary basis coefficients for the elements 146020cf1dd8SToby Isaac . t - The time 146120cf1dd8SToby Isaac - u_tShift - A multiplier for the dF/du_t term (as opposed to the dF/du term) 146220cf1dd8SToby Isaac 14637a7aea1fSJed Brown Output Parameter: 146420cf1dd8SToby Isaac . elemMat - the element matrices for the Jacobian from each element 146520cf1dd8SToby Isaac 146620cf1dd8SToby Isaac Note: 146720cf1dd8SToby Isaac $ Loop over batch of elements (e): 146820cf1dd8SToby Isaac $ Loop over element matrix entries (f,fc,g,gc --> i,j): 146920cf1dd8SToby Isaac $ Loop over quadrature points (q): 147020cf1dd8SToby Isaac $ Make u_q and gradU_q (loops over fields,Nb,Ncomp) 147120cf1dd8SToby Isaac $ elemMat[i,j] += \psi^{fc}_f(q) g0_{fc,gc}(u, \nabla u) \phi^{gc}_g(q) 147220cf1dd8SToby Isaac $ + \psi^{fc}_f(q) \cdot g1_{fc,gc,dg}(u, \nabla u) \nabla\phi^{gc}_g(q) 147320cf1dd8SToby Isaac $ + \nabla\psi^{fc}_f(q) \cdot g2_{fc,gc,df}(u, \nabla u) \phi^{gc}_g(q) 147420cf1dd8SToby Isaac $ + \nabla\psi^{fc}_f(q) \cdot g3_{fc,gc,df,dg}(u, \nabla u) \nabla\phi^{gc}_g(q) 14752b99622eSMatthew G. Knepley Level: intermediate 147620cf1dd8SToby Isaac 1477db781477SPatrick Sanan .seealso: `PetscFEIntegrateResidual()` 147820cf1dd8SToby Isaac @*/ 14799371c9d4SSatish Balay PetscErrorCode PetscFEIntegrateJacobian(PetscDS ds, PetscFEJacobianType jtype, PetscFormKey key, PetscInt Ne, PetscFEGeom *cgeom, const PetscScalar coefficients[], const PetscScalar coefficients_t[], PetscDS probAux, const PetscScalar coefficientsAux[], PetscReal t, PetscReal u_tshift, PetscScalar elemMat[]) { 14804bee2e38SMatthew G. Knepley PetscFE fe; 14816528b96dSMatthew G. Knepley PetscInt Nf; 148220cf1dd8SToby Isaac 148320cf1dd8SToby Isaac PetscFunctionBegin; 14846528b96dSMatthew G. Knepley PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1); 14859566063dSJacob Faibussowitsch PetscCall(PetscDSGetNumFields(ds, &Nf)); 14869566063dSJacob Faibussowitsch PetscCall(PetscDSGetDiscretization(ds, key.field / Nf, (PetscObject *)&fe)); 14879566063dSJacob Faibussowitsch if (fe->ops->integratejacobian) PetscCall((*fe->ops->integratejacobian)(ds, jtype, key, Ne, cgeom, coefficients, coefficients_t, probAux, coefficientsAux, t, u_tshift, elemMat)); 148820cf1dd8SToby Isaac PetscFunctionReturn(0); 148920cf1dd8SToby Isaac } 149020cf1dd8SToby Isaac 149120cf1dd8SToby Isaac /*@C 149220cf1dd8SToby Isaac PetscFEIntegrateBdJacobian - Produce the boundary element Jacobian for a chunk of elements by quadrature integration 149320cf1dd8SToby Isaac 149420cf1dd8SToby Isaac Not collective 149520cf1dd8SToby Isaac 149620cf1dd8SToby Isaac Input Parameters: 149745480ffeSMatthew G. Knepley + ds - The PetscDS specifying the discretizations and continuum functions 149845480ffeSMatthew G. Knepley . wf - The PetscWeakForm holding the pointwise functions 149945480ffeSMatthew G. Knepley . key - The (label+value, fieldI*Nf + fieldJ) being integrated 150020cf1dd8SToby Isaac . Ne - The number of elements in the chunk 150120cf1dd8SToby Isaac . fgeom - The face geometry for each cell in the chunk 150220cf1dd8SToby Isaac . coefficients - The array of FEM basis coefficients for the elements for the Jacobian evaluation point 150320cf1dd8SToby Isaac . coefficients_t - The array of FEM basis time derivative coefficients for the elements 150420cf1dd8SToby Isaac . probAux - The PetscDS specifying the auxiliary discretizations 150520cf1dd8SToby Isaac . coefficientsAux - The array of FEM auxiliary basis coefficients for the elements 150620cf1dd8SToby Isaac . t - The time 150720cf1dd8SToby Isaac - u_tShift - A multiplier for the dF/du_t term (as opposed to the dF/du term) 150820cf1dd8SToby Isaac 15097a7aea1fSJed Brown Output Parameter: 151020cf1dd8SToby Isaac . elemMat - the element matrices for the Jacobian from each element 151120cf1dd8SToby Isaac 151220cf1dd8SToby Isaac Note: 151320cf1dd8SToby Isaac $ Loop over batch of elements (e): 151420cf1dd8SToby Isaac $ Loop over element matrix entries (f,fc,g,gc --> i,j): 151520cf1dd8SToby Isaac $ Loop over quadrature points (q): 151620cf1dd8SToby Isaac $ Make u_q and gradU_q (loops over fields,Nb,Ncomp) 151720cf1dd8SToby Isaac $ elemMat[i,j] += \psi^{fc}_f(q) g0_{fc,gc}(u, \nabla u) \phi^{gc}_g(q) 151820cf1dd8SToby Isaac $ + \psi^{fc}_f(q) \cdot g1_{fc,gc,dg}(u, \nabla u) \nabla\phi^{gc}_g(q) 151920cf1dd8SToby Isaac $ + \nabla\psi^{fc}_f(q) \cdot g2_{fc,gc,df}(u, \nabla u) \phi^{gc}_g(q) 152020cf1dd8SToby Isaac $ + \nabla\psi^{fc}_f(q) \cdot g3_{fc,gc,df,dg}(u, \nabla u) \nabla\phi^{gc}_g(q) 15212b99622eSMatthew G. Knepley Level: intermediate 152220cf1dd8SToby Isaac 1523db781477SPatrick Sanan .seealso: `PetscFEIntegrateJacobian()`, `PetscFEIntegrateResidual()` 152420cf1dd8SToby Isaac @*/ 15259371c9d4SSatish Balay PetscErrorCode PetscFEIntegrateBdJacobian(PetscDS ds, PetscWeakForm wf, PetscFormKey key, PetscInt Ne, PetscFEGeom *fgeom, const PetscScalar coefficients[], const PetscScalar coefficients_t[], PetscDS probAux, const PetscScalar coefficientsAux[], PetscReal t, PetscReal u_tshift, PetscScalar elemMat[]) { 15264bee2e38SMatthew G. Knepley PetscFE fe; 152745480ffeSMatthew G. Knepley PetscInt Nf; 152820cf1dd8SToby Isaac 152920cf1dd8SToby Isaac PetscFunctionBegin; 153045480ffeSMatthew G. Knepley PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1); 15319566063dSJacob Faibussowitsch PetscCall(PetscDSGetNumFields(ds, &Nf)); 15329566063dSJacob Faibussowitsch PetscCall(PetscDSGetDiscretization(ds, key.field / Nf, (PetscObject *)&fe)); 15339566063dSJacob Faibussowitsch if (fe->ops->integratebdjacobian) PetscCall((*fe->ops->integratebdjacobian)(ds, wf, key, Ne, fgeom, coefficients, coefficients_t, probAux, coefficientsAux, t, u_tshift, elemMat)); 153420cf1dd8SToby Isaac PetscFunctionReturn(0); 153520cf1dd8SToby Isaac } 153620cf1dd8SToby Isaac 153727f02ce8SMatthew G. Knepley /*@C 153827f02ce8SMatthew G. Knepley PetscFEIntegrateHybridJacobian - Produce the boundary element Jacobian for a chunk of hybrid elements by quadrature integration 153927f02ce8SMatthew G. Knepley 154027f02ce8SMatthew G. Knepley Not collective 154127f02ce8SMatthew G. Knepley 154227f02ce8SMatthew G. Knepley Input Parameters: 154345480ffeSMatthew G. Knepley + ds - The PetscDS specifying the discretizations and continuum functions 154427f02ce8SMatthew G. Knepley . jtype - The type of matrix pointwise functions that should be used 154545480ffeSMatthew G. Knepley . key - The (label+value, fieldI*Nf + fieldJ) being integrated 15465fedec97SMatthew G. Knepley . s - The side of the cell being integrated, 0 for negative and 1 for positive 154727f02ce8SMatthew G. Knepley . Ne - The number of elements in the chunk 154827f02ce8SMatthew G. Knepley . fgeom - The face geometry for each cell in the chunk 154927f02ce8SMatthew G. Knepley . coefficients - The array of FEM basis coefficients for the elements for the Jacobian evaluation point 155027f02ce8SMatthew G. Knepley . coefficients_t - The array of FEM basis time derivative coefficients for the elements 155127f02ce8SMatthew G. Knepley . probAux - The PetscDS specifying the auxiliary discretizations 155227f02ce8SMatthew G. Knepley . coefficientsAux - The array of FEM auxiliary basis coefficients for the elements 155327f02ce8SMatthew G. Knepley . t - The time 155427f02ce8SMatthew G. Knepley - u_tShift - A multiplier for the dF/du_t term (as opposed to the dF/du term) 155527f02ce8SMatthew G. Knepley 155627f02ce8SMatthew G. Knepley Output Parameter 155727f02ce8SMatthew G. Knepley . elemMat - the element matrices for the Jacobian from each element 155827f02ce8SMatthew G. Knepley 155927f02ce8SMatthew G. Knepley Note: 156027f02ce8SMatthew G. Knepley $ Loop over batch of elements (e): 156127f02ce8SMatthew G. Knepley $ Loop over element matrix entries (f,fc,g,gc --> i,j): 156227f02ce8SMatthew G. Knepley $ Loop over quadrature points (q): 156327f02ce8SMatthew G. Knepley $ Make u_q and gradU_q (loops over fields,Nb,Ncomp) 156427f02ce8SMatthew G. Knepley $ elemMat[i,j] += \psi^{fc}_f(q) g0_{fc,gc}(u, \nabla u) \phi^{gc}_g(q) 156527f02ce8SMatthew G. Knepley $ + \psi^{fc}_f(q) \cdot g1_{fc,gc,dg}(u, \nabla u) \nabla\phi^{gc}_g(q) 156627f02ce8SMatthew G. Knepley $ + \nabla\psi^{fc}_f(q) \cdot g2_{fc,gc,df}(u, \nabla u) \phi^{gc}_g(q) 156727f02ce8SMatthew G. Knepley $ + \nabla\psi^{fc}_f(q) \cdot g3_{fc,gc,df,dg}(u, \nabla u) \nabla\phi^{gc}_g(q) 156827f02ce8SMatthew G. Knepley Level: developer 156927f02ce8SMatthew G. Knepley 1570db781477SPatrick Sanan .seealso: `PetscFEIntegrateJacobian()`, `PetscFEIntegrateResidual()` 157127f02ce8SMatthew G. Knepley @*/ 15729371c9d4SSatish Balay PetscErrorCode PetscFEIntegrateHybridJacobian(PetscDS ds, PetscFEJacobianType jtype, PetscFormKey key, PetscInt s, PetscInt Ne, PetscFEGeom *fgeom, const PetscScalar coefficients[], const PetscScalar coefficients_t[], PetscDS probAux, const PetscScalar coefficientsAux[], PetscReal t, PetscReal u_tshift, PetscScalar elemMat[]) { 157327f02ce8SMatthew G. Knepley PetscFE fe; 157445480ffeSMatthew G. Knepley PetscInt Nf; 157527f02ce8SMatthew G. Knepley 157627f02ce8SMatthew G. Knepley PetscFunctionBegin; 157745480ffeSMatthew G. Knepley PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1); 15789566063dSJacob Faibussowitsch PetscCall(PetscDSGetNumFields(ds, &Nf)); 15799566063dSJacob Faibussowitsch PetscCall(PetscDSGetDiscretization(ds, key.field / Nf, (PetscObject *)&fe)); 15809566063dSJacob Faibussowitsch if (fe->ops->integratehybridjacobian) PetscCall((*fe->ops->integratehybridjacobian)(ds, jtype, key, s, Ne, fgeom, coefficients, coefficients_t, probAux, coefficientsAux, t, u_tshift, elemMat)); 158127f02ce8SMatthew G. Knepley PetscFunctionReturn(0); 158227f02ce8SMatthew G. Knepley } 158327f02ce8SMatthew G. Knepley 15842b99622eSMatthew G. Knepley /*@ 15852b99622eSMatthew G. Knepley PetscFEGetHeightSubspace - Get the subspace of this space for a mesh point of a given height 15862b99622eSMatthew G. Knepley 15872b99622eSMatthew G. Knepley Input Parameters: 15882b99622eSMatthew G. Knepley + fe - The finite element space 15892b99622eSMatthew G. Knepley - height - The height of the Plex point 15902b99622eSMatthew G. Knepley 15912b99622eSMatthew G. Knepley Output Parameter: 15922b99622eSMatthew G. Knepley . subfe - The subspace of this FE space 15932b99622eSMatthew G. Knepley 15942b99622eSMatthew G. Knepley Note: For example, if we want the subspace of this space for a face, we would choose height = 1. 15952b99622eSMatthew G. Knepley 15962b99622eSMatthew G. Knepley Level: advanced 15972b99622eSMatthew G. Knepley 1598db781477SPatrick Sanan .seealso: `PetscFECreateDefault()` 15992b99622eSMatthew G. Knepley @*/ 16009371c9d4SSatish Balay PetscErrorCode PetscFEGetHeightSubspace(PetscFE fe, PetscInt height, PetscFE *subfe) { 160120cf1dd8SToby Isaac PetscSpace P, subP; 160220cf1dd8SToby Isaac PetscDualSpace Q, subQ; 160320cf1dd8SToby Isaac PetscQuadrature subq; 160420cf1dd8SToby Isaac PetscFEType fetype; 160520cf1dd8SToby Isaac PetscInt dim, Nc; 160620cf1dd8SToby Isaac 160720cf1dd8SToby Isaac PetscFunctionBegin; 160820cf1dd8SToby Isaac PetscValidHeaderSpecific(fe, PETSCFE_CLASSID, 1); 160920cf1dd8SToby Isaac PetscValidPointer(subfe, 3); 161020cf1dd8SToby Isaac if (height == 0) { 161120cf1dd8SToby Isaac *subfe = fe; 161220cf1dd8SToby Isaac PetscFunctionReturn(0); 161320cf1dd8SToby Isaac } 16149566063dSJacob Faibussowitsch PetscCall(PetscFEGetBasisSpace(fe, &P)); 16159566063dSJacob Faibussowitsch PetscCall(PetscFEGetDualSpace(fe, &Q)); 16169566063dSJacob Faibussowitsch PetscCall(PetscFEGetNumComponents(fe, &Nc)); 16179566063dSJacob Faibussowitsch PetscCall(PetscFEGetFaceQuadrature(fe, &subq)); 16189566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetDimension(Q, &dim)); 16191dca8a05SBarry Smith PetscCheck(height <= dim && height >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Asked for space at height %" PetscInt_FMT " for dimension %" PetscInt_FMT " space", height, dim); 16209566063dSJacob Faibussowitsch if (!fe->subspaces) PetscCall(PetscCalloc1(dim, &fe->subspaces)); 162120cf1dd8SToby Isaac if (height <= dim) { 162220cf1dd8SToby Isaac if (!fe->subspaces[height - 1]) { 1623665f567fSMatthew G. Knepley PetscFE sub = NULL; 16243f6b16c7SMatthew G. Knepley const char *name; 162520cf1dd8SToby Isaac 16269566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetHeightSubspace(P, height, &subP)); 16279566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetHeightSubspace(Q, height, &subQ)); 1628665f567fSMatthew G. Knepley if (subQ) { 16299566063dSJacob Faibussowitsch PetscCall(PetscFECreate(PetscObjectComm((PetscObject)fe), &sub)); 16309566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)fe, &name)); 16319566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)sub, name)); 16329566063dSJacob Faibussowitsch PetscCall(PetscFEGetType(fe, &fetype)); 16339566063dSJacob Faibussowitsch PetscCall(PetscFESetType(sub, fetype)); 16349566063dSJacob Faibussowitsch PetscCall(PetscFESetBasisSpace(sub, subP)); 16359566063dSJacob Faibussowitsch PetscCall(PetscFESetDualSpace(sub, subQ)); 16369566063dSJacob Faibussowitsch PetscCall(PetscFESetNumComponents(sub, Nc)); 16379566063dSJacob Faibussowitsch PetscCall(PetscFESetUp(sub)); 16389566063dSJacob Faibussowitsch PetscCall(PetscFESetQuadrature(sub, subq)); 1639665f567fSMatthew G. Knepley } 164020cf1dd8SToby Isaac fe->subspaces[height - 1] = sub; 164120cf1dd8SToby Isaac } 164220cf1dd8SToby Isaac *subfe = fe->subspaces[height - 1]; 164320cf1dd8SToby Isaac } else { 164420cf1dd8SToby Isaac *subfe = NULL; 164520cf1dd8SToby Isaac } 164620cf1dd8SToby Isaac PetscFunctionReturn(0); 164720cf1dd8SToby Isaac } 164820cf1dd8SToby Isaac 164920cf1dd8SToby Isaac /*@ 165020cf1dd8SToby Isaac PetscFERefine - Create a "refined" PetscFE object that refines the reference cell into smaller copies. This is typically used 165120cf1dd8SToby Isaac to precondition a higher order method with a lower order method on a refined mesh having the same number of dofs (but more 165220cf1dd8SToby Isaac sparsity). It is also used to create an interpolation between regularly refined meshes. 165320cf1dd8SToby Isaac 1654d083f849SBarry Smith Collective on fem 165520cf1dd8SToby Isaac 165620cf1dd8SToby Isaac Input Parameter: 165720cf1dd8SToby Isaac . fe - The initial PetscFE 165820cf1dd8SToby Isaac 165920cf1dd8SToby Isaac Output Parameter: 166020cf1dd8SToby Isaac . feRef - The refined PetscFE 166120cf1dd8SToby Isaac 16622b99622eSMatthew G. Knepley Level: advanced 166320cf1dd8SToby Isaac 1664db781477SPatrick Sanan .seealso: `PetscFEType`, `PetscFECreate()`, `PetscFESetType()` 166520cf1dd8SToby Isaac @*/ 16669371c9d4SSatish Balay PetscErrorCode PetscFERefine(PetscFE fe, PetscFE *feRef) { 166720cf1dd8SToby Isaac PetscSpace P, Pref; 166820cf1dd8SToby Isaac PetscDualSpace Q, Qref; 166920cf1dd8SToby Isaac DM K, Kref; 167020cf1dd8SToby Isaac PetscQuadrature q, qref; 167120cf1dd8SToby Isaac const PetscReal *v0, *jac; 167220cf1dd8SToby Isaac PetscInt numComp, numSubelements; 16731ac17e89SToby Isaac PetscInt cStart, cEnd, c; 16741ac17e89SToby Isaac PetscDualSpace *cellSpaces; 167520cf1dd8SToby Isaac 167620cf1dd8SToby Isaac PetscFunctionBegin; 16779566063dSJacob Faibussowitsch PetscCall(PetscFEGetBasisSpace(fe, &P)); 16789566063dSJacob Faibussowitsch PetscCall(PetscFEGetDualSpace(fe, &Q)); 16799566063dSJacob Faibussowitsch PetscCall(PetscFEGetQuadrature(fe, &q)); 16809566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetDM(Q, &K)); 168120cf1dd8SToby Isaac /* Create space */ 16829566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)P)); 168320cf1dd8SToby Isaac Pref = P; 168420cf1dd8SToby Isaac /* Create dual space */ 16859566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceDuplicate(Q, &Qref)); 16869566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetType(Qref, PETSCDUALSPACEREFINED)); 16879566063dSJacob Faibussowitsch PetscCall(DMRefine(K, PetscObjectComm((PetscObject)fe), &Kref)); 16889566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetDM(Qref, Kref)); 16899566063dSJacob Faibussowitsch PetscCall(DMPlexGetHeightStratum(Kref, 0, &cStart, &cEnd)); 16909566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(cEnd - cStart, &cellSpaces)); 16911ac17e89SToby Isaac /* TODO: fix for non-uniform refinement */ 16921ac17e89SToby Isaac for (c = 0; c < cEnd - cStart; c++) cellSpaces[c] = Q; 16939566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceRefinedSetCellSpaces(Qref, cellSpaces)); 16949566063dSJacob Faibussowitsch PetscCall(PetscFree(cellSpaces)); 16959566063dSJacob Faibussowitsch PetscCall(DMDestroy(&Kref)); 16969566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetUp(Qref)); 169720cf1dd8SToby Isaac /* Create element */ 16989566063dSJacob Faibussowitsch PetscCall(PetscFECreate(PetscObjectComm((PetscObject)fe), feRef)); 16999566063dSJacob Faibussowitsch PetscCall(PetscFESetType(*feRef, PETSCFECOMPOSITE)); 17009566063dSJacob Faibussowitsch PetscCall(PetscFESetBasisSpace(*feRef, Pref)); 17019566063dSJacob Faibussowitsch PetscCall(PetscFESetDualSpace(*feRef, Qref)); 17029566063dSJacob Faibussowitsch PetscCall(PetscFEGetNumComponents(fe, &numComp)); 17039566063dSJacob Faibussowitsch PetscCall(PetscFESetNumComponents(*feRef, numComp)); 17049566063dSJacob Faibussowitsch PetscCall(PetscFESetUp(*feRef)); 17059566063dSJacob Faibussowitsch PetscCall(PetscSpaceDestroy(&Pref)); 17069566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceDestroy(&Qref)); 170720cf1dd8SToby Isaac /* Create quadrature */ 17089566063dSJacob Faibussowitsch PetscCall(PetscFECompositeGetMapping(*feRef, &numSubelements, &v0, &jac, NULL)); 17099566063dSJacob Faibussowitsch PetscCall(PetscQuadratureExpandComposite(q, numSubelements, v0, jac, &qref)); 17109566063dSJacob Faibussowitsch PetscCall(PetscFESetQuadrature(*feRef, qref)); 17119566063dSJacob Faibussowitsch PetscCall(PetscQuadratureDestroy(&qref)); 171220cf1dd8SToby Isaac PetscFunctionReturn(0); 171320cf1dd8SToby Isaac } 171420cf1dd8SToby Isaac 17159371c9d4SSatish Balay static PetscErrorCode PetscFESetDefaultName_Private(PetscFE fe) { 17167c48043bSMatthew G. Knepley PetscSpace P; 17177c48043bSMatthew G. Knepley PetscDualSpace Q; 17187c48043bSMatthew G. Knepley DM K; 17197c48043bSMatthew G. Knepley DMPolytopeType ct; 17207c48043bSMatthew G. Knepley PetscInt degree; 17217c48043bSMatthew G. Knepley char name[64]; 17227c48043bSMatthew G. Knepley 17237c48043bSMatthew G. Knepley PetscFunctionBegin; 17247c48043bSMatthew G. Knepley PetscCall(PetscFEGetBasisSpace(fe, &P)); 17257c48043bSMatthew G. Knepley PetscCall(PetscSpaceGetDegree(P, °ree, NULL)); 17267c48043bSMatthew G. Knepley PetscCall(PetscFEGetDualSpace(fe, &Q)); 17277c48043bSMatthew G. Knepley PetscCall(PetscDualSpaceGetDM(Q, &K)); 17287c48043bSMatthew G. Knepley PetscCall(DMPlexGetCellType(K, 0, &ct)); 17297c48043bSMatthew G. Knepley switch (ct) { 17307c48043bSMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 17317c48043bSMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: 17327c48043bSMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 17337c48043bSMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 17347c48043bSMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 17359371c9d4SSatish Balay case DM_POLYTOPE_QUAD_PRISM_TENSOR: PetscCall(PetscSNPrintf(name, sizeof(name), "Q%" PetscInt_FMT, degree)); break; 17367c48043bSMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 17379371c9d4SSatish Balay case DM_POLYTOPE_TETRAHEDRON: PetscCall(PetscSNPrintf(name, sizeof(name), "P%" PetscInt_FMT, degree)); break; 17387c48043bSMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM: 17399371c9d4SSatish Balay case DM_POLYTOPE_TRI_PRISM_TENSOR: PetscCall(PetscSNPrintf(name, sizeof(name), "P%" PetscInt_FMT "xQ%" PetscInt_FMT, degree, degree)); break; 17409371c9d4SSatish Balay default: PetscCall(PetscSNPrintf(name, sizeof(name), "FE")); 17417c48043bSMatthew G. Knepley } 17427c48043bSMatthew G. Knepley PetscCall(PetscFESetName(fe, name)); 17437c48043bSMatthew G. Knepley PetscFunctionReturn(0); 17447c48043bSMatthew G. Knepley } 17457c48043bSMatthew G. Knepley 17469371c9d4SSatish Balay static PetscErrorCode PetscFECreateDefaultQuadrature_Private(PetscInt dim, DMPolytopeType ct, PetscInt qorder, PetscQuadrature *q, PetscQuadrature *fq) { 17477c48043bSMatthew G. Knepley const PetscInt quadPointsPerEdge = PetscMax(qorder + 1, 1); 17487c48043bSMatthew G. Knepley 17497c48043bSMatthew G. Knepley PetscFunctionBegin; 17507c48043bSMatthew G. Knepley switch (ct) { 17517c48043bSMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 17527c48043bSMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: 17537c48043bSMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 17547c48043bSMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 17557c48043bSMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 17567c48043bSMatthew G. Knepley case DM_POLYTOPE_QUAD_PRISM_TENSOR: 17577c48043bSMatthew G. Knepley PetscCall(PetscDTGaussTensorQuadrature(dim, 1, quadPointsPerEdge, -1.0, 1.0, q)); 17587c48043bSMatthew G. Knepley PetscCall(PetscDTGaussTensorQuadrature(dim - 1, 1, quadPointsPerEdge, -1.0, 1.0, fq)); 17597c48043bSMatthew G. Knepley break; 17607c48043bSMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 17617c48043bSMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: 17627c48043bSMatthew G. Knepley PetscCall(PetscDTStroudConicalQuadrature(dim, 1, quadPointsPerEdge, -1.0, 1.0, q)); 17637c48043bSMatthew G. Knepley PetscCall(PetscDTStroudConicalQuadrature(dim - 1, 1, quadPointsPerEdge, -1.0, 1.0, fq)); 17647c48043bSMatthew G. Knepley break; 17657c48043bSMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM: 17669371c9d4SSatish Balay case DM_POLYTOPE_TRI_PRISM_TENSOR: { 17677c48043bSMatthew G. Knepley PetscQuadrature q1, q2; 17687c48043bSMatthew G. Knepley 17697c48043bSMatthew G. Knepley PetscCall(PetscDTStroudConicalQuadrature(2, 1, quadPointsPerEdge, -1.0, 1.0, &q1)); 17707c48043bSMatthew G. Knepley PetscCall(PetscDTGaussTensorQuadrature(1, 1, quadPointsPerEdge, -1.0, 1.0, &q2)); 17717c48043bSMatthew G. Knepley PetscCall(PetscDTTensorQuadratureCreate(q1, q2, q)); 17727c48043bSMatthew G. Knepley PetscCall(PetscQuadratureDestroy(&q1)); 17737c48043bSMatthew G. Knepley PetscCall(PetscQuadratureDestroy(&q2)); 17747c48043bSMatthew G. Knepley } 17757c48043bSMatthew G. Knepley PetscCall(PetscDTStroudConicalQuadrature(dim - 1, 1, quadPointsPerEdge, -1.0, 1.0, fq)); 17767c48043bSMatthew G. Knepley /* TODO Need separate quadratures for each face */ 17777c48043bSMatthew G. Knepley break; 17787c48043bSMatthew G. Knepley default: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No quadrature for celltype %s", DMPolytopeTypes[PetscMin(ct, DM_POLYTOPE_UNKNOWN)]); 17797c48043bSMatthew G. Knepley } 17807c48043bSMatthew G. Knepley PetscFunctionReturn(0); 17817c48043bSMatthew G. Knepley } 17827c48043bSMatthew G. Knepley 17837c48043bSMatthew G. Knepley /*@ 17847c48043bSMatthew G. Knepley PetscFECreateFromSpaces - Create a PetscFE from the basis and dual spaces 17857c48043bSMatthew G. Knepley 17867c48043bSMatthew G. Knepley Collective 17877c48043bSMatthew G. Knepley 17887c48043bSMatthew G. Knepley Input Parameters: 17897c48043bSMatthew G. Knepley + P - The basis space 17907c48043bSMatthew G. Knepley . Q - The dual space 17917c48043bSMatthew G. Knepley . q - The cell quadrature 17927c48043bSMatthew G. Knepley - fq - The face quadrature 17937c48043bSMatthew G. Knepley 17947c48043bSMatthew G. Knepley Output Parameter: 17957c48043bSMatthew G. Knepley . fem - The PetscFE object 17967c48043bSMatthew G. Knepley 17977c48043bSMatthew G. Knepley Note: 17987c48043bSMatthew G. Knepley The PetscFE takes ownership of these spaces by calling destroy on each. They should not be used after this call, and for borrowed references from `PetscFEGetSpace()` and the like, the caller must use `PetscObjectReference` before this call. 17997c48043bSMatthew G. Knepley 18007c48043bSMatthew G. Knepley Level: beginner 18017c48043bSMatthew G. Knepley 18027c48043bSMatthew G. Knepley .seealso: `PetscFECreateLagrangeByCell()`, `PetscFECreateDefault()`, `PetscFECreateByCell()`, `PetscFECreate()`, `PetscSpaceCreate()`, `PetscDualSpaceCreate()` 18037c48043bSMatthew G. Knepley @*/ 18049371c9d4SSatish Balay PetscErrorCode PetscFECreateFromSpaces(PetscSpace P, PetscDualSpace Q, PetscQuadrature q, PetscQuadrature fq, PetscFE *fem) { 18057c48043bSMatthew G. Knepley PetscInt Nc; 18067c48043bSMatthew G. Knepley const char *prefix; 18077c48043bSMatthew G. Knepley 18087c48043bSMatthew G. Knepley PetscFunctionBegin; 18097c48043bSMatthew G. Knepley PetscCall(PetscFECreate(PetscObjectComm((PetscObject)P), fem)); 18107c48043bSMatthew G. Knepley PetscCall(PetscObjectGetOptionsPrefix((PetscObject)P, &prefix)); 18117c48043bSMatthew G. Knepley PetscCall(PetscObjectSetOptionsPrefix((PetscObject)*fem, prefix)); 18127c48043bSMatthew G. Knepley PetscCall(PetscFESetType(*fem, PETSCFEBASIC)); 18137c48043bSMatthew G. Knepley PetscCall(PetscFESetBasisSpace(*fem, P)); 18147c48043bSMatthew G. Knepley PetscCall(PetscFESetDualSpace(*fem, Q)); 18157c48043bSMatthew G. Knepley PetscCall(PetscSpaceGetNumComponents(P, &Nc)); 18167c48043bSMatthew G. Knepley PetscCall(PetscFESetNumComponents(*fem, Nc)); 18177c48043bSMatthew G. Knepley PetscCall(PetscFESetUp(*fem)); 18187c48043bSMatthew G. Knepley PetscCall(PetscSpaceDestroy(&P)); 18197c48043bSMatthew G. Knepley PetscCall(PetscDualSpaceDestroy(&Q)); 18207c48043bSMatthew G. Knepley PetscCall(PetscFESetQuadrature(*fem, q)); 18217c48043bSMatthew G. Knepley PetscCall(PetscFESetFaceQuadrature(*fem, fq)); 18227c48043bSMatthew G. Knepley PetscCall(PetscQuadratureDestroy(&q)); 18237c48043bSMatthew G. Knepley PetscCall(PetscQuadratureDestroy(&fq)); 18247c48043bSMatthew G. Knepley PetscCall(PetscFESetDefaultName_Private(*fem)); 18257c48043bSMatthew G. Knepley PetscFunctionReturn(0); 18267c48043bSMatthew G. Knepley } 18277c48043bSMatthew G. Knepley 18289371c9d4SSatish Balay static PetscErrorCode PetscFECreate_Internal(MPI_Comm comm, PetscInt dim, PetscInt Nc, DMPolytopeType ct, const char prefix[], PetscInt degree, PetscInt qorder, PetscBool setFromOptions, PetscFE *fem) { 18292df84da0SMatthew G. Knepley DM K; 18302df84da0SMatthew G. Knepley PetscSpace P; 18312df84da0SMatthew G. Knepley PetscDualSpace Q; 18327c48043bSMatthew G. Knepley PetscQuadrature q, fq; 18332df84da0SMatthew G. Knepley PetscBool tensor; 18342df84da0SMatthew G. Knepley 18352df84da0SMatthew G. Knepley PetscFunctionBegin; 18362df84da0SMatthew G. Knepley if (prefix) PetscValidCharPointer(prefix, 5); 18372df84da0SMatthew G. Knepley PetscValidPointer(fem, 9); 18382df84da0SMatthew G. Knepley switch (ct) { 18392df84da0SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 18402df84da0SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: 18412df84da0SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 18422df84da0SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 18432df84da0SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 18449371c9d4SSatish Balay case DM_POLYTOPE_QUAD_PRISM_TENSOR: tensor = PETSC_TRUE; break; 18452df84da0SMatthew G. Knepley default: tensor = PETSC_FALSE; 18462df84da0SMatthew G. Knepley } 18472df84da0SMatthew G. Knepley /* Create space */ 18489566063dSJacob Faibussowitsch PetscCall(PetscSpaceCreate(comm, &P)); 18499566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetType(P, PETSCSPACEPOLYNOMIAL)); 18509566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)P, prefix)); 18519566063dSJacob Faibussowitsch PetscCall(PetscSpacePolynomialSetTensor(P, tensor)); 18529566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetNumComponents(P, Nc)); 18539566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetNumVariables(P, dim)); 18542df84da0SMatthew G. Knepley if (degree >= 0) { 18559566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetDegree(P, degree, PETSC_DETERMINE)); 1856cfd33b42SLisandro Dalcin if (ct == DM_POLYTOPE_TRI_PRISM || ct == DM_POLYTOPE_TRI_PRISM_TENSOR) { 18572df84da0SMatthew G. Knepley PetscSpace Pend, Pside; 18582df84da0SMatthew G. Knepley 18599566063dSJacob Faibussowitsch PetscCall(PetscSpaceCreate(comm, &Pend)); 18609566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetType(Pend, PETSCSPACEPOLYNOMIAL)); 18619566063dSJacob Faibussowitsch PetscCall(PetscSpacePolynomialSetTensor(Pend, PETSC_FALSE)); 18629566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetNumComponents(Pend, Nc)); 18639566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetNumVariables(Pend, dim - 1)); 18649566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetDegree(Pend, degree, PETSC_DETERMINE)); 18659566063dSJacob Faibussowitsch PetscCall(PetscSpaceCreate(comm, &Pside)); 18669566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetType(Pside, PETSCSPACEPOLYNOMIAL)); 18679566063dSJacob Faibussowitsch PetscCall(PetscSpacePolynomialSetTensor(Pside, PETSC_FALSE)); 18689566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetNumComponents(Pside, 1)); 18699566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetNumVariables(Pside, 1)); 18709566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetDegree(Pside, degree, PETSC_DETERMINE)); 18719566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetType(P, PETSCSPACETENSOR)); 18729566063dSJacob Faibussowitsch PetscCall(PetscSpaceTensorSetNumSubspaces(P, 2)); 18739566063dSJacob Faibussowitsch PetscCall(PetscSpaceTensorSetSubspace(P, 0, Pend)); 18749566063dSJacob Faibussowitsch PetscCall(PetscSpaceTensorSetSubspace(P, 1, Pside)); 18759566063dSJacob Faibussowitsch PetscCall(PetscSpaceDestroy(&Pend)); 18769566063dSJacob Faibussowitsch PetscCall(PetscSpaceDestroy(&Pside)); 18772df84da0SMatthew G. Knepley } 18782df84da0SMatthew G. Knepley } 18799566063dSJacob Faibussowitsch if (setFromOptions) PetscCall(PetscSpaceSetFromOptions(P)); 18809566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetUp(P)); 18819566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetDegree(P, °ree, NULL)); 18829566063dSJacob Faibussowitsch PetscCall(PetscSpacePolynomialGetTensor(P, &tensor)); 18839566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetNumComponents(P, &Nc)); 18842df84da0SMatthew G. Knepley /* Create dual space */ 18859566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceCreate(comm, &Q)); 18869566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetType(Q, PETSCDUALSPACELAGRANGE)); 18879566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)Q, prefix)); 18889566063dSJacob Faibussowitsch PetscCall(DMPlexCreateReferenceCell(PETSC_COMM_SELF, ct, &K)); 18899566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetDM(Q, K)); 18909566063dSJacob Faibussowitsch PetscCall(DMDestroy(&K)); 18919566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetNumComponents(Q, Nc)); 18929566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetOrder(Q, degree)); 18932df84da0SMatthew G. Knepley /* TODO For some reason, we need a tensor dualspace with wedges */ 18949566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceLagrangeSetTensor(Q, (tensor || (ct == DM_POLYTOPE_TRI_PRISM)) ? PETSC_TRUE : PETSC_FALSE)); 18959566063dSJacob Faibussowitsch if (setFromOptions) PetscCall(PetscDualSpaceSetFromOptions(Q)); 18969566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetUp(Q)); 18977c48043bSMatthew G. Knepley /* Create quadrature */ 18982df84da0SMatthew G. Knepley qorder = qorder >= 0 ? qorder : degree; 18992df84da0SMatthew G. Knepley if (setFromOptions) { 19007c48043bSMatthew G. Knepley PetscObjectOptionsBegin((PetscObject)P); 19019566063dSJacob Faibussowitsch PetscCall(PetscOptionsBoundedInt("-petscfe_default_quadrature_order", "Quadrature order is one less than quadrature points per edge", "PetscFECreateDefault", qorder, &qorder, NULL, 0)); 1902d0609cedSBarry Smith PetscOptionsEnd(); 19032df84da0SMatthew G. Knepley } 19047c48043bSMatthew G. Knepley PetscCall(PetscFECreateDefaultQuadrature_Private(dim, ct, qorder, &q, &fq)); 19057c48043bSMatthew G. Knepley /* Create finite element */ 19067c48043bSMatthew G. Knepley PetscCall(PetscFECreateFromSpaces(P, Q, q, fq, fem)); 19077c48043bSMatthew G. Knepley if (setFromOptions) PetscCall(PetscFESetFromOptions(*fem)); 19082df84da0SMatthew G. Knepley PetscFunctionReturn(0); 19092df84da0SMatthew G. Knepley } 19102df84da0SMatthew G. Knepley 191120cf1dd8SToby Isaac /*@C 191220cf1dd8SToby Isaac PetscFECreateDefault - Create a PetscFE for basic FEM computation 191320cf1dd8SToby Isaac 1914d083f849SBarry Smith Collective 191520cf1dd8SToby Isaac 191620cf1dd8SToby Isaac Input Parameters: 19177be5e748SToby Isaac + comm - The MPI comm 191820cf1dd8SToby Isaac . dim - The spatial dimension 191920cf1dd8SToby Isaac . Nc - The number of components 192020cf1dd8SToby Isaac . isSimplex - Flag for simplex reference cell, otherwise its a tensor product 192120cf1dd8SToby Isaac . prefix - The options prefix, or NULL 1922727cddd5SJacob Faibussowitsch - qorder - The quadrature order or PETSC_DETERMINE to use PetscSpace polynomial degree 192320cf1dd8SToby Isaac 192420cf1dd8SToby Isaac Output Parameter: 192520cf1dd8SToby Isaac . fem - The PetscFE object 192620cf1dd8SToby Isaac 1927e703855dSMatthew G. Knepley Note: 19288f2aacc6SMatthew G. Knepley Each subobject is SetFromOption() during creation, so that the object may be customized from the command line, using the prefix specified above. See the links below for the particular options available. 1929e703855dSMatthew G. Knepley 193020cf1dd8SToby Isaac Level: beginner 193120cf1dd8SToby Isaac 1932db781477SPatrick Sanan .seealso: `PetscFECreateLagrange()`, `PetscFECreateByCell()`, `PetscSpaceSetFromOptions()`, `PetscDualSpaceSetFromOptions()`, `PetscFESetFromOptions()`, `PetscFECreate()`, `PetscSpaceCreate()`, `PetscDualSpaceCreate()` 193320cf1dd8SToby Isaac @*/ 19349371c9d4SSatish Balay PetscErrorCode PetscFECreateDefault(MPI_Comm comm, PetscInt dim, PetscInt Nc, PetscBool isSimplex, const char prefix[], PetscInt qorder, PetscFE *fem) { 193520cf1dd8SToby Isaac PetscFunctionBegin; 19369566063dSJacob Faibussowitsch PetscCall(PetscFECreate_Internal(comm, dim, Nc, DMPolytopeTypeSimpleShape(dim, isSimplex), prefix, PETSC_DECIDE, qorder, PETSC_TRUE, fem)); 19372df84da0SMatthew G. Knepley PetscFunctionReturn(0); 193820cf1dd8SToby Isaac } 19392df84da0SMatthew G. Knepley 19402df84da0SMatthew G. Knepley /*@C 19412df84da0SMatthew G. Knepley PetscFECreateByCell - Create a PetscFE for basic FEM computation 19422df84da0SMatthew G. Knepley 19432df84da0SMatthew G. Knepley Collective 19442df84da0SMatthew G. Knepley 19452df84da0SMatthew G. Knepley Input Parameters: 19462df84da0SMatthew G. Knepley + comm - The MPI comm 19472df84da0SMatthew G. Knepley . dim - The spatial dimension 19482df84da0SMatthew G. Knepley . Nc - The number of components 19492df84da0SMatthew G. Knepley . ct - The celltype of the reference cell 19502df84da0SMatthew G. Knepley . prefix - The options prefix, or NULL 19512df84da0SMatthew G. Knepley - qorder - The quadrature order or PETSC_DETERMINE to use PetscSpace polynomial degree 19522df84da0SMatthew G. Knepley 19532df84da0SMatthew G. Knepley Output Parameter: 19542df84da0SMatthew G. Knepley . fem - The PetscFE object 19552df84da0SMatthew G. Knepley 19562df84da0SMatthew G. Knepley Note: 19572df84da0SMatthew G. Knepley Each subobject is SetFromOption() during creation, so that the object may be customized from the command line, using the prefix specified above. See the links below for the particular options available. 19582df84da0SMatthew G. Knepley 19592df84da0SMatthew G. Knepley Level: beginner 19602df84da0SMatthew G. Knepley 1961db781477SPatrick Sanan .seealso: `PetscFECreateDefault()`, `PetscFECreateLagrange()`, `PetscSpaceSetFromOptions()`, `PetscDualSpaceSetFromOptions()`, `PetscFESetFromOptions()`, `PetscFECreate()`, `PetscSpaceCreate()`, `PetscDualSpaceCreate()` 19622df84da0SMatthew G. Knepley @*/ 19639371c9d4SSatish Balay PetscErrorCode PetscFECreateByCell(MPI_Comm comm, PetscInt dim, PetscInt Nc, DMPolytopeType ct, const char prefix[], PetscInt qorder, PetscFE *fem) { 19642df84da0SMatthew G. Knepley PetscFunctionBegin; 19659566063dSJacob Faibussowitsch PetscCall(PetscFECreate_Internal(comm, dim, Nc, ct, prefix, PETSC_DECIDE, qorder, PETSC_TRUE, fem)); 196620cf1dd8SToby Isaac PetscFunctionReturn(0); 196720cf1dd8SToby Isaac } 19683f6b16c7SMatthew G. Knepley 1969e703855dSMatthew G. Knepley /*@ 1970e703855dSMatthew G. Knepley PetscFECreateLagrange - Create a PetscFE for the basic Lagrange space of degree k 1971e703855dSMatthew G. Knepley 1972e703855dSMatthew G. Knepley Collective 1973e703855dSMatthew G. Knepley 1974e703855dSMatthew G. Knepley Input Parameters: 1975e703855dSMatthew G. Knepley + comm - The MPI comm 1976e703855dSMatthew G. Knepley . dim - The spatial dimension 1977e703855dSMatthew G. Knepley . Nc - The number of components 1978e703855dSMatthew G. Knepley . isSimplex - Flag for simplex reference cell, otherwise its a tensor product 1979e703855dSMatthew G. Knepley . k - The degree k of the space 1980e703855dSMatthew G. Knepley - qorder - The quadrature order or PETSC_DETERMINE to use PetscSpace polynomial degree 1981e703855dSMatthew G. Knepley 1982e703855dSMatthew G. Knepley Output Parameter: 1983e703855dSMatthew G. Knepley . fem - The PetscFE object 1984e703855dSMatthew G. Knepley 1985e703855dSMatthew G. Knepley Level: beginner 1986e703855dSMatthew G. Knepley 1987e703855dSMatthew G. Knepley Notes: 1988e703855dSMatthew G. Knepley For simplices, this element is the space of maximum polynomial degree k, otherwise it is a tensor product of 1D polynomials, each with maximal degree k. 1989e703855dSMatthew G. Knepley 1990db781477SPatrick Sanan .seealso: `PetscFECreateLagrangeByCell()`, `PetscFECreateDefault()`, `PetscFECreateByCell()`, `PetscFECreate()`, `PetscSpaceCreate()`, `PetscDualSpaceCreate()` 1991e703855dSMatthew G. Knepley @*/ 19929371c9d4SSatish Balay PetscErrorCode PetscFECreateLagrange(MPI_Comm comm, PetscInt dim, PetscInt Nc, PetscBool isSimplex, PetscInt k, PetscInt qorder, PetscFE *fem) { 1993e703855dSMatthew G. Knepley PetscFunctionBegin; 19949566063dSJacob Faibussowitsch PetscCall(PetscFECreate_Internal(comm, dim, Nc, DMPolytopeTypeSimpleShape(dim, isSimplex), NULL, k, qorder, PETSC_FALSE, fem)); 19952df84da0SMatthew G. Knepley PetscFunctionReturn(0); 1996e703855dSMatthew G. Knepley } 19972df84da0SMatthew G. Knepley 19982df84da0SMatthew G. Knepley /*@ 19992df84da0SMatthew G. Knepley PetscFECreateLagrangeByCell - Create a PetscFE for the basic Lagrange space of degree k 20002df84da0SMatthew G. Knepley 20012df84da0SMatthew G. Knepley Collective 20022df84da0SMatthew G. Knepley 20032df84da0SMatthew G. Knepley Input Parameters: 20042df84da0SMatthew G. Knepley + comm - The MPI comm 20052df84da0SMatthew G. Knepley . dim - The spatial dimension 20062df84da0SMatthew G. Knepley . Nc - The number of components 20072df84da0SMatthew G. Knepley . ct - The celltype of the reference cell 20082df84da0SMatthew G. Knepley . k - The degree k of the space 20092df84da0SMatthew G. Knepley - qorder - The quadrature order or PETSC_DETERMINE to use PetscSpace polynomial degree 20102df84da0SMatthew G. Knepley 20112df84da0SMatthew G. Knepley Output Parameter: 20122df84da0SMatthew G. Knepley . fem - The PetscFE object 20132df84da0SMatthew G. Knepley 20142df84da0SMatthew G. Knepley Level: beginner 20152df84da0SMatthew G. Knepley 20162df84da0SMatthew G. Knepley Notes: 20172df84da0SMatthew G. Knepley For simplices, this element is the space of maximum polynomial degree k, otherwise it is a tensor product of 1D polynomials, each with maximal degree k. 20182df84da0SMatthew G. Knepley 2019db781477SPatrick Sanan .seealso: `PetscFECreateLagrange()`, `PetscFECreateDefault()`, `PetscFECreateByCell()`, `PetscFECreate()`, `PetscSpaceCreate()`, `PetscDualSpaceCreate()` 20202df84da0SMatthew G. Knepley @*/ 20219371c9d4SSatish Balay PetscErrorCode PetscFECreateLagrangeByCell(MPI_Comm comm, PetscInt dim, PetscInt Nc, DMPolytopeType ct, PetscInt k, PetscInt qorder, PetscFE *fem) { 20222df84da0SMatthew G. Knepley PetscFunctionBegin; 20239566063dSJacob Faibussowitsch PetscCall(PetscFECreate_Internal(comm, dim, Nc, ct, NULL, k, qorder, PETSC_FALSE, fem)); 2024e703855dSMatthew G. Knepley PetscFunctionReturn(0); 2025e703855dSMatthew G. Knepley } 2026e703855dSMatthew G. Knepley 20273f6b16c7SMatthew G. Knepley /*@C 20283f6b16c7SMatthew G. Knepley PetscFESetName - Names the FE and its subobjects 20293f6b16c7SMatthew G. Knepley 20303f6b16c7SMatthew G. Knepley Not collective 20313f6b16c7SMatthew G. Knepley 20323f6b16c7SMatthew G. Knepley Input Parameters: 20333f6b16c7SMatthew G. Knepley + fe - The PetscFE 20343f6b16c7SMatthew G. Knepley - name - The name 20353f6b16c7SMatthew G. Knepley 20362b99622eSMatthew G. Knepley Level: intermediate 20373f6b16c7SMatthew G. Knepley 2038db781477SPatrick Sanan .seealso: `PetscFECreate()`, `PetscSpaceCreate()`, `PetscDualSpaceCreate()` 20393f6b16c7SMatthew G. Knepley @*/ 20409371c9d4SSatish Balay PetscErrorCode PetscFESetName(PetscFE fe, const char name[]) { 20413f6b16c7SMatthew G. Knepley PetscSpace P; 20423f6b16c7SMatthew G. Knepley PetscDualSpace Q; 20433f6b16c7SMatthew G. Knepley 20443f6b16c7SMatthew G. Knepley PetscFunctionBegin; 20459566063dSJacob Faibussowitsch PetscCall(PetscFEGetBasisSpace(fe, &P)); 20469566063dSJacob Faibussowitsch PetscCall(PetscFEGetDualSpace(fe, &Q)); 20479566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)fe, name)); 20489566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)P, name)); 20499566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)Q, name)); 20503f6b16c7SMatthew G. Knepley PetscFunctionReturn(0); 20513f6b16c7SMatthew G. Knepley } 2052a8f1f9e5SMatthew G. Knepley 20539371c9d4SSatish Balay PetscErrorCode PetscFEEvaluateFieldJets_Internal(PetscDS ds, PetscInt Nf, PetscInt r, PetscInt q, PetscTabulation T[], PetscFEGeom *fegeom, const PetscScalar coefficients[], const PetscScalar coefficients_t[], PetscScalar u[], PetscScalar u_x[], PetscScalar u_t[]) { 2054f9244615SMatthew G. Knepley PetscInt dOffset = 0, fOffset = 0, f, g; 2055a8f1f9e5SMatthew G. Knepley 2056a8f1f9e5SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 2057a8f1f9e5SMatthew G. Knepley PetscFE fe; 2058f9244615SMatthew G. Knepley const PetscInt k = ds->jetDegree[f]; 2059ef0bb6c7SMatthew G. Knepley const PetscInt cdim = T[f]->cdim; 2060ef0bb6c7SMatthew G. Knepley const PetscInt Nq = T[f]->Np; 2061ef0bb6c7SMatthew G. Knepley const PetscInt Nbf = T[f]->Nb; 2062ef0bb6c7SMatthew G. Knepley const PetscInt Ncf = T[f]->Nc; 2063ef0bb6c7SMatthew G. Knepley const PetscReal *Bq = &T[f]->T[0][(r * Nq + q) * Nbf * Ncf]; 2064ef0bb6c7SMatthew G. Knepley const PetscReal *Dq = &T[f]->T[1][(r * Nq + q) * Nbf * Ncf * cdim]; 2065f9244615SMatthew G. Knepley const PetscReal *Hq = k > 1 ? &T[f]->T[2][(r * Nq + q) * Nbf * Ncf * cdim * cdim] : NULL; 2066f9244615SMatthew G. Knepley PetscInt hOffset = 0, b, c, d; 2067a8f1f9e5SMatthew G. Knepley 20689566063dSJacob Faibussowitsch PetscCall(PetscDSGetDiscretization(ds, f, (PetscObject *)&fe)); 2069a8f1f9e5SMatthew G. Knepley for (c = 0; c < Ncf; ++c) u[fOffset + c] = 0.0; 2070ef0bb6c7SMatthew G. Knepley for (d = 0; d < cdim * Ncf; ++d) u_x[fOffset * cdim + d] = 0.0; 2071a8f1f9e5SMatthew G. Knepley for (b = 0; b < Nbf; ++b) { 2072a8f1f9e5SMatthew G. Knepley for (c = 0; c < Ncf; ++c) { 2073a8f1f9e5SMatthew G. Knepley const PetscInt cidx = b * Ncf + c; 2074a8f1f9e5SMatthew G. Knepley 2075a8f1f9e5SMatthew G. Knepley u[fOffset + c] += Bq[cidx] * coefficients[dOffset + b]; 2076ef0bb6c7SMatthew G. Knepley for (d = 0; d < cdim; ++d) u_x[(fOffset + c) * cdim + d] += Dq[cidx * cdim + d] * coefficients[dOffset + b]; 2077a8f1f9e5SMatthew G. Knepley } 2078a8f1f9e5SMatthew G. Knepley } 2079f9244615SMatthew G. Knepley if (k > 1) { 2080f9244615SMatthew G. Knepley for (g = 0; g < Nf; ++g) hOffset += T[g]->Nc * cdim; 2081f9244615SMatthew G. Knepley for (d = 0; d < cdim * cdim * Ncf; ++d) u_x[hOffset + fOffset * cdim * cdim + d] = 0.0; 2082f9244615SMatthew G. Knepley for (b = 0; b < Nbf; ++b) { 2083f9244615SMatthew G. Knepley for (c = 0; c < Ncf; ++c) { 2084f9244615SMatthew G. Knepley const PetscInt cidx = b * Ncf + c; 2085f9244615SMatthew G. Knepley 2086f9244615SMatthew G. Knepley for (d = 0; d < cdim * cdim; ++d) u_x[hOffset + (fOffset + c) * cdim * cdim + d] += Hq[cidx * cdim * cdim + d] * coefficients[dOffset + b]; 2087f9244615SMatthew G. Knepley } 2088f9244615SMatthew G. Knepley } 20899566063dSJacob Faibussowitsch PetscCall(PetscFEPushforwardHessian(fe, fegeom, 1, &u_x[hOffset + fOffset * cdim * cdim])); 2090f9244615SMatthew G. Knepley } 20919566063dSJacob Faibussowitsch PetscCall(PetscFEPushforward(fe, fegeom, 1, &u[fOffset])); 20929566063dSJacob Faibussowitsch PetscCall(PetscFEPushforwardGradient(fe, fegeom, 1, &u_x[fOffset * cdim])); 2093a8f1f9e5SMatthew G. Knepley if (u_t) { 2094a8f1f9e5SMatthew G. Knepley for (c = 0; c < Ncf; ++c) u_t[fOffset + c] = 0.0; 2095a8f1f9e5SMatthew G. Knepley for (b = 0; b < Nbf; ++b) { 2096a8f1f9e5SMatthew G. Knepley for (c = 0; c < Ncf; ++c) { 2097a8f1f9e5SMatthew G. Knepley const PetscInt cidx = b * Ncf + c; 2098a8f1f9e5SMatthew G. Knepley 2099a8f1f9e5SMatthew G. Knepley u_t[fOffset + c] += Bq[cidx] * coefficients_t[dOffset + b]; 2100a8f1f9e5SMatthew G. Knepley } 2101a8f1f9e5SMatthew G. Knepley } 21029566063dSJacob Faibussowitsch PetscCall(PetscFEPushforward(fe, fegeom, 1, &u_t[fOffset])); 2103a8f1f9e5SMatthew G. Knepley } 2104a8f1f9e5SMatthew G. Knepley fOffset += Ncf; 2105a8f1f9e5SMatthew G. Knepley dOffset += Nbf; 2106a8f1f9e5SMatthew G. Knepley } 2107a8f1f9e5SMatthew G. Knepley return 0; 2108a8f1f9e5SMatthew G. Knepley } 2109a8f1f9e5SMatthew G. Knepley 21109371c9d4SSatish Balay PetscErrorCode PetscFEEvaluateFieldJets_Hybrid_Internal(PetscDS ds, PetscInt Nf, PetscInt r, PetscInt q, PetscTabulation T[], PetscFEGeom *fegeom, const PetscScalar coefficients[], const PetscScalar coefficients_t[], PetscScalar u[], PetscScalar u_x[], PetscScalar u_t[]) { 21115fedec97SMatthew G. Knepley PetscInt dOffset = 0, fOffset = 0, f, g; 211227f02ce8SMatthew G. Knepley 21135fedec97SMatthew G. Knepley /* f is the field number in the DS, g is the field number in u[] */ 21145fedec97SMatthew G. Knepley for (f = 0, g = 0; f < Nf; ++f) { 21155fedec97SMatthew G. Knepley PetscFE fe = (PetscFE)ds->disc[f]; 21169ee2af8cSMatthew G. Knepley const PetscInt dEt = T[f]->cdim; 21179ee2af8cSMatthew G. Knepley const PetscInt dE = fegeom->dimEmbed; 2118665f567fSMatthew G. Knepley const PetscInt Nq = T[f]->Np; 2119665f567fSMatthew G. Knepley const PetscInt Nbf = T[f]->Nb; 2120665f567fSMatthew G. Knepley const PetscInt Ncf = T[f]->Nc; 2121665f567fSMatthew G. Knepley const PetscReal *Bq = &T[f]->T[0][(r * Nq + q) * Nbf * Ncf]; 21229ee2af8cSMatthew G. Knepley const PetscReal *Dq = &T[f]->T[1][(r * Nq + q) * Nbf * Ncf * dEt]; 21235fedec97SMatthew G. Knepley PetscBool isCohesive; 21245fedec97SMatthew G. Knepley PetscInt Ns, s; 21255fedec97SMatthew G. Knepley 21265fedec97SMatthew G. Knepley if (!T[f]) continue; 21279566063dSJacob Faibussowitsch PetscCall(PetscDSGetCohesive(ds, f, &isCohesive)); 21285fedec97SMatthew G. Knepley Ns = isCohesive ? 1 : 2; 21295fedec97SMatthew G. Knepley for (s = 0; s < Ns; ++s, ++g) { 213027f02ce8SMatthew G. Knepley PetscInt b, c, d; 213127f02ce8SMatthew G. Knepley 213227f02ce8SMatthew G. Knepley for (c = 0; c < Ncf; ++c) u[fOffset + c] = 0.0; 21339ee2af8cSMatthew G. Knepley for (d = 0; d < dE * Ncf; ++d) u_x[fOffset * dE + d] = 0.0; 213427f02ce8SMatthew G. Knepley for (b = 0; b < Nbf; ++b) { 213527f02ce8SMatthew G. Knepley for (c = 0; c < Ncf; ++c) { 213627f02ce8SMatthew G. Knepley const PetscInt cidx = b * Ncf + c; 213727f02ce8SMatthew G. Knepley 213827f02ce8SMatthew G. Knepley u[fOffset + c] += Bq[cidx] * coefficients[dOffset + b]; 21399ee2af8cSMatthew G. Knepley for (d = 0; d < dEt; ++d) u_x[(fOffset + c) * dE + d] += Dq[cidx * dEt + d] * coefficients[dOffset + b]; 214027f02ce8SMatthew G. Knepley } 214127f02ce8SMatthew G. Knepley } 21429566063dSJacob Faibussowitsch PetscCall(PetscFEPushforward(fe, fegeom, 1, &u[fOffset])); 21439566063dSJacob Faibussowitsch PetscCall(PetscFEPushforwardGradient(fe, fegeom, 1, &u_x[fOffset * dE])); 214427f02ce8SMatthew G. Knepley if (u_t) { 214527f02ce8SMatthew G. Knepley for (c = 0; c < Ncf; ++c) u_t[fOffset + c] = 0.0; 214627f02ce8SMatthew G. Knepley for (b = 0; b < Nbf; ++b) { 214727f02ce8SMatthew G. Knepley for (c = 0; c < Ncf; ++c) { 214827f02ce8SMatthew G. Knepley const PetscInt cidx = b * Ncf + c; 214927f02ce8SMatthew G. Knepley 215027f02ce8SMatthew G. Knepley u_t[fOffset + c] += Bq[cidx] * coefficients_t[dOffset + b]; 215127f02ce8SMatthew G. Knepley } 215227f02ce8SMatthew G. Knepley } 21539566063dSJacob Faibussowitsch PetscCall(PetscFEPushforward(fe, fegeom, 1, &u_t[fOffset])); 215427f02ce8SMatthew G. Knepley } 215527f02ce8SMatthew G. Knepley fOffset += Ncf; 215627f02ce8SMatthew G. Knepley dOffset += Nbf; 215727f02ce8SMatthew G. Knepley } 2158665f567fSMatthew G. Knepley } 215927f02ce8SMatthew G. Knepley return 0; 216027f02ce8SMatthew G. Knepley } 216127f02ce8SMatthew G. Knepley 21629371c9d4SSatish Balay PetscErrorCode PetscFEEvaluateFaceFields_Internal(PetscDS prob, PetscInt field, PetscInt faceLoc, const PetscScalar coefficients[], PetscScalar u[]) { 2163a8f1f9e5SMatthew G. Knepley PetscFE fe; 2164ef0bb6c7SMatthew G. Knepley PetscTabulation Tc; 2165ef0bb6c7SMatthew G. Knepley PetscInt b, c; 2166a8f1f9e5SMatthew G. Knepley 2167a8f1f9e5SMatthew G. Knepley if (!prob) return 0; 21689566063dSJacob Faibussowitsch PetscCall(PetscDSGetDiscretization(prob, field, (PetscObject *)&fe)); 21699566063dSJacob Faibussowitsch PetscCall(PetscFEGetFaceCentroidTabulation(fe, &Tc)); 2170ef0bb6c7SMatthew G. Knepley { 2171ef0bb6c7SMatthew G. Knepley const PetscReal *faceBasis = Tc->T[0]; 2172ef0bb6c7SMatthew G. Knepley const PetscInt Nb = Tc->Nb; 2173ef0bb6c7SMatthew G. Knepley const PetscInt Nc = Tc->Nc; 2174ef0bb6c7SMatthew G. Knepley 2175a8f1f9e5SMatthew G. Knepley for (c = 0; c < Nc; ++c) { u[c] = 0.0; } 2176a8f1f9e5SMatthew G. Knepley for (b = 0; b < Nb; ++b) { 21779371c9d4SSatish Balay for (c = 0; c < Nc; ++c) { u[c] += coefficients[b] * faceBasis[(faceLoc * Nb + b) * Nc + c]; } 2178a8f1f9e5SMatthew G. Knepley } 2179ef0bb6c7SMatthew G. Knepley } 2180a8f1f9e5SMatthew G. Knepley return 0; 2181a8f1f9e5SMatthew G. Knepley } 2182a8f1f9e5SMatthew G. Knepley 21839371c9d4SSatish Balay PetscErrorCode PetscFEUpdateElementVec_Internal(PetscFE fe, PetscTabulation T, PetscInt r, PetscScalar tmpBasis[], PetscScalar tmpBasisDer[], PetscInt e, PetscFEGeom *fegeom, PetscScalar f0[], PetscScalar f1[], PetscScalar elemVec[]) { 21846587ee25SMatthew G. Knepley PetscFEGeom pgeom; 2185bc3a64adSMatthew G. Knepley const PetscInt dEt = T->cdim; 2186bc3a64adSMatthew G. Knepley const PetscInt dE = fegeom->dimEmbed; 2187ef0bb6c7SMatthew G. Knepley const PetscInt Nq = T->Np; 2188ef0bb6c7SMatthew G. Knepley const PetscInt Nb = T->Nb; 2189ef0bb6c7SMatthew G. Knepley const PetscInt Nc = T->Nc; 2190ef0bb6c7SMatthew G. Knepley const PetscReal *basis = &T->T[0][r * Nq * Nb * Nc]; 2191bc3a64adSMatthew G. Knepley const PetscReal *basisDer = &T->T[1][r * Nq * Nb * Nc * dEt]; 2192a8f1f9e5SMatthew G. Knepley PetscInt q, b, c, d; 2193a8f1f9e5SMatthew G. Knepley 2194a8f1f9e5SMatthew G. Knepley for (q = 0; q < Nq; ++q) { 2195a8f1f9e5SMatthew G. Knepley for (b = 0; b < Nb; ++b) { 2196a8f1f9e5SMatthew G. Knepley for (c = 0; c < Nc; ++c) { 2197a8f1f9e5SMatthew G. Knepley const PetscInt bcidx = b * Nc + c; 2198a8f1f9e5SMatthew G. Knepley 2199a8f1f9e5SMatthew G. Knepley tmpBasis[bcidx] = basis[q * Nb * Nc + bcidx]; 2200bc3a64adSMatthew G. Knepley for (d = 0; d < dEt; ++d) tmpBasisDer[bcidx * dE + d] = basisDer[q * Nb * Nc * dEt + bcidx * dEt + d]; 22019ee2af8cSMatthew G. Knepley for (d = dEt; d < dE; ++d) tmpBasisDer[bcidx * dE + d] = 0.0; 2202a8f1f9e5SMatthew G. Knepley } 2203a8f1f9e5SMatthew G. Knepley } 22049566063dSJacob Faibussowitsch PetscCall(PetscFEGeomGetCellPoint(fegeom, e, q, &pgeom)); 22059566063dSJacob Faibussowitsch PetscCall(PetscFEPushforward(fe, &pgeom, Nb, tmpBasis)); 22069566063dSJacob Faibussowitsch PetscCall(PetscFEPushforwardGradient(fe, &pgeom, Nb, tmpBasisDer)); 2207a8f1f9e5SMatthew G. Knepley for (b = 0; b < Nb; ++b) { 2208a8f1f9e5SMatthew G. Knepley for (c = 0; c < Nc; ++c) { 2209a8f1f9e5SMatthew G. Knepley const PetscInt bcidx = b * Nc + c; 2210a8f1f9e5SMatthew G. Knepley const PetscInt qcidx = q * Nc + c; 2211a8f1f9e5SMatthew G. Knepley 2212a8f1f9e5SMatthew G. Knepley elemVec[b] += tmpBasis[bcidx] * f0[qcidx]; 221327f02ce8SMatthew G. Knepley for (d = 0; d < dE; ++d) elemVec[b] += tmpBasisDer[bcidx * dE + d] * f1[qcidx * dE + d]; 221427f02ce8SMatthew G. Knepley } 221527f02ce8SMatthew G. Knepley } 221627f02ce8SMatthew G. Knepley } 221727f02ce8SMatthew G. Knepley return (0); 221827f02ce8SMatthew G. Knepley } 221927f02ce8SMatthew G. Knepley 22209371c9d4SSatish Balay PetscErrorCode PetscFEUpdateElementVec_Hybrid_Internal(PetscFE fe, PetscTabulation T, PetscInt r, PetscInt s, PetscScalar tmpBasis[], PetscScalar tmpBasisDer[], PetscFEGeom *fegeom, PetscScalar f0[], PetscScalar f1[], PetscScalar elemVec[]) { 222127f02ce8SMatthew G. Knepley const PetscInt dE = T->cdim; 222227f02ce8SMatthew G. Knepley const PetscInt Nq = T->Np; 222327f02ce8SMatthew G. Knepley const PetscInt Nb = T->Nb; 222427f02ce8SMatthew G. Knepley const PetscInt Nc = T->Nc; 222527f02ce8SMatthew G. Knepley const PetscReal *basis = &T->T[0][r * Nq * Nb * Nc]; 222627f02ce8SMatthew G. Knepley const PetscReal *basisDer = &T->T[1][r * Nq * Nb * Nc * dE]; 2227c2b7495fSMatthew G. Knepley PetscInt q, b, c, d; 222827f02ce8SMatthew G. Knepley 222927f02ce8SMatthew G. Knepley for (q = 0; q < Nq; ++q) { 223027f02ce8SMatthew G. Knepley for (b = 0; b < Nb; ++b) { 223127f02ce8SMatthew G. Knepley for (c = 0; c < Nc; ++c) { 223227f02ce8SMatthew G. Knepley const PetscInt bcidx = b * Nc + c; 223327f02ce8SMatthew G. Knepley 223427f02ce8SMatthew G. Knepley tmpBasis[bcidx] = basis[q * Nb * Nc + bcidx]; 223527f02ce8SMatthew G. Knepley for (d = 0; d < dE; ++d) tmpBasisDer[bcidx * dE + d] = basisDer[q * Nb * Nc * dE + bcidx * dE + d]; 223627f02ce8SMatthew G. Knepley } 223727f02ce8SMatthew G. Knepley } 22389566063dSJacob Faibussowitsch PetscCall(PetscFEPushforward(fe, fegeom, Nb, tmpBasis)); 22399566063dSJacob Faibussowitsch PetscCall(PetscFEPushforwardGradient(fe, fegeom, Nb, tmpBasisDer)); 224027f02ce8SMatthew G. Knepley for (b = 0; b < Nb; ++b) { 224127f02ce8SMatthew G. Knepley for (c = 0; c < Nc; ++c) { 224227f02ce8SMatthew G. Knepley const PetscInt bcidx = b * Nc + c; 2243c2b7495fSMatthew G. Knepley const PetscInt qcidx = q * Nc + c; 224427f02ce8SMatthew G. Knepley 224527f02ce8SMatthew G. Knepley elemVec[Nb * s + b] += tmpBasis[bcidx] * f0[qcidx]; 224627f02ce8SMatthew G. Knepley for (d = 0; d < dE; ++d) elemVec[Nb * s + b] += tmpBasisDer[bcidx * dE + d] * f1[qcidx * dE + d]; 224727f02ce8SMatthew G. Knepley } 2248a8f1f9e5SMatthew G. Knepley } 2249a8f1f9e5SMatthew G. Knepley } 2250a8f1f9e5SMatthew G. Knepley return (0); 2251a8f1f9e5SMatthew G. Knepley } 2252a8f1f9e5SMatthew G. Knepley 22539371c9d4SSatish Balay PetscErrorCode PetscFEUpdateElementMat_Internal(PetscFE feI, PetscFE feJ, PetscInt r, PetscInt q, PetscTabulation TI, PetscScalar tmpBasisI[], PetscScalar tmpBasisDerI[], PetscTabulation TJ, PetscScalar tmpBasisJ[], PetscScalar tmpBasisDerJ[], PetscFEGeom *fegeom, const PetscScalar g0[], const PetscScalar g1[], const PetscScalar g2[], const PetscScalar g3[], PetscInt eOffset, PetscInt totDim, PetscInt offsetI, PetscInt offsetJ, PetscScalar elemMat[]) { 225427f02ce8SMatthew G. Knepley const PetscInt dE = TI->cdim; 2255ef0bb6c7SMatthew G. Knepley const PetscInt NqI = TI->Np; 2256ef0bb6c7SMatthew G. Knepley const PetscInt NbI = TI->Nb; 2257ef0bb6c7SMatthew G. Knepley const PetscInt NcI = TI->Nc; 2258ef0bb6c7SMatthew G. Knepley const PetscReal *basisI = &TI->T[0][(r * NqI + q) * NbI * NcI]; 2259665f567fSMatthew G. Knepley const PetscReal *basisDerI = &TI->T[1][(r * NqI + q) * NbI * NcI * dE]; 2260ef0bb6c7SMatthew G. Knepley const PetscInt NqJ = TJ->Np; 2261ef0bb6c7SMatthew G. Knepley const PetscInt NbJ = TJ->Nb; 2262ef0bb6c7SMatthew G. Knepley const PetscInt NcJ = TJ->Nc; 2263ef0bb6c7SMatthew G. Knepley const PetscReal *basisJ = &TJ->T[0][(r * NqJ + q) * NbJ * NcJ]; 2264665f567fSMatthew G. Knepley const PetscReal *basisDerJ = &TJ->T[1][(r * NqJ + q) * NbJ * NcJ * dE]; 2265a8f1f9e5SMatthew G. Knepley PetscInt f, fc, g, gc, df, dg; 2266a8f1f9e5SMatthew G. Knepley 2267a8f1f9e5SMatthew G. Knepley for (f = 0; f < NbI; ++f) { 2268a8f1f9e5SMatthew G. Knepley for (fc = 0; fc < NcI; ++fc) { 2269a8f1f9e5SMatthew G. Knepley const PetscInt fidx = f * NcI + fc; /* Test function basis index */ 2270a8f1f9e5SMatthew G. Knepley 2271a8f1f9e5SMatthew G. Knepley tmpBasisI[fidx] = basisI[fidx]; 227227f02ce8SMatthew G. Knepley for (df = 0; df < dE; ++df) tmpBasisDerI[fidx * dE + df] = basisDerI[fidx * dE + df]; 2273a8f1f9e5SMatthew G. Knepley } 2274a8f1f9e5SMatthew G. Knepley } 22759566063dSJacob Faibussowitsch PetscCall(PetscFEPushforward(feI, fegeom, NbI, tmpBasisI)); 22769566063dSJacob Faibussowitsch PetscCall(PetscFEPushforwardGradient(feI, fegeom, NbI, tmpBasisDerI)); 2277a8f1f9e5SMatthew G. Knepley for (g = 0; g < NbJ; ++g) { 2278a8f1f9e5SMatthew G. Knepley for (gc = 0; gc < NcJ; ++gc) { 2279a8f1f9e5SMatthew G. Knepley const PetscInt gidx = g * NcJ + gc; /* Trial function basis index */ 2280a8f1f9e5SMatthew G. Knepley 2281a8f1f9e5SMatthew G. Knepley tmpBasisJ[gidx] = basisJ[gidx]; 228227f02ce8SMatthew G. Knepley for (dg = 0; dg < dE; ++dg) tmpBasisDerJ[gidx * dE + dg] = basisDerJ[gidx * dE + dg]; 2283a8f1f9e5SMatthew G. Knepley } 2284a8f1f9e5SMatthew G. Knepley } 22859566063dSJacob Faibussowitsch PetscCall(PetscFEPushforward(feJ, fegeom, NbJ, tmpBasisJ)); 22869566063dSJacob Faibussowitsch PetscCall(PetscFEPushforwardGradient(feJ, fegeom, NbJ, tmpBasisDerJ)); 2287a8f1f9e5SMatthew G. Knepley for (f = 0; f < NbI; ++f) { 2288a8f1f9e5SMatthew G. Knepley for (fc = 0; fc < NcI; ++fc) { 2289a8f1f9e5SMatthew G. Knepley const PetscInt fidx = f * NcI + fc; /* Test function basis index */ 2290a8f1f9e5SMatthew G. Knepley const PetscInt i = offsetI + f; /* Element matrix row */ 2291a8f1f9e5SMatthew G. Knepley for (g = 0; g < NbJ; ++g) { 2292a8f1f9e5SMatthew G. Knepley for (gc = 0; gc < NcJ; ++gc) { 2293a8f1f9e5SMatthew G. Knepley const PetscInt gidx = g * NcJ + gc; /* Trial function basis index */ 2294a8f1f9e5SMatthew G. Knepley const PetscInt j = offsetJ + g; /* Element matrix column */ 2295a8f1f9e5SMatthew G. Knepley const PetscInt fOff = eOffset + i * totDim + j; 2296a8f1f9e5SMatthew G. Knepley 2297a8f1f9e5SMatthew G. Knepley elemMat[fOff] += tmpBasisI[fidx] * g0[fc * NcJ + gc] * tmpBasisJ[gidx]; 229827f02ce8SMatthew G. Knepley for (df = 0; df < dE; ++df) { 229927f02ce8SMatthew G. Knepley elemMat[fOff] += tmpBasisI[fidx] * g1[(fc * NcJ + gc) * dE + df] * tmpBasisDerJ[gidx * dE + df]; 230027f02ce8SMatthew G. Knepley elemMat[fOff] += tmpBasisDerI[fidx * dE + df] * g2[(fc * NcJ + gc) * dE + df] * tmpBasisJ[gidx]; 23019371c9d4SSatish Balay for (dg = 0; dg < dE; ++dg) { elemMat[fOff] += tmpBasisDerI[fidx * dE + df] * g3[((fc * NcJ + gc) * dE + df) * dE + dg] * tmpBasisDerJ[gidx * dE + dg]; } 230227f02ce8SMatthew G. Knepley } 230327f02ce8SMatthew G. Knepley } 230427f02ce8SMatthew G. Knepley } 230527f02ce8SMatthew G. Knepley } 230627f02ce8SMatthew G. Knepley } 230727f02ce8SMatthew G. Knepley return (0); 230827f02ce8SMatthew G. Knepley } 230927f02ce8SMatthew G. Knepley 23109371c9d4SSatish Balay PetscErrorCode PetscFEUpdateElementMat_Hybrid_Internal(PetscFE feI, PetscBool isHybridI, PetscFE feJ, PetscBool isHybridJ, PetscInt r, PetscInt s, PetscInt q, PetscTabulation TI, PetscScalar tmpBasisI[], PetscScalar tmpBasisDerI[], PetscTabulation TJ, PetscScalar tmpBasisJ[], PetscScalar tmpBasisDerJ[], PetscFEGeom *fegeom, const PetscScalar g0[], const PetscScalar g1[], const PetscScalar g2[], const PetscScalar g3[], PetscInt eOffset, PetscInt totDim, PetscInt offsetI, PetscInt offsetJ, PetscScalar elemMat[]) { 2311665f567fSMatthew G. Knepley const PetscInt dE = TI->cdim; 2312665f567fSMatthew G. Knepley const PetscInt NqI = TI->Np; 2313665f567fSMatthew G. Knepley const PetscInt NbI = TI->Nb; 2314665f567fSMatthew G. Knepley const PetscInt NcI = TI->Nc; 2315665f567fSMatthew G. Knepley const PetscReal *basisI = &TI->T[0][(r * NqI + q) * NbI * NcI]; 2316665f567fSMatthew G. Knepley const PetscReal *basisDerI = &TI->T[1][(r * NqI + q) * NbI * NcI * dE]; 2317665f567fSMatthew G. Knepley const PetscInt NqJ = TJ->Np; 2318665f567fSMatthew G. Knepley const PetscInt NbJ = TJ->Nb; 2319665f567fSMatthew G. Knepley const PetscInt NcJ = TJ->Nc; 2320665f567fSMatthew G. Knepley const PetscReal *basisJ = &TJ->T[0][(r * NqJ + q) * NbJ * NcJ]; 2321665f567fSMatthew G. Knepley const PetscReal *basisDerJ = &TJ->T[1][(r * NqJ + q) * NbJ * NcJ * dE]; 23225fedec97SMatthew G. Knepley const PetscInt so = isHybridI ? 0 : s; 23235fedec97SMatthew G. Knepley const PetscInt to = isHybridJ ? 0 : s; 23245fedec97SMatthew G. Knepley PetscInt f, fc, g, gc, df, dg; 232527f02ce8SMatthew G. Knepley 232627f02ce8SMatthew G. Knepley for (f = 0; f < NbI; ++f) { 232727f02ce8SMatthew G. Knepley for (fc = 0; fc < NcI; ++fc) { 232827f02ce8SMatthew G. Knepley const PetscInt fidx = f * NcI + fc; /* Test function basis index */ 232927f02ce8SMatthew G. Knepley 233027f02ce8SMatthew G. Knepley tmpBasisI[fidx] = basisI[fidx]; 2331665f567fSMatthew G. Knepley for (df = 0; df < dE; ++df) tmpBasisDerI[fidx * dE + df] = basisDerI[fidx * dE + df]; 233227f02ce8SMatthew G. Knepley } 233327f02ce8SMatthew G. Knepley } 23349566063dSJacob Faibussowitsch PetscCall(PetscFEPushforward(feI, fegeom, NbI, tmpBasisI)); 23359566063dSJacob Faibussowitsch PetscCall(PetscFEPushforwardGradient(feI, fegeom, NbI, tmpBasisDerI)); 233627f02ce8SMatthew G. Knepley for (g = 0; g < NbJ; ++g) { 233727f02ce8SMatthew G. Knepley for (gc = 0; gc < NcJ; ++gc) { 233827f02ce8SMatthew G. Knepley const PetscInt gidx = g * NcJ + gc; /* Trial function basis index */ 233927f02ce8SMatthew G. Knepley 234027f02ce8SMatthew G. Knepley tmpBasisJ[gidx] = basisJ[gidx]; 2341665f567fSMatthew G. Knepley for (dg = 0; dg < dE; ++dg) tmpBasisDerJ[gidx * dE + dg] = basisDerJ[gidx * dE + dg]; 234227f02ce8SMatthew G. Knepley } 234327f02ce8SMatthew G. Knepley } 23449566063dSJacob Faibussowitsch PetscCall(PetscFEPushforward(feJ, fegeom, NbJ, tmpBasisJ)); 23459566063dSJacob Faibussowitsch PetscCall(PetscFEPushforwardGradient(feJ, fegeom, NbJ, tmpBasisDerJ)); 234627f02ce8SMatthew G. Knepley for (f = 0; f < NbI; ++f) { 234727f02ce8SMatthew G. Knepley for (fc = 0; fc < NcI; ++fc) { 234827f02ce8SMatthew G. Knepley const PetscInt fidx = f * NcI + fc; /* Test function basis index */ 23495fedec97SMatthew G. Knepley const PetscInt i = offsetI + NbI * so + f; /* Element matrix row */ 235027f02ce8SMatthew G. Knepley for (g = 0; g < NbJ; ++g) { 235127f02ce8SMatthew G. Knepley for (gc = 0; gc < NcJ; ++gc) { 235227f02ce8SMatthew G. Knepley const PetscInt gidx = g * NcJ + gc; /* Trial function basis index */ 23535fedec97SMatthew G. Knepley const PetscInt j = offsetJ + NbJ * to + g; /* Element matrix column */ 235427f02ce8SMatthew G. Knepley const PetscInt fOff = eOffset + i * totDim + j; 235527f02ce8SMatthew G. Knepley 23565fedec97SMatthew G. Knepley elemMat[fOff] += tmpBasisI[fidx] * g0[fc * NcJ + gc] * tmpBasisJ[gidx]; 235727f02ce8SMatthew G. Knepley for (df = 0; df < dE; ++df) { 23585fedec97SMatthew G. Knepley elemMat[fOff] += tmpBasisI[fidx] * g1[(fc * NcJ + gc) * dE + df] * tmpBasisDerJ[gidx * dE + df]; 23595fedec97SMatthew G. Knepley elemMat[fOff] += tmpBasisDerI[fidx * dE + df] * g2[(fc * NcJ + gc) * dE + df] * tmpBasisJ[gidx]; 23609371c9d4SSatish Balay for (dg = 0; dg < dE; ++dg) { elemMat[fOff] += tmpBasisDerI[fidx * dE + df] * g3[((fc * NcJ + gc) * dE + df) * dE + dg] * tmpBasisDerJ[gidx * dE + dg]; } 2361a8f1f9e5SMatthew G. Knepley } 2362a8f1f9e5SMatthew G. Knepley } 2363a8f1f9e5SMatthew G. Knepley } 2364a8f1f9e5SMatthew G. Knepley } 2365a8f1f9e5SMatthew G. Knepley } 2366a8f1f9e5SMatthew G. Knepley return (0); 2367a8f1f9e5SMatthew G. Knepley } 2368c9ba7969SMatthew G. Knepley 23699371c9d4SSatish Balay PetscErrorCode PetscFECreateCellGeometry(PetscFE fe, PetscQuadrature quad, PetscFEGeom *cgeom) { 2370c9ba7969SMatthew G. Knepley PetscDualSpace dsp; 2371c9ba7969SMatthew G. Knepley DM dm; 2372c9ba7969SMatthew G. Knepley PetscQuadrature quadDef; 2373c9ba7969SMatthew G. Knepley PetscInt dim, cdim, Nq; 2374c9ba7969SMatthew G. Knepley 2375c9ba7969SMatthew G. Knepley PetscFunctionBegin; 23769566063dSJacob Faibussowitsch PetscCall(PetscFEGetDualSpace(fe, &dsp)); 23779566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetDM(dsp, &dm)); 23789566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &dim)); 23799566063dSJacob Faibussowitsch PetscCall(DMGetCoordinateDim(dm, &cdim)); 23809566063dSJacob Faibussowitsch PetscCall(PetscFEGetQuadrature(fe, &quadDef)); 2381c9ba7969SMatthew G. Knepley quad = quad ? quad : quadDef; 23829566063dSJacob Faibussowitsch PetscCall(PetscQuadratureGetData(quad, NULL, NULL, &Nq, NULL, NULL)); 23839566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(Nq * cdim, &cgeom->v)); 23849566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(Nq * cdim * cdim, &cgeom->J)); 23859566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(Nq * cdim * cdim, &cgeom->invJ)); 23869566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(Nq, &cgeom->detJ)); 2387c9ba7969SMatthew G. Knepley cgeom->dim = dim; 2388c9ba7969SMatthew G. Knepley cgeom->dimEmbed = cdim; 2389c9ba7969SMatthew G. Knepley cgeom->numCells = 1; 2390c9ba7969SMatthew G. Knepley cgeom->numPoints = Nq; 23919566063dSJacob Faibussowitsch PetscCall(DMPlexComputeCellGeometryFEM(dm, 0, quad, cgeom->v, cgeom->J, cgeom->invJ, cgeom->detJ)); 2392c9ba7969SMatthew G. Knepley PetscFunctionReturn(0); 2393c9ba7969SMatthew G. Knepley } 2394c9ba7969SMatthew G. Knepley 23959371c9d4SSatish Balay PetscErrorCode PetscFEDestroyCellGeometry(PetscFE fe, PetscFEGeom *cgeom) { 2396c9ba7969SMatthew G. Knepley PetscFunctionBegin; 23979566063dSJacob Faibussowitsch PetscCall(PetscFree(cgeom->v)); 23989566063dSJacob Faibussowitsch PetscCall(PetscFree(cgeom->J)); 23999566063dSJacob Faibussowitsch PetscCall(PetscFree(cgeom->invJ)); 24009566063dSJacob Faibussowitsch PetscCall(PetscFree(cgeom->detJ)); 2401c9ba7969SMatthew G. Knepley PetscFunctionReturn(0); 2402c9ba7969SMatthew G. Knepley } 2403