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 59dce8aebaSBarry Smith PetscFERegister - Adds a new `PetscFEType` 6020cf1dd8SToby Isaac 61cc4c1da9SBarry Smith Not Collective, No Fortran Support 6220cf1dd8SToby Isaac 6320cf1dd8SToby Isaac Input Parameters: 642fe279fdSBarry Smith + sname - The name of a new user-defined creation routine 652fe279fdSBarry Smith - function - The creation routine 6620cf1dd8SToby Isaac 6760225df5SJacob Faibussowitsch Example Usage: 6820cf1dd8SToby Isaac .vb 6920cf1dd8SToby Isaac PetscFERegister("my_fe", MyPetscFECreate); 7020cf1dd8SToby Isaac .ve 7120cf1dd8SToby Isaac 7220cf1dd8SToby Isaac Then, your PetscFE type can be chosen with the procedural interface via 7320cf1dd8SToby Isaac .vb 7420cf1dd8SToby Isaac PetscFECreate(MPI_Comm, PetscFE *); 7520cf1dd8SToby Isaac PetscFESetType(PetscFE, "my_fe"); 7620cf1dd8SToby Isaac .ve 7720cf1dd8SToby Isaac or at runtime via the option 7820cf1dd8SToby Isaac .vb 7920cf1dd8SToby Isaac -petscfe_type my_fe 8020cf1dd8SToby Isaac .ve 8120cf1dd8SToby Isaac 8220cf1dd8SToby Isaac Level: advanced 8320cf1dd8SToby Isaac 84dce8aebaSBarry Smith Note: 85dce8aebaSBarry Smith `PetscFERegister()` may be called multiple times to add several user-defined `PetscFE`s 8620cf1dd8SToby Isaac 87dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscFEType`, `PetscFERegisterAll()`, `PetscFERegisterDestroy()` 8820cf1dd8SToby Isaac @*/ 89d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFERegister(const char sname[], PetscErrorCode (*function)(PetscFE)) 90d71ae5a4SJacob Faibussowitsch { 9120cf1dd8SToby Isaac PetscFunctionBegin; 929566063dSJacob Faibussowitsch PetscCall(PetscFunctionListAdd(&PetscFEList, sname, function)); 933ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9420cf1dd8SToby Isaac } 9520cf1dd8SToby Isaac 96cc4c1da9SBarry Smith /*@ 97dce8aebaSBarry Smith PetscFESetType - Builds a particular `PetscFE` 9820cf1dd8SToby Isaac 9920f4b53cSBarry Smith Collective 10020cf1dd8SToby Isaac 10120cf1dd8SToby Isaac Input Parameters: 102dce8aebaSBarry Smith + fem - The `PetscFE` object 10320cf1dd8SToby Isaac - name - The kind of FEM space 10420cf1dd8SToby Isaac 10520cf1dd8SToby Isaac Options Database Key: 10620f4b53cSBarry Smith . -petscfe_type <type> - Sets the `PetscFE` type; use -help for a list of available types 10720cf1dd8SToby Isaac 10820cf1dd8SToby Isaac Level: intermediate 10920cf1dd8SToby Isaac 110dce8aebaSBarry Smith .seealso: `PetscFEType`, `PetscFE`, `PetscFEGetType()`, `PetscFECreate()` 11120cf1dd8SToby Isaac @*/ 112d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFESetType(PetscFE fem, PetscFEType name) 113d71ae5a4SJacob Faibussowitsch { 11420cf1dd8SToby Isaac PetscErrorCode (*r)(PetscFE); 11520cf1dd8SToby Isaac PetscBool match; 11620cf1dd8SToby Isaac 11720cf1dd8SToby Isaac PetscFunctionBegin; 11820cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 1199566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)fem, name, &match)); 1203ba16761SJacob Faibussowitsch if (match) PetscFunctionReturn(PETSC_SUCCESS); 12120cf1dd8SToby Isaac 1229566063dSJacob Faibussowitsch if (!PetscFERegisterAllCalled) PetscCall(PetscFERegisterAll()); 1239566063dSJacob Faibussowitsch PetscCall(PetscFunctionListFind(PetscFEList, name, &r)); 12428b400f6SJacob Faibussowitsch PetscCheck(r, PetscObjectComm((PetscObject)fem), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown PetscFE type: %s", name); 12520cf1dd8SToby Isaac 126dbbe0bcdSBarry Smith PetscTryTypeMethod(fem, destroy); 12720cf1dd8SToby Isaac fem->ops->destroy = NULL; 128dbbe0bcdSBarry Smith 1299566063dSJacob Faibussowitsch PetscCall((*r)(fem)); 1309566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)fem, name)); 1313ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 13220cf1dd8SToby Isaac } 13320cf1dd8SToby Isaac 134cc4c1da9SBarry Smith /*@ 135dce8aebaSBarry Smith PetscFEGetType - Gets the `PetscFEType` (as a string) from the `PetscFE` object. 13620cf1dd8SToby Isaac 13720cf1dd8SToby Isaac Not Collective 13820cf1dd8SToby Isaac 13920cf1dd8SToby Isaac Input Parameter: 140dce8aebaSBarry Smith . fem - The `PetscFE` 14120cf1dd8SToby Isaac 14220cf1dd8SToby Isaac Output Parameter: 143dce8aebaSBarry Smith . name - The `PetscFEType` name 14420cf1dd8SToby Isaac 14520cf1dd8SToby Isaac Level: intermediate 14620cf1dd8SToby Isaac 147dce8aebaSBarry Smith .seealso: `PetscFEType`, `PetscFE`, `PetscFESetType()`, `PetscFECreate()` 14820cf1dd8SToby Isaac @*/ 149d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEGetType(PetscFE fem, PetscFEType *name) 150d71ae5a4SJacob Faibussowitsch { 15120cf1dd8SToby Isaac PetscFunctionBegin; 15220cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 1534f572ea9SToby Isaac PetscAssertPointer(name, 2); 15448a46eb9SPierre Jolivet if (!PetscFERegisterAllCalled) PetscCall(PetscFERegisterAll()); 15520cf1dd8SToby Isaac *name = ((PetscObject)fem)->type_name; 1563ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 15720cf1dd8SToby Isaac } 15820cf1dd8SToby Isaac 159ffeef943SBarry Smith /*@ 160dce8aebaSBarry Smith PetscFEViewFromOptions - View from a `PetscFE` based on values in the options database 161fe2efc57SMark 16220f4b53cSBarry Smith Collective 163fe2efc57SMark 164fe2efc57SMark Input Parameters: 165dce8aebaSBarry Smith + A - the `PetscFE` object 166dce8aebaSBarry Smith . obj - Optional object that provides the options prefix 167dce8aebaSBarry Smith - name - command line option name 168fe2efc57SMark 169fe2efc57SMark Level: intermediate 170dce8aebaSBarry Smith 171dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscFEView()`, `PetscObjectViewFromOptions()`, `PetscFECreate()` 172fe2efc57SMark @*/ 173d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEViewFromOptions(PetscFE A, PetscObject obj, const char name[]) 174d71ae5a4SJacob Faibussowitsch { 175fe2efc57SMark PetscFunctionBegin; 176fe2efc57SMark PetscValidHeaderSpecific(A, PETSCFE_CLASSID, 1); 1779566063dSJacob Faibussowitsch PetscCall(PetscObjectViewFromOptions((PetscObject)A, obj, name)); 1783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 179fe2efc57SMark } 180fe2efc57SMark 181ffeef943SBarry Smith /*@ 182dce8aebaSBarry Smith PetscFEView - Views a `PetscFE` 18320cf1dd8SToby Isaac 18420f4b53cSBarry Smith Collective 18520cf1dd8SToby Isaac 186d8d19677SJose E. Roman Input Parameters: 187dce8aebaSBarry Smith + fem - the `PetscFE` object to view 188d9bac1caSLisandro Dalcin - viewer - the viewer 18920cf1dd8SToby Isaac 1902b99622eSMatthew G. Knepley Level: beginner 19120cf1dd8SToby Isaac 192dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscViewer`, `PetscFEDestroy()`, `PetscFEViewFromOptions()` 19320cf1dd8SToby Isaac @*/ 194d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEView(PetscFE fem, PetscViewer viewer) 195d71ae5a4SJacob Faibussowitsch { 196d9bac1caSLisandro Dalcin PetscBool iascii; 19720cf1dd8SToby Isaac 19820cf1dd8SToby Isaac PetscFunctionBegin; 19920cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 200d9bac1caSLisandro Dalcin if (viewer) PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 2019566063dSJacob Faibussowitsch if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)fem), &viewer)); 2029566063dSJacob Faibussowitsch PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)fem, viewer)); 2039566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 204dbbe0bcdSBarry Smith PetscTryTypeMethod(fem, view, viewer); 2053ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 20620cf1dd8SToby Isaac } 20720cf1dd8SToby Isaac 20820cf1dd8SToby Isaac /*@ 209dce8aebaSBarry Smith PetscFESetFromOptions - sets parameters in a `PetscFE` from the options database 21020cf1dd8SToby Isaac 21120f4b53cSBarry Smith Collective 21220cf1dd8SToby Isaac 21320cf1dd8SToby Isaac Input Parameter: 214dce8aebaSBarry Smith . fem - the `PetscFE` object to set options for 21520cf1dd8SToby Isaac 216dce8aebaSBarry Smith Options Database Keys: 217a2b725a8SWilliam Gropp + -petscfe_num_blocks - the number of cell blocks to integrate concurrently 218a2b725a8SWilliam Gropp - -petscfe_num_batches - the number of cell batches to integrate serially 21920cf1dd8SToby Isaac 2202b99622eSMatthew G. Knepley Level: intermediate 22120cf1dd8SToby Isaac 222dce8aebaSBarry Smith .seealso: `PetscFEV`, `PetscFEView()` 22320cf1dd8SToby Isaac @*/ 224d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFESetFromOptions(PetscFE fem) 225d71ae5a4SJacob Faibussowitsch { 22620cf1dd8SToby Isaac const char *defaultType; 22720cf1dd8SToby Isaac char name[256]; 22820cf1dd8SToby Isaac PetscBool flg; 22920cf1dd8SToby Isaac 23020cf1dd8SToby Isaac PetscFunctionBegin; 23120cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 23220cf1dd8SToby Isaac if (!((PetscObject)fem)->type_name) { 23320cf1dd8SToby Isaac defaultType = PETSCFEBASIC; 23420cf1dd8SToby Isaac } else { 23520cf1dd8SToby Isaac defaultType = ((PetscObject)fem)->type_name; 23620cf1dd8SToby Isaac } 2379566063dSJacob Faibussowitsch if (!PetscFERegisterAllCalled) PetscCall(PetscFERegisterAll()); 23820cf1dd8SToby Isaac 239d0609cedSBarry Smith PetscObjectOptionsBegin((PetscObject)fem); 2409566063dSJacob Faibussowitsch PetscCall(PetscOptionsFList("-petscfe_type", "Finite element space", "PetscFESetType", PetscFEList, defaultType, name, 256, &flg)); 24120cf1dd8SToby Isaac if (flg) { 2429566063dSJacob Faibussowitsch PetscCall(PetscFESetType(fem, name)); 24320cf1dd8SToby Isaac } else if (!((PetscObject)fem)->type_name) { 2449566063dSJacob Faibussowitsch PetscCall(PetscFESetType(fem, defaultType)); 24520cf1dd8SToby Isaac } 2469566063dSJacob Faibussowitsch PetscCall(PetscOptionsBoundedInt("-petscfe_num_blocks", "The number of cell blocks to integrate concurrently", "PetscSpaceSetTileSizes", fem->numBlocks, &fem->numBlocks, NULL, 1)); 2479566063dSJacob Faibussowitsch PetscCall(PetscOptionsBoundedInt("-petscfe_num_batches", "The number of cell batches to integrate serially", "PetscSpaceSetTileSizes", fem->numBatches, &fem->numBatches, NULL, 1)); 248dbbe0bcdSBarry Smith PetscTryTypeMethod(fem, setfromoptions, PetscOptionsObject); 24920cf1dd8SToby Isaac /* process any options handlers added with PetscObjectAddOptionsHandler() */ 250dbbe0bcdSBarry Smith PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)fem, PetscOptionsObject)); 251d0609cedSBarry Smith PetscOptionsEnd(); 2529566063dSJacob Faibussowitsch PetscCall(PetscFEViewFromOptions(fem, NULL, "-petscfe_view")); 2533ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 25420cf1dd8SToby Isaac } 25520cf1dd8SToby Isaac 256cc4c1da9SBarry Smith /*@ 257dce8aebaSBarry Smith PetscFESetUp - Construct data structures for the `PetscFE` after the `PetscFEType` has been set 25820cf1dd8SToby Isaac 25920f4b53cSBarry Smith Collective 26020cf1dd8SToby Isaac 26120cf1dd8SToby Isaac Input Parameter: 262dce8aebaSBarry Smith . fem - the `PetscFE` object to setup 26320cf1dd8SToby Isaac 2642b99622eSMatthew G. Knepley Level: intermediate 26520cf1dd8SToby Isaac 266dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscFEView()`, `PetscFEDestroy()` 26720cf1dd8SToby Isaac @*/ 268d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFESetUp(PetscFE fem) 269d71ae5a4SJacob Faibussowitsch { 27020cf1dd8SToby Isaac PetscFunctionBegin; 27120cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 2723ba16761SJacob Faibussowitsch if (fem->setupcalled) PetscFunctionReturn(PETSC_SUCCESS); 2739566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(PETSCFE_SetUp, fem, 0, 0, 0)); 27420cf1dd8SToby Isaac fem->setupcalled = PETSC_TRUE; 275dbbe0bcdSBarry Smith PetscTryTypeMethod(fem, setup); 2769566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(PETSCFE_SetUp, fem, 0, 0, 0)); 2773ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 27820cf1dd8SToby Isaac } 27920cf1dd8SToby Isaac 28020cf1dd8SToby Isaac /*@ 281dce8aebaSBarry Smith PetscFEDestroy - Destroys a `PetscFE` object 28220cf1dd8SToby Isaac 28320f4b53cSBarry Smith Collective 28420cf1dd8SToby Isaac 28520cf1dd8SToby Isaac Input Parameter: 286dce8aebaSBarry Smith . fem - the `PetscFE` object to destroy 28720cf1dd8SToby Isaac 2882b99622eSMatthew G. Knepley Level: beginner 28920cf1dd8SToby Isaac 290dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscFEView()` 29120cf1dd8SToby Isaac @*/ 292d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEDestroy(PetscFE *fem) 293d71ae5a4SJacob Faibussowitsch { 29420cf1dd8SToby Isaac PetscFunctionBegin; 2953ba16761SJacob Faibussowitsch if (!*fem) PetscFunctionReturn(PETSC_SUCCESS); 296f4f49eeaSPierre Jolivet PetscValidHeaderSpecific(*fem, PETSCFE_CLASSID, 1); 29720cf1dd8SToby Isaac 298f4f49eeaSPierre Jolivet if (--((PetscObject)*fem)->refct > 0) { 2999371c9d4SSatish Balay *fem = NULL; 3003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3019371c9d4SSatish Balay } 302f4f49eeaSPierre Jolivet ((PetscObject)*fem)->refct = 0; 30320cf1dd8SToby Isaac 30420cf1dd8SToby Isaac if ((*fem)->subspaces) { 30520cf1dd8SToby Isaac PetscInt dim, d; 30620cf1dd8SToby Isaac 3079566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetDimension((*fem)->dualSpace, &dim)); 3089566063dSJacob Faibussowitsch for (d = 0; d < dim; ++d) PetscCall(PetscFEDestroy(&(*fem)->subspaces[d])); 30920cf1dd8SToby Isaac } 3109566063dSJacob Faibussowitsch PetscCall(PetscFree((*fem)->subspaces)); 3119566063dSJacob Faibussowitsch PetscCall(PetscFree((*fem)->invV)); 3129566063dSJacob Faibussowitsch PetscCall(PetscTabulationDestroy(&(*fem)->T)); 3139566063dSJacob Faibussowitsch PetscCall(PetscTabulationDestroy(&(*fem)->Tf)); 3149566063dSJacob Faibussowitsch PetscCall(PetscTabulationDestroy(&(*fem)->Tc)); 3159566063dSJacob Faibussowitsch PetscCall(PetscSpaceDestroy(&(*fem)->basisSpace)); 3169566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceDestroy(&(*fem)->dualSpace)); 3179566063dSJacob Faibussowitsch PetscCall(PetscQuadratureDestroy(&(*fem)->quadrature)); 3189566063dSJacob Faibussowitsch PetscCall(PetscQuadratureDestroy(&(*fem)->faceQuadrature)); 319f918ec44SMatthew G. Knepley #ifdef PETSC_HAVE_LIBCEED 3209566063dSJacob Faibussowitsch PetscCallCEED(CeedBasisDestroy(&(*fem)->ceedBasis)); 3219566063dSJacob Faibussowitsch PetscCallCEED(CeedDestroy(&(*fem)->ceed)); 322f918ec44SMatthew G. Knepley #endif 32320cf1dd8SToby Isaac 324f4f49eeaSPierre Jolivet PetscTryTypeMethod(*fem, destroy); 3259566063dSJacob Faibussowitsch PetscCall(PetscHeaderDestroy(fem)); 3263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 32720cf1dd8SToby Isaac } 32820cf1dd8SToby Isaac 32920cf1dd8SToby Isaac /*@ 330dce8aebaSBarry Smith PetscFECreate - Creates an empty `PetscFE` object. The type can then be set with `PetscFESetType()`. 33120cf1dd8SToby Isaac 332d083f849SBarry Smith Collective 33320cf1dd8SToby Isaac 33420cf1dd8SToby Isaac Input Parameter: 335dce8aebaSBarry Smith . comm - The communicator for the `PetscFE` object 33620cf1dd8SToby Isaac 33720cf1dd8SToby Isaac Output Parameter: 338dce8aebaSBarry Smith . fem - The `PetscFE` object 33920cf1dd8SToby Isaac 34020cf1dd8SToby Isaac Level: beginner 34120cf1dd8SToby Isaac 342a01caf64Smarkadams4 .seealso: `PetscFE`, `PetscFEType`, `PetscFESetType()`, `PetscFECreateDefault()`, `PETSCFEGALERKIN` 34320cf1dd8SToby Isaac @*/ 344d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFECreate(MPI_Comm comm, PetscFE *fem) 345d71ae5a4SJacob Faibussowitsch { 34620cf1dd8SToby Isaac PetscFE f; 34720cf1dd8SToby Isaac 34820cf1dd8SToby Isaac PetscFunctionBegin; 3494f572ea9SToby Isaac PetscAssertPointer(fem, 2); 3509566063dSJacob Faibussowitsch PetscCall(PetscCitationsRegister(FECitation, &FEcite)); 3519566063dSJacob Faibussowitsch PetscCall(PetscFEInitializePackage()); 35220cf1dd8SToby Isaac 3539566063dSJacob Faibussowitsch PetscCall(PetscHeaderCreate(f, PETSCFE_CLASSID, "PetscFE", "Finite Element", "PetscFE", comm, PetscFEDestroy, PetscFEView)); 35420cf1dd8SToby Isaac 35520cf1dd8SToby Isaac f->basisSpace = NULL; 35620cf1dd8SToby Isaac f->dualSpace = NULL; 35720cf1dd8SToby Isaac f->numComponents = 1; 35820cf1dd8SToby Isaac f->subspaces = NULL; 35920cf1dd8SToby Isaac f->invV = NULL; 360ef0bb6c7SMatthew G. Knepley f->T = NULL; 361ef0bb6c7SMatthew G. Knepley f->Tf = NULL; 362ef0bb6c7SMatthew G. Knepley f->Tc = NULL; 3639566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(&f->quadrature, 1)); 3649566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(&f->faceQuadrature, 1)); 36520cf1dd8SToby Isaac f->blockSize = 0; 36620cf1dd8SToby Isaac f->numBlocks = 1; 36720cf1dd8SToby Isaac f->batchSize = 0; 36820cf1dd8SToby Isaac f->numBatches = 1; 36920cf1dd8SToby Isaac 37020cf1dd8SToby Isaac *fem = f; 3713ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 37220cf1dd8SToby Isaac } 37320cf1dd8SToby Isaac 37420cf1dd8SToby Isaac /*@ 37520cf1dd8SToby Isaac PetscFEGetSpatialDimension - Returns the spatial dimension of the element 37620cf1dd8SToby Isaac 37720f4b53cSBarry Smith Not Collective 37820cf1dd8SToby Isaac 37920cf1dd8SToby Isaac Input Parameter: 380dce8aebaSBarry Smith . fem - The `PetscFE` object 38120cf1dd8SToby Isaac 38220cf1dd8SToby Isaac Output Parameter: 38320cf1dd8SToby Isaac . dim - The spatial dimension 38420cf1dd8SToby Isaac 38520cf1dd8SToby Isaac Level: intermediate 38620cf1dd8SToby Isaac 387dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscFECreate()` 38820cf1dd8SToby Isaac @*/ 389d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEGetSpatialDimension(PetscFE fem, PetscInt *dim) 390d71ae5a4SJacob Faibussowitsch { 39120cf1dd8SToby Isaac DM dm; 39220cf1dd8SToby Isaac 39320cf1dd8SToby Isaac PetscFunctionBegin; 39420cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 3954f572ea9SToby Isaac PetscAssertPointer(dim, 2); 3969566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetDM(fem->dualSpace, &dm)); 3979566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, dim)); 3983ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 39920cf1dd8SToby Isaac } 40020cf1dd8SToby Isaac 40120cf1dd8SToby Isaac /*@ 402dce8aebaSBarry Smith PetscFESetNumComponents - Sets the number of field components in the element 40320cf1dd8SToby Isaac 40420f4b53cSBarry Smith Not Collective 40520cf1dd8SToby Isaac 40620cf1dd8SToby Isaac Input Parameters: 407dce8aebaSBarry Smith + fem - The `PetscFE` object 40820cf1dd8SToby Isaac - comp - The number of field components 40920cf1dd8SToby Isaac 41020cf1dd8SToby Isaac Level: intermediate 41120cf1dd8SToby Isaac 412dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscFECreate()`, `PetscFEGetSpatialDimension()`, `PetscFEGetNumComponents()` 41320cf1dd8SToby Isaac @*/ 414d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFESetNumComponents(PetscFE fem, PetscInt comp) 415d71ae5a4SJacob Faibussowitsch { 41620cf1dd8SToby Isaac PetscFunctionBegin; 41720cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 41820cf1dd8SToby Isaac fem->numComponents = comp; 4193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 42020cf1dd8SToby Isaac } 42120cf1dd8SToby Isaac 42220cf1dd8SToby Isaac /*@ 42320cf1dd8SToby Isaac PetscFEGetNumComponents - Returns the number of components in the element 42420cf1dd8SToby Isaac 42520f4b53cSBarry Smith Not Collective 42620cf1dd8SToby Isaac 42720cf1dd8SToby Isaac Input Parameter: 428dce8aebaSBarry Smith . fem - The `PetscFE` object 42920cf1dd8SToby Isaac 43020cf1dd8SToby Isaac Output Parameter: 43120cf1dd8SToby Isaac . comp - The number of field components 43220cf1dd8SToby Isaac 43320cf1dd8SToby Isaac Level: intermediate 43420cf1dd8SToby Isaac 43542747ad1SJacob Faibussowitsch .seealso: `PetscFE`, `PetscFECreate()`, `PetscFEGetSpatialDimension()` 43620cf1dd8SToby Isaac @*/ 437d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEGetNumComponents(PetscFE fem, PetscInt *comp) 438d71ae5a4SJacob Faibussowitsch { 43920cf1dd8SToby Isaac PetscFunctionBegin; 44020cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 4414f572ea9SToby Isaac PetscAssertPointer(comp, 2); 44220cf1dd8SToby Isaac *comp = fem->numComponents; 4433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 44420cf1dd8SToby Isaac } 44520cf1dd8SToby Isaac 44620cf1dd8SToby Isaac /*@ 44720cf1dd8SToby Isaac PetscFESetTileSizes - Sets the tile sizes for evaluation 44820cf1dd8SToby Isaac 44920f4b53cSBarry Smith Not Collective 45020cf1dd8SToby Isaac 45120cf1dd8SToby Isaac Input Parameters: 452dce8aebaSBarry Smith + fem - The `PetscFE` object 45320cf1dd8SToby Isaac . blockSize - The number of elements in a block 45420cf1dd8SToby Isaac . numBlocks - The number of blocks in a batch 45520cf1dd8SToby Isaac . batchSize - The number of elements in a batch 45620cf1dd8SToby Isaac - numBatches - The number of batches in a chunk 45720cf1dd8SToby Isaac 45820cf1dd8SToby Isaac Level: intermediate 45920cf1dd8SToby Isaac 460dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscFECreate()`, `PetscFEGetTileSizes()` 46120cf1dd8SToby Isaac @*/ 462d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFESetTileSizes(PetscFE fem, PetscInt blockSize, PetscInt numBlocks, PetscInt batchSize, PetscInt numBatches) 463d71ae5a4SJacob Faibussowitsch { 46420cf1dd8SToby Isaac PetscFunctionBegin; 46520cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 46620cf1dd8SToby Isaac fem->blockSize = blockSize; 46720cf1dd8SToby Isaac fem->numBlocks = numBlocks; 46820cf1dd8SToby Isaac fem->batchSize = batchSize; 46920cf1dd8SToby Isaac fem->numBatches = numBatches; 4703ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 47120cf1dd8SToby Isaac } 47220cf1dd8SToby Isaac 47320cf1dd8SToby Isaac /*@ 47420cf1dd8SToby Isaac PetscFEGetTileSizes - Returns the tile sizes for evaluation 47520cf1dd8SToby Isaac 47620f4b53cSBarry Smith Not Collective 47720cf1dd8SToby Isaac 47820cf1dd8SToby Isaac Input Parameter: 479dce8aebaSBarry Smith . fem - The `PetscFE` object 48020cf1dd8SToby Isaac 48120cf1dd8SToby Isaac Output Parameters: 48220cf1dd8SToby Isaac + blockSize - The number of elements in a block 48320cf1dd8SToby Isaac . numBlocks - The number of blocks in a batch 48420cf1dd8SToby Isaac . batchSize - The number of elements in a batch 48520cf1dd8SToby Isaac - numBatches - The number of batches in a chunk 48620cf1dd8SToby Isaac 48720cf1dd8SToby Isaac Level: intermediate 48820cf1dd8SToby Isaac 489dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscFECreate()`, `PetscFESetTileSizes()` 49020cf1dd8SToby Isaac @*/ 491d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEGetTileSizes(PetscFE fem, PetscInt *blockSize, PetscInt *numBlocks, PetscInt *batchSize, PetscInt *numBatches) 492d71ae5a4SJacob Faibussowitsch { 49320cf1dd8SToby Isaac PetscFunctionBegin; 49420cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 4954f572ea9SToby Isaac if (blockSize) PetscAssertPointer(blockSize, 2); 4964f572ea9SToby Isaac if (numBlocks) PetscAssertPointer(numBlocks, 3); 4974f572ea9SToby Isaac if (batchSize) PetscAssertPointer(batchSize, 4); 4984f572ea9SToby Isaac if (numBatches) PetscAssertPointer(numBatches, 5); 49920cf1dd8SToby Isaac if (blockSize) *blockSize = fem->blockSize; 50020cf1dd8SToby Isaac if (numBlocks) *numBlocks = fem->numBlocks; 50120cf1dd8SToby Isaac if (batchSize) *batchSize = fem->batchSize; 50220cf1dd8SToby Isaac if (numBatches) *numBatches = fem->numBatches; 5033ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 50420cf1dd8SToby Isaac } 50520cf1dd8SToby Isaac 50620cf1dd8SToby Isaac /*@ 507dce8aebaSBarry Smith PetscFEGetBasisSpace - Returns the `PetscSpace` used for the approximation of the solution for the `PetscFE` 50820cf1dd8SToby Isaac 50920f4b53cSBarry Smith Not Collective 51020cf1dd8SToby Isaac 51120cf1dd8SToby Isaac Input Parameter: 512dce8aebaSBarry Smith . fem - The `PetscFE` object 51320cf1dd8SToby Isaac 51420cf1dd8SToby Isaac Output Parameter: 515dce8aebaSBarry Smith . sp - The `PetscSpace` object 51620cf1dd8SToby Isaac 51720cf1dd8SToby Isaac Level: intermediate 51820cf1dd8SToby Isaac 519dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscSpace`, `PetscFECreate()` 52020cf1dd8SToby Isaac @*/ 521d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEGetBasisSpace(PetscFE fem, PetscSpace *sp) 522d71ae5a4SJacob Faibussowitsch { 52320cf1dd8SToby Isaac PetscFunctionBegin; 52420cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 5254f572ea9SToby Isaac PetscAssertPointer(sp, 2); 52620cf1dd8SToby Isaac *sp = fem->basisSpace; 5273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 52820cf1dd8SToby Isaac } 52920cf1dd8SToby Isaac 53020cf1dd8SToby Isaac /*@ 531dce8aebaSBarry Smith PetscFESetBasisSpace - Sets the `PetscSpace` used for the approximation of the solution 53220cf1dd8SToby Isaac 53320f4b53cSBarry Smith Not Collective 53420cf1dd8SToby Isaac 53520cf1dd8SToby Isaac Input Parameters: 536dce8aebaSBarry Smith + fem - The `PetscFE` object 537dce8aebaSBarry Smith - sp - The `PetscSpace` object 53820cf1dd8SToby Isaac 53920cf1dd8SToby Isaac Level: intermediate 54020cf1dd8SToby Isaac 54160225df5SJacob Faibussowitsch Developer Notes: 542dce8aebaSBarry Smith There is `PetscFESetBasisSpace()` but the `PetscFESetDualSpace()`, likely the Basis is unneeded in the function name 543dce8aebaSBarry Smith 544dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscSpace`, `PetscDualSpace`, `PetscFECreate()`, `PetscFESetDualSpace()` 54520cf1dd8SToby Isaac @*/ 546d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFESetBasisSpace(PetscFE fem, PetscSpace sp) 547d71ae5a4SJacob Faibussowitsch { 54820cf1dd8SToby Isaac PetscFunctionBegin; 54920cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 55020cf1dd8SToby Isaac PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 2); 5519566063dSJacob Faibussowitsch PetscCall(PetscSpaceDestroy(&fem->basisSpace)); 55220cf1dd8SToby Isaac fem->basisSpace = sp; 5539566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)fem->basisSpace)); 5543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 55520cf1dd8SToby Isaac } 55620cf1dd8SToby Isaac 55720cf1dd8SToby Isaac /*@ 558dce8aebaSBarry Smith PetscFEGetDualSpace - Returns the `PetscDualSpace` used to define the inner product for a `PetscFE` 55920cf1dd8SToby Isaac 56020f4b53cSBarry Smith Not Collective 56120cf1dd8SToby Isaac 56220cf1dd8SToby Isaac Input Parameter: 563dce8aebaSBarry Smith . fem - The `PetscFE` object 56420cf1dd8SToby Isaac 56520cf1dd8SToby Isaac Output Parameter: 566dce8aebaSBarry Smith . sp - The `PetscDualSpace` object 56720cf1dd8SToby Isaac 56820cf1dd8SToby Isaac Level: intermediate 56920cf1dd8SToby Isaac 570dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscSpace`, `PetscDualSpace`, `PetscFECreate()` 57120cf1dd8SToby Isaac @*/ 572d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEGetDualSpace(PetscFE fem, PetscDualSpace *sp) 573d71ae5a4SJacob Faibussowitsch { 57420cf1dd8SToby Isaac PetscFunctionBegin; 57520cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 5764f572ea9SToby Isaac PetscAssertPointer(sp, 2); 57720cf1dd8SToby Isaac *sp = fem->dualSpace; 5783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 57920cf1dd8SToby Isaac } 58020cf1dd8SToby Isaac 58120cf1dd8SToby Isaac /*@ 582dce8aebaSBarry Smith PetscFESetDualSpace - Sets the `PetscDualSpace` used to define the inner product 58320cf1dd8SToby Isaac 58420f4b53cSBarry Smith Not Collective 58520cf1dd8SToby Isaac 58620cf1dd8SToby Isaac Input Parameters: 587dce8aebaSBarry Smith + fem - The `PetscFE` object 588dce8aebaSBarry Smith - sp - The `PetscDualSpace` object 58920cf1dd8SToby Isaac 59020cf1dd8SToby Isaac Level: intermediate 59120cf1dd8SToby Isaac 592dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscSpace`, `PetscDualSpace`, `PetscFECreate()`, `PetscFESetBasisSpace()` 59320cf1dd8SToby Isaac @*/ 594d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFESetDualSpace(PetscFE fem, PetscDualSpace sp) 595d71ae5a4SJacob Faibussowitsch { 59620cf1dd8SToby Isaac PetscFunctionBegin; 59720cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 59820cf1dd8SToby Isaac PetscValidHeaderSpecific(sp, PETSCDUALSPACE_CLASSID, 2); 5999566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceDestroy(&fem->dualSpace)); 60020cf1dd8SToby Isaac fem->dualSpace = sp; 6019566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)fem->dualSpace)); 6023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 60320cf1dd8SToby Isaac } 60420cf1dd8SToby Isaac 60520cf1dd8SToby Isaac /*@ 606dce8aebaSBarry Smith PetscFEGetQuadrature - Returns the `PetscQuadrature` used to calculate inner products 60720cf1dd8SToby Isaac 60820f4b53cSBarry Smith Not Collective 60920cf1dd8SToby Isaac 61020cf1dd8SToby Isaac Input Parameter: 611dce8aebaSBarry Smith . fem - The `PetscFE` object 61220cf1dd8SToby Isaac 61320cf1dd8SToby Isaac Output Parameter: 614dce8aebaSBarry Smith . q - The `PetscQuadrature` object 61520cf1dd8SToby Isaac 61620cf1dd8SToby Isaac Level: intermediate 61720cf1dd8SToby Isaac 618dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscSpace`, `PetscDualSpace`, `PetscQuadrature`, `PetscFECreate()` 61920cf1dd8SToby Isaac @*/ 620d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEGetQuadrature(PetscFE fem, PetscQuadrature *q) 621d71ae5a4SJacob Faibussowitsch { 62220cf1dd8SToby Isaac PetscFunctionBegin; 62320cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 6244f572ea9SToby Isaac PetscAssertPointer(q, 2); 62520cf1dd8SToby Isaac *q = fem->quadrature; 6263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 62720cf1dd8SToby Isaac } 62820cf1dd8SToby Isaac 62920cf1dd8SToby Isaac /*@ 630dce8aebaSBarry Smith PetscFESetQuadrature - Sets the `PetscQuadrature` used to calculate inner products 63120cf1dd8SToby Isaac 63220f4b53cSBarry Smith Not Collective 63320cf1dd8SToby Isaac 63420cf1dd8SToby Isaac Input Parameters: 635dce8aebaSBarry Smith + fem - The `PetscFE` object 636dce8aebaSBarry Smith - q - The `PetscQuadrature` object 63720cf1dd8SToby Isaac 63820cf1dd8SToby Isaac Level: intermediate 63920cf1dd8SToby Isaac 640dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscSpace`, `PetscDualSpace`, `PetscQuadrature`, `PetscFECreate()`, `PetscFEGetFaceQuadrature()` 64120cf1dd8SToby Isaac @*/ 642d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFESetQuadrature(PetscFE fem, PetscQuadrature q) 643d71ae5a4SJacob Faibussowitsch { 64420cf1dd8SToby Isaac PetscInt Nc, qNc; 64520cf1dd8SToby Isaac 64620cf1dd8SToby Isaac PetscFunctionBegin; 64720cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 6483ba16761SJacob Faibussowitsch if (q == fem->quadrature) PetscFunctionReturn(PETSC_SUCCESS); 6499566063dSJacob Faibussowitsch PetscCall(PetscFEGetNumComponents(fem, &Nc)); 6509566063dSJacob Faibussowitsch PetscCall(PetscQuadratureGetNumComponents(q, &qNc)); 65163a3b9bcSJacob 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); 6529566063dSJacob Faibussowitsch PetscCall(PetscTabulationDestroy(&fem->T)); 6539566063dSJacob Faibussowitsch PetscCall(PetscTabulationDestroy(&fem->Tc)); 6549566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)q)); 6559566063dSJacob Faibussowitsch PetscCall(PetscQuadratureDestroy(&fem->quadrature)); 65620cf1dd8SToby Isaac fem->quadrature = q; 6573ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 65820cf1dd8SToby Isaac } 65920cf1dd8SToby Isaac 66020cf1dd8SToby Isaac /*@ 661dce8aebaSBarry Smith PetscFEGetFaceQuadrature - Returns the `PetscQuadrature` used to calculate inner products on faces 66220cf1dd8SToby Isaac 66320f4b53cSBarry Smith Not Collective 66420cf1dd8SToby Isaac 66520cf1dd8SToby Isaac Input Parameter: 666dce8aebaSBarry Smith . fem - The `PetscFE` object 66720cf1dd8SToby Isaac 66820cf1dd8SToby Isaac Output Parameter: 669dce8aebaSBarry Smith . q - The `PetscQuadrature` object 67020cf1dd8SToby Isaac 67120cf1dd8SToby Isaac Level: intermediate 67220cf1dd8SToby Isaac 67360225df5SJacob Faibussowitsch Developer Notes: 67435cb6cd3SPierre Jolivet There is a special face quadrature but not edge, likely this API would benefit from a refactorization 675dce8aebaSBarry Smith 676dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscSpace`, `PetscDualSpace`, `PetscQuadrature`, `PetscFECreate()`, `PetscFESetQuadrature()`, `PetscFESetFaceQuadrature()` 67720cf1dd8SToby Isaac @*/ 678d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEGetFaceQuadrature(PetscFE fem, PetscQuadrature *q) 679d71ae5a4SJacob Faibussowitsch { 68020cf1dd8SToby Isaac PetscFunctionBegin; 68120cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 6824f572ea9SToby Isaac PetscAssertPointer(q, 2); 68320cf1dd8SToby Isaac *q = fem->faceQuadrature; 6843ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 68520cf1dd8SToby Isaac } 68620cf1dd8SToby Isaac 68720cf1dd8SToby Isaac /*@ 688dce8aebaSBarry Smith PetscFESetFaceQuadrature - Sets the `PetscQuadrature` used to calculate inner products on faces 68920cf1dd8SToby Isaac 69020f4b53cSBarry Smith Not Collective 69120cf1dd8SToby Isaac 69220cf1dd8SToby Isaac Input Parameters: 693dce8aebaSBarry Smith + fem - The `PetscFE` object 694dce8aebaSBarry Smith - q - The `PetscQuadrature` object 69520cf1dd8SToby Isaac 69620cf1dd8SToby Isaac Level: intermediate 69720cf1dd8SToby Isaac 69842747ad1SJacob Faibussowitsch .seealso: `PetscFE`, `PetscSpace`, `PetscDualSpace`, `PetscQuadrature`, `PetscFECreate()`, `PetscFESetQuadrature()` 69920cf1dd8SToby Isaac @*/ 700d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFESetFaceQuadrature(PetscFE fem, PetscQuadrature q) 701d71ae5a4SJacob Faibussowitsch { 702ef0bb6c7SMatthew G. Knepley PetscInt Nc, qNc; 70320cf1dd8SToby Isaac 70420cf1dd8SToby Isaac PetscFunctionBegin; 70520cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 70626add6b9SMatthew G. Knepley if (q == fem->faceQuadrature) PetscFunctionReturn(PETSC_SUCCESS); 7079566063dSJacob Faibussowitsch PetscCall(PetscFEGetNumComponents(fem, &Nc)); 7089566063dSJacob Faibussowitsch PetscCall(PetscQuadratureGetNumComponents(q, &qNc)); 70963a3b9bcSJacob 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); 7109566063dSJacob Faibussowitsch PetscCall(PetscTabulationDestroy(&fem->Tf)); 71126add6b9SMatthew G. Knepley PetscCall(PetscObjectReference((PetscObject)q)); 7129566063dSJacob Faibussowitsch PetscCall(PetscQuadratureDestroy(&fem->faceQuadrature)); 71320cf1dd8SToby Isaac fem->faceQuadrature = q; 7143ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 71520cf1dd8SToby Isaac } 71620cf1dd8SToby Isaac 7175dc5c000SMatthew G. Knepley /*@ 718dce8aebaSBarry Smith PetscFECopyQuadrature - Copy both volumetric and surface quadrature to a new `PetscFE` 7195dc5c000SMatthew G. Knepley 72020f4b53cSBarry Smith Not Collective 7215dc5c000SMatthew G. Knepley 7225dc5c000SMatthew G. Knepley Input Parameters: 723dce8aebaSBarry Smith + sfe - The `PetscFE` source for the quadratures 724dce8aebaSBarry Smith - tfe - The `PetscFE` target for the quadratures 7255dc5c000SMatthew G. Knepley 7265dc5c000SMatthew G. Knepley Level: intermediate 7275dc5c000SMatthew G. Knepley 728dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscSpace`, `PetscDualSpace`, `PetscQuadrature`, `PetscFECreate()`, `PetscFESetQuadrature()`, `PetscFESetFaceQuadrature()` 7295dc5c000SMatthew G. Knepley @*/ 730d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFECopyQuadrature(PetscFE sfe, PetscFE tfe) 731d71ae5a4SJacob Faibussowitsch { 7325dc5c000SMatthew G. Knepley PetscQuadrature q; 7335dc5c000SMatthew G. Knepley 7345dc5c000SMatthew G. Knepley PetscFunctionBegin; 7355dc5c000SMatthew G. Knepley PetscValidHeaderSpecific(sfe, PETSCFE_CLASSID, 1); 7365dc5c000SMatthew G. Knepley PetscValidHeaderSpecific(tfe, PETSCFE_CLASSID, 2); 7379566063dSJacob Faibussowitsch PetscCall(PetscFEGetQuadrature(sfe, &q)); 7389566063dSJacob Faibussowitsch PetscCall(PetscFESetQuadrature(tfe, q)); 7399566063dSJacob Faibussowitsch PetscCall(PetscFEGetFaceQuadrature(sfe, &q)); 7409566063dSJacob Faibussowitsch PetscCall(PetscFESetFaceQuadrature(tfe, q)); 7413ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7425dc5c000SMatthew G. Knepley } 7435dc5c000SMatthew G. Knepley 74420cf1dd8SToby Isaac /*@C 74520cf1dd8SToby Isaac PetscFEGetNumDof - Returns the number of dofs (dual basis vectors) associated to mesh points on the reference cell of a given dimension 74620cf1dd8SToby Isaac 74720f4b53cSBarry Smith Not Collective 74820cf1dd8SToby Isaac 74920cf1dd8SToby Isaac Input Parameter: 750dce8aebaSBarry Smith . fem - The `PetscFE` object 75120cf1dd8SToby Isaac 75220cf1dd8SToby Isaac Output Parameter: 753f13dfd9eSBarry Smith . numDof - Array of length `dim` with the number of dofs in each dimension 75420cf1dd8SToby Isaac 75520cf1dd8SToby Isaac Level: intermediate 75620cf1dd8SToby Isaac 757dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscSpace`, `PetscDualSpace`, `PetscFECreate()` 75820cf1dd8SToby Isaac @*/ 759f13dfd9eSBarry Smith PetscErrorCode PetscFEGetNumDof(PetscFE fem, const PetscInt *numDof[]) 760d71ae5a4SJacob Faibussowitsch { 76120cf1dd8SToby Isaac PetscFunctionBegin; 76220cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 7634f572ea9SToby Isaac PetscAssertPointer(numDof, 2); 7649566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetNumDof(fem->dualSpace, numDof)); 7653ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 76620cf1dd8SToby Isaac } 76720cf1dd8SToby Isaac 76820cf1dd8SToby Isaac /*@C 769ef0bb6c7SMatthew G. Knepley PetscFEGetCellTabulation - Returns the tabulation of the basis functions at the quadrature points on the reference cell 77020cf1dd8SToby Isaac 77120f4b53cSBarry Smith Not Collective 77220cf1dd8SToby Isaac 773d8d19677SJose E. Roman Input Parameters: 774dce8aebaSBarry Smith + fem - The `PetscFE` object 775f9244615SMatthew G. Knepley - k - The highest derivative we need to tabulate, very often 1 77620cf1dd8SToby Isaac 777ef0bb6c7SMatthew G. Knepley Output Parameter: 778ef0bb6c7SMatthew G. Knepley . T - The basis function values and derivatives at quadrature points 77920cf1dd8SToby Isaac 78020cf1dd8SToby Isaac Level: intermediate 78120cf1dd8SToby Isaac 782dce8aebaSBarry Smith Note: 783dce8aebaSBarry Smith .vb 784dce8aebaSBarry Smith T->T[0] = B[(p*pdim + i)*Nc + c] is the value at point p for basis function i and component c 785dce8aebaSBarry Smith 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 786dce8aebaSBarry Smith 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 787dce8aebaSBarry Smith .ve 788dce8aebaSBarry Smith 789dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscSpace`, `PetscDualSpace`, `PetscTabulation`, `PetscFECreateTabulation()`, `PetscTabulationDestroy()` 79020cf1dd8SToby Isaac @*/ 791d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEGetCellTabulation(PetscFE fem, PetscInt k, PetscTabulation *T) 792d71ae5a4SJacob Faibussowitsch { 79320cf1dd8SToby Isaac PetscInt npoints; 79420cf1dd8SToby Isaac const PetscReal *points; 79520cf1dd8SToby Isaac 79620cf1dd8SToby Isaac PetscFunctionBegin; 79720cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 7984f572ea9SToby Isaac PetscAssertPointer(T, 3); 7999566063dSJacob Faibussowitsch PetscCall(PetscQuadratureGetData(fem->quadrature, NULL, NULL, &npoints, &points, NULL)); 8009566063dSJacob Faibussowitsch if (!fem->T) PetscCall(PetscFECreateTabulation(fem, 1, npoints, points, k, &fem->T)); 801aa9788aaSMatthew G. Knepley PetscCheck(!fem->T || k <= fem->T->K || (!fem->T->cdim && !fem->T->K), PetscObjectComm((PetscObject)fem), PETSC_ERR_ARG_OUTOFRANGE, "Requested %" PetscInt_FMT " derivatives, but only tabulated %" PetscInt_FMT, k, fem->T->K); 802ef0bb6c7SMatthew G. Knepley *T = fem->T; 8033ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 80420cf1dd8SToby Isaac } 80520cf1dd8SToby Isaac 8062b99622eSMatthew G. Knepley /*@C 807ef0bb6c7SMatthew G. Knepley PetscFEGetFaceTabulation - Returns the tabulation of the basis functions at the face quadrature points for each face of the reference cell 8082b99622eSMatthew G. Knepley 80920f4b53cSBarry Smith Not Collective 8102b99622eSMatthew G. Knepley 811d8d19677SJose E. Roman Input Parameters: 812dce8aebaSBarry Smith + fem - The `PetscFE` object 813f9244615SMatthew G. Knepley - k - The highest derivative we need to tabulate, very often 1 8142b99622eSMatthew G. Knepley 8152fe279fdSBarry Smith Output Parameter: 816a5b23f4aSJose E. Roman . Tf - The basis function values and derivatives at face quadrature points 8172b99622eSMatthew G. Knepley 8182b99622eSMatthew G. Knepley Level: intermediate 8192b99622eSMatthew G. Knepley 820dce8aebaSBarry Smith Note: 821dce8aebaSBarry Smith .vb 822dce8aebaSBarry Smith 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 823dce8aebaSBarry Smith 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 824dce8aebaSBarry Smith 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 825dce8aebaSBarry Smith .ve 826dce8aebaSBarry Smith 827dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscSpace`, `PetscDualSpace`, `PetscTabulation`, `PetscFEGetCellTabulation()`, `PetscFECreateTabulation()`, `PetscTabulationDestroy()` 8282b99622eSMatthew G. Knepley @*/ 829d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEGetFaceTabulation(PetscFE fem, PetscInt k, PetscTabulation *Tf) 830d71ae5a4SJacob Faibussowitsch { 83120cf1dd8SToby Isaac PetscFunctionBegin; 83220cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 8334f572ea9SToby Isaac PetscAssertPointer(Tf, 3); 834ef0bb6c7SMatthew G. Knepley if (!fem->Tf) { 83520cf1dd8SToby Isaac const PetscReal xi0[3] = {-1., -1., -1.}; 83620cf1dd8SToby Isaac PetscReal v0[3], J[9], detJ; 83720cf1dd8SToby Isaac PetscQuadrature fq; 83820cf1dd8SToby Isaac PetscDualSpace sp; 83920cf1dd8SToby Isaac DM dm; 84020cf1dd8SToby Isaac const PetscInt *faces; 84120cf1dd8SToby Isaac PetscInt dim, numFaces, f, npoints, q; 84220cf1dd8SToby Isaac const PetscReal *points; 84320cf1dd8SToby Isaac PetscReal *facePoints; 84420cf1dd8SToby Isaac 8459566063dSJacob Faibussowitsch PetscCall(PetscFEGetDualSpace(fem, &sp)); 8469566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetDM(sp, &dm)); 8479566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &dim)); 8489566063dSJacob Faibussowitsch PetscCall(DMPlexGetConeSize(dm, 0, &numFaces)); 8499566063dSJacob Faibussowitsch PetscCall(DMPlexGetCone(dm, 0, &faces)); 8509566063dSJacob Faibussowitsch PetscCall(PetscFEGetFaceQuadrature(fem, &fq)); 85120cf1dd8SToby Isaac if (fq) { 8529566063dSJacob Faibussowitsch PetscCall(PetscQuadratureGetData(fq, NULL, NULL, &npoints, &points, NULL)); 8539566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(numFaces * npoints * dim, &facePoints)); 85420cf1dd8SToby Isaac for (f = 0; f < numFaces; ++f) { 8559566063dSJacob Faibussowitsch PetscCall(DMPlexComputeCellGeometryFEM(dm, faces[f], NULL, v0, J, NULL, &detJ)); 85620cf1dd8SToby Isaac for (q = 0; q < npoints; ++q) CoordinatesRefToReal(dim, dim - 1, xi0, v0, J, &points[q * (dim - 1)], &facePoints[(f * npoints + q) * dim]); 85720cf1dd8SToby Isaac } 8589566063dSJacob Faibussowitsch PetscCall(PetscFECreateTabulation(fem, numFaces, npoints, facePoints, k, &fem->Tf)); 8599566063dSJacob Faibussowitsch PetscCall(PetscFree(facePoints)); 86020cf1dd8SToby Isaac } 86120cf1dd8SToby Isaac } 8621dca8a05SBarry 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); 863ef0bb6c7SMatthew G. Knepley *Tf = fem->Tf; 8643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 86520cf1dd8SToby Isaac } 86620cf1dd8SToby Isaac 8672b99622eSMatthew G. Knepley /*@C 868ef0bb6c7SMatthew G. Knepley PetscFEGetFaceCentroidTabulation - Returns the tabulation of the basis functions at the face centroid points 8692b99622eSMatthew G. Knepley 87020f4b53cSBarry Smith Not Collective 8712b99622eSMatthew G. Knepley 8722b99622eSMatthew G. Knepley Input Parameter: 873dce8aebaSBarry Smith . fem - The `PetscFE` object 8742b99622eSMatthew G. Knepley 8752fe279fdSBarry Smith Output Parameter: 876ef0bb6c7SMatthew G. Knepley . Tc - The basis function values at face centroid points 8772b99622eSMatthew G. Knepley 8782b99622eSMatthew G. Knepley Level: intermediate 8792b99622eSMatthew G. Knepley 880dce8aebaSBarry Smith Note: 881dce8aebaSBarry Smith .vb 882dce8aebaSBarry Smith T->T[0] = Bf[(f*pdim + i)*Nc + c] is the value at point f for basis function i and component c 883dce8aebaSBarry Smith .ve 884dce8aebaSBarry Smith 885dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscSpace`, `PetscDualSpace`, `PetscTabulation`, `PetscFEGetFaceTabulation()`, `PetscFEGetCellTabulation()`, `PetscFECreateTabulation()`, `PetscTabulationDestroy()` 8862b99622eSMatthew G. Knepley @*/ 887d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEGetFaceCentroidTabulation(PetscFE fem, PetscTabulation *Tc) 888d71ae5a4SJacob Faibussowitsch { 88920cf1dd8SToby Isaac PetscFunctionBegin; 89020cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 8914f572ea9SToby Isaac PetscAssertPointer(Tc, 2); 892ef0bb6c7SMatthew G. Knepley if (!fem->Tc) { 89320cf1dd8SToby Isaac PetscDualSpace sp; 89420cf1dd8SToby Isaac DM dm; 89520cf1dd8SToby Isaac const PetscInt *cone; 89620cf1dd8SToby Isaac PetscReal *centroids; 89720cf1dd8SToby Isaac PetscInt dim, numFaces, f; 89820cf1dd8SToby Isaac 8999566063dSJacob Faibussowitsch PetscCall(PetscFEGetDualSpace(fem, &sp)); 9009566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetDM(sp, &dm)); 9019566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &dim)); 9029566063dSJacob Faibussowitsch PetscCall(DMPlexGetConeSize(dm, 0, &numFaces)); 9039566063dSJacob Faibussowitsch PetscCall(DMPlexGetCone(dm, 0, &cone)); 9049566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(numFaces * dim, ¢roids)); 9059566063dSJacob Faibussowitsch for (f = 0; f < numFaces; ++f) PetscCall(DMPlexComputeCellGeometryFVM(dm, cone[f], NULL, ¢roids[f * dim], NULL)); 9069566063dSJacob Faibussowitsch PetscCall(PetscFECreateTabulation(fem, 1, numFaces, centroids, 0, &fem->Tc)); 9079566063dSJacob Faibussowitsch PetscCall(PetscFree(centroids)); 90820cf1dd8SToby Isaac } 909ef0bb6c7SMatthew G. Knepley *Tc = fem->Tc; 9103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 91120cf1dd8SToby Isaac } 91220cf1dd8SToby Isaac 91320cf1dd8SToby Isaac /*@C 914ef0bb6c7SMatthew G. Knepley PetscFECreateTabulation - Tabulates the basis functions, and perhaps derivatives, at the points provided. 91520cf1dd8SToby Isaac 91620f4b53cSBarry Smith Not Collective 91720cf1dd8SToby Isaac 91820cf1dd8SToby Isaac Input Parameters: 919dce8aebaSBarry Smith + fem - The `PetscFE` object 920ef0bb6c7SMatthew G. Knepley . nrepl - The number of replicas 921ef0bb6c7SMatthew G. Knepley . npoints - The number of tabulation points in a replica 922ef0bb6c7SMatthew G. Knepley . points - The tabulation point coordinates 923ef0bb6c7SMatthew G. Knepley - K - The number of derivatives calculated 92420cf1dd8SToby Isaac 925ef0bb6c7SMatthew G. Knepley Output Parameter: 926ef0bb6c7SMatthew G. Knepley . T - The basis function values and derivatives at tabulation points 92720cf1dd8SToby Isaac 92820cf1dd8SToby Isaac Level: intermediate 92920cf1dd8SToby Isaac 930dce8aebaSBarry Smith Note: 931dce8aebaSBarry Smith .vb 932dce8aebaSBarry Smith T->T[0] = B[(p*pdim + i)*Nc + c] is the value at point p for basis function i and component c 933dce8aebaSBarry Smith 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 934a4e35b19SJacob Faibussowitsch T->T[2] = H[(((p*pdim + i)*Nc + c)*dim + d)*dim + e] is the value at point p for basis 935a4e35b19SJacob Faibussowitsch T->function i, component c, in directions d and e 936a4e35b19SJacob Faibussowitsch .ve 937dce8aebaSBarry Smith 938dce8aebaSBarry Smith .seealso: `PetscTabulation`, `PetscFEGetCellTabulation()`, `PetscTabulationDestroy()` 93920cf1dd8SToby Isaac @*/ 940d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFECreateTabulation(PetscFE fem, PetscInt nrepl, PetscInt npoints, const PetscReal points[], PetscInt K, PetscTabulation *T) 941d71ae5a4SJacob Faibussowitsch { 94220cf1dd8SToby Isaac DM dm; 943ef0bb6c7SMatthew G. Knepley PetscDualSpace Q; 944ef0bb6c7SMatthew G. Knepley PetscInt Nb; /* Dimension of FE space P */ 945ef0bb6c7SMatthew G. Knepley PetscInt Nc; /* Field components */ 946ef0bb6c7SMatthew G. Knepley PetscInt cdim; /* Reference coordinate dimension */ 947ef0bb6c7SMatthew G. Knepley PetscInt k; 94820cf1dd8SToby Isaac 94920cf1dd8SToby Isaac PetscFunctionBegin; 950ef0bb6c7SMatthew G. Knepley if (!npoints || !fem->dualSpace || K < 0) { 951ef0bb6c7SMatthew G. Knepley *T = NULL; 9523ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 95320cf1dd8SToby Isaac } 95420cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 9554f572ea9SToby Isaac PetscAssertPointer(points, 4); 9564f572ea9SToby Isaac PetscAssertPointer(T, 6); 9579566063dSJacob Faibussowitsch PetscCall(PetscFEGetDualSpace(fem, &Q)); 9589566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetDM(Q, &dm)); 9599566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &cdim)); 9609566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetDimension(Q, &Nb)); 9619566063dSJacob Faibussowitsch PetscCall(PetscFEGetNumComponents(fem, &Nc)); 9629566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(1, T)); 963ef0bb6c7SMatthew G. Knepley (*T)->K = !cdim ? 0 : K; 964ef0bb6c7SMatthew G. Knepley (*T)->Nr = nrepl; 965ef0bb6c7SMatthew G. Knepley (*T)->Np = npoints; 966ef0bb6c7SMatthew G. Knepley (*T)->Nb = Nb; 967ef0bb6c7SMatthew G. Knepley (*T)->Nc = Nc; 968ef0bb6c7SMatthew G. Knepley (*T)->cdim = cdim; 9699566063dSJacob Faibussowitsch PetscCall(PetscMalloc1((*T)->K + 1, &(*T)->T)); 9702dce792eSToby Isaac for (k = 0; k <= (*T)->K; ++k) PetscCall(PetscCalloc1(nrepl * npoints * Nb * Nc * PetscPowInt(cdim, k), &(*T)->T[k])); 971dbbe0bcdSBarry Smith PetscUseTypeMethod(fem, createtabulation, nrepl * npoints, points, K, *T); 9723ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 97320cf1dd8SToby Isaac } 97420cf1dd8SToby Isaac 9752b99622eSMatthew G. Knepley /*@C 976ef0bb6c7SMatthew G. Knepley PetscFEComputeTabulation - Tabulates the basis functions, and perhaps derivatives, at the points provided. 9772b99622eSMatthew G. Knepley 97820f4b53cSBarry Smith Not Collective 9792b99622eSMatthew G. Knepley 9802b99622eSMatthew G. Knepley Input Parameters: 981dce8aebaSBarry Smith + fem - The `PetscFE` object 9822b99622eSMatthew G. Knepley . npoints - The number of tabulation points 9832b99622eSMatthew G. Knepley . points - The tabulation point coordinates 984ef0bb6c7SMatthew G. Knepley . K - The number of derivatives calculated 985ef0bb6c7SMatthew G. Knepley - T - An existing tabulation object with enough allocated space 986ef0bb6c7SMatthew G. Knepley 987ef0bb6c7SMatthew G. Knepley Output Parameter: 988ef0bb6c7SMatthew G. Knepley . T - The basis function values and derivatives at tabulation points 9892b99622eSMatthew G. Knepley 9902b99622eSMatthew G. Knepley Level: intermediate 9912b99622eSMatthew G. Knepley 992dce8aebaSBarry Smith Note: 993dce8aebaSBarry Smith .vb 994dce8aebaSBarry Smith T->T[0] = B[(p*pdim + i)*Nc + c] is the value at point p for basis function i and component c 995dce8aebaSBarry Smith 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 996dce8aebaSBarry Smith 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 997dce8aebaSBarry Smith .ve 998dce8aebaSBarry Smith 999dce8aebaSBarry Smith .seealso: `PetscTabulation`, `PetscFEGetCellTabulation()`, `PetscTabulationDestroy()` 10002b99622eSMatthew G. Knepley @*/ 1001d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEComputeTabulation(PetscFE fem, PetscInt npoints, const PetscReal points[], PetscInt K, PetscTabulation T) 1002d71ae5a4SJacob Faibussowitsch { 1003ef0bb6c7SMatthew G. Knepley PetscFunctionBeginHot; 10043ba16761SJacob Faibussowitsch if (!npoints || !fem->dualSpace || K < 0) PetscFunctionReturn(PETSC_SUCCESS); 1005ef0bb6c7SMatthew G. Knepley PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 10064f572ea9SToby Isaac PetscAssertPointer(points, 3); 10074f572ea9SToby Isaac PetscAssertPointer(T, 5); 100876bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 100920cf1dd8SToby Isaac DM dm; 1010ef0bb6c7SMatthew G. Knepley PetscDualSpace Q; 1011ef0bb6c7SMatthew G. Knepley PetscInt Nb; /* Dimension of FE space P */ 1012ef0bb6c7SMatthew G. Knepley PetscInt Nc; /* Field components */ 1013ef0bb6c7SMatthew G. Knepley PetscInt cdim; /* Reference coordinate dimension */ 1014ef0bb6c7SMatthew G. Knepley 10159566063dSJacob Faibussowitsch PetscCall(PetscFEGetDualSpace(fem, &Q)); 10169566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetDM(Q, &dm)); 10179566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &cdim)); 10189566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetDimension(Q, &Nb)); 10199566063dSJacob Faibussowitsch PetscCall(PetscFEGetNumComponents(fem, &Nc)); 102063a3b9bcSJacob 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); 102163a3b9bcSJacob 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); 102263a3b9bcSJacob 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); 102363a3b9bcSJacob 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); 1024ef0bb6c7SMatthew G. Knepley } 1025ef0bb6c7SMatthew G. Knepley T->Nr = 1; 1026ef0bb6c7SMatthew G. Knepley T->Np = npoints; 1027dbbe0bcdSBarry Smith PetscUseTypeMethod(fem, createtabulation, npoints, points, K, T); 10283ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1029ef0bb6c7SMatthew G. Knepley } 1030ef0bb6c7SMatthew G. Knepley 1031cc4c1da9SBarry Smith /*@ 1032ef0bb6c7SMatthew G. Knepley PetscTabulationDestroy - Frees memory from the associated tabulation. 1033ef0bb6c7SMatthew G. Knepley 103420f4b53cSBarry Smith Not Collective 1035ef0bb6c7SMatthew G. Knepley 1036ef0bb6c7SMatthew G. Knepley Input Parameter: 1037ef0bb6c7SMatthew G. Knepley . T - The tabulation 1038ef0bb6c7SMatthew G. Knepley 1039ef0bb6c7SMatthew G. Knepley Level: intermediate 1040ef0bb6c7SMatthew G. Knepley 1041dce8aebaSBarry Smith .seealso: `PetscTabulation`, `PetscFECreateTabulation()`, `PetscFEGetCellTabulation()` 1042ef0bb6c7SMatthew G. Knepley @*/ 1043d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscTabulationDestroy(PetscTabulation *T) 1044d71ae5a4SJacob Faibussowitsch { 1045ef0bb6c7SMatthew G. Knepley PetscInt k; 104620cf1dd8SToby Isaac 104720cf1dd8SToby Isaac PetscFunctionBegin; 10484f572ea9SToby Isaac PetscAssertPointer(T, 1); 10493ba16761SJacob Faibussowitsch if (!T || !(*T)) PetscFunctionReturn(PETSC_SUCCESS); 10509566063dSJacob Faibussowitsch for (k = 0; k <= (*T)->K; ++k) PetscCall(PetscFree((*T)->T[k])); 10519566063dSJacob Faibussowitsch PetscCall(PetscFree((*T)->T)); 10529566063dSJacob Faibussowitsch PetscCall(PetscFree(*T)); 1053ef0bb6c7SMatthew G. Knepley *T = NULL; 10543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 105520cf1dd8SToby Isaac } 105620cf1dd8SToby Isaac 10572dce792eSToby Isaac static PetscErrorCode PetscFECreatePointTraceDefault_Internal(PetscFE fe, PetscInt refPoint, PetscFE *trFE) 1058d71ae5a4SJacob Faibussowitsch { 105920cf1dd8SToby Isaac PetscSpace bsp, bsubsp; 106020cf1dd8SToby Isaac PetscDualSpace dsp, dsubsp; 106120cf1dd8SToby Isaac PetscInt dim, depth, numComp, i, j, coneSize, order; 106220cf1dd8SToby Isaac DM dm; 106320cf1dd8SToby Isaac DMLabel label; 106420cf1dd8SToby Isaac PetscReal *xi, *v, *J, detJ; 1065db11e2ebSMatthew G. Knepley const char *name; 106620cf1dd8SToby Isaac PetscQuadrature origin, fullQuad, subQuad; 106720cf1dd8SToby Isaac 106820cf1dd8SToby Isaac PetscFunctionBegin; 10699566063dSJacob Faibussowitsch PetscCall(PetscFEGetBasisSpace(fe, &bsp)); 10709566063dSJacob Faibussowitsch PetscCall(PetscFEGetDualSpace(fe, &dsp)); 10719566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetDM(dsp, &dm)); 10729566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &dim)); 10739566063dSJacob Faibussowitsch PetscCall(DMPlexGetDepthLabel(dm, &label)); 10749566063dSJacob Faibussowitsch PetscCall(DMLabelGetValue(label, refPoint, &depth)); 10759566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(depth, &xi)); 10769566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(dim, &v)); 10779566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(dim * dim, &J)); 107820cf1dd8SToby Isaac for (i = 0; i < depth; i++) xi[i] = 0.; 10799566063dSJacob Faibussowitsch PetscCall(PetscQuadratureCreate(PETSC_COMM_SELF, &origin)); 10809566063dSJacob Faibussowitsch PetscCall(PetscQuadratureSetData(origin, depth, 0, 1, xi, NULL)); 10819566063dSJacob Faibussowitsch PetscCall(DMPlexComputeCellGeometryFEM(dm, refPoint, origin, v, J, NULL, &detJ)); 108220cf1dd8SToby Isaac /* CellGeometryFEM computes the expanded Jacobian, we want the true jacobian */ 108320cf1dd8SToby Isaac for (i = 1; i < dim; i++) { 1084ad540459SPierre Jolivet for (j = 0; j < depth; j++) J[i * depth + j] = J[i * dim + j]; 108520cf1dd8SToby Isaac } 10869566063dSJacob Faibussowitsch PetscCall(PetscQuadratureDestroy(&origin)); 10879566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetPointSubspace(dsp, refPoint, &dsubsp)); 10889566063dSJacob Faibussowitsch PetscCall(PetscSpaceCreateSubspace(bsp, dsubsp, v, J, NULL, NULL, PETSC_OWN_POINTER, &bsubsp)); 10899566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetUp(bsubsp)); 10909566063dSJacob Faibussowitsch PetscCall(PetscFECreate(PetscObjectComm((PetscObject)fe), trFE)); 10912dce792eSToby Isaac PetscCall(PetscFESetType(*trFE, PETSCFEBASIC)); 10929566063dSJacob Faibussowitsch PetscCall(PetscFEGetNumComponents(fe, &numComp)); 10939566063dSJacob Faibussowitsch PetscCall(PetscFESetNumComponents(*trFE, numComp)); 10949566063dSJacob Faibussowitsch PetscCall(PetscFESetBasisSpace(*trFE, bsubsp)); 10959566063dSJacob Faibussowitsch PetscCall(PetscFESetDualSpace(*trFE, dsubsp)); 10969566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)fe, &name)); 10979566063dSJacob Faibussowitsch if (name) PetscCall(PetscFESetName(*trFE, name)); 10989566063dSJacob Faibussowitsch PetscCall(PetscFEGetQuadrature(fe, &fullQuad)); 10999566063dSJacob Faibussowitsch PetscCall(PetscQuadratureGetOrder(fullQuad, &order)); 11009566063dSJacob Faibussowitsch PetscCall(DMPlexGetConeSize(dm, refPoint, &coneSize)); 11018b6ef6a4SJed Brown if (coneSize == 2 * depth) PetscCall(PetscDTGaussTensorQuadrature(depth, 1, (order + 2) / 2, -1., 1., &subQuad)); 11028b6ef6a4SJed Brown else PetscCall(PetscDTSimplexQuadrature(depth, order, PETSCDTSIMPLEXQUAD_DEFAULT, &subQuad)); 11039566063dSJacob Faibussowitsch PetscCall(PetscFESetQuadrature(*trFE, subQuad)); 11049566063dSJacob Faibussowitsch PetscCall(PetscFESetUp(*trFE)); 11059566063dSJacob Faibussowitsch PetscCall(PetscQuadratureDestroy(&subQuad)); 11069566063dSJacob Faibussowitsch PetscCall(PetscSpaceDestroy(&bsubsp)); 11073ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 110820cf1dd8SToby Isaac } 110920cf1dd8SToby Isaac 11102dce792eSToby Isaac PETSC_EXTERN PetscErrorCode PetscFECreatePointTrace(PetscFE fe, PetscInt refPoint, PetscFE *trFE) 11112dce792eSToby Isaac { 11122dce792eSToby Isaac PetscFunctionBegin; 11132dce792eSToby Isaac PetscValidHeaderSpecific(fe, PETSCFE_CLASSID, 1); 11142dce792eSToby Isaac PetscAssertPointer(trFE, 3); 11159927e4dfSBarry Smith if (fe->ops->createpointtrace) PetscUseTypeMethod(fe, createpointtrace, refPoint, trFE); 11169927e4dfSBarry Smith else PetscCall(PetscFECreatePointTraceDefault_Internal(fe, refPoint, trFE)); 11172dce792eSToby Isaac PetscFunctionReturn(PETSC_SUCCESS); 11182dce792eSToby Isaac } 11192dce792eSToby Isaac 1120d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFECreateHeightTrace(PetscFE fe, PetscInt height, PetscFE *trFE) 1121d71ae5a4SJacob Faibussowitsch { 112220cf1dd8SToby Isaac PetscInt hStart, hEnd; 112320cf1dd8SToby Isaac PetscDualSpace dsp; 112420cf1dd8SToby Isaac DM dm; 112520cf1dd8SToby Isaac 112620cf1dd8SToby Isaac PetscFunctionBegin; 112720cf1dd8SToby Isaac PetscValidHeaderSpecific(fe, PETSCFE_CLASSID, 1); 11284f572ea9SToby Isaac PetscAssertPointer(trFE, 3); 112920cf1dd8SToby Isaac *trFE = NULL; 11309566063dSJacob Faibussowitsch PetscCall(PetscFEGetDualSpace(fe, &dsp)); 11319566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetDM(dsp, &dm)); 11329566063dSJacob Faibussowitsch PetscCall(DMPlexGetHeightStratum(dm, height, &hStart, &hEnd)); 11333ba16761SJacob Faibussowitsch if (hEnd <= hStart) PetscFunctionReturn(PETSC_SUCCESS); 11349566063dSJacob Faibussowitsch PetscCall(PetscFECreatePointTrace(fe, hStart, trFE)); 11353ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 113620cf1dd8SToby Isaac } 113720cf1dd8SToby Isaac 113820cf1dd8SToby Isaac /*@ 113920cf1dd8SToby Isaac PetscFEGetDimension - Get the dimension of the finite element space on a cell 114020cf1dd8SToby Isaac 114120f4b53cSBarry Smith Not Collective 114220cf1dd8SToby Isaac 114320cf1dd8SToby Isaac Input Parameter: 114460225df5SJacob Faibussowitsch . fem - The `PetscFE` 114520cf1dd8SToby Isaac 114620cf1dd8SToby Isaac Output Parameter: 114720cf1dd8SToby Isaac . dim - The dimension 114820cf1dd8SToby Isaac 114920cf1dd8SToby Isaac Level: intermediate 115020cf1dd8SToby Isaac 1151dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscFECreate()`, `PetscSpaceGetDimension()`, `PetscDualSpaceGetDimension()` 115220cf1dd8SToby Isaac @*/ 1153d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEGetDimension(PetscFE fem, PetscInt *dim) 1154d71ae5a4SJacob Faibussowitsch { 115520cf1dd8SToby Isaac PetscFunctionBegin; 115620cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 11574f572ea9SToby Isaac PetscAssertPointer(dim, 2); 1158dbbe0bcdSBarry Smith PetscTryTypeMethod(fem, getdimension, dim); 11593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 116020cf1dd8SToby Isaac } 116120cf1dd8SToby Isaac 1162cc4c1da9SBarry Smith /*@ 11634bee2e38SMatthew G. Knepley PetscFEPushforward - Map the reference element function to real space 11644bee2e38SMatthew G. Knepley 11654bee2e38SMatthew G. Knepley Input Parameters: 1166dce8aebaSBarry Smith + fe - The `PetscFE` 11674bee2e38SMatthew G. Knepley . fegeom - The cell geometry 11684bee2e38SMatthew G. Knepley . Nv - The number of function values 11694bee2e38SMatthew G. Knepley - vals - The function values 11704bee2e38SMatthew G. Knepley 11714bee2e38SMatthew G. Knepley Output Parameter: 11724bee2e38SMatthew G. Knepley . vals - The transformed function values 11734bee2e38SMatthew G. Knepley 11744bee2e38SMatthew G. Knepley Level: advanced 11754bee2e38SMatthew G. Knepley 1176dce8aebaSBarry Smith Notes: 1177dce8aebaSBarry Smith This just forwards the call onto `PetscDualSpacePushforward()`. 11784bee2e38SMatthew G. Knepley 1179dce8aebaSBarry Smith It only handles transformations when the embedding dimension of the geometry in fegeom is the same as the reference dimension. 11802edcad52SToby Isaac 1181dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscFEGeom`, `PetscDualSpace`, `PetscDualSpacePushforward()` 11824bee2e38SMatthew G. Knepley @*/ 1183d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEPushforward(PetscFE fe, PetscFEGeom *fegeom, PetscInt Nv, PetscScalar vals[]) 1184d71ae5a4SJacob Faibussowitsch { 11852ae266adSMatthew G. Knepley PetscFunctionBeginHot; 11869566063dSJacob Faibussowitsch PetscCall(PetscDualSpacePushforward(fe->dualSpace, fegeom, Nv, fe->numComponents, vals)); 11873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 11884bee2e38SMatthew G. Knepley } 11894bee2e38SMatthew G. Knepley 1190cc4c1da9SBarry Smith /*@ 11914bee2e38SMatthew G. Knepley PetscFEPushforwardGradient - Map the reference element function gradient to real space 11924bee2e38SMatthew G. Knepley 11934bee2e38SMatthew G. Knepley Input Parameters: 1194dce8aebaSBarry Smith + fe - The `PetscFE` 11954bee2e38SMatthew G. Knepley . fegeom - The cell geometry 11964bee2e38SMatthew G. Knepley . Nv - The number of function gradient values 11974bee2e38SMatthew G. Knepley - vals - The function gradient values 11984bee2e38SMatthew G. Knepley 11994bee2e38SMatthew G. Knepley Output Parameter: 12004bee2e38SMatthew G. Knepley . vals - The transformed function gradient values 12014bee2e38SMatthew G. Knepley 12024bee2e38SMatthew G. Knepley Level: advanced 12034bee2e38SMatthew G. Knepley 1204dce8aebaSBarry Smith Notes: 1205dce8aebaSBarry Smith This just forwards the call onto `PetscDualSpacePushforwardGradient()`. 12064bee2e38SMatthew G. Knepley 1207dce8aebaSBarry Smith It only handles transformations when the embedding dimension of the geometry in fegeom is the same as the reference dimension. 12082edcad52SToby Isaac 1209dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscFEGeom`, `PetscDualSpace`, `PetscFEPushforward()`, `PetscDualSpacePushforwardGradient()`, `PetscDualSpacePushforward()` 12104bee2e38SMatthew G. Knepley @*/ 1211d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEPushforwardGradient(PetscFE fe, PetscFEGeom *fegeom, PetscInt Nv, PetscScalar vals[]) 1212d71ae5a4SJacob Faibussowitsch { 12132ae266adSMatthew G. Knepley PetscFunctionBeginHot; 12149566063dSJacob Faibussowitsch PetscCall(PetscDualSpacePushforwardGradient(fe->dualSpace, fegeom, Nv, fe->numComponents, vals)); 12153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 12164bee2e38SMatthew G. Knepley } 12174bee2e38SMatthew G. Knepley 1218cc4c1da9SBarry Smith /*@ 1219f9244615SMatthew G. Knepley PetscFEPushforwardHessian - Map the reference element function Hessian to real space 1220f9244615SMatthew G. Knepley 1221f9244615SMatthew G. Knepley Input Parameters: 1222dce8aebaSBarry Smith + fe - The `PetscFE` 1223f9244615SMatthew G. Knepley . fegeom - The cell geometry 1224f9244615SMatthew G. Knepley . Nv - The number of function Hessian values 1225f9244615SMatthew G. Knepley - vals - The function Hessian values 1226f9244615SMatthew G. Knepley 1227f9244615SMatthew G. Knepley Output Parameter: 1228f9244615SMatthew G. Knepley . vals - The transformed function Hessian values 1229f9244615SMatthew G. Knepley 1230f9244615SMatthew G. Knepley Level: advanced 1231f9244615SMatthew G. Knepley 1232dce8aebaSBarry Smith Notes: 1233dce8aebaSBarry Smith This just forwards the call onto `PetscDualSpacePushforwardHessian()`. 1234f9244615SMatthew G. Knepley 1235dce8aebaSBarry Smith It only handles transformations when the embedding dimension of the geometry in fegeom is the same as the reference dimension. 1236f9244615SMatthew G. Knepley 123760225df5SJacob Faibussowitsch Developer Notes: 1238dce8aebaSBarry Smith It is unclear why all these one line convenience routines are desirable 1239dce8aebaSBarry Smith 1240dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscFEGeom`, `PetscDualSpace`, `PetscFEPushforward()`, `PetscDualSpacePushforwardHessian()`, `PetscDualSpacePushforward()` 1241f9244615SMatthew G. Knepley @*/ 1242d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEPushforwardHessian(PetscFE fe, PetscFEGeom *fegeom, PetscInt Nv, PetscScalar vals[]) 1243d71ae5a4SJacob Faibussowitsch { 1244f9244615SMatthew G. Knepley PetscFunctionBeginHot; 12459566063dSJacob Faibussowitsch PetscCall(PetscDualSpacePushforwardHessian(fe->dualSpace, fegeom, Nv, fe->numComponents, vals)); 12463ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1247f9244615SMatthew G. Knepley } 1248f9244615SMatthew G. Knepley 124920cf1dd8SToby Isaac /* 125020cf1dd8SToby Isaac Purpose: Compute element vector for chunk of elements 125120cf1dd8SToby Isaac 125220cf1dd8SToby Isaac Input: 125320cf1dd8SToby Isaac Sizes: 125420cf1dd8SToby Isaac Ne: number of elements 125520cf1dd8SToby Isaac Nf: number of fields 125620cf1dd8SToby Isaac PetscFE 125720cf1dd8SToby Isaac dim: spatial dimension 125820cf1dd8SToby Isaac Nb: number of basis functions 125920cf1dd8SToby Isaac Nc: number of field components 126020cf1dd8SToby Isaac PetscQuadrature 126120cf1dd8SToby Isaac Nq: number of quadrature points 126220cf1dd8SToby Isaac 126320cf1dd8SToby Isaac Geometry: 126420cf1dd8SToby Isaac PetscFEGeom[Ne] possibly *Nq 126520cf1dd8SToby Isaac PetscReal v0s[dim] 126620cf1dd8SToby Isaac PetscReal n[dim] 126720cf1dd8SToby Isaac PetscReal jacobians[dim*dim] 126820cf1dd8SToby Isaac PetscReal jacobianInverses[dim*dim] 126920cf1dd8SToby Isaac PetscReal jacobianDeterminants 127020cf1dd8SToby Isaac FEM: 127120cf1dd8SToby Isaac PetscFE 127220cf1dd8SToby Isaac PetscQuadrature 127320cf1dd8SToby Isaac PetscReal quadPoints[Nq*dim] 127420cf1dd8SToby Isaac PetscReal quadWeights[Nq] 127520cf1dd8SToby Isaac PetscReal basis[Nq*Nb*Nc] 127620cf1dd8SToby Isaac PetscReal basisDer[Nq*Nb*Nc*dim] 127720cf1dd8SToby Isaac PetscScalar coefficients[Ne*Nb*Nc] 127820cf1dd8SToby Isaac PetscScalar elemVec[Ne*Nb*Nc] 127920cf1dd8SToby Isaac 128020cf1dd8SToby Isaac Problem: 128120cf1dd8SToby Isaac PetscInt f: the active field 128220cf1dd8SToby Isaac f0, f1 128320cf1dd8SToby Isaac 128420cf1dd8SToby Isaac Work Space: 128520cf1dd8SToby Isaac PetscFE 128620cf1dd8SToby Isaac PetscScalar f0[Nq*dim]; 128720cf1dd8SToby Isaac PetscScalar f1[Nq*dim*dim]; 128820cf1dd8SToby Isaac PetscScalar u[Nc]; 128920cf1dd8SToby Isaac PetscScalar gradU[Nc*dim]; 129020cf1dd8SToby Isaac PetscReal x[dim]; 129120cf1dd8SToby Isaac PetscScalar realSpaceDer[dim]; 129220cf1dd8SToby Isaac 129320cf1dd8SToby Isaac Purpose: Compute element vector for N_cb batches of elements 129420cf1dd8SToby Isaac 129520cf1dd8SToby Isaac Input: 129620cf1dd8SToby Isaac Sizes: 129720cf1dd8SToby Isaac N_cb: Number of serial cell batches 129820cf1dd8SToby Isaac 129920cf1dd8SToby Isaac Geometry: 130020cf1dd8SToby Isaac PetscReal v0s[Ne*dim] 130120cf1dd8SToby Isaac PetscReal jacobians[Ne*dim*dim] possibly *Nq 130220cf1dd8SToby Isaac PetscReal jacobianInverses[Ne*dim*dim] possibly *Nq 130320cf1dd8SToby Isaac PetscReal jacobianDeterminants[Ne] possibly *Nq 130420cf1dd8SToby Isaac FEM: 130520cf1dd8SToby Isaac static PetscReal quadPoints[Nq*dim] 130620cf1dd8SToby Isaac static PetscReal quadWeights[Nq] 130720cf1dd8SToby Isaac static PetscReal basis[Nq*Nb*Nc] 130820cf1dd8SToby Isaac static PetscReal basisDer[Nq*Nb*Nc*dim] 130920cf1dd8SToby Isaac PetscScalar coefficients[Ne*Nb*Nc] 131020cf1dd8SToby Isaac PetscScalar elemVec[Ne*Nb*Nc] 131120cf1dd8SToby Isaac 131220cf1dd8SToby Isaac ex62.c: 131320cf1dd8SToby Isaac PetscErrorCode PetscFEIntegrateResidualBatch(PetscInt Ne, PetscInt numFields, PetscInt field, PetscQuadrature quad[], const PetscScalar coefficients[], 131420cf1dd8SToby Isaac const PetscReal v0s[], const PetscReal jacobians[], const PetscReal jacobianInverses[], const PetscReal jacobianDeterminants[], 131520cf1dd8SToby Isaac void (*f0_func)(const PetscScalar u[], const PetscScalar gradU[], const PetscReal x[], PetscScalar f0[]), 131620cf1dd8SToby Isaac void (*f1_func)(const PetscScalar u[], const PetscScalar gradU[], const PetscReal x[], PetscScalar f1[]), PetscScalar elemVec[]) 131720cf1dd8SToby Isaac 131820cf1dd8SToby Isaac ex52.c: 131920cf1dd8SToby 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) 132020cf1dd8SToby 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) 132120cf1dd8SToby Isaac 132220cf1dd8SToby Isaac ex52_integrateElement.cu 132320cf1dd8SToby Isaac __global__ void integrateElementQuadrature(int N_cb, realType *coefficients, realType *jacobianInverses, realType *jacobianDeterminants, realType *elemVec) 132420cf1dd8SToby Isaac 132520cf1dd8SToby Isaac PETSC_EXTERN PetscErrorCode IntegrateElementBatchGPU(PetscInt spatial_dim, PetscInt Ne, PetscInt Ncb, PetscInt Nbc, PetscInt Nbl, const PetscScalar coefficients[], 132620cf1dd8SToby Isaac const PetscReal jacobianInverses[], const PetscReal jacobianDeterminants[], PetscScalar elemVec[], 132720cf1dd8SToby Isaac PetscLogEvent event, PetscInt debug, PetscInt pde_op) 132820cf1dd8SToby Isaac 132920cf1dd8SToby Isaac ex52_integrateElementOpenCL.c: 133020cf1dd8SToby Isaac PETSC_EXTERN PetscErrorCode IntegrateElementBatchGPU(PetscInt spatial_dim, PetscInt Ne, PetscInt Ncb, PetscInt Nbc, PetscInt N_bl, const PetscScalar coefficients[], 133120cf1dd8SToby Isaac const PetscReal jacobianInverses[], const PetscReal jacobianDeterminants[], PetscScalar elemVec[], 133220cf1dd8SToby Isaac PetscLogEvent event, PetscInt debug, PetscInt pde_op) 133320cf1dd8SToby Isaac 133420cf1dd8SToby Isaac __kernel void integrateElementQuadrature(int N_cb, __global float *coefficients, __global float *jacobianInverses, __global float *jacobianDeterminants, __global float *elemVec) 133520cf1dd8SToby Isaac */ 133620cf1dd8SToby Isaac 1337cc4c1da9SBarry Smith /*@ 133820cf1dd8SToby Isaac PetscFEIntegrate - Produce the integral for the given field for a chunk of elements by quadrature integration 133920cf1dd8SToby Isaac 134020f4b53cSBarry Smith Not Collective 134120cf1dd8SToby Isaac 134220cf1dd8SToby Isaac Input Parameters: 1343dce8aebaSBarry Smith + prob - The `PetscDS` specifying the discretizations and continuum functions 134420cf1dd8SToby Isaac . field - The field being integrated 134520cf1dd8SToby Isaac . Ne - The number of elements in the chunk 134620cf1dd8SToby Isaac . cgeom - The cell geometry for each cell in the chunk 134720cf1dd8SToby Isaac . coefficients - The array of FEM basis coefficients for the elements 1348dce8aebaSBarry Smith . probAux - The `PetscDS` specifying the auxiliary discretizations 134920cf1dd8SToby Isaac - coefficientsAux - The array of FEM auxiliary basis coefficients for the elements 135020cf1dd8SToby Isaac 13517a7aea1fSJed Brown Output Parameter: 135220cf1dd8SToby Isaac . integral - the integral for this field 135320cf1dd8SToby Isaac 13542b99622eSMatthew G. Knepley Level: intermediate 135520cf1dd8SToby Isaac 135660225df5SJacob Faibussowitsch Developer Notes: 1357dce8aebaSBarry Smith The function name begins with `PetscFE` and yet the first argument is `PetscDS` and it has no `PetscFE` arguments. 1358dce8aebaSBarry Smith 1359dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscDS`, `PetscFEIntegrateResidual()`, `PetscFEIntegrateBd()` 136020cf1dd8SToby Isaac @*/ 1361d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEIntegrate(PetscDS prob, PetscInt field, PetscInt Ne, PetscFEGeom *cgeom, const PetscScalar coefficients[], PetscDS probAux, const PetscScalar coefficientsAux[], PetscScalar integral[]) 1362d71ae5a4SJacob Faibussowitsch { 13634bee2e38SMatthew G. Knepley PetscFE fe; 136420cf1dd8SToby Isaac 136520cf1dd8SToby Isaac PetscFunctionBegin; 13664bee2e38SMatthew G. Knepley PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 13679566063dSJacob Faibussowitsch PetscCall(PetscDSGetDiscretization(prob, field, (PetscObject *)&fe)); 13689566063dSJacob Faibussowitsch if (fe->ops->integrate) PetscCall((*fe->ops->integrate)(prob, field, Ne, cgeom, coefficients, probAux, coefficientsAux, integral)); 13693ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 137020cf1dd8SToby Isaac } 137120cf1dd8SToby Isaac 137220cf1dd8SToby Isaac /*@C 1373afe6d6adSToby Isaac PetscFEIntegrateBd - Produce the integral for the given field for a chunk of elements by quadrature integration 1374afe6d6adSToby Isaac 137520f4b53cSBarry Smith Not Collective 1376afe6d6adSToby Isaac 1377afe6d6adSToby Isaac Input Parameters: 1378dce8aebaSBarry Smith + prob - The `PetscDS` specifying the discretizations and continuum functions 1379afe6d6adSToby Isaac . field - The field being integrated 1380afe6d6adSToby Isaac . obj_func - The function to be integrated 1381afe6d6adSToby Isaac . Ne - The number of elements in the chunk 138260225df5SJacob Faibussowitsch . geom - The face geometry for each face in the chunk 1383afe6d6adSToby Isaac . coefficients - The array of FEM basis coefficients for the elements 1384dce8aebaSBarry Smith . probAux - The `PetscDS` specifying the auxiliary discretizations 1385afe6d6adSToby Isaac - coefficientsAux - The array of FEM auxiliary basis coefficients for the elements 1386afe6d6adSToby Isaac 13877a7aea1fSJed Brown Output Parameter: 1388afe6d6adSToby Isaac . integral - the integral for this field 1389afe6d6adSToby Isaac 13902b99622eSMatthew G. Knepley Level: intermediate 1391afe6d6adSToby Isaac 139260225df5SJacob Faibussowitsch Developer Notes: 1393dce8aebaSBarry Smith The function name begins with `PetscFE` and yet the first argument is `PetscDS` and it has no `PetscFE` arguments. 1394dce8aebaSBarry Smith 1395dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscDS`, `PetscFEIntegrateResidual()`, `PetscFEIntegrate()` 1396afe6d6adSToby Isaac @*/ 1397d71ae5a4SJacob Faibussowitsch 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[]) 1398d71ae5a4SJacob Faibussowitsch { 13994bee2e38SMatthew G. Knepley PetscFE fe; 1400afe6d6adSToby Isaac 1401afe6d6adSToby Isaac PetscFunctionBegin; 14024bee2e38SMatthew G. Knepley PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 14039566063dSJacob Faibussowitsch PetscCall(PetscDSGetDiscretization(prob, field, (PetscObject *)&fe)); 14049566063dSJacob Faibussowitsch if (fe->ops->integratebd) PetscCall((*fe->ops->integratebd)(prob, field, obj_func, Ne, geom, coefficients, probAux, coefficientsAux, integral)); 14053ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1406afe6d6adSToby Isaac } 1407afe6d6adSToby Isaac 1408cc4c1da9SBarry Smith /*@ 140920cf1dd8SToby Isaac PetscFEIntegrateResidual - Produce the element residual vector for a chunk of elements by quadrature integration 141020cf1dd8SToby Isaac 141120f4b53cSBarry Smith Not Collective 141220cf1dd8SToby Isaac 141320cf1dd8SToby Isaac Input Parameters: 141420f4b53cSBarry Smith + ds - The `PetscDS` specifying the discretizations and continuum functions 14156528b96dSMatthew G. Knepley . key - The (label+value, field) being integrated 141620cf1dd8SToby Isaac . Ne - The number of elements in the chunk 141720cf1dd8SToby Isaac . cgeom - The cell geometry for each cell in the chunk 141820cf1dd8SToby Isaac . coefficients - The array of FEM basis coefficients for the elements 141920cf1dd8SToby Isaac . coefficients_t - The array of FEM basis time derivative coefficients for the elements 142020f4b53cSBarry Smith . probAux - The `PetscDS` specifying the auxiliary discretizations 142120cf1dd8SToby Isaac . coefficientsAux - The array of FEM auxiliary basis coefficients for the elements 142220cf1dd8SToby Isaac - t - The time 142320cf1dd8SToby Isaac 14247a7aea1fSJed Brown Output Parameter: 142520cf1dd8SToby Isaac . elemVec - the element residual vectors from each element 142620cf1dd8SToby Isaac 14272b99622eSMatthew G. Knepley Level: intermediate 142820cf1dd8SToby Isaac 1429dce8aebaSBarry Smith Note: 1430dce8aebaSBarry Smith .vb 1431dce8aebaSBarry Smith Loop over batch of elements (e): 1432dce8aebaSBarry Smith Loop over quadrature points (q): 1433dce8aebaSBarry Smith Make u_q and gradU_q (loops over fields,Nb,Ncomp) and x_q 1434dce8aebaSBarry Smith Call f_0 and f_1 1435dce8aebaSBarry Smith Loop over element vector entries (f,fc --> i): 1436dce8aebaSBarry Smith elemVec[i] += \psi^{fc}_f(q) f0_{fc}(u, \nabla u) + \nabla\psi^{fc}_f(q) \cdot f1_{fc,df}(u, \nabla u) 1437dce8aebaSBarry Smith .ve 1438dce8aebaSBarry Smith 143942747ad1SJacob Faibussowitsch .seealso: `PetscFEIntegrateBdResidual()` 144020cf1dd8SToby Isaac @*/ 1441d71ae5a4SJacob Faibussowitsch 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[]) 1442d71ae5a4SJacob Faibussowitsch { 14434bee2e38SMatthew G. Knepley PetscFE fe; 144420cf1dd8SToby Isaac 14456528b96dSMatthew G. Knepley PetscFunctionBeginHot; 14466528b96dSMatthew G. Knepley PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1); 14479566063dSJacob Faibussowitsch PetscCall(PetscDSGetDiscretization(ds, key.field, (PetscObject *)&fe)); 14489566063dSJacob Faibussowitsch if (fe->ops->integrateresidual) PetscCall((*fe->ops->integrateresidual)(ds, key, Ne, cgeom, coefficients, coefficients_t, probAux, coefficientsAux, t, elemVec)); 14493ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 145020cf1dd8SToby Isaac } 145120cf1dd8SToby Isaac 1452cc4c1da9SBarry Smith /*@ 145320cf1dd8SToby Isaac PetscFEIntegrateBdResidual - Produce the element residual vector for a chunk of elements by quadrature integration over a boundary 145420cf1dd8SToby Isaac 145520f4b53cSBarry Smith Not Collective 145620cf1dd8SToby Isaac 145720cf1dd8SToby Isaac Input Parameters: 145820f4b53cSBarry Smith + ds - The `PetscDS` specifying the discretizations and continuum functions 145945480ffeSMatthew G. Knepley . wf - The PetscWeakForm object holding the pointwise functions 146006d8a0d3SMatthew G. Knepley . key - The (label+value, field) being integrated 146120cf1dd8SToby Isaac . Ne - The number of elements in the chunk 146220cf1dd8SToby Isaac . fgeom - The face geometry for each cell in the chunk 146320cf1dd8SToby Isaac . coefficients - The array of FEM basis coefficients for the elements 146420cf1dd8SToby Isaac . coefficients_t - The array of FEM basis time derivative coefficients for the elements 146520f4b53cSBarry Smith . probAux - The `PetscDS` specifying the auxiliary discretizations 146620cf1dd8SToby Isaac . coefficientsAux - The array of FEM auxiliary basis coefficients for the elements 146720cf1dd8SToby Isaac - t - The time 146820cf1dd8SToby Isaac 14697a7aea1fSJed Brown Output Parameter: 147020cf1dd8SToby Isaac . elemVec - the element residual vectors from each element 147120cf1dd8SToby Isaac 14722b99622eSMatthew G. Knepley Level: intermediate 147320cf1dd8SToby Isaac 1474db781477SPatrick Sanan .seealso: `PetscFEIntegrateResidual()` 147520cf1dd8SToby Isaac @*/ 1476d71ae5a4SJacob Faibussowitsch 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[]) 1477d71ae5a4SJacob Faibussowitsch { 14784bee2e38SMatthew G. Knepley PetscFE fe; 147920cf1dd8SToby Isaac 148020cf1dd8SToby Isaac PetscFunctionBegin; 148106d8a0d3SMatthew G. Knepley PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1); 14829566063dSJacob Faibussowitsch PetscCall(PetscDSGetDiscretization(ds, key.field, (PetscObject *)&fe)); 14839566063dSJacob Faibussowitsch if (fe->ops->integratebdresidual) PetscCall((*fe->ops->integratebdresidual)(ds, wf, key, Ne, fgeom, coefficients, coefficients_t, probAux, coefficientsAux, t, elemVec)); 14843ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 148520cf1dd8SToby Isaac } 148620cf1dd8SToby Isaac 1487cc4c1da9SBarry Smith /*@ 148827f02ce8SMatthew G. Knepley PetscFEIntegrateHybridResidual - Produce the element residual vector for a chunk of hybrid element faces by quadrature integration 148927f02ce8SMatthew G. Knepley 149020f4b53cSBarry Smith Not Collective 149127f02ce8SMatthew G. Knepley 149227f02ce8SMatthew G. Knepley Input Parameters: 149307218a29SMatthew G. Knepley + ds - The `PetscDS` specifying the discretizations and continuum functions 149407218a29SMatthew G. Knepley . dsIn - The `PetscDS` specifying the discretizations and continuum functions for input 14956528b96dSMatthew G. Knepley . key - The (label+value, field) being integrated 1496c2b7495fSMatthew G. Knepley . s - The side of the cell being integrated, 0 for negative and 1 for positive 149727f02ce8SMatthew G. Knepley . Ne - The number of elements in the chunk 149827f02ce8SMatthew G. Knepley . fgeom - The face geometry for each cell in the chunk 149927f02ce8SMatthew G. Knepley . coefficients - The array of FEM basis coefficients for the elements 150027f02ce8SMatthew G. Knepley . coefficients_t - The array of FEM basis time derivative coefficients for the elements 150120f4b53cSBarry Smith . probAux - The `PetscDS` specifying the auxiliary discretizations 150227f02ce8SMatthew G. Knepley . coefficientsAux - The array of FEM auxiliary basis coefficients for the elements 150327f02ce8SMatthew G. Knepley - t - The time 150427f02ce8SMatthew G. Knepley 1505a4e35b19SJacob Faibussowitsch Output Parameter: 150627f02ce8SMatthew G. Knepley . elemVec - the element residual vectors from each element 150727f02ce8SMatthew G. Knepley 150827f02ce8SMatthew G. Knepley Level: developer 150927f02ce8SMatthew G. Knepley 1510db781477SPatrick Sanan .seealso: `PetscFEIntegrateResidual()` 151127f02ce8SMatthew G. Knepley @*/ 151207218a29SMatthew G. Knepley PetscErrorCode PetscFEIntegrateHybridResidual(PetscDS ds, PetscDS dsIn, PetscFormKey key, PetscInt s, PetscInt Ne, PetscFEGeom *fgeom, const PetscScalar coefficients[], const PetscScalar coefficients_t[], PetscDS probAux, const PetscScalar coefficientsAux[], PetscReal t, PetscScalar elemVec[]) 1513d71ae5a4SJacob Faibussowitsch { 151427f02ce8SMatthew G. Knepley PetscFE fe; 151527f02ce8SMatthew G. Knepley 151627f02ce8SMatthew G. Knepley PetscFunctionBegin; 151707218a29SMatthew G. Knepley PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1); 151807218a29SMatthew G. Knepley PetscValidHeaderSpecific(dsIn, PETSCDS_CLASSID, 2); 151907218a29SMatthew G. Knepley PetscCall(PetscDSGetDiscretization(ds, key.field, (PetscObject *)&fe)); 152007218a29SMatthew G. Knepley if (fe->ops->integratehybridresidual) PetscCall((*fe->ops->integratehybridresidual)(ds, dsIn, key, s, Ne, fgeom, coefficients, coefficients_t, probAux, coefficientsAux, t, elemVec)); 15213ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 152227f02ce8SMatthew G. Knepley } 152327f02ce8SMatthew G. Knepley 1524cc4c1da9SBarry Smith /*@ 152520cf1dd8SToby Isaac PetscFEIntegrateJacobian - Produce the element Jacobian for a chunk of elements by quadrature integration 152620cf1dd8SToby Isaac 152720f4b53cSBarry Smith Not Collective 152820cf1dd8SToby Isaac 152920cf1dd8SToby Isaac Input Parameters: 153020f4b53cSBarry Smith + ds - The `PetscDS` specifying the discretizations and continuum functions 153120cf1dd8SToby Isaac . jtype - The type of matrix pointwise functions that should be used 15326528b96dSMatthew G. Knepley . key - The (label+value, fieldI*Nf + fieldJ) being integrated 153320cf1dd8SToby Isaac . Ne - The number of elements in the chunk 153420cf1dd8SToby Isaac . cgeom - The cell geometry for each cell in the chunk 153520cf1dd8SToby Isaac . coefficients - The array of FEM basis coefficients for the elements for the Jacobian evaluation point 153620cf1dd8SToby Isaac . coefficients_t - The array of FEM basis time derivative coefficients for the elements 153720f4b53cSBarry Smith . probAux - The `PetscDS` specifying the auxiliary discretizations 153820cf1dd8SToby Isaac . coefficientsAux - The array of FEM auxiliary basis coefficients for the elements 153920cf1dd8SToby Isaac . t - The time 154060225df5SJacob Faibussowitsch - u_tshift - A multiplier for the dF/du_t term (as opposed to the dF/du term) 154120cf1dd8SToby Isaac 15427a7aea1fSJed Brown Output Parameter: 154320cf1dd8SToby Isaac . elemMat - the element matrices for the Jacobian from each element 154420cf1dd8SToby Isaac 15452b99622eSMatthew G. Knepley Level: intermediate 154620cf1dd8SToby Isaac 1547dce8aebaSBarry Smith Note: 1548dce8aebaSBarry Smith .vb 1549dce8aebaSBarry Smith Loop over batch of elements (e): 1550dce8aebaSBarry Smith Loop over element matrix entries (f,fc,g,gc --> i,j): 1551dce8aebaSBarry Smith Loop over quadrature points (q): 1552dce8aebaSBarry Smith Make u_q and gradU_q (loops over fields,Nb,Ncomp) 1553dce8aebaSBarry Smith elemMat[i,j] += \psi^{fc}_f(q) g0_{fc,gc}(u, \nabla u) \phi^{gc}_g(q) 1554dce8aebaSBarry Smith + \psi^{fc}_f(q) \cdot g1_{fc,gc,dg}(u, \nabla u) \nabla\phi^{gc}_g(q) 1555dce8aebaSBarry Smith + \nabla\psi^{fc}_f(q) \cdot g2_{fc,gc,df}(u, \nabla u) \phi^{gc}_g(q) 1556dce8aebaSBarry Smith + \nabla\psi^{fc}_f(q) \cdot g3_{fc,gc,df,dg}(u, \nabla u) \nabla\phi^{gc}_g(q) 1557dce8aebaSBarry Smith .ve 1558dce8aebaSBarry Smith 1559db781477SPatrick Sanan .seealso: `PetscFEIntegrateResidual()` 156020cf1dd8SToby Isaac @*/ 1561d71ae5a4SJacob Faibussowitsch 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[]) 1562d71ae5a4SJacob Faibussowitsch { 15634bee2e38SMatthew G. Knepley PetscFE fe; 15646528b96dSMatthew G. Knepley PetscInt Nf; 156520cf1dd8SToby Isaac 156620cf1dd8SToby Isaac PetscFunctionBegin; 15676528b96dSMatthew G. Knepley PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1); 15689566063dSJacob Faibussowitsch PetscCall(PetscDSGetNumFields(ds, &Nf)); 15699566063dSJacob Faibussowitsch PetscCall(PetscDSGetDiscretization(ds, key.field / Nf, (PetscObject *)&fe)); 15709566063dSJacob Faibussowitsch if (fe->ops->integratejacobian) PetscCall((*fe->ops->integratejacobian)(ds, jtype, key, Ne, cgeom, coefficients, coefficients_t, probAux, coefficientsAux, t, u_tshift, elemMat)); 15713ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 157220cf1dd8SToby Isaac } 157320cf1dd8SToby Isaac 1574cc4c1da9SBarry Smith /*@ 157520cf1dd8SToby Isaac PetscFEIntegrateBdJacobian - Produce the boundary element Jacobian for a chunk of elements by quadrature integration 157620cf1dd8SToby Isaac 157720f4b53cSBarry Smith Not Collective 157820cf1dd8SToby Isaac 157920cf1dd8SToby Isaac Input Parameters: 158020f4b53cSBarry Smith + ds - The `PetscDS` specifying the discretizations and continuum functions 158145480ffeSMatthew G. Knepley . wf - The PetscWeakForm holding the pointwise functions 1582e3d591f2SMatthew G. Knepley . jtype - The type of matrix pointwise functions that should be used 158345480ffeSMatthew G. Knepley . key - The (label+value, fieldI*Nf + fieldJ) being integrated 158420cf1dd8SToby Isaac . Ne - The number of elements in the chunk 158520cf1dd8SToby Isaac . fgeom - The face geometry for each cell in the chunk 158620cf1dd8SToby Isaac . coefficients - The array of FEM basis coefficients for the elements for the Jacobian evaluation point 158720cf1dd8SToby Isaac . coefficients_t - The array of FEM basis time derivative coefficients for the elements 158820f4b53cSBarry Smith . probAux - The `PetscDS` specifying the auxiliary discretizations 158920cf1dd8SToby Isaac . coefficientsAux - The array of FEM auxiliary basis coefficients for the elements 159020cf1dd8SToby Isaac . t - The time 159160225df5SJacob Faibussowitsch - u_tshift - A multiplier for the dF/du_t term (as opposed to the dF/du term) 159220cf1dd8SToby Isaac 15937a7aea1fSJed Brown Output Parameter: 159420cf1dd8SToby Isaac . elemMat - the element matrices for the Jacobian from each element 159520cf1dd8SToby Isaac 15962b99622eSMatthew G. Knepley Level: intermediate 159720cf1dd8SToby Isaac 1598dce8aebaSBarry Smith Note: 1599dce8aebaSBarry Smith .vb 1600dce8aebaSBarry Smith Loop over batch of elements (e): 1601dce8aebaSBarry Smith Loop over element matrix entries (f,fc,g,gc --> i,j): 1602dce8aebaSBarry Smith Loop over quadrature points (q): 1603dce8aebaSBarry Smith Make u_q and gradU_q (loops over fields,Nb,Ncomp) 1604dce8aebaSBarry Smith elemMat[i,j] += \psi^{fc}_f(q) g0_{fc,gc}(u, \nabla u) \phi^{gc}_g(q) 1605dce8aebaSBarry Smith + \psi^{fc}_f(q) \cdot g1_{fc,gc,dg}(u, \nabla u) \nabla\phi^{gc}_g(q) 1606dce8aebaSBarry Smith + \nabla\psi^{fc}_f(q) \cdot g2_{fc,gc,df}(u, \nabla u) \phi^{gc}_g(q) 1607dce8aebaSBarry Smith + \nabla\psi^{fc}_f(q) \cdot g3_{fc,gc,df,dg}(u, \nabla u) \nabla\phi^{gc}_g(q) 1608dce8aebaSBarry Smith .ve 1609dce8aebaSBarry Smith 1610db781477SPatrick Sanan .seealso: `PetscFEIntegrateJacobian()`, `PetscFEIntegrateResidual()` 161120cf1dd8SToby Isaac @*/ 1612e3d591f2SMatthew G. Knepley PetscErrorCode PetscFEIntegrateBdJacobian(PetscDS ds, PetscWeakForm wf, PetscFEJacobianType jtype, 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[]) 1613d71ae5a4SJacob Faibussowitsch { 16144bee2e38SMatthew G. Knepley PetscFE fe; 161545480ffeSMatthew G. Knepley PetscInt Nf; 161620cf1dd8SToby Isaac 161720cf1dd8SToby Isaac PetscFunctionBegin; 161845480ffeSMatthew G. Knepley PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1); 16199566063dSJacob Faibussowitsch PetscCall(PetscDSGetNumFields(ds, &Nf)); 16209566063dSJacob Faibussowitsch PetscCall(PetscDSGetDiscretization(ds, key.field / Nf, (PetscObject *)&fe)); 1621e3d591f2SMatthew G. Knepley if (fe->ops->integratebdjacobian) PetscCall((*fe->ops->integratebdjacobian)(ds, wf, jtype, key, Ne, fgeom, coefficients, coefficients_t, probAux, coefficientsAux, t, u_tshift, elemMat)); 16223ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 162320cf1dd8SToby Isaac } 162420cf1dd8SToby Isaac 1625cc4c1da9SBarry Smith /*@ 162627f02ce8SMatthew G. Knepley PetscFEIntegrateHybridJacobian - Produce the boundary element Jacobian for a chunk of hybrid elements by quadrature integration 162727f02ce8SMatthew G. Knepley 162820f4b53cSBarry Smith Not Collective 162927f02ce8SMatthew G. Knepley 163027f02ce8SMatthew G. Knepley Input Parameters: 163107218a29SMatthew G. Knepley + ds - The `PetscDS` specifying the discretizations and continuum functions for the output 163207218a29SMatthew G. Knepley . dsIn - The `PetscDS` specifying the discretizations and continuum functions for the input 163327f02ce8SMatthew G. Knepley . jtype - The type of matrix pointwise functions that should be used 163445480ffeSMatthew G. Knepley . key - The (label+value, fieldI*Nf + fieldJ) being integrated 16355fedec97SMatthew G. Knepley . s - The side of the cell being integrated, 0 for negative and 1 for positive 163627f02ce8SMatthew G. Knepley . Ne - The number of elements in the chunk 163727f02ce8SMatthew G. Knepley . fgeom - The face geometry for each cell in the chunk 163827f02ce8SMatthew G. Knepley . coefficients - The array of FEM basis coefficients for the elements for the Jacobian evaluation point 163927f02ce8SMatthew G. Knepley . coefficients_t - The array of FEM basis time derivative coefficients for the elements 164020f4b53cSBarry Smith . probAux - The `PetscDS` specifying the auxiliary discretizations 164127f02ce8SMatthew G. Knepley . coefficientsAux - The array of FEM auxiliary basis coefficients for the elements 164227f02ce8SMatthew G. Knepley . t - The time 164360225df5SJacob Faibussowitsch - u_tshift - A multiplier for the dF/du_t term (as opposed to the dF/du term) 164427f02ce8SMatthew G. Knepley 1645a4e35b19SJacob Faibussowitsch Output Parameter: 164627f02ce8SMatthew G. Knepley . elemMat - the element matrices for the Jacobian from each element 164727f02ce8SMatthew G. Knepley 164827f02ce8SMatthew G. Knepley Level: developer 164927f02ce8SMatthew G. Knepley 1650dce8aebaSBarry Smith Note: 1651dce8aebaSBarry Smith .vb 1652dce8aebaSBarry Smith Loop over batch of elements (e): 1653dce8aebaSBarry Smith Loop over element matrix entries (f,fc,g,gc --> i,j): 1654dce8aebaSBarry Smith Loop over quadrature points (q): 1655dce8aebaSBarry Smith Make u_q and gradU_q (loops over fields,Nb,Ncomp) 1656dce8aebaSBarry Smith elemMat[i,j] += \psi^{fc}_f(q) g0_{fc,gc}(u, \nabla u) \phi^{gc}_g(q) 1657dce8aebaSBarry Smith + \psi^{fc}_f(q) \cdot g1_{fc,gc,dg}(u, \nabla u) \nabla\phi^{gc}_g(q) 1658dce8aebaSBarry Smith + \nabla\psi^{fc}_f(q) \cdot g2_{fc,gc,df}(u, \nabla u) \phi^{gc}_g(q) 1659dce8aebaSBarry Smith + \nabla\psi^{fc}_f(q) \cdot g3_{fc,gc,df,dg}(u, \nabla u) \nabla\phi^{gc}_g(q) 1660dce8aebaSBarry Smith .ve 1661dce8aebaSBarry Smith 1662db781477SPatrick Sanan .seealso: `PetscFEIntegrateJacobian()`, `PetscFEIntegrateResidual()` 166327f02ce8SMatthew G. Knepley @*/ 166407218a29SMatthew G. Knepley PetscErrorCode PetscFEIntegrateHybridJacobian(PetscDS ds, PetscDS dsIn, 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[]) 1665d71ae5a4SJacob Faibussowitsch { 166627f02ce8SMatthew G. Knepley PetscFE fe; 166745480ffeSMatthew G. Knepley PetscInt Nf; 166827f02ce8SMatthew G. Knepley 166927f02ce8SMatthew G. Knepley PetscFunctionBegin; 167045480ffeSMatthew G. Knepley PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1); 16719566063dSJacob Faibussowitsch PetscCall(PetscDSGetNumFields(ds, &Nf)); 16729566063dSJacob Faibussowitsch PetscCall(PetscDSGetDiscretization(ds, key.field / Nf, (PetscObject *)&fe)); 167307218a29SMatthew G. Knepley if (fe->ops->integratehybridjacobian) PetscCall((*fe->ops->integratehybridjacobian)(ds, dsIn, jtype, key, s, Ne, fgeom, coefficients, coefficients_t, probAux, coefficientsAux, t, u_tshift, elemMat)); 16743ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 167527f02ce8SMatthew G. Knepley } 167627f02ce8SMatthew G. Knepley 16772b99622eSMatthew G. Knepley /*@ 16782b99622eSMatthew G. Knepley PetscFEGetHeightSubspace - Get the subspace of this space for a mesh point of a given height 16792b99622eSMatthew G. Knepley 16802b99622eSMatthew G. Knepley Input Parameters: 16812b99622eSMatthew G. Knepley + fe - The finite element space 168220f4b53cSBarry Smith - height - The height of the `DMPLEX` point 16832b99622eSMatthew G. Knepley 16842b99622eSMatthew G. Knepley Output Parameter: 168520f4b53cSBarry Smith . subfe - The subspace of this `PetscFE` space 16862b99622eSMatthew G. Knepley 16872b99622eSMatthew G. Knepley Level: advanced 16882b99622eSMatthew G. Knepley 1689dce8aebaSBarry Smith Note: 1690dce8aebaSBarry Smith For example, if we want the subspace of this space for a face, we would choose height = 1. 1691dce8aebaSBarry Smith 1692db781477SPatrick Sanan .seealso: `PetscFECreateDefault()` 16932b99622eSMatthew G. Knepley @*/ 1694d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEGetHeightSubspace(PetscFE fe, PetscInt height, PetscFE *subfe) 1695d71ae5a4SJacob Faibussowitsch { 169620cf1dd8SToby Isaac PetscSpace P, subP; 169720cf1dd8SToby Isaac PetscDualSpace Q, subQ; 169820cf1dd8SToby Isaac PetscQuadrature subq; 169920cf1dd8SToby Isaac PetscInt dim, Nc; 170020cf1dd8SToby Isaac 170120cf1dd8SToby Isaac PetscFunctionBegin; 170220cf1dd8SToby Isaac PetscValidHeaderSpecific(fe, PETSCFE_CLASSID, 1); 17034f572ea9SToby Isaac PetscAssertPointer(subfe, 3); 170420cf1dd8SToby Isaac if (height == 0) { 170520cf1dd8SToby Isaac *subfe = fe; 17063ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 170720cf1dd8SToby Isaac } 17089566063dSJacob Faibussowitsch PetscCall(PetscFEGetBasisSpace(fe, &P)); 17099566063dSJacob Faibussowitsch PetscCall(PetscFEGetDualSpace(fe, &Q)); 17109566063dSJacob Faibussowitsch PetscCall(PetscFEGetNumComponents(fe, &Nc)); 17119566063dSJacob Faibussowitsch PetscCall(PetscFEGetFaceQuadrature(fe, &subq)); 17129566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetDimension(Q, &dim)); 17131dca8a05SBarry 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); 17149566063dSJacob Faibussowitsch if (!fe->subspaces) PetscCall(PetscCalloc1(dim, &fe->subspaces)); 171520cf1dd8SToby Isaac if (height <= dim) { 171620cf1dd8SToby Isaac if (!fe->subspaces[height - 1]) { 1717665f567fSMatthew G. Knepley PetscFE sub = NULL; 17183f6b16c7SMatthew G. Knepley const char *name; 171920cf1dd8SToby Isaac 17209566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetHeightSubspace(P, height, &subP)); 17219566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetHeightSubspace(Q, height, &subQ)); 1722665f567fSMatthew G. Knepley if (subQ) { 17232dce792eSToby Isaac PetscCall(PetscObjectReference((PetscObject)subP)); 17242dce792eSToby Isaac PetscCall(PetscObjectReference((PetscObject)subQ)); 17252dce792eSToby Isaac PetscCall(PetscObjectReference((PetscObject)subq)); 17262dce792eSToby Isaac PetscCall(PetscFECreateFromSpaces(subP, subQ, subq, NULL, &sub)); 17272dce792eSToby Isaac } 17282dce792eSToby Isaac if (sub) { 17299566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)fe, &name)); 17302dce792eSToby Isaac if (name) PetscCall(PetscFESetName(sub, name)); 1731665f567fSMatthew G. Knepley } 173220cf1dd8SToby Isaac fe->subspaces[height - 1] = sub; 173320cf1dd8SToby Isaac } 173420cf1dd8SToby Isaac *subfe = fe->subspaces[height - 1]; 173520cf1dd8SToby Isaac } else { 173620cf1dd8SToby Isaac *subfe = NULL; 173720cf1dd8SToby Isaac } 17383ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 173920cf1dd8SToby Isaac } 174020cf1dd8SToby Isaac 174120cf1dd8SToby Isaac /*@ 1742a4e35b19SJacob Faibussowitsch PetscFERefine - Create a "refined" `PetscFE` object that refines the reference cell into 1743a4e35b19SJacob Faibussowitsch smaller copies. 174420cf1dd8SToby Isaac 174520f4b53cSBarry Smith Collective 174620cf1dd8SToby Isaac 174720cf1dd8SToby Isaac Input Parameter: 174820f4b53cSBarry Smith . fe - The initial `PetscFE` 174920cf1dd8SToby Isaac 175020cf1dd8SToby Isaac Output Parameter: 175120f4b53cSBarry Smith . feRef - The refined `PetscFE` 175220cf1dd8SToby Isaac 17532b99622eSMatthew G. Knepley Level: advanced 175420cf1dd8SToby Isaac 1755a4e35b19SJacob Faibussowitsch Notes: 1756a4e35b19SJacob Faibussowitsch This is typically used to generate a preconditioner for a higher order method from a lower order method on a 1757a4e35b19SJacob Faibussowitsch refined mesh having the same number of dofs (but more sparsity). It is also used to create an 1758a4e35b19SJacob Faibussowitsch interpolation between regularly refined meshes. 1759a4e35b19SJacob Faibussowitsch 1760db781477SPatrick Sanan .seealso: `PetscFEType`, `PetscFECreate()`, `PetscFESetType()` 176120cf1dd8SToby Isaac @*/ 1762d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFERefine(PetscFE fe, PetscFE *feRef) 1763d71ae5a4SJacob Faibussowitsch { 176420cf1dd8SToby Isaac PetscSpace P, Pref; 176520cf1dd8SToby Isaac PetscDualSpace Q, Qref; 176620cf1dd8SToby Isaac DM K, Kref; 176720cf1dd8SToby Isaac PetscQuadrature q, qref; 176820cf1dd8SToby Isaac const PetscReal *v0, *jac; 176920cf1dd8SToby Isaac PetscInt numComp, numSubelements; 17701ac17e89SToby Isaac PetscInt cStart, cEnd, c; 17711ac17e89SToby Isaac PetscDualSpace *cellSpaces; 177220cf1dd8SToby Isaac 177320cf1dd8SToby Isaac PetscFunctionBegin; 17749566063dSJacob Faibussowitsch PetscCall(PetscFEGetBasisSpace(fe, &P)); 17759566063dSJacob Faibussowitsch PetscCall(PetscFEGetDualSpace(fe, &Q)); 17769566063dSJacob Faibussowitsch PetscCall(PetscFEGetQuadrature(fe, &q)); 17779566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetDM(Q, &K)); 177820cf1dd8SToby Isaac /* Create space */ 17799566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)P)); 178020cf1dd8SToby Isaac Pref = P; 178120cf1dd8SToby Isaac /* Create dual space */ 17829566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceDuplicate(Q, &Qref)); 17839566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetType(Qref, PETSCDUALSPACEREFINED)); 17849566063dSJacob Faibussowitsch PetscCall(DMRefine(K, PetscObjectComm((PetscObject)fe), &Kref)); 1785e44f6aebSMatthew G. Knepley PetscCall(DMGetCoordinatesLocalSetUp(Kref)); 17869566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetDM(Qref, Kref)); 17879566063dSJacob Faibussowitsch PetscCall(DMPlexGetHeightStratum(Kref, 0, &cStart, &cEnd)); 17889566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(cEnd - cStart, &cellSpaces)); 17891ac17e89SToby Isaac /* TODO: fix for non-uniform refinement */ 17901ac17e89SToby Isaac for (c = 0; c < cEnd - cStart; c++) cellSpaces[c] = Q; 17919566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceRefinedSetCellSpaces(Qref, cellSpaces)); 17929566063dSJacob Faibussowitsch PetscCall(PetscFree(cellSpaces)); 17939566063dSJacob Faibussowitsch PetscCall(DMDestroy(&Kref)); 17949566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetUp(Qref)); 179520cf1dd8SToby Isaac /* Create element */ 17969566063dSJacob Faibussowitsch PetscCall(PetscFECreate(PetscObjectComm((PetscObject)fe), feRef)); 17979566063dSJacob Faibussowitsch PetscCall(PetscFESetType(*feRef, PETSCFECOMPOSITE)); 17989566063dSJacob Faibussowitsch PetscCall(PetscFESetBasisSpace(*feRef, Pref)); 17999566063dSJacob Faibussowitsch PetscCall(PetscFESetDualSpace(*feRef, Qref)); 18009566063dSJacob Faibussowitsch PetscCall(PetscFEGetNumComponents(fe, &numComp)); 18019566063dSJacob Faibussowitsch PetscCall(PetscFESetNumComponents(*feRef, numComp)); 18029566063dSJacob Faibussowitsch PetscCall(PetscFESetUp(*feRef)); 18039566063dSJacob Faibussowitsch PetscCall(PetscSpaceDestroy(&Pref)); 18049566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceDestroy(&Qref)); 180520cf1dd8SToby Isaac /* Create quadrature */ 18069566063dSJacob Faibussowitsch PetscCall(PetscFECompositeGetMapping(*feRef, &numSubelements, &v0, &jac, NULL)); 18079566063dSJacob Faibussowitsch PetscCall(PetscQuadratureExpandComposite(q, numSubelements, v0, jac, &qref)); 18089566063dSJacob Faibussowitsch PetscCall(PetscFESetQuadrature(*feRef, qref)); 18099566063dSJacob Faibussowitsch PetscCall(PetscQuadratureDestroy(&qref)); 18103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 181120cf1dd8SToby Isaac } 181220cf1dd8SToby Isaac 1813d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFESetDefaultName_Private(PetscFE fe) 1814d71ae5a4SJacob Faibussowitsch { 18157c48043bSMatthew G. Knepley PetscSpace P; 18167c48043bSMatthew G. Knepley PetscDualSpace Q; 18177c48043bSMatthew G. Knepley DM K; 18187c48043bSMatthew G. Knepley DMPolytopeType ct; 18197c48043bSMatthew G. Knepley PetscInt degree; 18207c48043bSMatthew G. Knepley char name[64]; 18217c48043bSMatthew G. Knepley 18227c48043bSMatthew G. Knepley PetscFunctionBegin; 18237c48043bSMatthew G. Knepley PetscCall(PetscFEGetBasisSpace(fe, &P)); 18247c48043bSMatthew G. Knepley PetscCall(PetscSpaceGetDegree(P, °ree, NULL)); 18257c48043bSMatthew G. Knepley PetscCall(PetscFEGetDualSpace(fe, &Q)); 18267c48043bSMatthew G. Knepley PetscCall(PetscDualSpaceGetDM(Q, &K)); 18277c48043bSMatthew G. Knepley PetscCall(DMPlexGetCellType(K, 0, &ct)); 18287c48043bSMatthew G. Knepley switch (ct) { 18297c48043bSMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 18307c48043bSMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: 18317c48043bSMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 18327c48043bSMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 18337c48043bSMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 1834d71ae5a4SJacob Faibussowitsch case DM_POLYTOPE_QUAD_PRISM_TENSOR: 1835d71ae5a4SJacob Faibussowitsch PetscCall(PetscSNPrintf(name, sizeof(name), "Q%" PetscInt_FMT, degree)); 1836d71ae5a4SJacob Faibussowitsch break; 18377c48043bSMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 1838d71ae5a4SJacob Faibussowitsch case DM_POLYTOPE_TETRAHEDRON: 1839d71ae5a4SJacob Faibussowitsch PetscCall(PetscSNPrintf(name, sizeof(name), "P%" PetscInt_FMT, degree)); 1840d71ae5a4SJacob Faibussowitsch break; 18417c48043bSMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM: 1842d71ae5a4SJacob Faibussowitsch case DM_POLYTOPE_TRI_PRISM_TENSOR: 1843d71ae5a4SJacob Faibussowitsch PetscCall(PetscSNPrintf(name, sizeof(name), "P%" PetscInt_FMT "xQ%" PetscInt_FMT, degree, degree)); 1844d71ae5a4SJacob Faibussowitsch break; 1845d71ae5a4SJacob Faibussowitsch default: 1846d71ae5a4SJacob Faibussowitsch PetscCall(PetscSNPrintf(name, sizeof(name), "FE")); 18477c48043bSMatthew G. Knepley } 18487c48043bSMatthew G. Knepley PetscCall(PetscFESetName(fe, name)); 18493ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 18507c48043bSMatthew G. Knepley } 18517c48043bSMatthew G. Knepley 18527c48043bSMatthew G. Knepley /*@ 1853dce8aebaSBarry Smith PetscFECreateFromSpaces - Create a `PetscFE` from the basis and dual spaces 18547c48043bSMatthew G. Knepley 18557c48043bSMatthew G. Knepley Collective 18567c48043bSMatthew G. Knepley 18577c48043bSMatthew G. Knepley Input Parameters: 18587c48043bSMatthew G. Knepley + P - The basis space 18597c48043bSMatthew G. Knepley . Q - The dual space 18607c48043bSMatthew G. Knepley . q - The cell quadrature 18617c48043bSMatthew G. Knepley - fq - The face quadrature 18627c48043bSMatthew G. Knepley 18637c48043bSMatthew G. Knepley Output Parameter: 186420f4b53cSBarry Smith . fem - The `PetscFE` object 18657c48043bSMatthew G. Knepley 18667c48043bSMatthew G. Knepley Level: beginner 18677c48043bSMatthew G. Knepley 1868dce8aebaSBarry Smith Note: 1869dce8aebaSBarry Smith 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. 1870dce8aebaSBarry Smith 1871dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscSpace`, `PetscDualSpace`, `PetscQuadrature`, 1872dce8aebaSBarry Smith `PetscFECreateLagrangeByCell()`, `PetscFECreateDefault()`, `PetscFECreateByCell()`, `PetscFECreate()`, `PetscSpaceCreate()`, `PetscDualSpaceCreate()` 18737c48043bSMatthew G. Knepley @*/ 1874d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFECreateFromSpaces(PetscSpace P, PetscDualSpace Q, PetscQuadrature q, PetscQuadrature fq, PetscFE *fem) 1875d71ae5a4SJacob Faibussowitsch { 18767c48043bSMatthew G. Knepley PetscInt Nc; 18772dce792eSToby Isaac PetscInt p_Ns = -1, p_Nc = -1, q_Ns = -1, q_Nc = -1; 18782dce792eSToby Isaac PetscBool p_is_uniform_sum = PETSC_FALSE, p_interleave_basis = PETSC_FALSE, p_interleave_components = PETSC_FALSE; 18792dce792eSToby Isaac PetscBool q_is_uniform_sum = PETSC_FALSE, q_interleave_basis = PETSC_FALSE, q_interleave_components = PETSC_FALSE; 18807c48043bSMatthew G. Knepley const char *prefix; 18817c48043bSMatthew G. Knepley 18827c48043bSMatthew G. Knepley PetscFunctionBegin; 18832dce792eSToby Isaac PetscCall(PetscObjectTypeCompare((PetscObject)P, PETSCSPACESUM, &p_is_uniform_sum)); 18842dce792eSToby Isaac if (p_is_uniform_sum) { 18852dce792eSToby Isaac PetscSpace subsp_0 = NULL; 18862dce792eSToby Isaac PetscCall(PetscSpaceSumGetNumSubspaces(P, &p_Ns)); 18872dce792eSToby Isaac PetscCall(PetscSpaceGetNumComponents(P, &p_Nc)); 18882dce792eSToby Isaac PetscCall(PetscSpaceSumGetConcatenate(P, &p_is_uniform_sum)); 18892dce792eSToby Isaac PetscCall(PetscSpaceSumGetInterleave(P, &p_interleave_basis, &p_interleave_components)); 18902dce792eSToby Isaac for (PetscInt s = 0; s < p_Ns; s++) { 18912dce792eSToby Isaac PetscSpace subsp; 18922dce792eSToby Isaac 18932dce792eSToby Isaac PetscCall(PetscSpaceSumGetSubspace(P, s, &subsp)); 18942dce792eSToby Isaac if (!s) { 18952dce792eSToby Isaac subsp_0 = subsp; 18962dce792eSToby Isaac } else if (subsp != subsp_0) { 18972dce792eSToby Isaac p_is_uniform_sum = PETSC_FALSE; 18982dce792eSToby Isaac } 18992dce792eSToby Isaac } 19002dce792eSToby Isaac } 19012dce792eSToby Isaac PetscCall(PetscObjectTypeCompare((PetscObject)Q, PETSCDUALSPACESUM, &q_is_uniform_sum)); 19022dce792eSToby Isaac if (q_is_uniform_sum) { 19032dce792eSToby Isaac PetscDualSpace subsp_0 = NULL; 19042dce792eSToby Isaac PetscCall(PetscDualSpaceSumGetNumSubspaces(Q, &q_Ns)); 19052dce792eSToby Isaac PetscCall(PetscDualSpaceGetNumComponents(Q, &q_Nc)); 19062dce792eSToby Isaac PetscCall(PetscDualSpaceSumGetConcatenate(Q, &q_is_uniform_sum)); 19072dce792eSToby Isaac PetscCall(PetscDualSpaceSumGetInterleave(Q, &q_interleave_basis, &q_interleave_components)); 19082dce792eSToby Isaac for (PetscInt s = 0; s < q_Ns; s++) { 19092dce792eSToby Isaac PetscDualSpace subsp; 19102dce792eSToby Isaac 19112dce792eSToby Isaac PetscCall(PetscDualSpaceSumGetSubspace(Q, s, &subsp)); 19122dce792eSToby Isaac if (!s) { 19132dce792eSToby Isaac subsp_0 = subsp; 19142dce792eSToby Isaac } else if (subsp != subsp_0) { 19152dce792eSToby Isaac q_is_uniform_sum = PETSC_FALSE; 19162dce792eSToby Isaac } 19172dce792eSToby Isaac } 19182dce792eSToby Isaac } 19192dce792eSToby Isaac if (p_is_uniform_sum && q_is_uniform_sum && (p_interleave_basis == q_interleave_basis) && (p_interleave_components == q_interleave_components) && (p_Ns == q_Ns) && (p_Nc == q_Nc)) { 19202dce792eSToby Isaac PetscSpace scalar_space; 19212dce792eSToby Isaac PetscDualSpace scalar_dspace; 19222dce792eSToby Isaac PetscFE scalar_fe; 19232dce792eSToby Isaac 19242dce792eSToby Isaac PetscCall(PetscSpaceSumGetSubspace(P, 0, &scalar_space)); 19252dce792eSToby Isaac PetscCall(PetscDualSpaceSumGetSubspace(Q, 0, &scalar_dspace)); 19262dce792eSToby Isaac PetscCall(PetscObjectReference((PetscObject)scalar_space)); 19272dce792eSToby Isaac PetscCall(PetscObjectReference((PetscObject)scalar_dspace)); 19282dce792eSToby Isaac PetscCall(PetscObjectReference((PetscObject)q)); 19292dce792eSToby Isaac PetscCall(PetscObjectReference((PetscObject)fq)); 19302dce792eSToby Isaac PetscCall(PetscFECreateFromSpaces(scalar_space, scalar_dspace, q, fq, &scalar_fe)); 19312dce792eSToby Isaac PetscCall(PetscFECreateVector(scalar_fe, p_Ns, p_interleave_basis, p_interleave_components, fem)); 19322dce792eSToby Isaac PetscCall(PetscFEDestroy(&scalar_fe)); 19332dce792eSToby Isaac } else { 19347c48043bSMatthew G. Knepley PetscCall(PetscFECreate(PetscObjectComm((PetscObject)P), fem)); 19357c48043bSMatthew G. Knepley PetscCall(PetscFESetType(*fem, PETSCFEBASIC)); 19362dce792eSToby Isaac } 19377c48043bSMatthew G. Knepley PetscCall(PetscSpaceGetNumComponents(P, &Nc)); 19387c48043bSMatthew G. Knepley PetscCall(PetscFESetNumComponents(*fem, Nc)); 19392dce792eSToby Isaac PetscCall(PetscFESetBasisSpace(*fem, P)); 19402dce792eSToby Isaac PetscCall(PetscFESetDualSpace(*fem, Q)); 19412dce792eSToby Isaac PetscCall(PetscObjectGetOptionsPrefix((PetscObject)P, &prefix)); 19422dce792eSToby Isaac PetscCall(PetscObjectSetOptionsPrefix((PetscObject)*fem, prefix)); 19437c48043bSMatthew G. Knepley PetscCall(PetscFESetUp(*fem)); 19447c48043bSMatthew G. Knepley PetscCall(PetscSpaceDestroy(&P)); 19457c48043bSMatthew G. Knepley PetscCall(PetscDualSpaceDestroy(&Q)); 19467c48043bSMatthew G. Knepley PetscCall(PetscFESetQuadrature(*fem, q)); 19477c48043bSMatthew G. Knepley PetscCall(PetscFESetFaceQuadrature(*fem, fq)); 19487c48043bSMatthew G. Knepley PetscCall(PetscQuadratureDestroy(&q)); 19497c48043bSMatthew G. Knepley PetscCall(PetscQuadratureDestroy(&fq)); 19507c48043bSMatthew G. Knepley PetscCall(PetscFESetDefaultName_Private(*fem)); 19513ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 19527c48043bSMatthew G. Knepley } 19537c48043bSMatthew G. Knepley 1954d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFECreate_Internal(MPI_Comm comm, PetscInt dim, PetscInt Nc, DMPolytopeType ct, const char prefix[], PetscInt degree, PetscInt qorder, PetscBool setFromOptions, PetscFE *fem) 1955d71ae5a4SJacob Faibussowitsch { 19562df84da0SMatthew G. Knepley DM K; 19572df84da0SMatthew G. Knepley PetscSpace P; 19582df84da0SMatthew G. Knepley PetscDualSpace Q; 19597c48043bSMatthew G. Knepley PetscQuadrature q, fq; 19602df84da0SMatthew G. Knepley PetscBool tensor; 19612df84da0SMatthew G. Knepley 19622df84da0SMatthew G. Knepley PetscFunctionBegin; 19634f572ea9SToby Isaac if (prefix) PetscAssertPointer(prefix, 5); 19644f572ea9SToby Isaac PetscAssertPointer(fem, 9); 19652df84da0SMatthew G. Knepley switch (ct) { 19662df84da0SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 19672df84da0SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: 19682df84da0SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 19692df84da0SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 19702df84da0SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 1971d71ae5a4SJacob Faibussowitsch case DM_POLYTOPE_QUAD_PRISM_TENSOR: 1972d71ae5a4SJacob Faibussowitsch tensor = PETSC_TRUE; 1973d71ae5a4SJacob Faibussowitsch break; 1974d71ae5a4SJacob Faibussowitsch default: 1975d71ae5a4SJacob Faibussowitsch tensor = PETSC_FALSE; 19762df84da0SMatthew G. Knepley } 19772df84da0SMatthew G. Knepley /* Create space */ 19789566063dSJacob Faibussowitsch PetscCall(PetscSpaceCreate(comm, &P)); 19799566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetType(P, PETSCSPACEPOLYNOMIAL)); 19809566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)P, prefix)); 19819566063dSJacob Faibussowitsch PetscCall(PetscSpacePolynomialSetTensor(P, tensor)); 19829566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetNumComponents(P, Nc)); 19839566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetNumVariables(P, dim)); 19842df84da0SMatthew G. Knepley if (degree >= 0) { 19859566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetDegree(P, degree, PETSC_DETERMINE)); 1986cfd33b42SLisandro Dalcin if (ct == DM_POLYTOPE_TRI_PRISM || ct == DM_POLYTOPE_TRI_PRISM_TENSOR) { 19872df84da0SMatthew G. Knepley PetscSpace Pend, Pside; 19882df84da0SMatthew G. Knepley 19892dce792eSToby Isaac PetscCall(PetscSpaceSetNumComponents(P, 1)); 19909566063dSJacob Faibussowitsch PetscCall(PetscSpaceCreate(comm, &Pend)); 19919566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetType(Pend, PETSCSPACEPOLYNOMIAL)); 19929566063dSJacob Faibussowitsch PetscCall(PetscSpacePolynomialSetTensor(Pend, PETSC_FALSE)); 19932dce792eSToby Isaac PetscCall(PetscSpaceSetNumComponents(Pend, 1)); 19949566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetNumVariables(Pend, dim - 1)); 19959566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetDegree(Pend, degree, PETSC_DETERMINE)); 19969566063dSJacob Faibussowitsch PetscCall(PetscSpaceCreate(comm, &Pside)); 19979566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetType(Pside, PETSCSPACEPOLYNOMIAL)); 19989566063dSJacob Faibussowitsch PetscCall(PetscSpacePolynomialSetTensor(Pside, PETSC_FALSE)); 19999566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetNumComponents(Pside, 1)); 20009566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetNumVariables(Pside, 1)); 20019566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetDegree(Pside, degree, PETSC_DETERMINE)); 20029566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetType(P, PETSCSPACETENSOR)); 20039566063dSJacob Faibussowitsch PetscCall(PetscSpaceTensorSetNumSubspaces(P, 2)); 20049566063dSJacob Faibussowitsch PetscCall(PetscSpaceTensorSetSubspace(P, 0, Pend)); 20059566063dSJacob Faibussowitsch PetscCall(PetscSpaceTensorSetSubspace(P, 1, Pside)); 20069566063dSJacob Faibussowitsch PetscCall(PetscSpaceDestroy(&Pend)); 20079566063dSJacob Faibussowitsch PetscCall(PetscSpaceDestroy(&Pside)); 20082dce792eSToby Isaac 20092dce792eSToby Isaac if (Nc > 1) { 20102dce792eSToby Isaac PetscSpace scalar_P = P; 20112dce792eSToby Isaac 20122dce792eSToby Isaac PetscCall(PetscSpaceCreate(comm, &P)); 20132dce792eSToby Isaac PetscCall(PetscSpaceSetNumVariables(P, dim)); 20142dce792eSToby Isaac PetscCall(PetscSpaceSetNumComponents(P, Nc)); 20152dce792eSToby Isaac PetscCall(PetscSpaceSetType(P, PETSCSPACESUM)); 20162dce792eSToby Isaac PetscCall(PetscSpaceSumSetNumSubspaces(P, Nc)); 20172dce792eSToby Isaac PetscCall(PetscSpaceSumSetConcatenate(P, PETSC_TRUE)); 20182dce792eSToby Isaac PetscCall(PetscSpaceSumSetInterleave(P, PETSC_TRUE, PETSC_FALSE)); 20192dce792eSToby Isaac for (PetscInt i = 0; i < Nc; i++) PetscCall(PetscSpaceSumSetSubspace(P, i, scalar_P)); 20202dce792eSToby Isaac PetscCall(PetscSpaceDestroy(&scalar_P)); 20212dce792eSToby Isaac } 20222df84da0SMatthew G. Knepley } 20232df84da0SMatthew G. Knepley } 20249566063dSJacob Faibussowitsch if (setFromOptions) PetscCall(PetscSpaceSetFromOptions(P)); 20259566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetUp(P)); 20269566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetDegree(P, °ree, NULL)); 20279566063dSJacob Faibussowitsch PetscCall(PetscSpacePolynomialGetTensor(P, &tensor)); 20289566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetNumComponents(P, &Nc)); 20292df84da0SMatthew G. Knepley /* Create dual space */ 20309566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceCreate(comm, &Q)); 20319566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetType(Q, PETSCDUALSPACELAGRANGE)); 20329566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)Q, prefix)); 20339566063dSJacob Faibussowitsch PetscCall(DMPlexCreateReferenceCell(PETSC_COMM_SELF, ct, &K)); 20349566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetDM(Q, K)); 20359566063dSJacob Faibussowitsch PetscCall(DMDestroy(&K)); 20369566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetNumComponents(Q, Nc)); 20379566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetOrder(Q, degree)); 20389566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceLagrangeSetTensor(Q, (tensor || (ct == DM_POLYTOPE_TRI_PRISM)) ? PETSC_TRUE : PETSC_FALSE)); 20399566063dSJacob Faibussowitsch if (setFromOptions) PetscCall(PetscDualSpaceSetFromOptions(Q)); 20409566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetUp(Q)); 20417c48043bSMatthew G. Knepley /* Create quadrature */ 20422df84da0SMatthew G. Knepley qorder = qorder >= 0 ? qorder : degree; 20432df84da0SMatthew G. Knepley if (setFromOptions) { 20447c48043bSMatthew G. Knepley PetscObjectOptionsBegin((PetscObject)P); 20459566063dSJacob Faibussowitsch PetscCall(PetscOptionsBoundedInt("-petscfe_default_quadrature_order", "Quadrature order is one less than quadrature points per edge", "PetscFECreateDefault", qorder, &qorder, NULL, 0)); 2046d0609cedSBarry Smith PetscOptionsEnd(); 20472df84da0SMatthew G. Knepley } 20484366bac7SMatthew G. Knepley PetscCall(PetscDTCreateDefaultQuadrature(ct, qorder, &q, &fq)); 20497c48043bSMatthew G. Knepley /* Create finite element */ 20507c48043bSMatthew G. Knepley PetscCall(PetscFECreateFromSpaces(P, Q, q, fq, fem)); 20517c48043bSMatthew G. Knepley if (setFromOptions) PetscCall(PetscFESetFromOptions(*fem)); 20523ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 20532df84da0SMatthew G. Knepley } 20542df84da0SMatthew G. Knepley 2055cc4c1da9SBarry Smith /*@ 205620f4b53cSBarry Smith PetscFECreateDefault - Create a `PetscFE` for basic FEM computation 205720cf1dd8SToby Isaac 2058d083f849SBarry Smith Collective 205920cf1dd8SToby Isaac 206020cf1dd8SToby Isaac Input Parameters: 20617be5e748SToby Isaac + comm - The MPI comm 206220cf1dd8SToby Isaac . dim - The spatial dimension 206320cf1dd8SToby Isaac . Nc - The number of components 206420cf1dd8SToby Isaac . isSimplex - Flag for simplex reference cell, otherwise its a tensor product 206520f4b53cSBarry Smith . prefix - The options prefix, or `NULL` 206620f4b53cSBarry Smith - qorder - The quadrature order or `PETSC_DETERMINE` to use `PetscSpace` polynomial degree 206720cf1dd8SToby Isaac 206820cf1dd8SToby Isaac Output Parameter: 206920f4b53cSBarry Smith . fem - The `PetscFE` object 207020cf1dd8SToby Isaac 2071dce8aebaSBarry Smith Level: beginner 2072dce8aebaSBarry Smith 2073e703855dSMatthew G. Knepley Note: 20748f2aacc6SMatthew 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. 2075e703855dSMatthew G. Knepley 2076db781477SPatrick Sanan .seealso: `PetscFECreateLagrange()`, `PetscFECreateByCell()`, `PetscSpaceSetFromOptions()`, `PetscDualSpaceSetFromOptions()`, `PetscFESetFromOptions()`, `PetscFECreate()`, `PetscSpaceCreate()`, `PetscDualSpaceCreate()` 207720cf1dd8SToby Isaac @*/ 2078d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFECreateDefault(MPI_Comm comm, PetscInt dim, PetscInt Nc, PetscBool isSimplex, const char prefix[], PetscInt qorder, PetscFE *fem) 2079d71ae5a4SJacob Faibussowitsch { 208020cf1dd8SToby Isaac PetscFunctionBegin; 20819566063dSJacob Faibussowitsch PetscCall(PetscFECreate_Internal(comm, dim, Nc, DMPolytopeTypeSimpleShape(dim, isSimplex), prefix, PETSC_DECIDE, qorder, PETSC_TRUE, fem)); 20823ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 208320cf1dd8SToby Isaac } 20842df84da0SMatthew G. Knepley 2085cc4c1da9SBarry Smith /*@ 208620f4b53cSBarry Smith PetscFECreateByCell - Create a `PetscFE` for basic FEM computation 20872df84da0SMatthew G. Knepley 20882df84da0SMatthew G. Knepley Collective 20892df84da0SMatthew G. Knepley 20902df84da0SMatthew G. Knepley Input Parameters: 20912df84da0SMatthew G. Knepley + comm - The MPI comm 20922df84da0SMatthew G. Knepley . dim - The spatial dimension 20932df84da0SMatthew G. Knepley . Nc - The number of components 20942df84da0SMatthew G. Knepley . ct - The celltype of the reference cell 209520f4b53cSBarry Smith . prefix - The options prefix, or `NULL` 209620f4b53cSBarry Smith - qorder - The quadrature order or `PETSC_DETERMINE` to use `PetscSpace` polynomial degree 20972df84da0SMatthew G. Knepley 20982df84da0SMatthew G. Knepley Output Parameter: 209920f4b53cSBarry Smith . fem - The `PetscFE` object 21002df84da0SMatthew G. Knepley 2101dce8aebaSBarry Smith Level: beginner 2102dce8aebaSBarry Smith 21032df84da0SMatthew G. Knepley Note: 21042df84da0SMatthew 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. 21052df84da0SMatthew G. Knepley 2106db781477SPatrick Sanan .seealso: `PetscFECreateDefault()`, `PetscFECreateLagrange()`, `PetscSpaceSetFromOptions()`, `PetscDualSpaceSetFromOptions()`, `PetscFESetFromOptions()`, `PetscFECreate()`, `PetscSpaceCreate()`, `PetscDualSpaceCreate()` 21072df84da0SMatthew G. Knepley @*/ 2108d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFECreateByCell(MPI_Comm comm, PetscInt dim, PetscInt Nc, DMPolytopeType ct, const char prefix[], PetscInt qorder, PetscFE *fem) 2109d71ae5a4SJacob Faibussowitsch { 21102df84da0SMatthew G. Knepley PetscFunctionBegin; 21119566063dSJacob Faibussowitsch PetscCall(PetscFECreate_Internal(comm, dim, Nc, ct, prefix, PETSC_DECIDE, qorder, PETSC_TRUE, fem)); 21123ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 211320cf1dd8SToby Isaac } 21143f6b16c7SMatthew G. Knepley 2115e703855dSMatthew G. Knepley /*@ 211620f4b53cSBarry Smith PetscFECreateLagrange - Create a `PetscFE` for the basic Lagrange space of degree k 2117e703855dSMatthew G. Knepley 2118e703855dSMatthew G. Knepley Collective 2119e703855dSMatthew G. Knepley 2120e703855dSMatthew G. Knepley Input Parameters: 2121e703855dSMatthew G. Knepley + comm - The MPI comm 2122e703855dSMatthew G. Knepley . dim - The spatial dimension 2123e703855dSMatthew G. Knepley . Nc - The number of components 2124e703855dSMatthew G. Knepley . isSimplex - Flag for simplex reference cell, otherwise its a tensor product 2125e703855dSMatthew G. Knepley . k - The degree k of the space 212620f4b53cSBarry Smith - qorder - The quadrature order or `PETSC_DETERMINE` to use `PetscSpace` polynomial degree 2127e703855dSMatthew G. Knepley 2128e703855dSMatthew G. Knepley Output Parameter: 212920f4b53cSBarry Smith . fem - The `PetscFE` object 2130e703855dSMatthew G. Knepley 2131e703855dSMatthew G. Knepley Level: beginner 2132e703855dSMatthew G. Knepley 2133dce8aebaSBarry Smith Note: 2134e703855dSMatthew 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. 2135e703855dSMatthew G. Knepley 2136db781477SPatrick Sanan .seealso: `PetscFECreateLagrangeByCell()`, `PetscFECreateDefault()`, `PetscFECreateByCell()`, `PetscFECreate()`, `PetscSpaceCreate()`, `PetscDualSpaceCreate()` 2137e703855dSMatthew G. Knepley @*/ 2138d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFECreateLagrange(MPI_Comm comm, PetscInt dim, PetscInt Nc, PetscBool isSimplex, PetscInt k, PetscInt qorder, PetscFE *fem) 2139d71ae5a4SJacob Faibussowitsch { 2140e703855dSMatthew G. Knepley PetscFunctionBegin; 21419566063dSJacob Faibussowitsch PetscCall(PetscFECreate_Internal(comm, dim, Nc, DMPolytopeTypeSimpleShape(dim, isSimplex), NULL, k, qorder, PETSC_FALSE, fem)); 21423ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2143e703855dSMatthew G. Knepley } 21442df84da0SMatthew G. Knepley 21452df84da0SMatthew G. Knepley /*@ 214620f4b53cSBarry Smith PetscFECreateLagrangeByCell - Create a `PetscFE` for the basic Lagrange space of degree k 21472df84da0SMatthew G. Knepley 21482df84da0SMatthew G. Knepley Collective 21492df84da0SMatthew G. Knepley 21502df84da0SMatthew G. Knepley Input Parameters: 21512df84da0SMatthew G. Knepley + comm - The MPI comm 21522df84da0SMatthew G. Knepley . dim - The spatial dimension 21532df84da0SMatthew G. Knepley . Nc - The number of components 21542df84da0SMatthew G. Knepley . ct - The celltype of the reference cell 21552df84da0SMatthew G. Knepley . k - The degree k of the space 215620f4b53cSBarry Smith - qorder - The quadrature order or `PETSC_DETERMINE` to use `PetscSpace` polynomial degree 21572df84da0SMatthew G. Knepley 21582df84da0SMatthew G. Knepley Output Parameter: 215920f4b53cSBarry Smith . fem - The `PetscFE` object 21602df84da0SMatthew G. Knepley 21612df84da0SMatthew G. Knepley Level: beginner 21622df84da0SMatthew G. Knepley 2163dce8aebaSBarry Smith Note: 21642df84da0SMatthew 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. 21652df84da0SMatthew G. Knepley 2166db781477SPatrick Sanan .seealso: `PetscFECreateLagrange()`, `PetscFECreateDefault()`, `PetscFECreateByCell()`, `PetscFECreate()`, `PetscSpaceCreate()`, `PetscDualSpaceCreate()` 21672df84da0SMatthew G. Knepley @*/ 2168d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFECreateLagrangeByCell(MPI_Comm comm, PetscInt dim, PetscInt Nc, DMPolytopeType ct, PetscInt k, PetscInt qorder, PetscFE *fem) 2169d71ae5a4SJacob Faibussowitsch { 21702df84da0SMatthew G. Knepley PetscFunctionBegin; 21719566063dSJacob Faibussowitsch PetscCall(PetscFECreate_Internal(comm, dim, Nc, ct, NULL, k, qorder, PETSC_FALSE, fem)); 21723ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2173e703855dSMatthew G. Knepley } 2174e703855dSMatthew G. Knepley 2175cc4c1da9SBarry Smith /*@ 2176*bb4b53efSMatthew G. Knepley PetscFELimitDegree - Copy a `PetscFE` but limit the degree to be in the given range 2177*bb4b53efSMatthew G. Knepley 2178*bb4b53efSMatthew G. Knepley Collective 2179*bb4b53efSMatthew G. Knepley 2180*bb4b53efSMatthew G. Knepley Input Parameters: 2181*bb4b53efSMatthew G. Knepley + fe - The `PetscFE` 2182*bb4b53efSMatthew G. Knepley . minDegree - The minimum degree, or `PETSC_DETERMINE` for no limit 2183*bb4b53efSMatthew G. Knepley - maxDegree - The maximum degree, or `PETSC_DETERMINE` for no limit 2184*bb4b53efSMatthew G. Knepley 2185*bb4b53efSMatthew G. Knepley Output Parameter: 2186*bb4b53efSMatthew G. Knepley . newfe - The `PetscFE` object 2187*bb4b53efSMatthew G. Knepley 2188*bb4b53efSMatthew G. Knepley Level: advanced 2189*bb4b53efSMatthew G. Knepley 2190*bb4b53efSMatthew G. Knepley Note: 2191*bb4b53efSMatthew G. Knepley This currently only works for Lagrange elements. 2192*bb4b53efSMatthew G. Knepley 2193*bb4b53efSMatthew G. Knepley .seealso: `PetscFECreateLagrange()`, `PetscFECreateDefault()`, `PetscFECreateByCell()`, `PetscFECreate()`, `PetscSpaceCreate()`, `PetscDualSpaceCreate()` 2194*bb4b53efSMatthew G. Knepley @*/ 2195*bb4b53efSMatthew G. Knepley PetscErrorCode PetscFELimitDegree(PetscFE fe, PetscInt minDegree, PetscInt maxDegree, PetscFE *newfe) 2196*bb4b53efSMatthew G. Knepley { 2197*bb4b53efSMatthew G. Knepley PetscDualSpace Q; 2198*bb4b53efSMatthew G. Knepley PetscBool islag, issum; 2199*bb4b53efSMatthew G. Knepley PetscInt oldk = 0, k; 2200*bb4b53efSMatthew G. Knepley 2201*bb4b53efSMatthew G. Knepley PetscFunctionBegin; 2202*bb4b53efSMatthew G. Knepley PetscCall(PetscFEGetDualSpace(fe, &Q)); 2203*bb4b53efSMatthew G. Knepley PetscCall(PetscObjectTypeCompare((PetscObject)Q, PETSCDUALSPACELAGRANGE, &islag)); 2204*bb4b53efSMatthew G. Knepley PetscCall(PetscObjectTypeCompare((PetscObject)Q, PETSCDUALSPACESUM, &issum)); 2205*bb4b53efSMatthew G. Knepley if (islag) { 2206*bb4b53efSMatthew G. Knepley PetscCall(PetscDualSpaceGetOrder(Q, &oldk)); 2207*bb4b53efSMatthew G. Knepley } else if (issum) { 2208*bb4b53efSMatthew G. Knepley PetscDualSpace subQ; 2209*bb4b53efSMatthew G. Knepley 2210*bb4b53efSMatthew G. Knepley PetscCall(PetscDualSpaceSumGetSubspace(Q, 0, &subQ)); 2211*bb4b53efSMatthew G. Knepley PetscCall(PetscDualSpaceGetOrder(subQ, &oldk)); 2212*bb4b53efSMatthew G. Knepley } else { 2213*bb4b53efSMatthew G. Knepley PetscCall(PetscObjectReference((PetscObject)fe)); 2214*bb4b53efSMatthew G. Knepley *newfe = fe; 2215*bb4b53efSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 2216*bb4b53efSMatthew G. Knepley } 2217*bb4b53efSMatthew G. Knepley k = oldk; 2218*bb4b53efSMatthew G. Knepley if (minDegree >= 0) k = PetscMax(k, minDegree); 2219*bb4b53efSMatthew G. Knepley if (maxDegree >= 0) k = PetscMin(k, maxDegree); 2220*bb4b53efSMatthew G. Knepley if (k != oldk) { 2221*bb4b53efSMatthew G. Knepley DM K; 2222*bb4b53efSMatthew G. Knepley PetscSpace P; 2223*bb4b53efSMatthew G. Knepley PetscQuadrature q; 2224*bb4b53efSMatthew G. Knepley DMPolytopeType ct; 2225*bb4b53efSMatthew G. Knepley PetscInt dim, Nc; 2226*bb4b53efSMatthew G. Knepley 2227*bb4b53efSMatthew G. Knepley PetscCall(PetscFEGetBasisSpace(fe, &P)); 2228*bb4b53efSMatthew G. Knepley PetscCall(PetscSpaceGetNumVariables(P, &dim)); 2229*bb4b53efSMatthew G. Knepley PetscCall(PetscSpaceGetNumComponents(P, &Nc)); 2230*bb4b53efSMatthew G. Knepley PetscCall(PetscDualSpaceGetDM(Q, &K)); 2231*bb4b53efSMatthew G. Knepley PetscCall(DMPlexGetCellType(K, 0, &ct)); 2232*bb4b53efSMatthew G. Knepley PetscCall(PetscFECreateLagrangeByCell(PetscObjectComm((PetscObject)fe), dim, Nc, ct, k, PETSC_DETERMINE, newfe)); 2233*bb4b53efSMatthew G. Knepley PetscCall(PetscFEGetQuadrature(fe, &q)); 2234*bb4b53efSMatthew G. Knepley PetscCall(PetscFESetQuadrature(*newfe, q)); 2235*bb4b53efSMatthew G. Knepley } else { 2236*bb4b53efSMatthew G. Knepley PetscCall(PetscObjectReference((PetscObject)fe)); 2237*bb4b53efSMatthew G. Knepley *newfe = fe; 2238*bb4b53efSMatthew G. Knepley } 2239*bb4b53efSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 2240*bb4b53efSMatthew G. Knepley } 2241*bb4b53efSMatthew G. Knepley 2242*bb4b53efSMatthew G. Knepley /*@ 224320f4b53cSBarry Smith PetscFESetName - Names the `PetscFE` and its subobjects 22443f6b16c7SMatthew G. Knepley 224520f4b53cSBarry Smith Not Collective 22463f6b16c7SMatthew G. Knepley 22473f6b16c7SMatthew G. Knepley Input Parameters: 224820f4b53cSBarry Smith + fe - The `PetscFE` 22493f6b16c7SMatthew G. Knepley - name - The name 22503f6b16c7SMatthew G. Knepley 22512b99622eSMatthew G. Knepley Level: intermediate 22523f6b16c7SMatthew G. Knepley 2253db781477SPatrick Sanan .seealso: `PetscFECreate()`, `PetscSpaceCreate()`, `PetscDualSpaceCreate()` 22543f6b16c7SMatthew G. Knepley @*/ 2255d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFESetName(PetscFE fe, const char name[]) 2256d71ae5a4SJacob Faibussowitsch { 22573f6b16c7SMatthew G. Knepley PetscSpace P; 22583f6b16c7SMatthew G. Knepley PetscDualSpace Q; 22593f6b16c7SMatthew G. Knepley 22603f6b16c7SMatthew G. Knepley PetscFunctionBegin; 22619566063dSJacob Faibussowitsch PetscCall(PetscFEGetBasisSpace(fe, &P)); 22629566063dSJacob Faibussowitsch PetscCall(PetscFEGetDualSpace(fe, &Q)); 22639566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)fe, name)); 22649566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)P, name)); 22659566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)Q, name)); 22663ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 22673f6b16c7SMatthew G. Knepley } 2268a8f1f9e5SMatthew G. Knepley 2269d71ae5a4SJacob Faibussowitsch 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[]) 2270d71ae5a4SJacob Faibussowitsch { 2271f9244615SMatthew G. Knepley PetscInt dOffset = 0, fOffset = 0, f, g; 2272a8f1f9e5SMatthew G. Knepley 2273a8f1f9e5SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 227426add6b9SMatthew G. Knepley PetscCheck(r < T[f]->Nr, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Replica number %" PetscInt_FMT " should be in [0, %" PetscInt_FMT ")", r, T[f]->Nr); 227526add6b9SMatthew G. Knepley PetscCheck(q < T[f]->Np, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Point number %" PetscInt_FMT " should be in [0, %" PetscInt_FMT ")", q, T[f]->Np); 2276a8f1f9e5SMatthew G. Knepley PetscFE fe; 2277f9244615SMatthew G. Knepley const PetscInt k = ds->jetDegree[f]; 2278ef0bb6c7SMatthew G. Knepley const PetscInt cdim = T[f]->cdim; 22792b6f951bSStefano Zampini const PetscInt dE = fegeom->dimEmbed; 2280ef0bb6c7SMatthew G. Knepley const PetscInt Nq = T[f]->Np; 2281ef0bb6c7SMatthew G. Knepley const PetscInt Nbf = T[f]->Nb; 2282ef0bb6c7SMatthew G. Knepley const PetscInt Ncf = T[f]->Nc; 2283ef0bb6c7SMatthew G. Knepley const PetscReal *Bq = &T[f]->T[0][(r * Nq + q) * Nbf * Ncf]; 2284ef0bb6c7SMatthew G. Knepley const PetscReal *Dq = &T[f]->T[1][(r * Nq + q) * Nbf * Ncf * cdim]; 2285f9244615SMatthew G. Knepley const PetscReal *Hq = k > 1 ? &T[f]->T[2][(r * Nq + q) * Nbf * Ncf * cdim * cdim] : NULL; 2286f9244615SMatthew G. Knepley PetscInt hOffset = 0, b, c, d; 2287a8f1f9e5SMatthew G. Knepley 22889566063dSJacob Faibussowitsch PetscCall(PetscDSGetDiscretization(ds, f, (PetscObject *)&fe)); 2289a8f1f9e5SMatthew G. Knepley for (c = 0; c < Ncf; ++c) u[fOffset + c] = 0.0; 22902b6f951bSStefano Zampini for (d = 0; d < dE * Ncf; ++d) u_x[fOffset * dE + d] = 0.0; 2291a8f1f9e5SMatthew G. Knepley for (b = 0; b < Nbf; ++b) { 2292a8f1f9e5SMatthew G. Knepley for (c = 0; c < Ncf; ++c) { 2293a8f1f9e5SMatthew G. Knepley const PetscInt cidx = b * Ncf + c; 2294a8f1f9e5SMatthew G. Knepley 2295a8f1f9e5SMatthew G. Knepley u[fOffset + c] += Bq[cidx] * coefficients[dOffset + b]; 22962b6f951bSStefano Zampini for (d = 0; d < cdim; ++d) u_x[(fOffset + c) * dE + d] += Dq[cidx * cdim + d] * coefficients[dOffset + b]; 2297a8f1f9e5SMatthew G. Knepley } 2298a8f1f9e5SMatthew G. Knepley } 2299f9244615SMatthew G. Knepley if (k > 1) { 23002b6f951bSStefano Zampini for (g = 0; g < Nf; ++g) hOffset += T[g]->Nc * dE; 23012b6f951bSStefano Zampini for (d = 0; d < dE * dE * Ncf; ++d) u_x[hOffset + fOffset * dE * dE + d] = 0.0; 2302f9244615SMatthew G. Knepley for (b = 0; b < Nbf; ++b) { 2303f9244615SMatthew G. Knepley for (c = 0; c < Ncf; ++c) { 2304f9244615SMatthew G. Knepley const PetscInt cidx = b * Ncf + c; 2305f9244615SMatthew G. Knepley 23062b6f951bSStefano Zampini for (d = 0; d < cdim * cdim; ++d) u_x[hOffset + (fOffset + c) * dE * dE + d] += Hq[cidx * cdim * cdim + d] * coefficients[dOffset + b]; 2307f9244615SMatthew G. Knepley } 2308f9244615SMatthew G. Knepley } 23092b6f951bSStefano Zampini PetscCall(PetscFEPushforwardHessian(fe, fegeom, 1, &u_x[hOffset + fOffset * dE * dE])); 2310f9244615SMatthew G. Knepley } 23119566063dSJacob Faibussowitsch PetscCall(PetscFEPushforward(fe, fegeom, 1, &u[fOffset])); 23122b6f951bSStefano Zampini PetscCall(PetscFEPushforwardGradient(fe, fegeom, 1, &u_x[fOffset * dE])); 2313a8f1f9e5SMatthew G. Knepley if (u_t) { 2314a8f1f9e5SMatthew G. Knepley for (c = 0; c < Ncf; ++c) u_t[fOffset + c] = 0.0; 2315a8f1f9e5SMatthew G. Knepley for (b = 0; b < Nbf; ++b) { 2316a8f1f9e5SMatthew G. Knepley for (c = 0; c < Ncf; ++c) { 2317a8f1f9e5SMatthew G. Knepley const PetscInt cidx = b * Ncf + c; 2318a8f1f9e5SMatthew G. Knepley 2319a8f1f9e5SMatthew G. Knepley u_t[fOffset + c] += Bq[cidx] * coefficients_t[dOffset + b]; 2320a8f1f9e5SMatthew G. Knepley } 2321a8f1f9e5SMatthew G. Knepley } 23229566063dSJacob Faibussowitsch PetscCall(PetscFEPushforward(fe, fegeom, 1, &u_t[fOffset])); 2323a8f1f9e5SMatthew G. Knepley } 2324a8f1f9e5SMatthew G. Knepley fOffset += Ncf; 2325a8f1f9e5SMatthew G. Knepley dOffset += Nbf; 2326a8f1f9e5SMatthew G. Knepley } 23273ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 2328a8f1f9e5SMatthew G. Knepley } 2329a8f1f9e5SMatthew G. Knepley 233007218a29SMatthew G. Knepley PetscErrorCode PetscFEEvaluateFieldJets_Hybrid_Internal(PetscDS ds, PetscInt Nf, PetscInt rc, PetscInt qc, PetscTabulation Tab[], const PetscInt rf[], const PetscInt qf[], PetscTabulation Tabf[], PetscFEGeom *fegeom, const PetscScalar coefficients[], const PetscScalar coefficients_t[], PetscScalar u[], PetscScalar u_x[], PetscScalar u_t[]) 2331d71ae5a4SJacob Faibussowitsch { 23325fedec97SMatthew G. Knepley PetscInt dOffset = 0, fOffset = 0, f, g; 233327f02ce8SMatthew G. Knepley 23345fedec97SMatthew G. Knepley /* f is the field number in the DS, g is the field number in u[] */ 23355fedec97SMatthew G. Knepley for (f = 0, g = 0; f < Nf; ++f) { 23365fedec97SMatthew G. Knepley PetscBool isCohesive; 23375fedec97SMatthew G. Knepley PetscInt Ns, s; 23385fedec97SMatthew G. Knepley 233907218a29SMatthew G. Knepley if (!Tab[f]) continue; 23409566063dSJacob Faibussowitsch PetscCall(PetscDSGetCohesive(ds, f, &isCohesive)); 23415fedec97SMatthew G. Knepley Ns = isCohesive ? 1 : 2; 234207218a29SMatthew G. Knepley { 234307218a29SMatthew G. Knepley PetscTabulation T = isCohesive ? Tab[f] : Tabf[f]; 234407218a29SMatthew G. Knepley PetscFE fe = (PetscFE)ds->disc[f]; 234507218a29SMatthew G. Knepley const PetscInt dEt = T->cdim; 234607218a29SMatthew G. Knepley const PetscInt dE = fegeom->dimEmbed; 234707218a29SMatthew G. Knepley const PetscInt Nq = T->Np; 234807218a29SMatthew G. Knepley const PetscInt Nbf = T->Nb; 234907218a29SMatthew G. Knepley const PetscInt Ncf = T->Nc; 235007218a29SMatthew G. Knepley 23515fedec97SMatthew G. Knepley for (s = 0; s < Ns; ++s, ++g) { 235207218a29SMatthew G. Knepley const PetscInt r = isCohesive ? rc : rf[s]; 235307218a29SMatthew G. Knepley const PetscInt q = isCohesive ? qc : qf[s]; 235407218a29SMatthew G. Knepley const PetscReal *Bq = &T->T[0][(r * Nq + q) * Nbf * Ncf]; 235507218a29SMatthew G. Knepley const PetscReal *Dq = &T->T[1][(r * Nq + q) * Nbf * Ncf * dEt]; 235627f02ce8SMatthew G. Knepley PetscInt b, c, d; 235727f02ce8SMatthew G. Knepley 235807218a29SMatthew G. Knepley PetscCheck(r < T->Nr, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field %" PetscInt_FMT " Side %" PetscInt_FMT " Replica number %" PetscInt_FMT " should be in [0, %" PetscInt_FMT ")", f, s, r, T->Nr); 235907218a29SMatthew G. Knepley PetscCheck(q < T->Np, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field %" PetscInt_FMT " Side %" PetscInt_FMT " Point number %" PetscInt_FMT " should be in [0, %" PetscInt_FMT ")", f, s, q, T->Np); 236027f02ce8SMatthew G. Knepley for (c = 0; c < Ncf; ++c) u[fOffset + c] = 0.0; 23619ee2af8cSMatthew G. Knepley for (d = 0; d < dE * Ncf; ++d) u_x[fOffset * dE + d] = 0.0; 236227f02ce8SMatthew G. Knepley for (b = 0; b < Nbf; ++b) { 236327f02ce8SMatthew G. Knepley for (c = 0; c < Ncf; ++c) { 236427f02ce8SMatthew G. Knepley const PetscInt cidx = b * Ncf + c; 236527f02ce8SMatthew G. Knepley 236627f02ce8SMatthew G. Knepley u[fOffset + c] += Bq[cidx] * coefficients[dOffset + b]; 23679ee2af8cSMatthew G. Knepley for (d = 0; d < dEt; ++d) u_x[(fOffset + c) * dE + d] += Dq[cidx * dEt + d] * coefficients[dOffset + b]; 236827f02ce8SMatthew G. Knepley } 236927f02ce8SMatthew G. Knepley } 23709566063dSJacob Faibussowitsch PetscCall(PetscFEPushforward(fe, fegeom, 1, &u[fOffset])); 23719566063dSJacob Faibussowitsch PetscCall(PetscFEPushforwardGradient(fe, fegeom, 1, &u_x[fOffset * dE])); 237227f02ce8SMatthew G. Knepley if (u_t) { 237327f02ce8SMatthew G. Knepley for (c = 0; c < Ncf; ++c) u_t[fOffset + c] = 0.0; 237427f02ce8SMatthew G. Knepley for (b = 0; b < Nbf; ++b) { 237527f02ce8SMatthew G. Knepley for (c = 0; c < Ncf; ++c) { 237627f02ce8SMatthew G. Knepley const PetscInt cidx = b * Ncf + c; 237727f02ce8SMatthew G. Knepley 237827f02ce8SMatthew G. Knepley u_t[fOffset + c] += Bq[cidx] * coefficients_t[dOffset + b]; 237927f02ce8SMatthew G. Knepley } 238027f02ce8SMatthew G. Knepley } 23819566063dSJacob Faibussowitsch PetscCall(PetscFEPushforward(fe, fegeom, 1, &u_t[fOffset])); 238227f02ce8SMatthew G. Knepley } 238327f02ce8SMatthew G. Knepley fOffset += Ncf; 238427f02ce8SMatthew G. Knepley dOffset += Nbf; 238527f02ce8SMatthew G. Knepley } 2386665f567fSMatthew G. Knepley } 238707218a29SMatthew G. Knepley } 23883ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 238927f02ce8SMatthew G. Knepley } 239027f02ce8SMatthew G. Knepley 2391d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEEvaluateFaceFields_Internal(PetscDS prob, PetscInt field, PetscInt faceLoc, const PetscScalar coefficients[], PetscScalar u[]) 2392d71ae5a4SJacob Faibussowitsch { 2393a8f1f9e5SMatthew G. Knepley PetscFE fe; 2394ef0bb6c7SMatthew G. Knepley PetscTabulation Tc; 2395ef0bb6c7SMatthew G. Knepley PetscInt b, c; 2396a8f1f9e5SMatthew G. Knepley 23973ba16761SJacob Faibussowitsch if (!prob) return PETSC_SUCCESS; 23989566063dSJacob Faibussowitsch PetscCall(PetscDSGetDiscretization(prob, field, (PetscObject *)&fe)); 23999566063dSJacob Faibussowitsch PetscCall(PetscFEGetFaceCentroidTabulation(fe, &Tc)); 2400ef0bb6c7SMatthew G. Knepley { 2401ef0bb6c7SMatthew G. Knepley const PetscReal *faceBasis = Tc->T[0]; 2402ef0bb6c7SMatthew G. Knepley const PetscInt Nb = Tc->Nb; 2403ef0bb6c7SMatthew G. Knepley const PetscInt Nc = Tc->Nc; 2404ef0bb6c7SMatthew G. Knepley 2405ad540459SPierre Jolivet for (c = 0; c < Nc; ++c) u[c] = 0.0; 2406a8f1f9e5SMatthew G. Knepley for (b = 0; b < Nb; ++b) { 2407ad540459SPierre Jolivet for (c = 0; c < Nc; ++c) u[c] += coefficients[b] * faceBasis[(faceLoc * Nb + b) * Nc + c]; 2408a8f1f9e5SMatthew G. Knepley } 2409ef0bb6c7SMatthew G. Knepley } 24103ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 2411a8f1f9e5SMatthew G. Knepley } 2412a8f1f9e5SMatthew G. Knepley 2413d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEUpdateElementVec_Internal(PetscFE fe, PetscTabulation T, PetscInt r, PetscScalar tmpBasis[], PetscScalar tmpBasisDer[], PetscInt e, PetscFEGeom *fegeom, PetscScalar f0[], PetscScalar f1[], PetscScalar elemVec[]) 2414d71ae5a4SJacob Faibussowitsch { 24156587ee25SMatthew G. Knepley PetscFEGeom pgeom; 2416bc3a64adSMatthew G. Knepley const PetscInt dEt = T->cdim; 2417bc3a64adSMatthew G. Knepley const PetscInt dE = fegeom->dimEmbed; 2418ef0bb6c7SMatthew G. Knepley const PetscInt Nq = T->Np; 2419ef0bb6c7SMatthew G. Knepley const PetscInt Nb = T->Nb; 2420ef0bb6c7SMatthew G. Knepley const PetscInt Nc = T->Nc; 2421ef0bb6c7SMatthew G. Knepley const PetscReal *basis = &T->T[0][r * Nq * Nb * Nc]; 2422bc3a64adSMatthew G. Knepley const PetscReal *basisDer = &T->T[1][r * Nq * Nb * Nc * dEt]; 2423a8f1f9e5SMatthew G. Knepley PetscInt q, b, c, d; 2424a8f1f9e5SMatthew G. Knepley 2425a8f1f9e5SMatthew G. Knepley for (q = 0; q < Nq; ++q) { 2426a8f1f9e5SMatthew G. Knepley for (b = 0; b < Nb; ++b) { 2427a8f1f9e5SMatthew G. Knepley for (c = 0; c < Nc; ++c) { 2428a8f1f9e5SMatthew G. Knepley const PetscInt bcidx = b * Nc + c; 2429a8f1f9e5SMatthew G. Knepley 2430a8f1f9e5SMatthew G. Knepley tmpBasis[bcidx] = basis[q * Nb * Nc + bcidx]; 2431bc3a64adSMatthew G. Knepley for (d = 0; d < dEt; ++d) tmpBasisDer[bcidx * dE + d] = basisDer[q * Nb * Nc * dEt + bcidx * dEt + d]; 24329ee2af8cSMatthew G. Knepley for (d = dEt; d < dE; ++d) tmpBasisDer[bcidx * dE + d] = 0.0; 2433a8f1f9e5SMatthew G. Knepley } 2434a8f1f9e5SMatthew G. Knepley } 24359566063dSJacob Faibussowitsch PetscCall(PetscFEGeomGetCellPoint(fegeom, e, q, &pgeom)); 24369566063dSJacob Faibussowitsch PetscCall(PetscFEPushforward(fe, &pgeom, Nb, tmpBasis)); 24379566063dSJacob Faibussowitsch PetscCall(PetscFEPushforwardGradient(fe, &pgeom, Nb, tmpBasisDer)); 2438a8f1f9e5SMatthew G. Knepley for (b = 0; b < Nb; ++b) { 2439a8f1f9e5SMatthew G. Knepley for (c = 0; c < Nc; ++c) { 2440a8f1f9e5SMatthew G. Knepley const PetscInt bcidx = b * Nc + c; 2441a8f1f9e5SMatthew G. Knepley const PetscInt qcidx = q * Nc + c; 2442a8f1f9e5SMatthew G. Knepley 2443a8f1f9e5SMatthew G. Knepley elemVec[b] += tmpBasis[bcidx] * f0[qcidx]; 244427f02ce8SMatthew G. Knepley for (d = 0; d < dE; ++d) elemVec[b] += tmpBasisDer[bcidx * dE + d] * f1[qcidx * dE + d]; 244527f02ce8SMatthew G. Knepley } 244627f02ce8SMatthew G. Knepley } 244727f02ce8SMatthew G. Knepley } 24483ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 244927f02ce8SMatthew G. Knepley } 245027f02ce8SMatthew G. Knepley 24510abb75b6SMatthew G. Knepley PetscErrorCode PetscFEUpdateElementVec_Hybrid_Internal(PetscFE fe, PetscTabulation T, PetscInt r, PetscInt side, PetscScalar tmpBasis[], PetscScalar tmpBasisDer[], PetscFEGeom *fegeom, PetscScalar f0[], PetscScalar f1[], PetscScalar elemVec[]) 2452d71ae5a4SJacob Faibussowitsch { 245327f02ce8SMatthew G. Knepley const PetscInt dE = T->cdim; 245427f02ce8SMatthew G. Knepley const PetscInt Nq = T->Np; 245527f02ce8SMatthew G. Knepley const PetscInt Nb = T->Nb; 245627f02ce8SMatthew G. Knepley const PetscInt Nc = T->Nc; 245727f02ce8SMatthew G. Knepley const PetscReal *basis = &T->T[0][r * Nq * Nb * Nc]; 245827f02ce8SMatthew G. Knepley const PetscReal *basisDer = &T->T[1][r * Nq * Nb * Nc * dE]; 245927f02ce8SMatthew G. Knepley 24600abb75b6SMatthew G. Knepley for (PetscInt q = 0; q < Nq; ++q) { 24610abb75b6SMatthew G. Knepley for (PetscInt b = 0; b < Nb; ++b) { 24620abb75b6SMatthew G. Knepley for (PetscInt c = 0; c < Nc; ++c) { 246327f02ce8SMatthew G. Knepley const PetscInt bcidx = b * Nc + c; 246427f02ce8SMatthew G. Knepley 246527f02ce8SMatthew G. Knepley tmpBasis[bcidx] = basis[q * Nb * Nc + bcidx]; 24660abb75b6SMatthew G. Knepley for (PetscInt d = 0; d < dE; ++d) tmpBasisDer[bcidx * dE + d] = basisDer[q * Nb * Nc * dE + bcidx * dE + d]; 246727f02ce8SMatthew G. Knepley } 246827f02ce8SMatthew G. Knepley } 24699566063dSJacob Faibussowitsch PetscCall(PetscFEPushforward(fe, fegeom, Nb, tmpBasis)); 24702b6f951bSStefano Zampini // TODO This is currently broken since we do not pull the geometry down to the lower dimension 24712b6f951bSStefano Zampini // PetscCall(PetscFEPushforwardGradient(fe, fegeom, Nb, tmpBasisDer)); 24720abb75b6SMatthew G. Knepley if (side == 2) { 24730abb75b6SMatthew G. Knepley // Integrating over whole cohesive cell, so insert for both sides 24740abb75b6SMatthew G. Knepley for (PetscInt s = 0; s < 2; ++s) { 24750abb75b6SMatthew G. Knepley for (PetscInt b = 0; b < Nb; ++b) { 24760abb75b6SMatthew G. Knepley for (PetscInt c = 0; c < Nc; ++c) { 24770abb75b6SMatthew G. Knepley const PetscInt bcidx = b * Nc + c; 24780abb75b6SMatthew G. Knepley const PetscInt qcidx = (q * 2 + s) * Nc + c; 24790abb75b6SMatthew G. Knepley 24800abb75b6SMatthew G. Knepley elemVec[Nb * s + b] += tmpBasis[bcidx] * f0[qcidx]; 24810abb75b6SMatthew G. Knepley for (PetscInt d = 0; d < dE; ++d) elemVec[Nb * s + b] += tmpBasisDer[bcidx * dE + d] * f1[qcidx * dE + d]; 24820abb75b6SMatthew G. Knepley } 24830abb75b6SMatthew G. Knepley } 24840abb75b6SMatthew G. Knepley } 24850abb75b6SMatthew G. Knepley } else { 24860abb75b6SMatthew G. Knepley // Integrating over endcaps of cohesive cell, so insert for correct side 24870abb75b6SMatthew G. Knepley for (PetscInt b = 0; b < Nb; ++b) { 24880abb75b6SMatthew G. Knepley for (PetscInt c = 0; c < Nc; ++c) { 248927f02ce8SMatthew G. Knepley const PetscInt bcidx = b * Nc + c; 2490c2b7495fSMatthew G. Knepley const PetscInt qcidx = q * Nc + c; 249127f02ce8SMatthew G. Knepley 24920abb75b6SMatthew G. Knepley elemVec[Nb * side + b] += tmpBasis[bcidx] * f0[qcidx]; 24930abb75b6SMatthew G. Knepley for (PetscInt d = 0; d < dE; ++d) elemVec[Nb * side + b] += tmpBasisDer[bcidx * dE + d] * f1[qcidx * dE + d]; 24940abb75b6SMatthew G. Knepley } 249527f02ce8SMatthew G. Knepley } 2496a8f1f9e5SMatthew G. Knepley } 2497a8f1f9e5SMatthew G. Knepley } 24983ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 2499a8f1f9e5SMatthew G. Knepley } 2500a8f1f9e5SMatthew G. Knepley 2501d71ae5a4SJacob Faibussowitsch 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[]) 2502d71ae5a4SJacob Faibussowitsch { 25032b6f951bSStefano Zampini const PetscInt cdim = TI->cdim; 25042b6f951bSStefano Zampini const PetscInt dE = fegeom->dimEmbed; 2505ef0bb6c7SMatthew G. Knepley const PetscInt NqI = TI->Np; 2506ef0bb6c7SMatthew G. Knepley const PetscInt NbI = TI->Nb; 2507ef0bb6c7SMatthew G. Knepley const PetscInt NcI = TI->Nc; 2508ef0bb6c7SMatthew G. Knepley const PetscReal *basisI = &TI->T[0][(r * NqI + q) * NbI * NcI]; 25092b6f951bSStefano Zampini const PetscReal *basisDerI = &TI->T[1][(r * NqI + q) * NbI * NcI * cdim]; 2510ef0bb6c7SMatthew G. Knepley const PetscInt NqJ = TJ->Np; 2511ef0bb6c7SMatthew G. Knepley const PetscInt NbJ = TJ->Nb; 2512ef0bb6c7SMatthew G. Knepley const PetscInt NcJ = TJ->Nc; 2513ef0bb6c7SMatthew G. Knepley const PetscReal *basisJ = &TJ->T[0][(r * NqJ + q) * NbJ * NcJ]; 25142b6f951bSStefano Zampini const PetscReal *basisDerJ = &TJ->T[1][(r * NqJ + q) * NbJ * NcJ * cdim]; 2515a8f1f9e5SMatthew G. Knepley PetscInt f, fc, g, gc, df, dg; 2516a8f1f9e5SMatthew G. Knepley 2517a8f1f9e5SMatthew G. Knepley for (f = 0; f < NbI; ++f) { 2518a8f1f9e5SMatthew G. Knepley for (fc = 0; fc < NcI; ++fc) { 2519a8f1f9e5SMatthew G. Knepley const PetscInt fidx = f * NcI + fc; /* Test function basis index */ 2520a8f1f9e5SMatthew G. Knepley 2521a8f1f9e5SMatthew G. Knepley tmpBasisI[fidx] = basisI[fidx]; 25222b6f951bSStefano Zampini for (df = 0; df < cdim; ++df) tmpBasisDerI[fidx * dE + df] = basisDerI[fidx * cdim + df]; 2523a8f1f9e5SMatthew G. Knepley } 2524a8f1f9e5SMatthew G. Knepley } 25259566063dSJacob Faibussowitsch PetscCall(PetscFEPushforward(feI, fegeom, NbI, tmpBasisI)); 25269566063dSJacob Faibussowitsch PetscCall(PetscFEPushforwardGradient(feI, fegeom, NbI, tmpBasisDerI)); 2527a8f1f9e5SMatthew G. Knepley for (g = 0; g < NbJ; ++g) { 2528a8f1f9e5SMatthew G. Knepley for (gc = 0; gc < NcJ; ++gc) { 2529a8f1f9e5SMatthew G. Knepley const PetscInt gidx = g * NcJ + gc; /* Trial function basis index */ 2530a8f1f9e5SMatthew G. Knepley 2531a8f1f9e5SMatthew G. Knepley tmpBasisJ[gidx] = basisJ[gidx]; 25322b6f951bSStefano Zampini for (dg = 0; dg < cdim; ++dg) tmpBasisDerJ[gidx * dE + dg] = basisDerJ[gidx * cdim + dg]; 2533a8f1f9e5SMatthew G. Knepley } 2534a8f1f9e5SMatthew G. Knepley } 25359566063dSJacob Faibussowitsch PetscCall(PetscFEPushforward(feJ, fegeom, NbJ, tmpBasisJ)); 25369566063dSJacob Faibussowitsch PetscCall(PetscFEPushforwardGradient(feJ, fegeom, NbJ, tmpBasisDerJ)); 2537a8f1f9e5SMatthew G. Knepley for (f = 0; f < NbI; ++f) { 2538a8f1f9e5SMatthew G. Knepley for (fc = 0; fc < NcI; ++fc) { 2539a8f1f9e5SMatthew G. Knepley const PetscInt fidx = f * NcI + fc; /* Test function basis index */ 2540a8f1f9e5SMatthew G. Knepley const PetscInt i = offsetI + f; /* Element matrix row */ 2541a8f1f9e5SMatthew G. Knepley for (g = 0; g < NbJ; ++g) { 2542a8f1f9e5SMatthew G. Knepley for (gc = 0; gc < NcJ; ++gc) { 2543a8f1f9e5SMatthew G. Knepley const PetscInt gidx = g * NcJ + gc; /* Trial function basis index */ 2544a8f1f9e5SMatthew G. Knepley const PetscInt j = offsetJ + g; /* Element matrix column */ 2545a8f1f9e5SMatthew G. Knepley const PetscInt fOff = eOffset + i * totDim + j; 2546a8f1f9e5SMatthew G. Knepley 2547a8f1f9e5SMatthew G. Knepley elemMat[fOff] += tmpBasisI[fidx] * g0[fc * NcJ + gc] * tmpBasisJ[gidx]; 254827f02ce8SMatthew G. Knepley for (df = 0; df < dE; ++df) { 254927f02ce8SMatthew G. Knepley elemMat[fOff] += tmpBasisI[fidx] * g1[(fc * NcJ + gc) * dE + df] * tmpBasisDerJ[gidx * dE + df]; 255027f02ce8SMatthew G. Knepley elemMat[fOff] += tmpBasisDerI[fidx * dE + df] * g2[(fc * NcJ + gc) * dE + df] * tmpBasisJ[gidx]; 2551ad540459SPierre Jolivet for (dg = 0; dg < dE; ++dg) elemMat[fOff] += tmpBasisDerI[fidx * dE + df] * g3[((fc * NcJ + gc) * dE + df) * dE + dg] * tmpBasisDerJ[gidx * dE + dg]; 255227f02ce8SMatthew G. Knepley } 255327f02ce8SMatthew G. Knepley } 255427f02ce8SMatthew G. Knepley } 255527f02ce8SMatthew G. Knepley } 255627f02ce8SMatthew G. Knepley } 25573ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 255827f02ce8SMatthew G. Knepley } 255927f02ce8SMatthew G. Knepley 25600abb75b6SMatthew G. Knepley PetscErrorCode PetscFEUpdateElementMat_Hybrid_Internal(PetscFE feI, PetscBool isHybridI, PetscFE feJ, PetscBool isHybridJ, PetscInt r, PetscInt s, PetscInt t, 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[]) 2561d71ae5a4SJacob Faibussowitsch { 2562665f567fSMatthew G. Knepley const PetscInt dE = TI->cdim; 2563665f567fSMatthew G. Knepley const PetscInt NqI = TI->Np; 2564665f567fSMatthew G. Knepley const PetscInt NbI = TI->Nb; 2565665f567fSMatthew G. Knepley const PetscInt NcI = TI->Nc; 2566665f567fSMatthew G. Knepley const PetscReal *basisI = &TI->T[0][(r * NqI + q) * NbI * NcI]; 2567665f567fSMatthew G. Knepley const PetscReal *basisDerI = &TI->T[1][(r * NqI + q) * NbI * NcI * dE]; 2568665f567fSMatthew G. Knepley const PetscInt NqJ = TJ->Np; 2569665f567fSMatthew G. Knepley const PetscInt NbJ = TJ->Nb; 2570665f567fSMatthew G. Knepley const PetscInt NcJ = TJ->Nc; 2571665f567fSMatthew G. Knepley const PetscReal *basisJ = &TJ->T[0][(r * NqJ + q) * NbJ * NcJ]; 2572665f567fSMatthew G. Knepley const PetscReal *basisDerJ = &TJ->T[1][(r * NqJ + q) * NbJ * NcJ * dE]; 25735fedec97SMatthew G. Knepley const PetscInt so = isHybridI ? 0 : s; 25740abb75b6SMatthew G. Knepley const PetscInt to = isHybridJ ? 0 : t; 25755fedec97SMatthew G. Knepley PetscInt f, fc, g, gc, df, dg; 257627f02ce8SMatthew G. Knepley 257727f02ce8SMatthew G. Knepley for (f = 0; f < NbI; ++f) { 257827f02ce8SMatthew G. Knepley for (fc = 0; fc < NcI; ++fc) { 257927f02ce8SMatthew G. Knepley const PetscInt fidx = f * NcI + fc; /* Test function basis index */ 258027f02ce8SMatthew G. Knepley 258127f02ce8SMatthew G. Knepley tmpBasisI[fidx] = basisI[fidx]; 2582665f567fSMatthew G. Knepley for (df = 0; df < dE; ++df) tmpBasisDerI[fidx * dE + df] = basisDerI[fidx * dE + df]; 258327f02ce8SMatthew G. Knepley } 258427f02ce8SMatthew G. Knepley } 25859566063dSJacob Faibussowitsch PetscCall(PetscFEPushforward(feI, fegeom, NbI, tmpBasisI)); 25869566063dSJacob Faibussowitsch PetscCall(PetscFEPushforwardGradient(feI, fegeom, NbI, tmpBasisDerI)); 258727f02ce8SMatthew G. Knepley for (g = 0; g < NbJ; ++g) { 258827f02ce8SMatthew G. Knepley for (gc = 0; gc < NcJ; ++gc) { 258927f02ce8SMatthew G. Knepley const PetscInt gidx = g * NcJ + gc; /* Trial function basis index */ 259027f02ce8SMatthew G. Knepley 259127f02ce8SMatthew G. Knepley tmpBasisJ[gidx] = basisJ[gidx]; 2592665f567fSMatthew G. Knepley for (dg = 0; dg < dE; ++dg) tmpBasisDerJ[gidx * dE + dg] = basisDerJ[gidx * dE + dg]; 259327f02ce8SMatthew G. Knepley } 259427f02ce8SMatthew G. Knepley } 25959566063dSJacob Faibussowitsch PetscCall(PetscFEPushforward(feJ, fegeom, NbJ, tmpBasisJ)); 25962b6f951bSStefano Zampini // TODO This is currently broken since we do not pull the geometry down to the lower dimension 25972b6f951bSStefano Zampini // PetscCall(PetscFEPushforwardGradient(feJ, fegeom, NbJ, tmpBasisDerJ)); 259827f02ce8SMatthew G. Knepley for (f = 0; f < NbI; ++f) { 259927f02ce8SMatthew G. Knepley for (fc = 0; fc < NcI; ++fc) { 260027f02ce8SMatthew G. Knepley const PetscInt fidx = f * NcI + fc; /* Test function basis index */ 26015fedec97SMatthew G. Knepley const PetscInt i = offsetI + NbI * so + f; /* Element matrix row */ 260227f02ce8SMatthew G. Knepley for (g = 0; g < NbJ; ++g) { 260327f02ce8SMatthew G. Knepley for (gc = 0; gc < NcJ; ++gc) { 260427f02ce8SMatthew G. Knepley const PetscInt gidx = g * NcJ + gc; /* Trial function basis index */ 26055fedec97SMatthew G. Knepley const PetscInt j = offsetJ + NbJ * to + g; /* Element matrix column */ 260627f02ce8SMatthew G. Knepley const PetscInt fOff = eOffset + i * totDim + j; 260727f02ce8SMatthew G. Knepley 26085fedec97SMatthew G. Knepley elemMat[fOff] += tmpBasisI[fidx] * g0[fc * NcJ + gc] * tmpBasisJ[gidx]; 260927f02ce8SMatthew G. Knepley for (df = 0; df < dE; ++df) { 26105fedec97SMatthew G. Knepley elemMat[fOff] += tmpBasisI[fidx] * g1[(fc * NcJ + gc) * dE + df] * tmpBasisDerJ[gidx * dE + df]; 26115fedec97SMatthew G. Knepley elemMat[fOff] += tmpBasisDerI[fidx * dE + df] * g2[(fc * NcJ + gc) * dE + df] * tmpBasisJ[gidx]; 2612ad540459SPierre Jolivet for (dg = 0; dg < dE; ++dg) elemMat[fOff] += tmpBasisDerI[fidx * dE + df] * g3[((fc * NcJ + gc) * dE + df) * dE + dg] * tmpBasisDerJ[gidx * dE + dg]; 2613a8f1f9e5SMatthew G. Knepley } 2614a8f1f9e5SMatthew G. Knepley } 2615a8f1f9e5SMatthew G. Knepley } 2616a8f1f9e5SMatthew G. Knepley } 2617a8f1f9e5SMatthew G. Knepley } 26183ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 2619a8f1f9e5SMatthew G. Knepley } 2620c9ba7969SMatthew G. Knepley 2621d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFECreateCellGeometry(PetscFE fe, PetscQuadrature quad, PetscFEGeom *cgeom) 2622d71ae5a4SJacob Faibussowitsch { 2623c9ba7969SMatthew G. Knepley PetscDualSpace dsp; 2624c9ba7969SMatthew G. Knepley DM dm; 2625c9ba7969SMatthew G. Knepley PetscQuadrature quadDef; 2626c9ba7969SMatthew G. Knepley PetscInt dim, cdim, Nq; 2627c9ba7969SMatthew G. Knepley 2628c9ba7969SMatthew G. Knepley PetscFunctionBegin; 26299566063dSJacob Faibussowitsch PetscCall(PetscFEGetDualSpace(fe, &dsp)); 26309566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetDM(dsp, &dm)); 26319566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &dim)); 26329566063dSJacob Faibussowitsch PetscCall(DMGetCoordinateDim(dm, &cdim)); 26339566063dSJacob Faibussowitsch PetscCall(PetscFEGetQuadrature(fe, &quadDef)); 2634c9ba7969SMatthew G. Knepley quad = quad ? quad : quadDef; 26359566063dSJacob Faibussowitsch PetscCall(PetscQuadratureGetData(quad, NULL, NULL, &Nq, NULL, NULL)); 26369566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(Nq * cdim, &cgeom->v)); 26379566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(Nq * cdim * cdim, &cgeom->J)); 26389566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(Nq * cdim * cdim, &cgeom->invJ)); 26399566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(Nq, &cgeom->detJ)); 2640c9ba7969SMatthew G. Knepley cgeom->dim = dim; 2641c9ba7969SMatthew G. Knepley cgeom->dimEmbed = cdim; 2642c9ba7969SMatthew G. Knepley cgeom->numCells = 1; 2643c9ba7969SMatthew G. Knepley cgeom->numPoints = Nq; 26449566063dSJacob Faibussowitsch PetscCall(DMPlexComputeCellGeometryFEM(dm, 0, quad, cgeom->v, cgeom->J, cgeom->invJ, cgeom->detJ)); 26453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2646c9ba7969SMatthew G. Knepley } 2647c9ba7969SMatthew G. Knepley 2648d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEDestroyCellGeometry(PetscFE fe, PetscFEGeom *cgeom) 2649d71ae5a4SJacob Faibussowitsch { 2650c9ba7969SMatthew G. Knepley PetscFunctionBegin; 26519566063dSJacob Faibussowitsch PetscCall(PetscFree(cgeom->v)); 26529566063dSJacob Faibussowitsch PetscCall(PetscFree(cgeom->J)); 26539566063dSJacob Faibussowitsch PetscCall(PetscFree(cgeom->invJ)); 26549566063dSJacob Faibussowitsch PetscCall(PetscFree(cgeom->detJ)); 26553ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2656c9ba7969SMatthew G. Knepley } 2657