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 166ce78bad3SBarry Smith . obj - Optional object that provides the options prefix, pass `NULL` to use the options prefix of `A` 167dce8aebaSBarry Smith - name - command line option name 168fe2efc57SMark 169fe2efc57SMark Level: intermediate 170dce8aebaSBarry Smith 171dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscFEView()`, `PetscObjectViewFromOptions()`, `PetscFECreate()` 172fe2efc57SMark @*/ 173ce78bad3SBarry Smith PetscErrorCode PetscFEViewFromOptions(PetscFE A, PeOp 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 { 1969f196a02SMartin Diehl PetscBool isascii; 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)); 2039f196a02SMartin Diehl PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii)); 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 222bfe80ac4SPierre Jolivet .seealso: `PetscFE`, `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: 482ce78bad3SBarry Smith + blockSize - The number of elements in a block, pass `NULL` if not needed 483ce78bad3SBarry Smith . numBlocks - The number of blocks in a batch, pass `NULL` if not needed 484ce78bad3SBarry Smith . batchSize - The number of elements in a batch, pass `NULL` if not needed 485ce78bad3SBarry Smith - numBatches - The number of batches in a chunk, pass `NULL` if not needed 48620cf1dd8SToby Isaac 48720cf1dd8SToby Isaac Level: intermediate 48820cf1dd8SToby Isaac 489dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscFECreate()`, `PetscFESetTileSizes()` 49020cf1dd8SToby Isaac @*/ 491ce78bad3SBarry Smith PetscErrorCode PetscFEGetTileSizes(PetscFE fem, PeOp PetscInt *blockSize, PeOp PetscInt *numBlocks, PeOp PetscInt *batchSize, PeOp 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 806989fa639SBrad Aagaard PetscErrorCode PetscFEExpandFaceQuadrature(PetscFE fe, PetscQuadrature fq, PetscQuadrature *efq) 807989fa639SBrad Aagaard { 808989fa639SBrad Aagaard DM dm; 809989fa639SBrad Aagaard PetscDualSpace sp; 810989fa639SBrad Aagaard const PetscInt *faces; 811989fa639SBrad Aagaard const PetscReal *points, *weights; 812989fa639SBrad Aagaard DMPolytopeType ct; 813989fa639SBrad Aagaard PetscReal *facePoints, *faceWeights; 814989fa639SBrad Aagaard PetscInt dim, cStart, Nf, Nc, Np, order; 815989fa639SBrad Aagaard 816989fa639SBrad Aagaard PetscFunctionBegin; 817989fa639SBrad Aagaard PetscCall(PetscFEGetDualSpace(fe, &sp)); 818989fa639SBrad Aagaard PetscCall(PetscDualSpaceGetDM(sp, &dm)); 819989fa639SBrad Aagaard PetscCall(DMGetDimension(dm, &dim)); 820989fa639SBrad Aagaard PetscCall(DMPlexGetHeightStratum(dm, 0, &cStart, NULL)); 821989fa639SBrad Aagaard PetscCall(DMPlexGetConeSize(dm, cStart, &Nf)); 822989fa639SBrad Aagaard PetscCall(DMPlexGetCone(dm, cStart, &faces)); 823989fa639SBrad Aagaard PetscCall(PetscQuadratureGetData(fq, NULL, &Nc, &Np, &points, &weights)); 824989fa639SBrad Aagaard PetscCall(PetscMalloc1(Nf * Np * dim, &facePoints)); 825989fa639SBrad Aagaard PetscCall(PetscMalloc1(Nf * Np * Nc, &faceWeights)); 826989fa639SBrad Aagaard for (PetscInt f = 0; f < Nf; ++f) { 827989fa639SBrad Aagaard const PetscReal xi0[3] = {-1., -1., -1.}; 828989fa639SBrad Aagaard PetscReal v0[3], J[9], detJ; 829989fa639SBrad Aagaard 830989fa639SBrad Aagaard PetscCall(DMPlexComputeCellGeometryFEM(dm, faces[f], NULL, v0, J, NULL, &detJ)); 831989fa639SBrad Aagaard for (PetscInt q = 0; q < Np; ++q) { 832989fa639SBrad Aagaard CoordinatesRefToReal(dim, dim - 1, xi0, v0, J, &points[q * (dim - 1)], &facePoints[(f * Np + q) * dim]); 833989fa639SBrad Aagaard for (PetscInt c = 0; c < Nc; ++c) faceWeights[(f * Np + q) * Nc + c] = weights[q * Nc + c]; 834989fa639SBrad Aagaard } 835989fa639SBrad Aagaard } 836989fa639SBrad Aagaard PetscCall(PetscQuadratureCreate(PetscObjectComm((PetscObject)fq), efq)); 837989fa639SBrad Aagaard PetscCall(PetscQuadratureGetCellType(fq, &ct)); 838989fa639SBrad Aagaard PetscCall(PetscQuadratureSetCellType(*efq, ct)); 839989fa639SBrad Aagaard PetscCall(PetscQuadratureGetOrder(fq, &order)); 840989fa639SBrad Aagaard PetscCall(PetscQuadratureSetOrder(*efq, order)); 841989fa639SBrad Aagaard PetscCall(PetscQuadratureSetData(*efq, dim, Nc, Nf * Np, facePoints, faceWeights)); 842989fa639SBrad Aagaard PetscFunctionReturn(PETSC_SUCCESS); 843989fa639SBrad Aagaard } 844989fa639SBrad Aagaard 8452b99622eSMatthew G. Knepley /*@C 846ef0bb6c7SMatthew G. Knepley PetscFEGetFaceTabulation - Returns the tabulation of the basis functions at the face quadrature points for each face of the reference cell 8472b99622eSMatthew G. Knepley 84820f4b53cSBarry Smith Not Collective 8492b99622eSMatthew G. Knepley 850d8d19677SJose E. Roman Input Parameters: 851dce8aebaSBarry Smith + fem - The `PetscFE` object 852f9244615SMatthew G. Knepley - k - The highest derivative we need to tabulate, very often 1 8532b99622eSMatthew G. Knepley 8542fe279fdSBarry Smith Output Parameter: 855a5b23f4aSJose E. Roman . Tf - The basis function values and derivatives at face quadrature points 8562b99622eSMatthew G. Knepley 8572b99622eSMatthew G. Knepley Level: intermediate 8582b99622eSMatthew G. Knepley 859dce8aebaSBarry Smith Note: 860dce8aebaSBarry Smith .vb 861dce8aebaSBarry 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 862dce8aebaSBarry 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 863dce8aebaSBarry 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 864dce8aebaSBarry Smith .ve 865dce8aebaSBarry Smith 866dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscSpace`, `PetscDualSpace`, `PetscTabulation`, `PetscFEGetCellTabulation()`, `PetscFECreateTabulation()`, `PetscTabulationDestroy()` 8672b99622eSMatthew G. Knepley @*/ 868d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEGetFaceTabulation(PetscFE fem, PetscInt k, PetscTabulation *Tf) 869d71ae5a4SJacob Faibussowitsch { 87020cf1dd8SToby Isaac PetscFunctionBegin; 87120cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 8724f572ea9SToby Isaac PetscAssertPointer(Tf, 3); 873ef0bb6c7SMatthew G. Knepley if (!fem->Tf) { 87420cf1dd8SToby Isaac PetscQuadrature fq; 875989fa639SBrad Aagaard 876989fa639SBrad Aagaard PetscCall(PetscFEGetFaceQuadrature(fem, &fq)); 877989fa639SBrad Aagaard if (fq) { 878989fa639SBrad Aagaard PetscQuadrature efq; 879989fa639SBrad Aagaard const PetscReal *facePoints; 880989fa639SBrad Aagaard PetscInt Np, eNp; 881989fa639SBrad Aagaard 882989fa639SBrad Aagaard PetscCall(PetscFEExpandFaceQuadrature(fem, fq, &efq)); 883989fa639SBrad Aagaard PetscCall(PetscQuadratureGetData(fq, NULL, NULL, &Np, NULL, NULL)); 884989fa639SBrad Aagaard PetscCall(PetscQuadratureGetData(efq, NULL, NULL, &eNp, &facePoints, NULL)); 885989fa639SBrad Aagaard if (PetscDefined(USE_DEBUG)) { 88620cf1dd8SToby Isaac PetscDualSpace sp; 88720cf1dd8SToby Isaac DM dm; 888989fa639SBrad Aagaard PetscInt cStart, Nf; 88920cf1dd8SToby Isaac 8909566063dSJacob Faibussowitsch PetscCall(PetscFEGetDualSpace(fem, &sp)); 8919566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetDM(sp, &dm)); 892989fa639SBrad Aagaard PetscCall(DMPlexGetHeightStratum(dm, 0, &cStart, NULL)); 893989fa639SBrad Aagaard PetscCall(DMPlexGetConeSize(dm, cStart, &Nf)); 894989fa639SBrad Aagaard PetscCheck(Nf == eNp / Np, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Number of faces %" PetscInt_FMT " != %" PetscInt_FMT " number of quadrature replicas", Nf, eNp / Np); 89520cf1dd8SToby Isaac } 896989fa639SBrad Aagaard PetscCall(PetscFECreateTabulation(fem, eNp / Np, Np, facePoints, k, &fem->Tf)); 897989fa639SBrad Aagaard PetscCall(PetscQuadratureDestroy(&efq)); 89820cf1dd8SToby Isaac } 89920cf1dd8SToby Isaac } 9001dca8a05SBarry 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); 901ef0bb6c7SMatthew G. Knepley *Tf = fem->Tf; 9023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 90320cf1dd8SToby Isaac } 90420cf1dd8SToby Isaac 9052b99622eSMatthew G. Knepley /*@C 906ef0bb6c7SMatthew G. Knepley PetscFEGetFaceCentroidTabulation - Returns the tabulation of the basis functions at the face centroid points 9072b99622eSMatthew G. Knepley 90820f4b53cSBarry Smith Not Collective 9092b99622eSMatthew G. Knepley 9102b99622eSMatthew G. Knepley Input Parameter: 911dce8aebaSBarry Smith . fem - The `PetscFE` object 9122b99622eSMatthew G. Knepley 9132fe279fdSBarry Smith Output Parameter: 914ef0bb6c7SMatthew G. Knepley . Tc - The basis function values at face centroid points 9152b99622eSMatthew G. Knepley 9162b99622eSMatthew G. Knepley Level: intermediate 9172b99622eSMatthew G. Knepley 918dce8aebaSBarry Smith Note: 919dce8aebaSBarry Smith .vb 920dce8aebaSBarry Smith T->T[0] = Bf[(f*pdim + i)*Nc + c] is the value at point f for basis function i and component c 921dce8aebaSBarry Smith .ve 922dce8aebaSBarry Smith 923dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscSpace`, `PetscDualSpace`, `PetscTabulation`, `PetscFEGetFaceTabulation()`, `PetscFEGetCellTabulation()`, `PetscFECreateTabulation()`, `PetscTabulationDestroy()` 9242b99622eSMatthew G. Knepley @*/ 925d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEGetFaceCentroidTabulation(PetscFE fem, PetscTabulation *Tc) 926d71ae5a4SJacob Faibussowitsch { 92720cf1dd8SToby Isaac PetscFunctionBegin; 92820cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 9294f572ea9SToby Isaac PetscAssertPointer(Tc, 2); 930ef0bb6c7SMatthew G. Knepley if (!fem->Tc) { 93120cf1dd8SToby Isaac PetscDualSpace sp; 93220cf1dd8SToby Isaac DM dm; 93320cf1dd8SToby Isaac const PetscInt *cone; 93420cf1dd8SToby Isaac PetscReal *centroids; 93520cf1dd8SToby Isaac PetscInt dim, numFaces, f; 93620cf1dd8SToby Isaac 9379566063dSJacob Faibussowitsch PetscCall(PetscFEGetDualSpace(fem, &sp)); 9389566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetDM(sp, &dm)); 9399566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &dim)); 9409566063dSJacob Faibussowitsch PetscCall(DMPlexGetConeSize(dm, 0, &numFaces)); 9419566063dSJacob Faibussowitsch PetscCall(DMPlexGetCone(dm, 0, &cone)); 9429566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(numFaces * dim, ¢roids)); 9439566063dSJacob Faibussowitsch for (f = 0; f < numFaces; ++f) PetscCall(DMPlexComputeCellGeometryFVM(dm, cone[f], NULL, ¢roids[f * dim], NULL)); 9449566063dSJacob Faibussowitsch PetscCall(PetscFECreateTabulation(fem, 1, numFaces, centroids, 0, &fem->Tc)); 9459566063dSJacob Faibussowitsch PetscCall(PetscFree(centroids)); 94620cf1dd8SToby Isaac } 947ef0bb6c7SMatthew G. Knepley *Tc = fem->Tc; 9483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 94920cf1dd8SToby Isaac } 95020cf1dd8SToby Isaac 95120cf1dd8SToby Isaac /*@C 952ef0bb6c7SMatthew G. Knepley PetscFECreateTabulation - Tabulates the basis functions, and perhaps derivatives, at the points provided. 95320cf1dd8SToby Isaac 95420f4b53cSBarry Smith Not Collective 95520cf1dd8SToby Isaac 95620cf1dd8SToby Isaac Input Parameters: 957dce8aebaSBarry Smith + fem - The `PetscFE` object 958ef0bb6c7SMatthew G. Knepley . nrepl - The number of replicas 959ef0bb6c7SMatthew G. Knepley . npoints - The number of tabulation points in a replica 960ef0bb6c7SMatthew G. Knepley . points - The tabulation point coordinates 961ef0bb6c7SMatthew G. Knepley - K - The number of derivatives calculated 96220cf1dd8SToby Isaac 963ef0bb6c7SMatthew G. Knepley Output Parameter: 964ef0bb6c7SMatthew G. Knepley . T - The basis function values and derivatives at tabulation points 96520cf1dd8SToby Isaac 96620cf1dd8SToby Isaac Level: intermediate 96720cf1dd8SToby Isaac 968dce8aebaSBarry Smith Note: 969dce8aebaSBarry Smith .vb 970dce8aebaSBarry Smith T->T[0] = B[(p*pdim + i)*Nc + c] is the value at point p for basis function i and component c 971dce8aebaSBarry 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 972a4e35b19SJacob Faibussowitsch T->T[2] = H[(((p*pdim + i)*Nc + c)*dim + d)*dim + e] is the value at point p for basis 973a4e35b19SJacob Faibussowitsch T->function i, component c, in directions d and e 974a4e35b19SJacob Faibussowitsch .ve 975dce8aebaSBarry Smith 976dce8aebaSBarry Smith .seealso: `PetscTabulation`, `PetscFEGetCellTabulation()`, `PetscTabulationDestroy()` 97720cf1dd8SToby Isaac @*/ 978d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFECreateTabulation(PetscFE fem, PetscInt nrepl, PetscInt npoints, const PetscReal points[], PetscInt K, PetscTabulation *T) 979d71ae5a4SJacob Faibussowitsch { 98020cf1dd8SToby Isaac DM dm; 981ef0bb6c7SMatthew G. Knepley PetscDualSpace Q; 982ef0bb6c7SMatthew G. Knepley PetscInt Nb; /* Dimension of FE space P */ 983ef0bb6c7SMatthew G. Knepley PetscInt Nc; /* Field components */ 984ef0bb6c7SMatthew G. Knepley PetscInt cdim; /* Reference coordinate dimension */ 985ef0bb6c7SMatthew G. Knepley PetscInt k; 98620cf1dd8SToby Isaac 98720cf1dd8SToby Isaac PetscFunctionBegin; 988ef0bb6c7SMatthew G. Knepley if (!npoints || !fem->dualSpace || K < 0) { 989ef0bb6c7SMatthew G. Knepley *T = NULL; 9903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 99120cf1dd8SToby Isaac } 99220cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 9934f572ea9SToby Isaac PetscAssertPointer(points, 4); 9944f572ea9SToby Isaac PetscAssertPointer(T, 6); 9959566063dSJacob Faibussowitsch PetscCall(PetscFEGetDualSpace(fem, &Q)); 9969566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetDM(Q, &dm)); 9979566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &cdim)); 9989566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetDimension(Q, &Nb)); 9999566063dSJacob Faibussowitsch PetscCall(PetscFEGetNumComponents(fem, &Nc)); 10009566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(1, T)); 1001ef0bb6c7SMatthew G. Knepley (*T)->K = !cdim ? 0 : K; 1002ef0bb6c7SMatthew G. Knepley (*T)->Nr = nrepl; 1003ef0bb6c7SMatthew G. Knepley (*T)->Np = npoints; 1004ef0bb6c7SMatthew G. Knepley (*T)->Nb = Nb; 1005ef0bb6c7SMatthew G. Knepley (*T)->Nc = Nc; 1006ef0bb6c7SMatthew G. Knepley (*T)->cdim = cdim; 10079566063dSJacob Faibussowitsch PetscCall(PetscMalloc1((*T)->K + 1, &(*T)->T)); 10082dce792eSToby Isaac for (k = 0; k <= (*T)->K; ++k) PetscCall(PetscCalloc1(nrepl * npoints * Nb * Nc * PetscPowInt(cdim, k), &(*T)->T[k])); 1009ce78bad3SBarry Smith PetscUseTypeMethod(fem, computetabulation, nrepl * npoints, points, K, *T); 10103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 101120cf1dd8SToby Isaac } 101220cf1dd8SToby Isaac 10132b99622eSMatthew G. Knepley /*@C 1014ef0bb6c7SMatthew G. Knepley PetscFEComputeTabulation - Tabulates the basis functions, and perhaps derivatives, at the points provided. 10152b99622eSMatthew G. Knepley 101620f4b53cSBarry Smith Not Collective 10172b99622eSMatthew G. Knepley 10182b99622eSMatthew G. Knepley Input Parameters: 1019dce8aebaSBarry Smith + fem - The `PetscFE` object 10202b99622eSMatthew G. Knepley . npoints - The number of tabulation points 10212b99622eSMatthew G. Knepley . points - The tabulation point coordinates 1022ef0bb6c7SMatthew G. Knepley . K - The number of derivatives calculated 1023ef0bb6c7SMatthew G. Knepley - T - An existing tabulation object with enough allocated space 1024ef0bb6c7SMatthew G. Knepley 1025ef0bb6c7SMatthew G. Knepley Output Parameter: 1026ef0bb6c7SMatthew G. Knepley . T - The basis function values and derivatives at tabulation points 10272b99622eSMatthew G. Knepley 10282b99622eSMatthew G. Knepley Level: intermediate 10292b99622eSMatthew G. Knepley 1030dce8aebaSBarry Smith Note: 1031dce8aebaSBarry Smith .vb 1032dce8aebaSBarry Smith T->T[0] = B[(p*pdim + i)*Nc + c] is the value at point p for basis function i and component c 1033dce8aebaSBarry 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 1034dce8aebaSBarry 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 1035dce8aebaSBarry Smith .ve 1036dce8aebaSBarry Smith 1037dce8aebaSBarry Smith .seealso: `PetscTabulation`, `PetscFEGetCellTabulation()`, `PetscTabulationDestroy()` 10382b99622eSMatthew G. Knepley @*/ 1039d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEComputeTabulation(PetscFE fem, PetscInt npoints, const PetscReal points[], PetscInt K, PetscTabulation T) 1040d71ae5a4SJacob Faibussowitsch { 1041ef0bb6c7SMatthew G. Knepley PetscFunctionBeginHot; 10423ba16761SJacob Faibussowitsch if (!npoints || !fem->dualSpace || K < 0) PetscFunctionReturn(PETSC_SUCCESS); 1043ef0bb6c7SMatthew G. Knepley PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 10444f572ea9SToby Isaac PetscAssertPointer(points, 3); 10454f572ea9SToby Isaac PetscAssertPointer(T, 5); 104676bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 104720cf1dd8SToby Isaac DM dm; 1048ef0bb6c7SMatthew G. Knepley PetscDualSpace Q; 1049ef0bb6c7SMatthew G. Knepley PetscInt Nb; /* Dimension of FE space P */ 1050ef0bb6c7SMatthew G. Knepley PetscInt Nc; /* Field components */ 1051ef0bb6c7SMatthew G. Knepley PetscInt cdim; /* Reference coordinate dimension */ 1052ef0bb6c7SMatthew G. Knepley 10539566063dSJacob Faibussowitsch PetscCall(PetscFEGetDualSpace(fem, &Q)); 10549566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetDM(Q, &dm)); 10559566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &cdim)); 10569566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetDimension(Q, &Nb)); 10579566063dSJacob Faibussowitsch PetscCall(PetscFEGetNumComponents(fem, &Nc)); 105863a3b9bcSJacob 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); 105963a3b9bcSJacob 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); 106063a3b9bcSJacob 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); 106163a3b9bcSJacob 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); 1062ef0bb6c7SMatthew G. Knepley } 1063ef0bb6c7SMatthew G. Knepley T->Nr = 1; 1064ef0bb6c7SMatthew G. Knepley T->Np = npoints; 1065ce78bad3SBarry Smith PetscUseTypeMethod(fem, computetabulation, npoints, points, K, T); 10663ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1067ef0bb6c7SMatthew G. Knepley } 1068ef0bb6c7SMatthew G. Knepley 1069cc4c1da9SBarry Smith /*@ 1070ef0bb6c7SMatthew G. Knepley PetscTabulationDestroy - Frees memory from the associated tabulation. 1071ef0bb6c7SMatthew G. Knepley 107220f4b53cSBarry Smith Not Collective 1073ef0bb6c7SMatthew G. Knepley 1074ef0bb6c7SMatthew G. Knepley Input Parameter: 1075ef0bb6c7SMatthew G. Knepley . T - The tabulation 1076ef0bb6c7SMatthew G. Knepley 1077ef0bb6c7SMatthew G. Knepley Level: intermediate 1078ef0bb6c7SMatthew G. Knepley 1079dce8aebaSBarry Smith .seealso: `PetscTabulation`, `PetscFECreateTabulation()`, `PetscFEGetCellTabulation()` 1080ef0bb6c7SMatthew G. Knepley @*/ 1081d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscTabulationDestroy(PetscTabulation *T) 1082d71ae5a4SJacob Faibussowitsch { 1083ef0bb6c7SMatthew G. Knepley PetscInt k; 108420cf1dd8SToby Isaac 108520cf1dd8SToby Isaac PetscFunctionBegin; 10864f572ea9SToby Isaac PetscAssertPointer(T, 1); 108757508eceSPierre Jolivet if (!T || !*T) PetscFunctionReturn(PETSC_SUCCESS); 10889566063dSJacob Faibussowitsch for (k = 0; k <= (*T)->K; ++k) PetscCall(PetscFree((*T)->T[k])); 10899566063dSJacob Faibussowitsch PetscCall(PetscFree((*T)->T)); 10909566063dSJacob Faibussowitsch PetscCall(PetscFree(*T)); 1091ef0bb6c7SMatthew G. Knepley *T = NULL; 10923ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 109320cf1dd8SToby Isaac } 109420cf1dd8SToby Isaac 10952dce792eSToby Isaac static PetscErrorCode PetscFECreatePointTraceDefault_Internal(PetscFE fe, PetscInt refPoint, PetscFE *trFE) 1096d71ae5a4SJacob Faibussowitsch { 109720cf1dd8SToby Isaac PetscSpace bsp, bsubsp; 109820cf1dd8SToby Isaac PetscDualSpace dsp, dsubsp; 109920cf1dd8SToby Isaac PetscInt dim, depth, numComp, i, j, coneSize, order; 110020cf1dd8SToby Isaac DM dm; 110120cf1dd8SToby Isaac DMLabel label; 110220cf1dd8SToby Isaac PetscReal *xi, *v, *J, detJ; 1103db11e2ebSMatthew G. Knepley const char *name; 110420cf1dd8SToby Isaac PetscQuadrature origin, fullQuad, subQuad; 110520cf1dd8SToby Isaac 110620cf1dd8SToby Isaac PetscFunctionBegin; 11079566063dSJacob Faibussowitsch PetscCall(PetscFEGetBasisSpace(fe, &bsp)); 11089566063dSJacob Faibussowitsch PetscCall(PetscFEGetDualSpace(fe, &dsp)); 11099566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetDM(dsp, &dm)); 11109566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &dim)); 11119566063dSJacob Faibussowitsch PetscCall(DMPlexGetDepthLabel(dm, &label)); 11129566063dSJacob Faibussowitsch PetscCall(DMLabelGetValue(label, refPoint, &depth)); 11139566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(depth, &xi)); 11149566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(dim, &v)); 11159566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(dim * dim, &J)); 111620cf1dd8SToby Isaac for (i = 0; i < depth; i++) xi[i] = 0.; 11179566063dSJacob Faibussowitsch PetscCall(PetscQuadratureCreate(PETSC_COMM_SELF, &origin)); 11189566063dSJacob Faibussowitsch PetscCall(PetscQuadratureSetData(origin, depth, 0, 1, xi, NULL)); 11199566063dSJacob Faibussowitsch PetscCall(DMPlexComputeCellGeometryFEM(dm, refPoint, origin, v, J, NULL, &detJ)); 112020cf1dd8SToby Isaac /* CellGeometryFEM computes the expanded Jacobian, we want the true jacobian */ 112120cf1dd8SToby Isaac for (i = 1; i < dim; i++) { 1122ad540459SPierre Jolivet for (j = 0; j < depth; j++) J[i * depth + j] = J[i * dim + j]; 112320cf1dd8SToby Isaac } 11249566063dSJacob Faibussowitsch PetscCall(PetscQuadratureDestroy(&origin)); 11259566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetPointSubspace(dsp, refPoint, &dsubsp)); 11269566063dSJacob Faibussowitsch PetscCall(PetscSpaceCreateSubspace(bsp, dsubsp, v, J, NULL, NULL, PETSC_OWN_POINTER, &bsubsp)); 11279566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetUp(bsubsp)); 11289566063dSJacob Faibussowitsch PetscCall(PetscFECreate(PetscObjectComm((PetscObject)fe), trFE)); 11292dce792eSToby Isaac PetscCall(PetscFESetType(*trFE, PETSCFEBASIC)); 11309566063dSJacob Faibussowitsch PetscCall(PetscFEGetNumComponents(fe, &numComp)); 11319566063dSJacob Faibussowitsch PetscCall(PetscFESetNumComponents(*trFE, numComp)); 11329566063dSJacob Faibussowitsch PetscCall(PetscFESetBasisSpace(*trFE, bsubsp)); 11339566063dSJacob Faibussowitsch PetscCall(PetscFESetDualSpace(*trFE, dsubsp)); 11349566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)fe, &name)); 11359566063dSJacob Faibussowitsch if (name) PetscCall(PetscFESetName(*trFE, name)); 11369566063dSJacob Faibussowitsch PetscCall(PetscFEGetQuadrature(fe, &fullQuad)); 11379566063dSJacob Faibussowitsch PetscCall(PetscQuadratureGetOrder(fullQuad, &order)); 11389566063dSJacob Faibussowitsch PetscCall(DMPlexGetConeSize(dm, refPoint, &coneSize)); 11398b6ef6a4SJed Brown if (coneSize == 2 * depth) PetscCall(PetscDTGaussTensorQuadrature(depth, 1, (order + 2) / 2, -1., 1., &subQuad)); 11408b6ef6a4SJed Brown else PetscCall(PetscDTSimplexQuadrature(depth, order, PETSCDTSIMPLEXQUAD_DEFAULT, &subQuad)); 11419566063dSJacob Faibussowitsch PetscCall(PetscFESetQuadrature(*trFE, subQuad)); 11429566063dSJacob Faibussowitsch PetscCall(PetscFESetUp(*trFE)); 11439566063dSJacob Faibussowitsch PetscCall(PetscQuadratureDestroy(&subQuad)); 11449566063dSJacob Faibussowitsch PetscCall(PetscSpaceDestroy(&bsubsp)); 11453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 114620cf1dd8SToby Isaac } 114720cf1dd8SToby Isaac 11482dce792eSToby Isaac PETSC_EXTERN PetscErrorCode PetscFECreatePointTrace(PetscFE fe, PetscInt refPoint, PetscFE *trFE) 11492dce792eSToby Isaac { 11502dce792eSToby Isaac PetscFunctionBegin; 11512dce792eSToby Isaac PetscValidHeaderSpecific(fe, PETSCFE_CLASSID, 1); 11522dce792eSToby Isaac PetscAssertPointer(trFE, 3); 11539927e4dfSBarry Smith if (fe->ops->createpointtrace) PetscUseTypeMethod(fe, createpointtrace, refPoint, trFE); 11549927e4dfSBarry Smith else PetscCall(PetscFECreatePointTraceDefault_Internal(fe, refPoint, trFE)); 11552dce792eSToby Isaac PetscFunctionReturn(PETSC_SUCCESS); 11562dce792eSToby Isaac } 11572dce792eSToby Isaac 1158d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFECreateHeightTrace(PetscFE fe, PetscInt height, PetscFE *trFE) 1159d71ae5a4SJacob Faibussowitsch { 116020cf1dd8SToby Isaac PetscInt hStart, hEnd; 116120cf1dd8SToby Isaac PetscDualSpace dsp; 116220cf1dd8SToby Isaac DM dm; 116320cf1dd8SToby Isaac 116420cf1dd8SToby Isaac PetscFunctionBegin; 116520cf1dd8SToby Isaac PetscValidHeaderSpecific(fe, PETSCFE_CLASSID, 1); 11664f572ea9SToby Isaac PetscAssertPointer(trFE, 3); 116720cf1dd8SToby Isaac *trFE = NULL; 11689566063dSJacob Faibussowitsch PetscCall(PetscFEGetDualSpace(fe, &dsp)); 11699566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetDM(dsp, &dm)); 11709566063dSJacob Faibussowitsch PetscCall(DMPlexGetHeightStratum(dm, height, &hStart, &hEnd)); 11713ba16761SJacob Faibussowitsch if (hEnd <= hStart) PetscFunctionReturn(PETSC_SUCCESS); 11729566063dSJacob Faibussowitsch PetscCall(PetscFECreatePointTrace(fe, hStart, trFE)); 11733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 117420cf1dd8SToby Isaac } 117520cf1dd8SToby Isaac 117620cf1dd8SToby Isaac /*@ 117720cf1dd8SToby Isaac PetscFEGetDimension - Get the dimension of the finite element space on a cell 117820cf1dd8SToby Isaac 117920f4b53cSBarry Smith Not Collective 118020cf1dd8SToby Isaac 118120cf1dd8SToby Isaac Input Parameter: 118260225df5SJacob Faibussowitsch . fem - The `PetscFE` 118320cf1dd8SToby Isaac 118420cf1dd8SToby Isaac Output Parameter: 118520cf1dd8SToby Isaac . dim - The dimension 118620cf1dd8SToby Isaac 118720cf1dd8SToby Isaac Level: intermediate 118820cf1dd8SToby Isaac 1189dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscFECreate()`, `PetscSpaceGetDimension()`, `PetscDualSpaceGetDimension()` 119020cf1dd8SToby Isaac @*/ 1191d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEGetDimension(PetscFE fem, PetscInt *dim) 1192d71ae5a4SJacob Faibussowitsch { 119320cf1dd8SToby Isaac PetscFunctionBegin; 119420cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 11954f572ea9SToby Isaac PetscAssertPointer(dim, 2); 1196dbbe0bcdSBarry Smith PetscTryTypeMethod(fem, getdimension, dim); 11973ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 119820cf1dd8SToby Isaac } 119920cf1dd8SToby Isaac 1200cc4c1da9SBarry Smith /*@ 12014bee2e38SMatthew G. Knepley PetscFEPushforward - Map the reference element function to real space 12024bee2e38SMatthew G. Knepley 12034bee2e38SMatthew G. Knepley Input Parameters: 1204dce8aebaSBarry Smith + fe - The `PetscFE` 12054bee2e38SMatthew G. Knepley . fegeom - The cell geometry 12064bee2e38SMatthew G. Knepley . Nv - The number of function values 12074bee2e38SMatthew G. Knepley - vals - The function values 12084bee2e38SMatthew G. Knepley 12094bee2e38SMatthew G. Knepley Output Parameter: 12104bee2e38SMatthew G. Knepley . vals - The transformed function values 12114bee2e38SMatthew G. Knepley 12124bee2e38SMatthew G. Knepley Level: advanced 12134bee2e38SMatthew G. Knepley 1214dce8aebaSBarry Smith Notes: 1215dce8aebaSBarry Smith This just forwards the call onto `PetscDualSpacePushforward()`. 12164bee2e38SMatthew G. Knepley 1217dce8aebaSBarry Smith It only handles transformations when the embedding dimension of the geometry in fegeom is the same as the reference dimension. 12182edcad52SToby Isaac 1219dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscFEGeom`, `PetscDualSpace`, `PetscDualSpacePushforward()` 12204bee2e38SMatthew G. Knepley @*/ 1221d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEPushforward(PetscFE fe, PetscFEGeom *fegeom, PetscInt Nv, PetscScalar vals[]) 1222d71ae5a4SJacob Faibussowitsch { 12232ae266adSMatthew G. Knepley PetscFunctionBeginHot; 12249566063dSJacob Faibussowitsch PetscCall(PetscDualSpacePushforward(fe->dualSpace, fegeom, Nv, fe->numComponents, vals)); 12253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 12264bee2e38SMatthew G. Knepley } 12274bee2e38SMatthew G. Knepley 1228cc4c1da9SBarry Smith /*@ 12294bee2e38SMatthew G. Knepley PetscFEPushforwardGradient - Map the reference element function gradient to real space 12304bee2e38SMatthew G. Knepley 12314bee2e38SMatthew G. Knepley Input Parameters: 1232dce8aebaSBarry Smith + fe - The `PetscFE` 12334bee2e38SMatthew G. Knepley . fegeom - The cell geometry 12344bee2e38SMatthew G. Knepley . Nv - The number of function gradient values 12354bee2e38SMatthew G. Knepley - vals - The function gradient values 12364bee2e38SMatthew G. Knepley 12374bee2e38SMatthew G. Knepley Output Parameter: 12384bee2e38SMatthew G. Knepley . vals - The transformed function gradient values 12394bee2e38SMatthew G. Knepley 12404bee2e38SMatthew G. Knepley Level: advanced 12414bee2e38SMatthew G. Knepley 1242dce8aebaSBarry Smith Notes: 1243dce8aebaSBarry Smith This just forwards the call onto `PetscDualSpacePushforwardGradient()`. 12444bee2e38SMatthew G. Knepley 1245dce8aebaSBarry Smith It only handles transformations when the embedding dimension of the geometry in fegeom is the same as the reference dimension. 12462edcad52SToby Isaac 1247dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscFEGeom`, `PetscDualSpace`, `PetscFEPushforward()`, `PetscDualSpacePushforwardGradient()`, `PetscDualSpacePushforward()` 12484bee2e38SMatthew G. Knepley @*/ 1249d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEPushforwardGradient(PetscFE fe, PetscFEGeom *fegeom, PetscInt Nv, PetscScalar vals[]) 1250d71ae5a4SJacob Faibussowitsch { 12512ae266adSMatthew G. Knepley PetscFunctionBeginHot; 12529566063dSJacob Faibussowitsch PetscCall(PetscDualSpacePushforwardGradient(fe->dualSpace, fegeom, Nv, fe->numComponents, vals)); 12533ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 12544bee2e38SMatthew G. Knepley } 12554bee2e38SMatthew G. Knepley 1256cc4c1da9SBarry Smith /*@ 1257f9244615SMatthew G. Knepley PetscFEPushforwardHessian - Map the reference element function Hessian to real space 1258f9244615SMatthew G. Knepley 1259f9244615SMatthew G. Knepley Input Parameters: 1260dce8aebaSBarry Smith + fe - The `PetscFE` 1261f9244615SMatthew G. Knepley . fegeom - The cell geometry 1262f9244615SMatthew G. Knepley . Nv - The number of function Hessian values 1263f9244615SMatthew G. Knepley - vals - The function Hessian values 1264f9244615SMatthew G. Knepley 1265f9244615SMatthew G. Knepley Output Parameter: 1266f9244615SMatthew G. Knepley . vals - The transformed function Hessian values 1267f9244615SMatthew G. Knepley 1268f9244615SMatthew G. Knepley Level: advanced 1269f9244615SMatthew G. Knepley 1270dce8aebaSBarry Smith Notes: 1271dce8aebaSBarry Smith This just forwards the call onto `PetscDualSpacePushforwardHessian()`. 1272f9244615SMatthew G. Knepley 1273dce8aebaSBarry Smith It only handles transformations when the embedding dimension of the geometry in fegeom is the same as the reference dimension. 1274f9244615SMatthew G. Knepley 127560225df5SJacob Faibussowitsch Developer Notes: 1276dce8aebaSBarry Smith It is unclear why all these one line convenience routines are desirable 1277dce8aebaSBarry Smith 1278dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscFEGeom`, `PetscDualSpace`, `PetscFEPushforward()`, `PetscDualSpacePushforwardHessian()`, `PetscDualSpacePushforward()` 1279f9244615SMatthew G. Knepley @*/ 1280d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEPushforwardHessian(PetscFE fe, PetscFEGeom *fegeom, PetscInt Nv, PetscScalar vals[]) 1281d71ae5a4SJacob Faibussowitsch { 1282f9244615SMatthew G. Knepley PetscFunctionBeginHot; 12839566063dSJacob Faibussowitsch PetscCall(PetscDualSpacePushforwardHessian(fe->dualSpace, fegeom, Nv, fe->numComponents, vals)); 12843ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1285f9244615SMatthew G. Knepley } 1286f9244615SMatthew G. Knepley 128720cf1dd8SToby Isaac /* 128820cf1dd8SToby Isaac Purpose: Compute element vector for chunk of elements 128920cf1dd8SToby Isaac 129020cf1dd8SToby Isaac Input: 129120cf1dd8SToby Isaac Sizes: 129220cf1dd8SToby Isaac Ne: number of elements 129320cf1dd8SToby Isaac Nf: number of fields 129420cf1dd8SToby Isaac PetscFE 129520cf1dd8SToby Isaac dim: spatial dimension 129620cf1dd8SToby Isaac Nb: number of basis functions 129720cf1dd8SToby Isaac Nc: number of field components 129820cf1dd8SToby Isaac PetscQuadrature 129920cf1dd8SToby Isaac Nq: number of quadrature points 130020cf1dd8SToby Isaac 130120cf1dd8SToby Isaac Geometry: 130220cf1dd8SToby Isaac PetscFEGeom[Ne] possibly *Nq 130320cf1dd8SToby Isaac PetscReal v0s[dim] 130420cf1dd8SToby Isaac PetscReal n[dim] 130520cf1dd8SToby Isaac PetscReal jacobians[dim*dim] 130620cf1dd8SToby Isaac PetscReal jacobianInverses[dim*dim] 130720cf1dd8SToby Isaac PetscReal jacobianDeterminants 130820cf1dd8SToby Isaac FEM: 130920cf1dd8SToby Isaac PetscFE 131020cf1dd8SToby Isaac PetscQuadrature 131120cf1dd8SToby Isaac PetscReal quadPoints[Nq*dim] 131220cf1dd8SToby Isaac PetscReal quadWeights[Nq] 131320cf1dd8SToby Isaac PetscReal basis[Nq*Nb*Nc] 131420cf1dd8SToby Isaac PetscReal basisDer[Nq*Nb*Nc*dim] 131520cf1dd8SToby Isaac PetscScalar coefficients[Ne*Nb*Nc] 131620cf1dd8SToby Isaac PetscScalar elemVec[Ne*Nb*Nc] 131720cf1dd8SToby Isaac 131820cf1dd8SToby Isaac Problem: 131920cf1dd8SToby Isaac PetscInt f: the active field 132020cf1dd8SToby Isaac f0, f1 132120cf1dd8SToby Isaac 132220cf1dd8SToby Isaac Work Space: 132320cf1dd8SToby Isaac PetscFE 132420cf1dd8SToby Isaac PetscScalar f0[Nq*dim]; 132520cf1dd8SToby Isaac PetscScalar f1[Nq*dim*dim]; 132620cf1dd8SToby Isaac PetscScalar u[Nc]; 132720cf1dd8SToby Isaac PetscScalar gradU[Nc*dim]; 132820cf1dd8SToby Isaac PetscReal x[dim]; 132920cf1dd8SToby Isaac PetscScalar realSpaceDer[dim]; 133020cf1dd8SToby Isaac 133120cf1dd8SToby Isaac Purpose: Compute element vector for N_cb batches of elements 133220cf1dd8SToby Isaac 133320cf1dd8SToby Isaac Input: 133420cf1dd8SToby Isaac Sizes: 133520cf1dd8SToby Isaac N_cb: Number of serial cell batches 133620cf1dd8SToby Isaac 133720cf1dd8SToby Isaac Geometry: 133820cf1dd8SToby Isaac PetscReal v0s[Ne*dim] 133920cf1dd8SToby Isaac PetscReal jacobians[Ne*dim*dim] possibly *Nq 134020cf1dd8SToby Isaac PetscReal jacobianInverses[Ne*dim*dim] possibly *Nq 134120cf1dd8SToby Isaac PetscReal jacobianDeterminants[Ne] possibly *Nq 134220cf1dd8SToby Isaac FEM: 134320cf1dd8SToby Isaac static PetscReal quadPoints[Nq*dim] 134420cf1dd8SToby Isaac static PetscReal quadWeights[Nq] 134520cf1dd8SToby Isaac static PetscReal basis[Nq*Nb*Nc] 134620cf1dd8SToby Isaac static PetscReal basisDer[Nq*Nb*Nc*dim] 134720cf1dd8SToby Isaac PetscScalar coefficients[Ne*Nb*Nc] 134820cf1dd8SToby Isaac PetscScalar elemVec[Ne*Nb*Nc] 134920cf1dd8SToby Isaac 135020cf1dd8SToby Isaac ex62.c: 135120cf1dd8SToby Isaac PetscErrorCode PetscFEIntegrateResidualBatch(PetscInt Ne, PetscInt numFields, PetscInt field, PetscQuadrature quad[], const PetscScalar coefficients[], 135220cf1dd8SToby Isaac const PetscReal v0s[], const PetscReal jacobians[], const PetscReal jacobianInverses[], const PetscReal jacobianDeterminants[], 135320cf1dd8SToby Isaac void (*f0_func)(const PetscScalar u[], const PetscScalar gradU[], const PetscReal x[], PetscScalar f0[]), 135420cf1dd8SToby Isaac void (*f1_func)(const PetscScalar u[], const PetscScalar gradU[], const PetscReal x[], PetscScalar f1[]), PetscScalar elemVec[]) 135520cf1dd8SToby Isaac 135620cf1dd8SToby Isaac ex52.c: 135720cf1dd8SToby 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) 135820cf1dd8SToby 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) 135920cf1dd8SToby Isaac 136020cf1dd8SToby Isaac ex52_integrateElement.cu 136120cf1dd8SToby Isaac __global__ void integrateElementQuadrature(int N_cb, realType *coefficients, realType *jacobianInverses, realType *jacobianDeterminants, realType *elemVec) 136220cf1dd8SToby Isaac 136320cf1dd8SToby Isaac PETSC_EXTERN PetscErrorCode IntegrateElementBatchGPU(PetscInt spatial_dim, PetscInt Ne, PetscInt Ncb, PetscInt Nbc, PetscInt Nbl, const PetscScalar coefficients[], 136420cf1dd8SToby Isaac const PetscReal jacobianInverses[], const PetscReal jacobianDeterminants[], PetscScalar elemVec[], 136520cf1dd8SToby Isaac PetscLogEvent event, PetscInt debug, PetscInt pde_op) 136620cf1dd8SToby Isaac 136720cf1dd8SToby Isaac ex52_integrateElementOpenCL.c: 136820cf1dd8SToby Isaac PETSC_EXTERN PetscErrorCode IntegrateElementBatchGPU(PetscInt spatial_dim, PetscInt Ne, PetscInt Ncb, PetscInt Nbc, PetscInt N_bl, const PetscScalar coefficients[], 136920cf1dd8SToby Isaac const PetscReal jacobianInverses[], const PetscReal jacobianDeterminants[], PetscScalar elemVec[], 137020cf1dd8SToby Isaac PetscLogEvent event, PetscInt debug, PetscInt pde_op) 137120cf1dd8SToby Isaac 137220cf1dd8SToby Isaac __kernel void integrateElementQuadrature(int N_cb, __global float *coefficients, __global float *jacobianInverses, __global float *jacobianDeterminants, __global float *elemVec) 137320cf1dd8SToby Isaac */ 137420cf1dd8SToby Isaac 1375cc4c1da9SBarry Smith /*@ 137620cf1dd8SToby Isaac PetscFEIntegrate - Produce the integral for the given field for a chunk of elements by quadrature integration 137720cf1dd8SToby Isaac 137820f4b53cSBarry Smith Not Collective 137920cf1dd8SToby Isaac 138020cf1dd8SToby Isaac Input Parameters: 1381dce8aebaSBarry Smith + prob - The `PetscDS` specifying the discretizations and continuum functions 138220cf1dd8SToby Isaac . field - The field being integrated 138320cf1dd8SToby Isaac . Ne - The number of elements in the chunk 138420cf1dd8SToby Isaac . cgeom - The cell geometry for each cell in the chunk 138520cf1dd8SToby Isaac . coefficients - The array of FEM basis coefficients for the elements 1386dce8aebaSBarry Smith . probAux - The `PetscDS` specifying the auxiliary discretizations 138720cf1dd8SToby Isaac - coefficientsAux - The array of FEM auxiliary basis coefficients for the elements 138820cf1dd8SToby Isaac 13897a7aea1fSJed Brown Output Parameter: 139020cf1dd8SToby Isaac . integral - the integral for this field 139120cf1dd8SToby Isaac 13922b99622eSMatthew G. Knepley Level: intermediate 139320cf1dd8SToby Isaac 139460225df5SJacob Faibussowitsch Developer Notes: 1395dce8aebaSBarry Smith The function name begins with `PetscFE` and yet the first argument is `PetscDS` and it has no `PetscFE` arguments. 1396dce8aebaSBarry Smith 1397dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscDS`, `PetscFEIntegrateResidual()`, `PetscFEIntegrateBd()` 139820cf1dd8SToby Isaac @*/ 1399d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEIntegrate(PetscDS prob, PetscInt field, PetscInt Ne, PetscFEGeom *cgeom, const PetscScalar coefficients[], PetscDS probAux, const PetscScalar coefficientsAux[], PetscScalar integral[]) 1400d71ae5a4SJacob Faibussowitsch { 14014bee2e38SMatthew G. Knepley PetscFE fe; 140220cf1dd8SToby Isaac 140320cf1dd8SToby Isaac PetscFunctionBegin; 14044bee2e38SMatthew G. Knepley PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 14059566063dSJacob Faibussowitsch PetscCall(PetscDSGetDiscretization(prob, field, (PetscObject *)&fe)); 14069566063dSJacob Faibussowitsch if (fe->ops->integrate) PetscCall((*fe->ops->integrate)(prob, field, Ne, cgeom, coefficients, probAux, coefficientsAux, integral)); 14073ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 140820cf1dd8SToby Isaac } 140920cf1dd8SToby Isaac 141020cf1dd8SToby Isaac /*@C 1411afe6d6adSToby Isaac PetscFEIntegrateBd - Produce the integral for the given field for a chunk of elements by quadrature integration 1412afe6d6adSToby Isaac 141320f4b53cSBarry Smith Not Collective 1414afe6d6adSToby Isaac 1415afe6d6adSToby Isaac Input Parameters: 1416dce8aebaSBarry Smith + prob - The `PetscDS` specifying the discretizations and continuum functions 1417afe6d6adSToby Isaac . field - The field being integrated 1418afe6d6adSToby Isaac . obj_func - The function to be integrated 1419afe6d6adSToby Isaac . Ne - The number of elements in the chunk 142060225df5SJacob Faibussowitsch . geom - The face geometry for each face in the chunk 1421afe6d6adSToby Isaac . coefficients - The array of FEM basis coefficients for the elements 1422dce8aebaSBarry Smith . probAux - The `PetscDS` specifying the auxiliary discretizations 1423afe6d6adSToby Isaac - coefficientsAux - The array of FEM auxiliary basis coefficients for the elements 1424afe6d6adSToby Isaac 14257a7aea1fSJed Brown Output Parameter: 1426afe6d6adSToby Isaac . integral - the integral for this field 1427afe6d6adSToby Isaac 14282b99622eSMatthew G. Knepley Level: intermediate 1429afe6d6adSToby Isaac 143060225df5SJacob Faibussowitsch Developer Notes: 1431dce8aebaSBarry Smith The function name begins with `PetscFE` and yet the first argument is `PetscDS` and it has no `PetscFE` arguments. 1432dce8aebaSBarry Smith 1433dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscDS`, `PetscFEIntegrateResidual()`, `PetscFEIntegrate()` 1434afe6d6adSToby Isaac @*/ 1435d71ae5a4SJacob 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[]) 1436d71ae5a4SJacob Faibussowitsch { 14374bee2e38SMatthew G. Knepley PetscFE fe; 1438afe6d6adSToby Isaac 1439afe6d6adSToby Isaac PetscFunctionBegin; 14404bee2e38SMatthew G. Knepley PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 14419566063dSJacob Faibussowitsch PetscCall(PetscDSGetDiscretization(prob, field, (PetscObject *)&fe)); 14429566063dSJacob Faibussowitsch if (fe->ops->integratebd) PetscCall((*fe->ops->integratebd)(prob, field, obj_func, Ne, geom, coefficients, probAux, coefficientsAux, integral)); 14433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1444afe6d6adSToby Isaac } 1445afe6d6adSToby Isaac 1446cc4c1da9SBarry Smith /*@ 144720cf1dd8SToby Isaac PetscFEIntegrateResidual - Produce the element residual vector for a chunk of elements by quadrature integration 144820cf1dd8SToby Isaac 144920f4b53cSBarry Smith Not Collective 145020cf1dd8SToby Isaac 145120cf1dd8SToby Isaac Input Parameters: 145220f4b53cSBarry Smith + ds - The `PetscDS` specifying the discretizations and continuum functions 14536528b96dSMatthew G. Knepley . key - The (label+value, field) being integrated 145420cf1dd8SToby Isaac . Ne - The number of elements in the chunk 145520cf1dd8SToby Isaac . cgeom - The cell geometry for each cell in the chunk 145620cf1dd8SToby Isaac . coefficients - The array of FEM basis coefficients for the elements 145720cf1dd8SToby Isaac . coefficients_t - The array of FEM basis time derivative coefficients for the elements 145820f4b53cSBarry Smith . probAux - The `PetscDS` specifying the auxiliary discretizations 145920cf1dd8SToby Isaac . coefficientsAux - The array of FEM auxiliary basis coefficients for the elements 146020cf1dd8SToby Isaac - t - The time 146120cf1dd8SToby Isaac 14627a7aea1fSJed Brown Output Parameter: 146320cf1dd8SToby Isaac . elemVec - the element residual vectors from each element 146420cf1dd8SToby Isaac 14652b99622eSMatthew G. Knepley Level: intermediate 146620cf1dd8SToby Isaac 1467dce8aebaSBarry Smith Note: 1468dce8aebaSBarry Smith .vb 1469dce8aebaSBarry Smith Loop over batch of elements (e): 1470dce8aebaSBarry Smith Loop over quadrature points (q): 1471dce8aebaSBarry Smith Make u_q and gradU_q (loops over fields,Nb,Ncomp) and x_q 1472dce8aebaSBarry Smith Call f_0 and f_1 1473dce8aebaSBarry Smith Loop over element vector entries (f,fc --> i): 1474dce8aebaSBarry Smith elemVec[i] += \psi^{fc}_f(q) f0_{fc}(u, \nabla u) + \nabla\psi^{fc}_f(q) \cdot f1_{fc,df}(u, \nabla u) 1475dce8aebaSBarry Smith .ve 1476dce8aebaSBarry Smith 147742747ad1SJacob Faibussowitsch .seealso: `PetscFEIntegrateBdResidual()` 147820cf1dd8SToby Isaac @*/ 1479d71ae5a4SJacob 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[]) 1480d71ae5a4SJacob Faibussowitsch { 14814bee2e38SMatthew G. Knepley PetscFE fe; 148220cf1dd8SToby Isaac 14836528b96dSMatthew G. Knepley PetscFunctionBeginHot; 14846528b96dSMatthew G. Knepley PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1); 14859566063dSJacob Faibussowitsch PetscCall(PetscDSGetDiscretization(ds, key.field, (PetscObject *)&fe)); 14869566063dSJacob Faibussowitsch if (fe->ops->integrateresidual) PetscCall((*fe->ops->integrateresidual)(ds, key, Ne, cgeom, coefficients, coefficients_t, probAux, coefficientsAux, t, elemVec)); 14873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 148820cf1dd8SToby Isaac } 148920cf1dd8SToby Isaac 1490cc4c1da9SBarry Smith /*@ 149120cf1dd8SToby Isaac PetscFEIntegrateBdResidual - Produce the element residual vector for a chunk of elements by quadrature integration over a boundary 149220cf1dd8SToby Isaac 149320f4b53cSBarry Smith Not Collective 149420cf1dd8SToby Isaac 149520cf1dd8SToby Isaac Input Parameters: 149620f4b53cSBarry Smith + ds - The `PetscDS` specifying the discretizations and continuum functions 149745480ffeSMatthew G. Knepley . wf - The PetscWeakForm object holding the pointwise functions 149806d8a0d3SMatthew G. Knepley . key - The (label+value, field) being integrated 149920cf1dd8SToby Isaac . Ne - The number of elements in the chunk 150020cf1dd8SToby Isaac . fgeom - The face geometry for each cell in the chunk 150120cf1dd8SToby Isaac . coefficients - The array of FEM basis coefficients for the elements 150220cf1dd8SToby Isaac . coefficients_t - The array of FEM basis time derivative coefficients for the elements 150320f4b53cSBarry Smith . probAux - The `PetscDS` specifying the auxiliary discretizations 150420cf1dd8SToby Isaac . coefficientsAux - The array of FEM auxiliary basis coefficients for the elements 150520cf1dd8SToby Isaac - t - The time 150620cf1dd8SToby Isaac 15077a7aea1fSJed Brown Output Parameter: 150820cf1dd8SToby Isaac . elemVec - the element residual vectors from each element 150920cf1dd8SToby Isaac 15102b99622eSMatthew G. Knepley Level: intermediate 151120cf1dd8SToby Isaac 1512db781477SPatrick Sanan .seealso: `PetscFEIntegrateResidual()` 151320cf1dd8SToby Isaac @*/ 1514d71ae5a4SJacob 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[]) 1515d71ae5a4SJacob Faibussowitsch { 15164bee2e38SMatthew G. Knepley PetscFE fe; 151720cf1dd8SToby Isaac 151820cf1dd8SToby Isaac PetscFunctionBegin; 151906d8a0d3SMatthew G. Knepley PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1); 15209566063dSJacob Faibussowitsch PetscCall(PetscDSGetDiscretization(ds, key.field, (PetscObject *)&fe)); 15219566063dSJacob Faibussowitsch if (fe->ops->integratebdresidual) PetscCall((*fe->ops->integratebdresidual)(ds, wf, key, Ne, fgeom, coefficients, coefficients_t, probAux, coefficientsAux, t, elemVec)); 15223ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 152320cf1dd8SToby Isaac } 152420cf1dd8SToby Isaac 1525cc4c1da9SBarry Smith /*@ 152627f02ce8SMatthew G. Knepley PetscFEIntegrateHybridResidual - Produce the element residual vector for a chunk of hybrid element faces by quadrature integration 152727f02ce8SMatthew G. Knepley 152820f4b53cSBarry Smith Not Collective 152927f02ce8SMatthew G. Knepley 153027f02ce8SMatthew G. Knepley Input Parameters: 153107218a29SMatthew G. Knepley + ds - The `PetscDS` specifying the discretizations and continuum functions 153207218a29SMatthew G. Knepley . dsIn - The `PetscDS` specifying the discretizations and continuum functions for input 15336528b96dSMatthew G. Knepley . key - The (label+value, field) being integrated 1534c2b7495fSMatthew G. Knepley . s - The side of the cell being integrated, 0 for negative and 1 for positive 153527f02ce8SMatthew G. Knepley . Ne - The number of elements in the chunk 153627f02ce8SMatthew G. Knepley . fgeom - The face geometry for each cell in the chunk 1537989fa639SBrad Aagaard . cgeom - The cell geometry for each neighbor cell in the chunk 153827f02ce8SMatthew G. Knepley . coefficients - The array of FEM basis coefficients for the elements 153927f02ce8SMatthew G. Knepley . coefficients_t - The array of FEM basis time derivative coefficients for the elements 154020f4b53cSBarry Smith . probAux - The `PetscDS` specifying the auxiliary discretizations 154127f02ce8SMatthew G. Knepley . coefficientsAux - The array of FEM auxiliary basis coefficients for the elements 154227f02ce8SMatthew G. Knepley - t - The time 154327f02ce8SMatthew G. Knepley 1544a4e35b19SJacob Faibussowitsch Output Parameter: 154527f02ce8SMatthew G. Knepley . elemVec - the element residual vectors from each element 154627f02ce8SMatthew G. Knepley 154727f02ce8SMatthew G. Knepley Level: developer 154827f02ce8SMatthew G. Knepley 1549db781477SPatrick Sanan .seealso: `PetscFEIntegrateResidual()` 155027f02ce8SMatthew G. Knepley @*/ 1551989fa639SBrad Aagaard PetscErrorCode PetscFEIntegrateHybridResidual(PetscDS ds, PetscDS dsIn, PetscFormKey key, PetscInt s, PetscInt Ne, PetscFEGeom *fgeom, PetscFEGeom *cgeom, const PetscScalar coefficients[], const PetscScalar coefficients_t[], PetscDS probAux, const PetscScalar coefficientsAux[], PetscReal t, PetscScalar elemVec[]) 1552d71ae5a4SJacob Faibussowitsch { 155327f02ce8SMatthew G. Knepley PetscFE fe; 155427f02ce8SMatthew G. Knepley 155527f02ce8SMatthew G. Knepley PetscFunctionBegin; 155607218a29SMatthew G. Knepley PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1); 155707218a29SMatthew G. Knepley PetscValidHeaderSpecific(dsIn, PETSCDS_CLASSID, 2); 155807218a29SMatthew G. Knepley PetscCall(PetscDSGetDiscretization(ds, key.field, (PetscObject *)&fe)); 1559989fa639SBrad Aagaard if (fe->ops->integratehybridresidual) PetscCall((*fe->ops->integratehybridresidual)(ds, dsIn, key, s, Ne, fgeom, cgeom, coefficients, coefficients_t, probAux, coefficientsAux, t, elemVec)); 15603ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 156127f02ce8SMatthew G. Knepley } 156227f02ce8SMatthew G. Knepley 1563cc4c1da9SBarry Smith /*@ 156420cf1dd8SToby Isaac PetscFEIntegrateJacobian - Produce the element Jacobian for a chunk of elements by quadrature integration 156520cf1dd8SToby Isaac 156620f4b53cSBarry Smith Not Collective 156720cf1dd8SToby Isaac 156820cf1dd8SToby Isaac Input Parameters: 15694561e6c9SMatthew G. Knepley + rds - The `PetscDS` specifying the row discretizations and continuum functions 15704561e6c9SMatthew G. Knepley . cds - The `PetscDS` specifying the column discretizations 157120cf1dd8SToby Isaac . jtype - The type of matrix pointwise functions that should be used 15726528b96dSMatthew G. Knepley . key - The (label+value, fieldI*Nf + fieldJ) being integrated 157320cf1dd8SToby Isaac . Ne - The number of elements in the chunk 157420cf1dd8SToby Isaac . cgeom - The cell geometry for each cell in the chunk 157520cf1dd8SToby Isaac . coefficients - The array of FEM basis coefficients for the elements for the Jacobian evaluation point 157620cf1dd8SToby Isaac . coefficients_t - The array of FEM basis time derivative coefficients for the elements 15774561e6c9SMatthew G. Knepley . dsAux - The `PetscDS` specifying the auxiliary discretizations 157820cf1dd8SToby Isaac . coefficientsAux - The array of FEM auxiliary basis coefficients for the elements 157920cf1dd8SToby Isaac . t - The time 158060225df5SJacob Faibussowitsch - u_tshift - A multiplier for the dF/du_t term (as opposed to the dF/du term) 158120cf1dd8SToby Isaac 15827a7aea1fSJed Brown Output Parameter: 158320cf1dd8SToby Isaac . elemMat - the element matrices for the Jacobian from each element 158420cf1dd8SToby Isaac 15852b99622eSMatthew G. Knepley Level: intermediate 158620cf1dd8SToby Isaac 1587dce8aebaSBarry Smith Note: 1588dce8aebaSBarry Smith .vb 1589dce8aebaSBarry Smith Loop over batch of elements (e): 1590dce8aebaSBarry Smith Loop over element matrix entries (f,fc,g,gc --> i,j): 1591dce8aebaSBarry Smith Loop over quadrature points (q): 1592dce8aebaSBarry Smith Make u_q and gradU_q (loops over fields,Nb,Ncomp) 1593dce8aebaSBarry Smith elemMat[i,j] += \psi^{fc}_f(q) g0_{fc,gc}(u, \nabla u) \phi^{gc}_g(q) 1594dce8aebaSBarry Smith + \psi^{fc}_f(q) \cdot g1_{fc,gc,dg}(u, \nabla u) \nabla\phi^{gc}_g(q) 1595dce8aebaSBarry Smith + \nabla\psi^{fc}_f(q) \cdot g2_{fc,gc,df}(u, \nabla u) \phi^{gc}_g(q) 1596dce8aebaSBarry Smith + \nabla\psi^{fc}_f(q) \cdot g3_{fc,gc,df,dg}(u, \nabla u) \nabla\phi^{gc}_g(q) 1597dce8aebaSBarry Smith .ve 1598dce8aebaSBarry Smith 1599db781477SPatrick Sanan .seealso: `PetscFEIntegrateResidual()` 160020cf1dd8SToby Isaac @*/ 16014561e6c9SMatthew G. Knepley PetscErrorCode PetscFEIntegrateJacobian(PetscDS rds, PetscDS cds, PetscFEJacobianType jtype, PetscFormKey key, PetscInt Ne, PetscFEGeom *cgeom, const PetscScalar coefficients[], const PetscScalar coefficients_t[], PetscDS dsAux, const PetscScalar coefficientsAux[], PetscReal t, PetscReal u_tshift, PetscScalar elemMat[]) 1602d71ae5a4SJacob Faibussowitsch { 16034bee2e38SMatthew G. Knepley PetscFE fe; 16046528b96dSMatthew G. Knepley PetscInt Nf; 160520cf1dd8SToby Isaac 160620cf1dd8SToby Isaac PetscFunctionBegin; 16074561e6c9SMatthew G. Knepley PetscValidHeaderSpecific(rds, PETSCDS_CLASSID, 1); 16084561e6c9SMatthew G. Knepley PetscValidHeaderSpecific(cds, PETSCDS_CLASSID, 2); 16094561e6c9SMatthew G. Knepley PetscCall(PetscDSGetNumFields(rds, &Nf)); 16104561e6c9SMatthew G. Knepley PetscCall(PetscDSGetDiscretization(rds, key.field / Nf, (PetscObject *)&fe)); 16114561e6c9SMatthew G. Knepley if (fe->ops->integratejacobian) PetscCall((*fe->ops->integratejacobian)(rds, cds, jtype, key, Ne, cgeom, coefficients, coefficients_t, dsAux, coefficientsAux, t, u_tshift, elemMat)); 16123ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 161320cf1dd8SToby Isaac } 161420cf1dd8SToby Isaac 1615cc4c1da9SBarry Smith /*@ 161620cf1dd8SToby Isaac PetscFEIntegrateBdJacobian - Produce the boundary element Jacobian for a chunk of elements by quadrature integration 161720cf1dd8SToby Isaac 161820f4b53cSBarry Smith Not Collective 161920cf1dd8SToby Isaac 162020cf1dd8SToby Isaac Input Parameters: 162120f4b53cSBarry Smith + ds - The `PetscDS` specifying the discretizations and continuum functions 162245480ffeSMatthew G. Knepley . wf - The PetscWeakForm holding the pointwise functions 1623e3d591f2SMatthew G. Knepley . jtype - The type of matrix pointwise functions that should be used 162445480ffeSMatthew G. Knepley . key - The (label+value, fieldI*Nf + fieldJ) being integrated 162520cf1dd8SToby Isaac . Ne - The number of elements in the chunk 162620cf1dd8SToby Isaac . fgeom - The face geometry for each cell in the chunk 162720cf1dd8SToby Isaac . coefficients - The array of FEM basis coefficients for the elements for the Jacobian evaluation point 162820cf1dd8SToby Isaac . coefficients_t - The array of FEM basis time derivative coefficients for the elements 162920f4b53cSBarry Smith . probAux - The `PetscDS` specifying the auxiliary discretizations 163020cf1dd8SToby Isaac . coefficientsAux - The array of FEM auxiliary basis coefficients for the elements 163120cf1dd8SToby Isaac . t - The time 163260225df5SJacob Faibussowitsch - u_tshift - A multiplier for the dF/du_t term (as opposed to the dF/du term) 163320cf1dd8SToby Isaac 16347a7aea1fSJed Brown Output Parameter: 163520cf1dd8SToby Isaac . elemMat - the element matrices for the Jacobian from each element 163620cf1dd8SToby Isaac 16372b99622eSMatthew G. Knepley Level: intermediate 163820cf1dd8SToby Isaac 1639dce8aebaSBarry Smith Note: 1640dce8aebaSBarry Smith .vb 1641dce8aebaSBarry Smith Loop over batch of elements (e): 1642dce8aebaSBarry Smith Loop over element matrix entries (f,fc,g,gc --> i,j): 1643dce8aebaSBarry Smith Loop over quadrature points (q): 1644dce8aebaSBarry Smith Make u_q and gradU_q (loops over fields,Nb,Ncomp) 1645dce8aebaSBarry Smith elemMat[i,j] += \psi^{fc}_f(q) g0_{fc,gc}(u, \nabla u) \phi^{gc}_g(q) 1646dce8aebaSBarry Smith + \psi^{fc}_f(q) \cdot g1_{fc,gc,dg}(u, \nabla u) \nabla\phi^{gc}_g(q) 1647dce8aebaSBarry Smith + \nabla\psi^{fc}_f(q) \cdot g2_{fc,gc,df}(u, \nabla u) \phi^{gc}_g(q) 1648dce8aebaSBarry Smith + \nabla\psi^{fc}_f(q) \cdot g3_{fc,gc,df,dg}(u, \nabla u) \nabla\phi^{gc}_g(q) 1649dce8aebaSBarry Smith .ve 1650dce8aebaSBarry Smith 1651db781477SPatrick Sanan .seealso: `PetscFEIntegrateJacobian()`, `PetscFEIntegrateResidual()` 165220cf1dd8SToby Isaac @*/ 1653e3d591f2SMatthew 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[]) 1654d71ae5a4SJacob Faibussowitsch { 16554bee2e38SMatthew G. Knepley PetscFE fe; 165645480ffeSMatthew G. Knepley PetscInt Nf; 165720cf1dd8SToby Isaac 165820cf1dd8SToby Isaac PetscFunctionBegin; 165945480ffeSMatthew G. Knepley PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1); 16609566063dSJacob Faibussowitsch PetscCall(PetscDSGetNumFields(ds, &Nf)); 16619566063dSJacob Faibussowitsch PetscCall(PetscDSGetDiscretization(ds, key.field / Nf, (PetscObject *)&fe)); 1662e3d591f2SMatthew 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)); 16633ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 166420cf1dd8SToby Isaac } 166520cf1dd8SToby Isaac 1666cc4c1da9SBarry Smith /*@ 166727f02ce8SMatthew G. Knepley PetscFEIntegrateHybridJacobian - Produce the boundary element Jacobian for a chunk of hybrid elements by quadrature integration 166827f02ce8SMatthew G. Knepley 166920f4b53cSBarry Smith Not Collective 167027f02ce8SMatthew G. Knepley 167127f02ce8SMatthew G. Knepley Input Parameters: 167207218a29SMatthew G. Knepley + ds - The `PetscDS` specifying the discretizations and continuum functions for the output 167307218a29SMatthew G. Knepley . dsIn - The `PetscDS` specifying the discretizations and continuum functions for the input 167427f02ce8SMatthew G. Knepley . jtype - The type of matrix pointwise functions that should be used 167545480ffeSMatthew G. Knepley . key - The (label+value, fieldI*Nf + fieldJ) being integrated 16765fedec97SMatthew G. Knepley . s - The side of the cell being integrated, 0 for negative and 1 for positive 167727f02ce8SMatthew G. Knepley . Ne - The number of elements in the chunk 167827f02ce8SMatthew G. Knepley . fgeom - The face geometry for each cell in the chunk 1679989fa639SBrad Aagaard . cgeom - The cell geometry for each neighbor cell in the chunk 168027f02ce8SMatthew G. Knepley . coefficients - The array of FEM basis coefficients for the elements for the Jacobian evaluation point 168127f02ce8SMatthew G. Knepley . coefficients_t - The array of FEM basis time derivative coefficients for the elements 168220f4b53cSBarry Smith . probAux - The `PetscDS` specifying the auxiliary discretizations 168327f02ce8SMatthew G. Knepley . coefficientsAux - The array of FEM auxiliary basis coefficients for the elements 168427f02ce8SMatthew G. Knepley . t - The time 168560225df5SJacob Faibussowitsch - u_tshift - A multiplier for the dF/du_t term (as opposed to the dF/du term) 168627f02ce8SMatthew G. Knepley 1687a4e35b19SJacob Faibussowitsch Output Parameter: 168827f02ce8SMatthew G. Knepley . elemMat - the element matrices for the Jacobian from each element 168927f02ce8SMatthew G. Knepley 169027f02ce8SMatthew G. Knepley Level: developer 169127f02ce8SMatthew G. Knepley 1692dce8aebaSBarry Smith Note: 1693dce8aebaSBarry Smith .vb 1694dce8aebaSBarry Smith Loop over batch of elements (e): 1695dce8aebaSBarry Smith Loop over element matrix entries (f,fc,g,gc --> i,j): 1696dce8aebaSBarry Smith Loop over quadrature points (q): 1697dce8aebaSBarry Smith Make u_q and gradU_q (loops over fields,Nb,Ncomp) 1698dce8aebaSBarry Smith elemMat[i,j] += \psi^{fc}_f(q) g0_{fc,gc}(u, \nabla u) \phi^{gc}_g(q) 1699dce8aebaSBarry Smith + \psi^{fc}_f(q) \cdot g1_{fc,gc,dg}(u, \nabla u) \nabla\phi^{gc}_g(q) 1700dce8aebaSBarry Smith + \nabla\psi^{fc}_f(q) \cdot g2_{fc,gc,df}(u, \nabla u) \phi^{gc}_g(q) 1701dce8aebaSBarry Smith + \nabla\psi^{fc}_f(q) \cdot g3_{fc,gc,df,dg}(u, \nabla u) \nabla\phi^{gc}_g(q) 1702dce8aebaSBarry Smith .ve 1703dce8aebaSBarry Smith 1704db781477SPatrick Sanan .seealso: `PetscFEIntegrateJacobian()`, `PetscFEIntegrateResidual()` 170527f02ce8SMatthew G. Knepley @*/ 1706989fa639SBrad Aagaard PetscErrorCode PetscFEIntegrateHybridJacobian(PetscDS ds, PetscDS dsIn, PetscFEJacobianType jtype, PetscFormKey key, PetscInt s, PetscInt Ne, PetscFEGeom *fgeom, PetscFEGeom *cgeom, const PetscScalar coefficients[], const PetscScalar coefficients_t[], PetscDS probAux, const PetscScalar coefficientsAux[], PetscReal t, PetscReal u_tshift, PetscScalar elemMat[]) 1707d71ae5a4SJacob Faibussowitsch { 170827f02ce8SMatthew G. Knepley PetscFE fe; 170945480ffeSMatthew G. Knepley PetscInt Nf; 171027f02ce8SMatthew G. Knepley 171127f02ce8SMatthew G. Knepley PetscFunctionBegin; 171245480ffeSMatthew G. Knepley PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1); 17139566063dSJacob Faibussowitsch PetscCall(PetscDSGetNumFields(ds, &Nf)); 17149566063dSJacob Faibussowitsch PetscCall(PetscDSGetDiscretization(ds, key.field / Nf, (PetscObject *)&fe)); 1715989fa639SBrad Aagaard if (fe->ops->integratehybridjacobian) PetscCall((*fe->ops->integratehybridjacobian)(ds, dsIn, jtype, key, s, Ne, fgeom, cgeom, coefficients, coefficients_t, probAux, coefficientsAux, t, u_tshift, elemMat)); 17163ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 171727f02ce8SMatthew G. Knepley } 171827f02ce8SMatthew G. Knepley 17192b99622eSMatthew G. Knepley /*@ 17202b99622eSMatthew G. Knepley PetscFEGetHeightSubspace - Get the subspace of this space for a mesh point of a given height 17212b99622eSMatthew G. Knepley 17222b99622eSMatthew G. Knepley Input Parameters: 17232b99622eSMatthew G. Knepley + fe - The finite element space 172420f4b53cSBarry Smith - height - The height of the `DMPLEX` point 17252b99622eSMatthew G. Knepley 17262b99622eSMatthew G. Knepley Output Parameter: 172720f4b53cSBarry Smith . subfe - The subspace of this `PetscFE` space 17282b99622eSMatthew G. Knepley 17292b99622eSMatthew G. Knepley Level: advanced 17302b99622eSMatthew G. Knepley 1731dce8aebaSBarry Smith Note: 1732dce8aebaSBarry Smith For example, if we want the subspace of this space for a face, we would choose height = 1. 1733dce8aebaSBarry Smith 1734db781477SPatrick Sanan .seealso: `PetscFECreateDefault()` 17352b99622eSMatthew G. Knepley @*/ 1736d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEGetHeightSubspace(PetscFE fe, PetscInt height, PetscFE *subfe) 1737d71ae5a4SJacob Faibussowitsch { 173820cf1dd8SToby Isaac PetscSpace P, subP; 173920cf1dd8SToby Isaac PetscDualSpace Q, subQ; 174020cf1dd8SToby Isaac PetscQuadrature subq; 174120cf1dd8SToby Isaac PetscInt dim, Nc; 174220cf1dd8SToby Isaac 174320cf1dd8SToby Isaac PetscFunctionBegin; 174420cf1dd8SToby Isaac PetscValidHeaderSpecific(fe, PETSCFE_CLASSID, 1); 17454f572ea9SToby Isaac PetscAssertPointer(subfe, 3); 174620cf1dd8SToby Isaac if (height == 0) { 174720cf1dd8SToby Isaac *subfe = fe; 17483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 174920cf1dd8SToby Isaac } 17509566063dSJacob Faibussowitsch PetscCall(PetscFEGetBasisSpace(fe, &P)); 17519566063dSJacob Faibussowitsch PetscCall(PetscFEGetDualSpace(fe, &Q)); 17529566063dSJacob Faibussowitsch PetscCall(PetscFEGetNumComponents(fe, &Nc)); 17539566063dSJacob Faibussowitsch PetscCall(PetscFEGetFaceQuadrature(fe, &subq)); 17549566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetDimension(Q, &dim)); 17551dca8a05SBarry 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); 17569566063dSJacob Faibussowitsch if (!fe->subspaces) PetscCall(PetscCalloc1(dim, &fe->subspaces)); 175720cf1dd8SToby Isaac if (height <= dim) { 175820cf1dd8SToby Isaac if (!fe->subspaces[height - 1]) { 1759665f567fSMatthew G. Knepley PetscFE sub = NULL; 17603f6b16c7SMatthew G. Knepley const char *name; 176120cf1dd8SToby Isaac 17629566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetHeightSubspace(P, height, &subP)); 17639566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetHeightSubspace(Q, height, &subQ)); 1764665f567fSMatthew G. Knepley if (subQ) { 17652dce792eSToby Isaac PetscCall(PetscObjectReference((PetscObject)subP)); 17662dce792eSToby Isaac PetscCall(PetscObjectReference((PetscObject)subQ)); 17672dce792eSToby Isaac PetscCall(PetscObjectReference((PetscObject)subq)); 17682dce792eSToby Isaac PetscCall(PetscFECreateFromSpaces(subP, subQ, subq, NULL, &sub)); 17692dce792eSToby Isaac } 17702dce792eSToby Isaac if (sub) { 17719566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)fe, &name)); 17722dce792eSToby Isaac if (name) PetscCall(PetscFESetName(sub, name)); 1773665f567fSMatthew G. Knepley } 177420cf1dd8SToby Isaac fe->subspaces[height - 1] = sub; 177520cf1dd8SToby Isaac } 177620cf1dd8SToby Isaac *subfe = fe->subspaces[height - 1]; 177720cf1dd8SToby Isaac } else { 177820cf1dd8SToby Isaac *subfe = NULL; 177920cf1dd8SToby Isaac } 17803ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 178120cf1dd8SToby Isaac } 178220cf1dd8SToby Isaac 178320cf1dd8SToby Isaac /*@ 1784a4e35b19SJacob Faibussowitsch PetscFERefine - Create a "refined" `PetscFE` object that refines the reference cell into 1785a4e35b19SJacob Faibussowitsch smaller copies. 178620cf1dd8SToby Isaac 178720f4b53cSBarry Smith Collective 178820cf1dd8SToby Isaac 178920cf1dd8SToby Isaac Input Parameter: 179020f4b53cSBarry Smith . fe - The initial `PetscFE` 179120cf1dd8SToby Isaac 179220cf1dd8SToby Isaac Output Parameter: 179320f4b53cSBarry Smith . feRef - The refined `PetscFE` 179420cf1dd8SToby Isaac 17952b99622eSMatthew G. Knepley Level: advanced 179620cf1dd8SToby Isaac 1797a4e35b19SJacob Faibussowitsch Notes: 1798a4e35b19SJacob Faibussowitsch This is typically used to generate a preconditioner for a higher order method from a lower order method on a 1799a4e35b19SJacob Faibussowitsch refined mesh having the same number of dofs (but more sparsity). It is also used to create an 1800a4e35b19SJacob Faibussowitsch interpolation between regularly refined meshes. 1801a4e35b19SJacob Faibussowitsch 1802db781477SPatrick Sanan .seealso: `PetscFEType`, `PetscFECreate()`, `PetscFESetType()` 180320cf1dd8SToby Isaac @*/ 1804d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFERefine(PetscFE fe, PetscFE *feRef) 1805d71ae5a4SJacob Faibussowitsch { 180620cf1dd8SToby Isaac PetscSpace P, Pref; 180720cf1dd8SToby Isaac PetscDualSpace Q, Qref; 180820cf1dd8SToby Isaac DM K, Kref; 180920cf1dd8SToby Isaac PetscQuadrature q, qref; 181020cf1dd8SToby Isaac const PetscReal *v0, *jac; 181120cf1dd8SToby Isaac PetscInt numComp, numSubelements; 18121ac17e89SToby Isaac PetscInt cStart, cEnd, c; 18131ac17e89SToby Isaac PetscDualSpace *cellSpaces; 181420cf1dd8SToby Isaac 181520cf1dd8SToby Isaac PetscFunctionBegin; 18169566063dSJacob Faibussowitsch PetscCall(PetscFEGetBasisSpace(fe, &P)); 18179566063dSJacob Faibussowitsch PetscCall(PetscFEGetDualSpace(fe, &Q)); 18189566063dSJacob Faibussowitsch PetscCall(PetscFEGetQuadrature(fe, &q)); 18199566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetDM(Q, &K)); 182020cf1dd8SToby Isaac /* Create space */ 18219566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)P)); 182220cf1dd8SToby Isaac Pref = P; 182320cf1dd8SToby Isaac /* Create dual space */ 18249566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceDuplicate(Q, &Qref)); 18259566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetType(Qref, PETSCDUALSPACEREFINED)); 18269566063dSJacob Faibussowitsch PetscCall(DMRefine(K, PetscObjectComm((PetscObject)fe), &Kref)); 1827e44f6aebSMatthew G. Knepley PetscCall(DMGetCoordinatesLocalSetUp(Kref)); 18289566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetDM(Qref, Kref)); 18299566063dSJacob Faibussowitsch PetscCall(DMPlexGetHeightStratum(Kref, 0, &cStart, &cEnd)); 18309566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(cEnd - cStart, &cellSpaces)); 18311ac17e89SToby Isaac /* TODO: fix for non-uniform refinement */ 18321ac17e89SToby Isaac for (c = 0; c < cEnd - cStart; c++) cellSpaces[c] = Q; 18339566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceRefinedSetCellSpaces(Qref, cellSpaces)); 18349566063dSJacob Faibussowitsch PetscCall(PetscFree(cellSpaces)); 18359566063dSJacob Faibussowitsch PetscCall(DMDestroy(&Kref)); 18369566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetUp(Qref)); 183720cf1dd8SToby Isaac /* Create element */ 18389566063dSJacob Faibussowitsch PetscCall(PetscFECreate(PetscObjectComm((PetscObject)fe), feRef)); 18399566063dSJacob Faibussowitsch PetscCall(PetscFESetType(*feRef, PETSCFECOMPOSITE)); 18409566063dSJacob Faibussowitsch PetscCall(PetscFESetBasisSpace(*feRef, Pref)); 18419566063dSJacob Faibussowitsch PetscCall(PetscFESetDualSpace(*feRef, Qref)); 18429566063dSJacob Faibussowitsch PetscCall(PetscFEGetNumComponents(fe, &numComp)); 18439566063dSJacob Faibussowitsch PetscCall(PetscFESetNumComponents(*feRef, numComp)); 18449566063dSJacob Faibussowitsch PetscCall(PetscFESetUp(*feRef)); 18459566063dSJacob Faibussowitsch PetscCall(PetscSpaceDestroy(&Pref)); 18469566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceDestroy(&Qref)); 184720cf1dd8SToby Isaac /* Create quadrature */ 18489566063dSJacob Faibussowitsch PetscCall(PetscFECompositeGetMapping(*feRef, &numSubelements, &v0, &jac, NULL)); 18499566063dSJacob Faibussowitsch PetscCall(PetscQuadratureExpandComposite(q, numSubelements, v0, jac, &qref)); 18509566063dSJacob Faibussowitsch PetscCall(PetscFESetQuadrature(*feRef, qref)); 18519566063dSJacob Faibussowitsch PetscCall(PetscQuadratureDestroy(&qref)); 18523ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 185320cf1dd8SToby Isaac } 185420cf1dd8SToby Isaac 1855d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFESetDefaultName_Private(PetscFE fe) 1856d71ae5a4SJacob Faibussowitsch { 18577c48043bSMatthew G. Knepley PetscSpace P; 18587c48043bSMatthew G. Knepley PetscDualSpace Q; 18597c48043bSMatthew G. Knepley DM K; 18607c48043bSMatthew G. Knepley DMPolytopeType ct; 18617c48043bSMatthew G. Knepley PetscInt degree; 18627c48043bSMatthew G. Knepley char name[64]; 18637c48043bSMatthew G. Knepley 18647c48043bSMatthew G. Knepley PetscFunctionBegin; 18657c48043bSMatthew G. Knepley PetscCall(PetscFEGetBasisSpace(fe, &P)); 18667c48043bSMatthew G. Knepley PetscCall(PetscSpaceGetDegree(P, °ree, NULL)); 18677c48043bSMatthew G. Knepley PetscCall(PetscFEGetDualSpace(fe, &Q)); 18687c48043bSMatthew G. Knepley PetscCall(PetscDualSpaceGetDM(Q, &K)); 18697c48043bSMatthew G. Knepley PetscCall(DMPlexGetCellType(K, 0, &ct)); 18707c48043bSMatthew G. Knepley switch (ct) { 18717c48043bSMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 18727c48043bSMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: 18737c48043bSMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 18747c48043bSMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 18757c48043bSMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 1876d71ae5a4SJacob Faibussowitsch case DM_POLYTOPE_QUAD_PRISM_TENSOR: 1877d71ae5a4SJacob Faibussowitsch PetscCall(PetscSNPrintf(name, sizeof(name), "Q%" PetscInt_FMT, degree)); 1878d71ae5a4SJacob Faibussowitsch break; 18797c48043bSMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 1880d71ae5a4SJacob Faibussowitsch case DM_POLYTOPE_TETRAHEDRON: 1881d71ae5a4SJacob Faibussowitsch PetscCall(PetscSNPrintf(name, sizeof(name), "P%" PetscInt_FMT, degree)); 1882d71ae5a4SJacob Faibussowitsch break; 18837c48043bSMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM: 1884d71ae5a4SJacob Faibussowitsch case DM_POLYTOPE_TRI_PRISM_TENSOR: 1885d71ae5a4SJacob Faibussowitsch PetscCall(PetscSNPrintf(name, sizeof(name), "P%" PetscInt_FMT "xQ%" PetscInt_FMT, degree, degree)); 1886d71ae5a4SJacob Faibussowitsch break; 1887d71ae5a4SJacob Faibussowitsch default: 1888d71ae5a4SJacob Faibussowitsch PetscCall(PetscSNPrintf(name, sizeof(name), "FE")); 18897c48043bSMatthew G. Knepley } 18907c48043bSMatthew G. Knepley PetscCall(PetscFESetName(fe, name)); 18913ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 18927c48043bSMatthew G. Knepley } 18937c48043bSMatthew G. Knepley 18947c48043bSMatthew G. Knepley /*@ 1895dce8aebaSBarry Smith PetscFECreateFromSpaces - Create a `PetscFE` from the basis and dual spaces 18967c48043bSMatthew G. Knepley 18977c48043bSMatthew G. Knepley Collective 18987c48043bSMatthew G. Knepley 18997c48043bSMatthew G. Knepley Input Parameters: 19007c48043bSMatthew G. Knepley + P - The basis space 19017c48043bSMatthew G. Knepley . Q - The dual space 19027c48043bSMatthew G. Knepley . q - The cell quadrature 19037c48043bSMatthew G. Knepley - fq - The face quadrature 19047c48043bSMatthew G. Knepley 19057c48043bSMatthew G. Knepley Output Parameter: 190620f4b53cSBarry Smith . fem - The `PetscFE` object 19077c48043bSMatthew G. Knepley 19087c48043bSMatthew G. Knepley Level: beginner 19097c48043bSMatthew G. Knepley 1910dce8aebaSBarry Smith Note: 1911dce8aebaSBarry 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. 1912dce8aebaSBarry Smith 1913dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscSpace`, `PetscDualSpace`, `PetscQuadrature`, 1914dce8aebaSBarry Smith `PetscFECreateLagrangeByCell()`, `PetscFECreateDefault()`, `PetscFECreateByCell()`, `PetscFECreate()`, `PetscSpaceCreate()`, `PetscDualSpaceCreate()` 19157c48043bSMatthew G. Knepley @*/ 1916d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFECreateFromSpaces(PetscSpace P, PetscDualSpace Q, PetscQuadrature q, PetscQuadrature fq, PetscFE *fem) 1917d71ae5a4SJacob Faibussowitsch { 19187c48043bSMatthew G. Knepley PetscInt Nc; 19192dce792eSToby Isaac PetscInt p_Ns = -1, p_Nc = -1, q_Ns = -1, q_Nc = -1; 19202dce792eSToby Isaac PetscBool p_is_uniform_sum = PETSC_FALSE, p_interleave_basis = PETSC_FALSE, p_interleave_components = PETSC_FALSE; 19212dce792eSToby Isaac PetscBool q_is_uniform_sum = PETSC_FALSE, q_interleave_basis = PETSC_FALSE, q_interleave_components = PETSC_FALSE; 19227c48043bSMatthew G. Knepley const char *prefix; 19237c48043bSMatthew G. Knepley 19247c48043bSMatthew G. Knepley PetscFunctionBegin; 19252dce792eSToby Isaac PetscCall(PetscObjectTypeCompare((PetscObject)P, PETSCSPACESUM, &p_is_uniform_sum)); 19262dce792eSToby Isaac if (p_is_uniform_sum) { 19272dce792eSToby Isaac PetscSpace subsp_0 = NULL; 19282dce792eSToby Isaac PetscCall(PetscSpaceSumGetNumSubspaces(P, &p_Ns)); 19292dce792eSToby Isaac PetscCall(PetscSpaceGetNumComponents(P, &p_Nc)); 19302dce792eSToby Isaac PetscCall(PetscSpaceSumGetConcatenate(P, &p_is_uniform_sum)); 19312dce792eSToby Isaac PetscCall(PetscSpaceSumGetInterleave(P, &p_interleave_basis, &p_interleave_components)); 19322dce792eSToby Isaac for (PetscInt s = 0; s < p_Ns; s++) { 19332dce792eSToby Isaac PetscSpace subsp; 19342dce792eSToby Isaac 19352dce792eSToby Isaac PetscCall(PetscSpaceSumGetSubspace(P, s, &subsp)); 19362dce792eSToby Isaac if (!s) { 19372dce792eSToby Isaac subsp_0 = subsp; 19382dce792eSToby Isaac } else if (subsp != subsp_0) { 19392dce792eSToby Isaac p_is_uniform_sum = PETSC_FALSE; 19402dce792eSToby Isaac } 19412dce792eSToby Isaac } 19422dce792eSToby Isaac } 19432dce792eSToby Isaac PetscCall(PetscObjectTypeCompare((PetscObject)Q, PETSCDUALSPACESUM, &q_is_uniform_sum)); 19442dce792eSToby Isaac if (q_is_uniform_sum) { 19452dce792eSToby Isaac PetscDualSpace subsp_0 = NULL; 19462dce792eSToby Isaac PetscCall(PetscDualSpaceSumGetNumSubspaces(Q, &q_Ns)); 19472dce792eSToby Isaac PetscCall(PetscDualSpaceGetNumComponents(Q, &q_Nc)); 19482dce792eSToby Isaac PetscCall(PetscDualSpaceSumGetConcatenate(Q, &q_is_uniform_sum)); 19492dce792eSToby Isaac PetscCall(PetscDualSpaceSumGetInterleave(Q, &q_interleave_basis, &q_interleave_components)); 19502dce792eSToby Isaac for (PetscInt s = 0; s < q_Ns; s++) { 19512dce792eSToby Isaac PetscDualSpace subsp; 19522dce792eSToby Isaac 19532dce792eSToby Isaac PetscCall(PetscDualSpaceSumGetSubspace(Q, s, &subsp)); 19542dce792eSToby Isaac if (!s) { 19552dce792eSToby Isaac subsp_0 = subsp; 19562dce792eSToby Isaac } else if (subsp != subsp_0) { 19572dce792eSToby Isaac q_is_uniform_sum = PETSC_FALSE; 19582dce792eSToby Isaac } 19592dce792eSToby Isaac } 19602dce792eSToby Isaac } 19612dce792eSToby 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)) { 19622dce792eSToby Isaac PetscSpace scalar_space; 19632dce792eSToby Isaac PetscDualSpace scalar_dspace; 19642dce792eSToby Isaac PetscFE scalar_fe; 19652dce792eSToby Isaac 19662dce792eSToby Isaac PetscCall(PetscSpaceSumGetSubspace(P, 0, &scalar_space)); 19672dce792eSToby Isaac PetscCall(PetscDualSpaceSumGetSubspace(Q, 0, &scalar_dspace)); 19682dce792eSToby Isaac PetscCall(PetscObjectReference((PetscObject)scalar_space)); 19692dce792eSToby Isaac PetscCall(PetscObjectReference((PetscObject)scalar_dspace)); 19702dce792eSToby Isaac PetscCall(PetscObjectReference((PetscObject)q)); 19712dce792eSToby Isaac PetscCall(PetscObjectReference((PetscObject)fq)); 19722dce792eSToby Isaac PetscCall(PetscFECreateFromSpaces(scalar_space, scalar_dspace, q, fq, &scalar_fe)); 19732dce792eSToby Isaac PetscCall(PetscFECreateVector(scalar_fe, p_Ns, p_interleave_basis, p_interleave_components, fem)); 19742dce792eSToby Isaac PetscCall(PetscFEDestroy(&scalar_fe)); 19752dce792eSToby Isaac } else { 19767c48043bSMatthew G. Knepley PetscCall(PetscFECreate(PetscObjectComm((PetscObject)P), fem)); 19777c48043bSMatthew G. Knepley PetscCall(PetscFESetType(*fem, PETSCFEBASIC)); 19782dce792eSToby Isaac } 19797c48043bSMatthew G. Knepley PetscCall(PetscSpaceGetNumComponents(P, &Nc)); 19807c48043bSMatthew G. Knepley PetscCall(PetscFESetNumComponents(*fem, Nc)); 19812dce792eSToby Isaac PetscCall(PetscFESetBasisSpace(*fem, P)); 19822dce792eSToby Isaac PetscCall(PetscFESetDualSpace(*fem, Q)); 19832dce792eSToby Isaac PetscCall(PetscObjectGetOptionsPrefix((PetscObject)P, &prefix)); 19842dce792eSToby Isaac PetscCall(PetscObjectSetOptionsPrefix((PetscObject)*fem, prefix)); 19857c48043bSMatthew G. Knepley PetscCall(PetscFESetUp(*fem)); 19867c48043bSMatthew G. Knepley PetscCall(PetscSpaceDestroy(&P)); 19877c48043bSMatthew G. Knepley PetscCall(PetscDualSpaceDestroy(&Q)); 19887c48043bSMatthew G. Knepley PetscCall(PetscFESetQuadrature(*fem, q)); 19897c48043bSMatthew G. Knepley PetscCall(PetscFESetFaceQuadrature(*fem, fq)); 19907c48043bSMatthew G. Knepley PetscCall(PetscQuadratureDestroy(&q)); 19917c48043bSMatthew G. Knepley PetscCall(PetscQuadratureDestroy(&fq)); 19927c48043bSMatthew G. Knepley PetscCall(PetscFESetDefaultName_Private(*fem)); 19933ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 19947c48043bSMatthew G. Knepley } 19957c48043bSMatthew G. Knepley 1996d71ae5a4SJacob 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) 1997d71ae5a4SJacob Faibussowitsch { 19982df84da0SMatthew G. Knepley DM K; 19992df84da0SMatthew G. Knepley PetscSpace P; 20002df84da0SMatthew G. Knepley PetscDualSpace Q; 20017c48043bSMatthew G. Knepley PetscQuadrature q, fq; 20022df84da0SMatthew G. Knepley PetscBool tensor; 20032df84da0SMatthew G. Knepley 20042df84da0SMatthew G. Knepley PetscFunctionBegin; 20054f572ea9SToby Isaac if (prefix) PetscAssertPointer(prefix, 5); 20064f572ea9SToby Isaac PetscAssertPointer(fem, 9); 20072df84da0SMatthew G. Knepley switch (ct) { 20082df84da0SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 20092df84da0SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: 20102df84da0SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 20112df84da0SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 20122df84da0SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 2013d71ae5a4SJacob Faibussowitsch case DM_POLYTOPE_QUAD_PRISM_TENSOR: 2014d71ae5a4SJacob Faibussowitsch tensor = PETSC_TRUE; 2015d71ae5a4SJacob Faibussowitsch break; 2016d71ae5a4SJacob Faibussowitsch default: 2017d71ae5a4SJacob Faibussowitsch tensor = PETSC_FALSE; 20182df84da0SMatthew G. Knepley } 20192df84da0SMatthew G. Knepley /* Create space */ 20209566063dSJacob Faibussowitsch PetscCall(PetscSpaceCreate(comm, &P)); 20219566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetType(P, PETSCSPACEPOLYNOMIAL)); 20229566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)P, prefix)); 20239566063dSJacob Faibussowitsch PetscCall(PetscSpacePolynomialSetTensor(P, tensor)); 20249566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetNumComponents(P, Nc)); 20259566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetNumVariables(P, dim)); 20262df84da0SMatthew G. Knepley if (degree >= 0) { 20279566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetDegree(P, degree, PETSC_DETERMINE)); 2028cfd33b42SLisandro Dalcin if (ct == DM_POLYTOPE_TRI_PRISM || ct == DM_POLYTOPE_TRI_PRISM_TENSOR) { 20292df84da0SMatthew G. Knepley PetscSpace Pend, Pside; 20302df84da0SMatthew G. Knepley 20312dce792eSToby Isaac PetscCall(PetscSpaceSetNumComponents(P, 1)); 20329566063dSJacob Faibussowitsch PetscCall(PetscSpaceCreate(comm, &Pend)); 20339566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetType(Pend, PETSCSPACEPOLYNOMIAL)); 20349566063dSJacob Faibussowitsch PetscCall(PetscSpacePolynomialSetTensor(Pend, PETSC_FALSE)); 20352dce792eSToby Isaac PetscCall(PetscSpaceSetNumComponents(Pend, 1)); 20369566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetNumVariables(Pend, dim - 1)); 20379566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetDegree(Pend, degree, PETSC_DETERMINE)); 20389566063dSJacob Faibussowitsch PetscCall(PetscSpaceCreate(comm, &Pside)); 20399566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetType(Pside, PETSCSPACEPOLYNOMIAL)); 20409566063dSJacob Faibussowitsch PetscCall(PetscSpacePolynomialSetTensor(Pside, PETSC_FALSE)); 20419566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetNumComponents(Pside, 1)); 20429566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetNumVariables(Pside, 1)); 20439566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetDegree(Pside, degree, PETSC_DETERMINE)); 20449566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetType(P, PETSCSPACETENSOR)); 20459566063dSJacob Faibussowitsch PetscCall(PetscSpaceTensorSetNumSubspaces(P, 2)); 20469566063dSJacob Faibussowitsch PetscCall(PetscSpaceTensorSetSubspace(P, 0, Pend)); 20479566063dSJacob Faibussowitsch PetscCall(PetscSpaceTensorSetSubspace(P, 1, Pside)); 20489566063dSJacob Faibussowitsch PetscCall(PetscSpaceDestroy(&Pend)); 20499566063dSJacob Faibussowitsch PetscCall(PetscSpaceDestroy(&Pside)); 20502dce792eSToby Isaac 20512dce792eSToby Isaac if (Nc > 1) { 20522dce792eSToby Isaac PetscSpace scalar_P = P; 20532dce792eSToby Isaac 20542dce792eSToby Isaac PetscCall(PetscSpaceCreate(comm, &P)); 20552dce792eSToby Isaac PetscCall(PetscSpaceSetNumVariables(P, dim)); 20562dce792eSToby Isaac PetscCall(PetscSpaceSetNumComponents(P, Nc)); 20572dce792eSToby Isaac PetscCall(PetscSpaceSetType(P, PETSCSPACESUM)); 20582dce792eSToby Isaac PetscCall(PetscSpaceSumSetNumSubspaces(P, Nc)); 20592dce792eSToby Isaac PetscCall(PetscSpaceSumSetConcatenate(P, PETSC_TRUE)); 20602dce792eSToby Isaac PetscCall(PetscSpaceSumSetInterleave(P, PETSC_TRUE, PETSC_FALSE)); 20612dce792eSToby Isaac for (PetscInt i = 0; i < Nc; i++) PetscCall(PetscSpaceSumSetSubspace(P, i, scalar_P)); 20622dce792eSToby Isaac PetscCall(PetscSpaceDestroy(&scalar_P)); 20632dce792eSToby Isaac } 20642df84da0SMatthew G. Knepley } 20652df84da0SMatthew G. Knepley } 20669566063dSJacob Faibussowitsch if (setFromOptions) PetscCall(PetscSpaceSetFromOptions(P)); 20679566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetUp(P)); 20689566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetDegree(P, °ree, NULL)); 20699566063dSJacob Faibussowitsch PetscCall(PetscSpacePolynomialGetTensor(P, &tensor)); 20709566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetNumComponents(P, &Nc)); 20712df84da0SMatthew G. Knepley /* Create dual space */ 20729566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceCreate(comm, &Q)); 20739566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetType(Q, PETSCDUALSPACELAGRANGE)); 20749566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)Q, prefix)); 20759566063dSJacob Faibussowitsch PetscCall(DMPlexCreateReferenceCell(PETSC_COMM_SELF, ct, &K)); 20769566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetDM(Q, K)); 20779566063dSJacob Faibussowitsch PetscCall(DMDestroy(&K)); 20789566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetNumComponents(Q, Nc)); 20799566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetOrder(Q, degree)); 20809566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceLagrangeSetTensor(Q, (tensor || (ct == DM_POLYTOPE_TRI_PRISM)) ? PETSC_TRUE : PETSC_FALSE)); 20819566063dSJacob Faibussowitsch if (setFromOptions) PetscCall(PetscDualSpaceSetFromOptions(Q)); 20829566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetUp(Q)); 20837c48043bSMatthew G. Knepley /* Create quadrature */ 2084f2c64c88SMatthew G. Knepley PetscDTSimplexQuadratureType qtype = PETSCDTSIMPLEXQUAD_DEFAULT; 2085f2c64c88SMatthew G. Knepley 20862df84da0SMatthew G. Knepley qorder = qorder >= 0 ? qorder : degree; 20872df84da0SMatthew G. Knepley if (setFromOptions) { 20887c48043bSMatthew G. Knepley PetscObjectOptionsBegin((PetscObject)P); 20899566063dSJacob Faibussowitsch PetscCall(PetscOptionsBoundedInt("-petscfe_default_quadrature_order", "Quadrature order is one less than quadrature points per edge", "PetscFECreateDefault", qorder, &qorder, NULL, 0)); 2090f2c64c88SMatthew G. Knepley PetscCall(PetscOptionsEnum("-petscfe_default_quadrature_type", "Simplex quadrature type", "PetscDTSimplexQuadratureType", PetscDTSimplexQuadratureTypes, (PetscEnum)qtype, (PetscEnum *)&qtype, NULL)); 2091d0609cedSBarry Smith PetscOptionsEnd(); 20922df84da0SMatthew G. Knepley } 2093f2c64c88SMatthew G. Knepley PetscCall(PetscDTCreateQuadratureByCell(ct, qorder, qtype, &q, &fq)); 20947c48043bSMatthew G. Knepley /* Create finite element */ 20957c48043bSMatthew G. Knepley PetscCall(PetscFECreateFromSpaces(P, Q, q, fq, fem)); 20967c48043bSMatthew G. Knepley if (setFromOptions) PetscCall(PetscFESetFromOptions(*fem)); 20973ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 20982df84da0SMatthew G. Knepley } 20992df84da0SMatthew G. Knepley 2100cc4c1da9SBarry Smith /*@ 210120f4b53cSBarry Smith PetscFECreateDefault - Create a `PetscFE` for basic FEM computation 210220cf1dd8SToby Isaac 2103d083f849SBarry Smith Collective 210420cf1dd8SToby Isaac 210520cf1dd8SToby Isaac Input Parameters: 21067be5e748SToby Isaac + comm - The MPI comm 210720cf1dd8SToby Isaac . dim - The spatial dimension 210820cf1dd8SToby Isaac . Nc - The number of components 210920cf1dd8SToby Isaac . isSimplex - Flag for simplex reference cell, otherwise its a tensor product 211020f4b53cSBarry Smith . prefix - The options prefix, or `NULL` 211120f4b53cSBarry Smith - qorder - The quadrature order or `PETSC_DETERMINE` to use `PetscSpace` polynomial degree 211220cf1dd8SToby Isaac 211320cf1dd8SToby Isaac Output Parameter: 211420f4b53cSBarry Smith . fem - The `PetscFE` object 211520cf1dd8SToby Isaac 2116dce8aebaSBarry Smith Level: beginner 2117dce8aebaSBarry Smith 2118e703855dSMatthew G. Knepley Note: 21198f2aacc6SMatthew 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. 2120e703855dSMatthew G. Knepley 2121db781477SPatrick Sanan .seealso: `PetscFECreateLagrange()`, `PetscFECreateByCell()`, `PetscSpaceSetFromOptions()`, `PetscDualSpaceSetFromOptions()`, `PetscFESetFromOptions()`, `PetscFECreate()`, `PetscSpaceCreate()`, `PetscDualSpaceCreate()` 212220cf1dd8SToby Isaac @*/ 2123d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFECreateDefault(MPI_Comm comm, PetscInt dim, PetscInt Nc, PetscBool isSimplex, const char prefix[], PetscInt qorder, PetscFE *fem) 2124d71ae5a4SJacob Faibussowitsch { 212520cf1dd8SToby Isaac PetscFunctionBegin; 21269566063dSJacob Faibussowitsch PetscCall(PetscFECreate_Internal(comm, dim, Nc, DMPolytopeTypeSimpleShape(dim, isSimplex), prefix, PETSC_DECIDE, qorder, PETSC_TRUE, fem)); 21273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 212820cf1dd8SToby Isaac } 21292df84da0SMatthew G. Knepley 2130cc4c1da9SBarry Smith /*@ 213120f4b53cSBarry Smith PetscFECreateByCell - Create a `PetscFE` for basic FEM computation 21322df84da0SMatthew G. Knepley 21332df84da0SMatthew G. Knepley Collective 21342df84da0SMatthew G. Knepley 21352df84da0SMatthew G. Knepley Input Parameters: 21362df84da0SMatthew G. Knepley + comm - The MPI comm 21372df84da0SMatthew G. Knepley . dim - The spatial dimension 21382df84da0SMatthew G. Knepley . Nc - The number of components 21392df84da0SMatthew G. Knepley . ct - The celltype of the reference cell 214020f4b53cSBarry Smith . prefix - The options prefix, or `NULL` 214120f4b53cSBarry Smith - qorder - The quadrature order or `PETSC_DETERMINE` to use `PetscSpace` polynomial degree 21422df84da0SMatthew G. Knepley 21432df84da0SMatthew G. Knepley Output Parameter: 214420f4b53cSBarry Smith . fem - The `PetscFE` object 21452df84da0SMatthew G. Knepley 2146dce8aebaSBarry Smith Level: beginner 2147dce8aebaSBarry Smith 21482df84da0SMatthew G. Knepley Note: 21492df84da0SMatthew 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. 21502df84da0SMatthew G. Knepley 2151db781477SPatrick Sanan .seealso: `PetscFECreateDefault()`, `PetscFECreateLagrange()`, `PetscSpaceSetFromOptions()`, `PetscDualSpaceSetFromOptions()`, `PetscFESetFromOptions()`, `PetscFECreate()`, `PetscSpaceCreate()`, `PetscDualSpaceCreate()` 21522df84da0SMatthew G. Knepley @*/ 2153d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFECreateByCell(MPI_Comm comm, PetscInt dim, PetscInt Nc, DMPolytopeType ct, const char prefix[], PetscInt qorder, PetscFE *fem) 2154d71ae5a4SJacob Faibussowitsch { 21552df84da0SMatthew G. Knepley PetscFunctionBegin; 21569566063dSJacob Faibussowitsch PetscCall(PetscFECreate_Internal(comm, dim, Nc, ct, prefix, PETSC_DECIDE, qorder, PETSC_TRUE, fem)); 21573ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 215820cf1dd8SToby Isaac } 21593f6b16c7SMatthew G. Knepley 2160e703855dSMatthew G. Knepley /*@ 216120f4b53cSBarry Smith PetscFECreateLagrange - Create a `PetscFE` for the basic Lagrange space of degree k 2162e703855dSMatthew G. Knepley 2163e703855dSMatthew G. Knepley Collective 2164e703855dSMatthew G. Knepley 2165e703855dSMatthew G. Knepley Input Parameters: 2166e703855dSMatthew G. Knepley + comm - The MPI comm 2167e703855dSMatthew G. Knepley . dim - The spatial dimension 2168e703855dSMatthew G. Knepley . Nc - The number of components 2169e703855dSMatthew G. Knepley . isSimplex - Flag for simplex reference cell, otherwise its a tensor product 2170e703855dSMatthew G. Knepley . k - The degree k of the space 217120f4b53cSBarry Smith - qorder - The quadrature order or `PETSC_DETERMINE` to use `PetscSpace` polynomial degree 2172e703855dSMatthew G. Knepley 2173e703855dSMatthew G. Knepley Output Parameter: 217420f4b53cSBarry Smith . fem - The `PetscFE` object 2175e703855dSMatthew G. Knepley 2176e703855dSMatthew G. Knepley Level: beginner 2177e703855dSMatthew G. Knepley 2178dce8aebaSBarry Smith Note: 2179e703855dSMatthew 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. 2180e703855dSMatthew G. Knepley 2181db781477SPatrick Sanan .seealso: `PetscFECreateLagrangeByCell()`, `PetscFECreateDefault()`, `PetscFECreateByCell()`, `PetscFECreate()`, `PetscSpaceCreate()`, `PetscDualSpaceCreate()` 2182e703855dSMatthew G. Knepley @*/ 2183d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFECreateLagrange(MPI_Comm comm, PetscInt dim, PetscInt Nc, PetscBool isSimplex, PetscInt k, PetscInt qorder, PetscFE *fem) 2184d71ae5a4SJacob Faibussowitsch { 2185e703855dSMatthew G. Knepley PetscFunctionBegin; 21869566063dSJacob Faibussowitsch PetscCall(PetscFECreate_Internal(comm, dim, Nc, DMPolytopeTypeSimpleShape(dim, isSimplex), NULL, k, qorder, PETSC_FALSE, fem)); 21873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2188e703855dSMatthew G. Knepley } 21892df84da0SMatthew G. Knepley 21902df84da0SMatthew G. Knepley /*@ 219120f4b53cSBarry Smith PetscFECreateLagrangeByCell - Create a `PetscFE` for the basic Lagrange space of degree k 21922df84da0SMatthew G. Knepley 21932df84da0SMatthew G. Knepley Collective 21942df84da0SMatthew G. Knepley 21952df84da0SMatthew G. Knepley Input Parameters: 21962df84da0SMatthew G. Knepley + comm - The MPI comm 21972df84da0SMatthew G. Knepley . dim - The spatial dimension 21982df84da0SMatthew G. Knepley . Nc - The number of components 21992df84da0SMatthew G. Knepley . ct - The celltype of the reference cell 22002df84da0SMatthew G. Knepley . k - The degree k of the space 220120f4b53cSBarry Smith - qorder - The quadrature order or `PETSC_DETERMINE` to use `PetscSpace` polynomial degree 22022df84da0SMatthew G. Knepley 22032df84da0SMatthew G. Knepley Output Parameter: 220420f4b53cSBarry Smith . fem - The `PetscFE` object 22052df84da0SMatthew G. Knepley 22062df84da0SMatthew G. Knepley Level: beginner 22072df84da0SMatthew G. Knepley 2208dce8aebaSBarry Smith Note: 22092df84da0SMatthew 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. 22102df84da0SMatthew G. Knepley 2211db781477SPatrick Sanan .seealso: `PetscFECreateLagrange()`, `PetscFECreateDefault()`, `PetscFECreateByCell()`, `PetscFECreate()`, `PetscSpaceCreate()`, `PetscDualSpaceCreate()` 22122df84da0SMatthew G. Knepley @*/ 2213d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFECreateLagrangeByCell(MPI_Comm comm, PetscInt dim, PetscInt Nc, DMPolytopeType ct, PetscInt k, PetscInt qorder, PetscFE *fem) 2214d71ae5a4SJacob Faibussowitsch { 22152df84da0SMatthew G. Knepley PetscFunctionBegin; 22169566063dSJacob Faibussowitsch PetscCall(PetscFECreate_Internal(comm, dim, Nc, ct, NULL, k, qorder, PETSC_FALSE, fem)); 22173ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2218e703855dSMatthew G. Knepley } 2219e703855dSMatthew G. Knepley 2220cc4c1da9SBarry Smith /*@ 2221bb4b53efSMatthew G. Knepley PetscFELimitDegree - Copy a `PetscFE` but limit the degree to be in the given range 2222bb4b53efSMatthew G. Knepley 2223bb4b53efSMatthew G. Knepley Collective 2224bb4b53efSMatthew G. Knepley 2225bb4b53efSMatthew G. Knepley Input Parameters: 2226bb4b53efSMatthew G. Knepley + fe - The `PetscFE` 2227bb4b53efSMatthew G. Knepley . minDegree - The minimum degree, or `PETSC_DETERMINE` for no limit 2228bb4b53efSMatthew G. Knepley - maxDegree - The maximum degree, or `PETSC_DETERMINE` for no limit 2229bb4b53efSMatthew G. Knepley 2230bb4b53efSMatthew G. Knepley Output Parameter: 2231bb4b53efSMatthew G. Knepley . newfe - The `PetscFE` object 2232bb4b53efSMatthew G. Knepley 2233bb4b53efSMatthew G. Knepley Level: advanced 2234bb4b53efSMatthew G. Knepley 2235bb4b53efSMatthew G. Knepley Note: 2236bb4b53efSMatthew G. Knepley This currently only works for Lagrange elements. 2237bb4b53efSMatthew G. Knepley 2238bb4b53efSMatthew G. Knepley .seealso: `PetscFECreateLagrange()`, `PetscFECreateDefault()`, `PetscFECreateByCell()`, `PetscFECreate()`, `PetscSpaceCreate()`, `PetscDualSpaceCreate()` 2239bb4b53efSMatthew G. Knepley @*/ 2240bb4b53efSMatthew G. Knepley PetscErrorCode PetscFELimitDegree(PetscFE fe, PetscInt minDegree, PetscInt maxDegree, PetscFE *newfe) 2241bb4b53efSMatthew G. Knepley { 2242bb4b53efSMatthew G. Knepley PetscDualSpace Q; 2243bb4b53efSMatthew G. Knepley PetscBool islag, issum; 2244bb4b53efSMatthew G. Knepley PetscInt oldk = 0, k; 2245bb4b53efSMatthew G. Knepley 2246bb4b53efSMatthew G. Knepley PetscFunctionBegin; 2247bb4b53efSMatthew G. Knepley PetscCall(PetscFEGetDualSpace(fe, &Q)); 2248bb4b53efSMatthew G. Knepley PetscCall(PetscObjectTypeCompare((PetscObject)Q, PETSCDUALSPACELAGRANGE, &islag)); 2249bb4b53efSMatthew G. Knepley PetscCall(PetscObjectTypeCompare((PetscObject)Q, PETSCDUALSPACESUM, &issum)); 2250bb4b53efSMatthew G. Knepley if (islag) { 2251bb4b53efSMatthew G. Knepley PetscCall(PetscDualSpaceGetOrder(Q, &oldk)); 2252bb4b53efSMatthew G. Knepley } else if (issum) { 2253bb4b53efSMatthew G. Knepley PetscDualSpace subQ; 2254bb4b53efSMatthew G. Knepley 2255bb4b53efSMatthew G. Knepley PetscCall(PetscDualSpaceSumGetSubspace(Q, 0, &subQ)); 2256bb4b53efSMatthew G. Knepley PetscCall(PetscDualSpaceGetOrder(subQ, &oldk)); 2257bb4b53efSMatthew G. Knepley } else { 2258bb4b53efSMatthew G. Knepley PetscCall(PetscObjectReference((PetscObject)fe)); 2259bb4b53efSMatthew G. Knepley *newfe = fe; 2260bb4b53efSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 2261bb4b53efSMatthew G. Knepley } 2262bb4b53efSMatthew G. Knepley k = oldk; 2263bb4b53efSMatthew G. Knepley if (minDegree >= 0) k = PetscMax(k, minDegree); 2264bb4b53efSMatthew G. Knepley if (maxDegree >= 0) k = PetscMin(k, maxDegree); 2265bb4b53efSMatthew G. Knepley if (k != oldk) { 2266bb4b53efSMatthew G. Knepley DM K; 2267bb4b53efSMatthew G. Knepley PetscSpace P; 2268bb4b53efSMatthew G. Knepley PetscQuadrature q; 2269bb4b53efSMatthew G. Knepley DMPolytopeType ct; 2270bb4b53efSMatthew G. Knepley PetscInt dim, Nc; 2271bb4b53efSMatthew G. Knepley 2272bb4b53efSMatthew G. Knepley PetscCall(PetscFEGetBasisSpace(fe, &P)); 2273bb4b53efSMatthew G. Knepley PetscCall(PetscSpaceGetNumVariables(P, &dim)); 2274bb4b53efSMatthew G. Knepley PetscCall(PetscSpaceGetNumComponents(P, &Nc)); 2275bb4b53efSMatthew G. Knepley PetscCall(PetscDualSpaceGetDM(Q, &K)); 2276bb4b53efSMatthew G. Knepley PetscCall(DMPlexGetCellType(K, 0, &ct)); 2277bb4b53efSMatthew G. Knepley PetscCall(PetscFECreateLagrangeByCell(PetscObjectComm((PetscObject)fe), dim, Nc, ct, k, PETSC_DETERMINE, newfe)); 2278bb4b53efSMatthew G. Knepley PetscCall(PetscFEGetQuadrature(fe, &q)); 2279bb4b53efSMatthew G. Knepley PetscCall(PetscFESetQuadrature(*newfe, q)); 2280bb4b53efSMatthew G. Knepley } else { 2281bb4b53efSMatthew G. Knepley PetscCall(PetscObjectReference((PetscObject)fe)); 2282bb4b53efSMatthew G. Knepley *newfe = fe; 2283bb4b53efSMatthew G. Knepley } 2284bb4b53efSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 2285bb4b53efSMatthew G. Knepley } 2286bb4b53efSMatthew G. Knepley 2287bb4b53efSMatthew G. Knepley /*@ 22884c712d99Sksagiyam PetscFECreateBrokenElement - Create a discontinuous version of the input `PetscFE` 22894c712d99Sksagiyam 22904c712d99Sksagiyam Collective 22914c712d99Sksagiyam 22924c712d99Sksagiyam Input Parameters: 22934c712d99Sksagiyam . cgfe - The continuous `PetscFE` object 22944c712d99Sksagiyam 22954c712d99Sksagiyam Output Parameter: 22964c712d99Sksagiyam . dgfe - The discontinuous `PetscFE` object 22974c712d99Sksagiyam 22984c712d99Sksagiyam Level: advanced 22994c712d99Sksagiyam 23004c712d99Sksagiyam Note: 23014c712d99Sksagiyam This only works for Lagrange elements. 23024c712d99Sksagiyam 23034c712d99Sksagiyam .seealso: `PetscFECreate()`, `PetscSpaceCreate()`, `PetscDualSpaceCreate()`, `PetscFECreateLagrange()`, `PetscFECreateLagrangeByCell()`, `PetscDualSpaceLagrangeSetContinuity()` 23044c712d99Sksagiyam @*/ 23054c712d99Sksagiyam PetscErrorCode PetscFECreateBrokenElement(PetscFE cgfe, PetscFE *dgfe) 23064c712d99Sksagiyam { 23074c712d99Sksagiyam PetscSpace P; 23084c712d99Sksagiyam PetscDualSpace Q, dgQ; 23094c712d99Sksagiyam PetscQuadrature q, fq; 23104c712d99Sksagiyam PetscBool is_lagrange, is_sum; 23114c712d99Sksagiyam 23124c712d99Sksagiyam PetscFunctionBegin; 23134c712d99Sksagiyam PetscCall(PetscFEGetBasisSpace(cgfe, &P)); 23144c712d99Sksagiyam PetscCall(PetscObjectReference((PetscObject)P)); 23154c712d99Sksagiyam PetscCall(PetscFEGetDualSpace(cgfe, &Q)); 23164c712d99Sksagiyam PetscCall(PetscObjectTypeCompare((PetscObject)Q, PETSCDUALSPACELAGRANGE, &is_lagrange)); 23174c712d99Sksagiyam PetscCall(PetscObjectTypeCompare((PetscObject)Q, PETSCDUALSPACESUM, &is_sum)); 23184c712d99Sksagiyam PetscCheck(is_lagrange || is_sum, PETSC_COMM_SELF, PETSC_ERR_SUP, "Can only create broken elements of Lagrange elements"); 23194c712d99Sksagiyam PetscCall(PetscDualSpaceDuplicate(Q, &dgQ)); 23204c712d99Sksagiyam PetscCall(PetscDualSpaceLagrangeSetContinuity(dgQ, PETSC_FALSE)); 23214c712d99Sksagiyam PetscCall(PetscDualSpaceSetUp(dgQ)); 23224c712d99Sksagiyam PetscCall(PetscFEGetQuadrature(cgfe, &q)); 23234c712d99Sksagiyam PetscCall(PetscObjectReference((PetscObject)q)); 23244c712d99Sksagiyam PetscCall(PetscFEGetFaceQuadrature(cgfe, &fq)); 23254c712d99Sksagiyam PetscCall(PetscObjectReference((PetscObject)fq)); 23264c712d99Sksagiyam PetscCall(PetscFECreateFromSpaces(P, dgQ, q, fq, dgfe)); 23274c712d99Sksagiyam PetscFunctionReturn(PETSC_SUCCESS); 23284c712d99Sksagiyam } 23294c712d99Sksagiyam 23304c712d99Sksagiyam /*@ 233120f4b53cSBarry Smith PetscFESetName - Names the `PetscFE` and its subobjects 23323f6b16c7SMatthew G. Knepley 233320f4b53cSBarry Smith Not Collective 23343f6b16c7SMatthew G. Knepley 23353f6b16c7SMatthew G. Knepley Input Parameters: 233620f4b53cSBarry Smith + fe - The `PetscFE` 23373f6b16c7SMatthew G. Knepley - name - The name 23383f6b16c7SMatthew G. Knepley 23392b99622eSMatthew G. Knepley Level: intermediate 23403f6b16c7SMatthew G. Knepley 2341db781477SPatrick Sanan .seealso: `PetscFECreate()`, `PetscSpaceCreate()`, `PetscDualSpaceCreate()` 23423f6b16c7SMatthew G. Knepley @*/ 2343d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFESetName(PetscFE fe, const char name[]) 2344d71ae5a4SJacob Faibussowitsch { 23453f6b16c7SMatthew G. Knepley PetscSpace P; 23463f6b16c7SMatthew G. Knepley PetscDualSpace Q; 23473f6b16c7SMatthew G. Knepley 23483f6b16c7SMatthew G. Knepley PetscFunctionBegin; 23499566063dSJacob Faibussowitsch PetscCall(PetscFEGetBasisSpace(fe, &P)); 23509566063dSJacob Faibussowitsch PetscCall(PetscFEGetDualSpace(fe, &Q)); 23519566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)fe, name)); 23529566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)P, name)); 23539566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)Q, name)); 23543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 23553f6b16c7SMatthew G. Knepley } 2356a8f1f9e5SMatthew G. Knepley 2357d71ae5a4SJacob 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[]) 2358d71ae5a4SJacob Faibussowitsch { 2359f9244615SMatthew G. Knepley PetscInt dOffset = 0, fOffset = 0, f, g; 2360a8f1f9e5SMatthew G. Knepley 2361a8f1f9e5SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 236226add6b9SMatthew 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); 236326add6b9SMatthew 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); 2364a8f1f9e5SMatthew G. Knepley PetscFE fe; 2365f9244615SMatthew G. Knepley const PetscInt k = ds->jetDegree[f]; 2366ef0bb6c7SMatthew G. Knepley const PetscInt cdim = T[f]->cdim; 23672b6f951bSStefano Zampini const PetscInt dE = fegeom->dimEmbed; 2368ef0bb6c7SMatthew G. Knepley const PetscInt Nq = T[f]->Np; 2369ef0bb6c7SMatthew G. Knepley const PetscInt Nbf = T[f]->Nb; 2370ef0bb6c7SMatthew G. Knepley const PetscInt Ncf = T[f]->Nc; 2371ef0bb6c7SMatthew G. Knepley const PetscReal *Bq = &T[f]->T[0][(r * Nq + q) * Nbf * Ncf]; 2372ef0bb6c7SMatthew G. Knepley const PetscReal *Dq = &T[f]->T[1][(r * Nq + q) * Nbf * Ncf * cdim]; 2373f9244615SMatthew G. Knepley const PetscReal *Hq = k > 1 ? &T[f]->T[2][(r * Nq + q) * Nbf * Ncf * cdim * cdim] : NULL; 2374f9244615SMatthew G. Knepley PetscInt hOffset = 0, b, c, d; 2375a8f1f9e5SMatthew G. Knepley 23769566063dSJacob Faibussowitsch PetscCall(PetscDSGetDiscretization(ds, f, (PetscObject *)&fe)); 2377a8f1f9e5SMatthew G. Knepley for (c = 0; c < Ncf; ++c) u[fOffset + c] = 0.0; 23782b6f951bSStefano Zampini for (d = 0; d < dE * Ncf; ++d) u_x[fOffset * dE + d] = 0.0; 2379a8f1f9e5SMatthew G. Knepley for (b = 0; b < Nbf; ++b) { 2380a8f1f9e5SMatthew G. Knepley for (c = 0; c < Ncf; ++c) { 2381a8f1f9e5SMatthew G. Knepley const PetscInt cidx = b * Ncf + c; 2382a8f1f9e5SMatthew G. Knepley 2383a8f1f9e5SMatthew G. Knepley u[fOffset + c] += Bq[cidx] * coefficients[dOffset + b]; 23842b6f951bSStefano Zampini for (d = 0; d < cdim; ++d) u_x[(fOffset + c) * dE + d] += Dq[cidx * cdim + d] * coefficients[dOffset + b]; 2385a8f1f9e5SMatthew G. Knepley } 2386a8f1f9e5SMatthew G. Knepley } 2387f9244615SMatthew G. Knepley if (k > 1) { 23882b6f951bSStefano Zampini for (g = 0; g < Nf; ++g) hOffset += T[g]->Nc * dE; 23892b6f951bSStefano Zampini for (d = 0; d < dE * dE * Ncf; ++d) u_x[hOffset + fOffset * dE * dE + d] = 0.0; 2390f9244615SMatthew G. Knepley for (b = 0; b < Nbf; ++b) { 2391f9244615SMatthew G. Knepley for (c = 0; c < Ncf; ++c) { 2392f9244615SMatthew G. Knepley const PetscInt cidx = b * Ncf + c; 2393f9244615SMatthew G. Knepley 23942b6f951bSStefano Zampini for (d = 0; d < cdim * cdim; ++d) u_x[hOffset + (fOffset + c) * dE * dE + d] += Hq[cidx * cdim * cdim + d] * coefficients[dOffset + b]; 2395f9244615SMatthew G. Knepley } 2396f9244615SMatthew G. Knepley } 23972b6f951bSStefano Zampini PetscCall(PetscFEPushforwardHessian(fe, fegeom, 1, &u_x[hOffset + fOffset * dE * dE])); 2398f9244615SMatthew G. Knepley } 23999566063dSJacob Faibussowitsch PetscCall(PetscFEPushforward(fe, fegeom, 1, &u[fOffset])); 24002b6f951bSStefano Zampini PetscCall(PetscFEPushforwardGradient(fe, fegeom, 1, &u_x[fOffset * dE])); 2401a8f1f9e5SMatthew G. Knepley if (u_t) { 2402a8f1f9e5SMatthew G. Knepley for (c = 0; c < Ncf; ++c) u_t[fOffset + c] = 0.0; 2403a8f1f9e5SMatthew G. Knepley for (b = 0; b < Nbf; ++b) { 2404a8f1f9e5SMatthew G. Knepley for (c = 0; c < Ncf; ++c) { 2405a8f1f9e5SMatthew G. Knepley const PetscInt cidx = b * Ncf + c; 2406a8f1f9e5SMatthew G. Knepley 2407a8f1f9e5SMatthew G. Knepley u_t[fOffset + c] += Bq[cidx] * coefficients_t[dOffset + b]; 2408a8f1f9e5SMatthew G. Knepley } 2409a8f1f9e5SMatthew G. Knepley } 24109566063dSJacob Faibussowitsch PetscCall(PetscFEPushforward(fe, fegeom, 1, &u_t[fOffset])); 2411a8f1f9e5SMatthew G. Knepley } 2412a8f1f9e5SMatthew G. Knepley fOffset += Ncf; 2413a8f1f9e5SMatthew G. Knepley dOffset += Nbf; 2414a8f1f9e5SMatthew G. Knepley } 24153ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 2416a8f1f9e5SMatthew G. Knepley } 2417a8f1f9e5SMatthew G. Knepley 2418989fa639SBrad Aagaard PetscErrorCode PetscFEEvaluateFieldJets_Hybrid_Internal(PetscDS ds, PetscInt Nf, PetscInt rc, PetscInt qc, PetscTabulation Tab[], const PetscInt rf[], const PetscInt qf[], PetscTabulation Tabf[], PetscFEGeom *fegeom, PetscFEGeom *fegeomNbr, const PetscScalar coefficients[], const PetscScalar coefficients_t[], PetscScalar u[], PetscScalar u_x[], PetscScalar u_t[]) 2419d71ae5a4SJacob Faibussowitsch { 2420*e60de12fSPierre Jolivet PetscInt dOffset = 0, fOffset = 0, f; 242127f02ce8SMatthew G. Knepley 2422*e60de12fSPierre Jolivet /* f is the field number in the DS */ 2423*e60de12fSPierre Jolivet for (f = 0; f < Nf; ++f) { 24245fedec97SMatthew G. Knepley PetscBool isCohesive; 24255fedec97SMatthew G. Knepley PetscInt Ns, s; 24265fedec97SMatthew G. Knepley 242707218a29SMatthew G. Knepley if (!Tab[f]) continue; 24289566063dSJacob Faibussowitsch PetscCall(PetscDSGetCohesive(ds, f, &isCohesive)); 24295fedec97SMatthew G. Knepley Ns = isCohesive ? 1 : 2; 243007218a29SMatthew G. Knepley { 243107218a29SMatthew G. Knepley PetscTabulation T = isCohesive ? Tab[f] : Tabf[f]; 243207218a29SMatthew G. Knepley PetscFE fe = (PetscFE)ds->disc[f]; 243307218a29SMatthew G. Knepley const PetscInt dEt = T->cdim; 243407218a29SMatthew G. Knepley const PetscInt dE = fegeom->dimEmbed; 243507218a29SMatthew G. Knepley const PetscInt Nq = T->Np; 243607218a29SMatthew G. Knepley const PetscInt Nbf = T->Nb; 243707218a29SMatthew G. Knepley const PetscInt Ncf = T->Nc; 243807218a29SMatthew G. Knepley 2439*e60de12fSPierre Jolivet for (s = 0; s < Ns; ++s) { 244007218a29SMatthew G. Knepley const PetscInt r = isCohesive ? rc : rf[s]; 244107218a29SMatthew G. Knepley const PetscInt q = isCohesive ? qc : qf[s]; 244207218a29SMatthew G. Knepley const PetscReal *Bq = &T->T[0][(r * Nq + q) * Nbf * Ncf]; 244307218a29SMatthew G. Knepley const PetscReal *Dq = &T->T[1][(r * Nq + q) * Nbf * Ncf * dEt]; 244427f02ce8SMatthew G. Knepley PetscInt b, c, d; 244527f02ce8SMatthew G. Knepley 244607218a29SMatthew 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); 244707218a29SMatthew 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); 244827f02ce8SMatthew G. Knepley for (c = 0; c < Ncf; ++c) u[fOffset + c] = 0.0; 24499ee2af8cSMatthew G. Knepley for (d = 0; d < dE * Ncf; ++d) u_x[fOffset * dE + d] = 0.0; 245027f02ce8SMatthew G. Knepley for (b = 0; b < Nbf; ++b) { 245127f02ce8SMatthew G. Knepley for (c = 0; c < Ncf; ++c) { 245227f02ce8SMatthew G. Knepley const PetscInt cidx = b * Ncf + c; 245327f02ce8SMatthew G. Knepley 245427f02ce8SMatthew G. Knepley u[fOffset + c] += Bq[cidx] * coefficients[dOffset + b]; 24559ee2af8cSMatthew G. Knepley for (d = 0; d < dEt; ++d) u_x[(fOffset + c) * dE + d] += Dq[cidx * dEt + d] * coefficients[dOffset + b]; 245627f02ce8SMatthew G. Knepley } 245727f02ce8SMatthew G. Knepley } 2458989fa639SBrad Aagaard PetscCall(PetscFEPushforward(fe, isCohesive ? fegeom : &fegeomNbr[s], 1, &u[fOffset])); 2459989fa639SBrad Aagaard PetscCall(PetscFEPushforwardGradient(fe, isCohesive ? fegeom : &fegeomNbr[s], 1, &u_x[fOffset * dE])); 246027f02ce8SMatthew G. Knepley if (u_t) { 246127f02ce8SMatthew G. Knepley for (c = 0; c < Ncf; ++c) u_t[fOffset + c] = 0.0; 246227f02ce8SMatthew G. Knepley for (b = 0; b < Nbf; ++b) { 246327f02ce8SMatthew G. Knepley for (c = 0; c < Ncf; ++c) { 246427f02ce8SMatthew G. Knepley const PetscInt cidx = b * Ncf + c; 246527f02ce8SMatthew G. Knepley 246627f02ce8SMatthew G. Knepley u_t[fOffset + c] += Bq[cidx] * coefficients_t[dOffset + b]; 246727f02ce8SMatthew G. Knepley } 246827f02ce8SMatthew G. Knepley } 24699566063dSJacob Faibussowitsch PetscCall(PetscFEPushforward(fe, fegeom, 1, &u_t[fOffset])); 247027f02ce8SMatthew G. Knepley } 247127f02ce8SMatthew G. Knepley fOffset += Ncf; 247227f02ce8SMatthew G. Knepley dOffset += Nbf; 247327f02ce8SMatthew G. Knepley } 2474665f567fSMatthew G. Knepley } 247507218a29SMatthew G. Knepley } 24763ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 247727f02ce8SMatthew G. Knepley } 247827f02ce8SMatthew G. Knepley 2479d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEEvaluateFaceFields_Internal(PetscDS prob, PetscInt field, PetscInt faceLoc, const PetscScalar coefficients[], PetscScalar u[]) 2480d71ae5a4SJacob Faibussowitsch { 2481a8f1f9e5SMatthew G. Knepley PetscFE fe; 2482ef0bb6c7SMatthew G. Knepley PetscTabulation Tc; 2483ef0bb6c7SMatthew G. Knepley PetscInt b, c; 2484a8f1f9e5SMatthew G. Knepley 24853ba16761SJacob Faibussowitsch if (!prob) return PETSC_SUCCESS; 24869566063dSJacob Faibussowitsch PetscCall(PetscDSGetDiscretization(prob, field, (PetscObject *)&fe)); 24879566063dSJacob Faibussowitsch PetscCall(PetscFEGetFaceCentroidTabulation(fe, &Tc)); 2488ef0bb6c7SMatthew G. Knepley { 2489ef0bb6c7SMatthew G. Knepley const PetscReal *faceBasis = Tc->T[0]; 2490ef0bb6c7SMatthew G. Knepley const PetscInt Nb = Tc->Nb; 2491ef0bb6c7SMatthew G. Knepley const PetscInt Nc = Tc->Nc; 2492ef0bb6c7SMatthew G. Knepley 2493ad540459SPierre Jolivet for (c = 0; c < Nc; ++c) u[c] = 0.0; 2494a8f1f9e5SMatthew G. Knepley for (b = 0; b < Nb; ++b) { 2495ad540459SPierre Jolivet for (c = 0; c < Nc; ++c) u[c] += coefficients[b] * faceBasis[(faceLoc * Nb + b) * Nc + c]; 2496a8f1f9e5SMatthew G. Knepley } 2497ef0bb6c7SMatthew G. Knepley } 24983ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 2499a8f1f9e5SMatthew G. Knepley } 2500a8f1f9e5SMatthew G. Knepley 2501d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEUpdateElementVec_Internal(PetscFE fe, PetscTabulation T, PetscInt r, PetscScalar tmpBasis[], PetscScalar tmpBasisDer[], PetscInt e, PetscFEGeom *fegeom, PetscScalar f0[], PetscScalar f1[], PetscScalar elemVec[]) 2502d71ae5a4SJacob Faibussowitsch { 25036587ee25SMatthew G. Knepley PetscFEGeom pgeom; 2504bc3a64adSMatthew G. Knepley const PetscInt dEt = T->cdim; 2505bc3a64adSMatthew G. Knepley const PetscInt dE = fegeom->dimEmbed; 2506ef0bb6c7SMatthew G. Knepley const PetscInt Nq = T->Np; 2507ef0bb6c7SMatthew G. Knepley const PetscInt Nb = T->Nb; 2508ef0bb6c7SMatthew G. Knepley const PetscInt Nc = T->Nc; 2509ef0bb6c7SMatthew G. Knepley const PetscReal *basis = &T->T[0][r * Nq * Nb * Nc]; 2510bc3a64adSMatthew G. Knepley const PetscReal *basisDer = &T->T[1][r * Nq * Nb * Nc * dEt]; 2511a8f1f9e5SMatthew G. Knepley PetscInt q, b, c, d; 2512a8f1f9e5SMatthew G. Knepley 2513a8f1f9e5SMatthew G. Knepley for (q = 0; q < Nq; ++q) { 2514a8f1f9e5SMatthew G. Knepley for (b = 0; b < Nb; ++b) { 2515a8f1f9e5SMatthew G. Knepley for (c = 0; c < Nc; ++c) { 2516a8f1f9e5SMatthew G. Knepley const PetscInt bcidx = b * Nc + c; 2517a8f1f9e5SMatthew G. Knepley 2518a8f1f9e5SMatthew G. Knepley tmpBasis[bcidx] = basis[q * Nb * Nc + bcidx]; 2519bc3a64adSMatthew G. Knepley for (d = 0; d < dEt; ++d) tmpBasisDer[bcidx * dE + d] = basisDer[q * Nb * Nc * dEt + bcidx * dEt + d]; 25209ee2af8cSMatthew G. Knepley for (d = dEt; d < dE; ++d) tmpBasisDer[bcidx * dE + d] = 0.0; 2521a8f1f9e5SMatthew G. Knepley } 2522a8f1f9e5SMatthew G. Knepley } 25239566063dSJacob Faibussowitsch PetscCall(PetscFEGeomGetCellPoint(fegeom, e, q, &pgeom)); 25249566063dSJacob Faibussowitsch PetscCall(PetscFEPushforward(fe, &pgeom, Nb, tmpBasis)); 25259566063dSJacob Faibussowitsch PetscCall(PetscFEPushforwardGradient(fe, &pgeom, Nb, tmpBasisDer)); 2526a8f1f9e5SMatthew G. Knepley for (b = 0; b < Nb; ++b) { 2527a8f1f9e5SMatthew G. Knepley for (c = 0; c < Nc; ++c) { 2528a8f1f9e5SMatthew G. Knepley const PetscInt bcidx = b * Nc + c; 2529a8f1f9e5SMatthew G. Knepley const PetscInt qcidx = q * Nc + c; 2530a8f1f9e5SMatthew G. Knepley 2531a8f1f9e5SMatthew G. Knepley elemVec[b] += tmpBasis[bcidx] * f0[qcidx]; 253227f02ce8SMatthew G. Knepley for (d = 0; d < dE; ++d) elemVec[b] += tmpBasisDer[bcidx * dE + d] * f1[qcidx * dE + d]; 253327f02ce8SMatthew G. Knepley } 253427f02ce8SMatthew G. Knepley } 253527f02ce8SMatthew G. Knepley } 25363ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 253727f02ce8SMatthew G. Knepley } 253827f02ce8SMatthew G. Knepley 25390abb75b6SMatthew 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[]) 2540d71ae5a4SJacob Faibussowitsch { 254127f02ce8SMatthew G. Knepley const PetscInt dE = T->cdim; 254227f02ce8SMatthew G. Knepley const PetscInt Nq = T->Np; 254327f02ce8SMatthew G. Knepley const PetscInt Nb = T->Nb; 254427f02ce8SMatthew G. Knepley const PetscInt Nc = T->Nc; 254527f02ce8SMatthew G. Knepley const PetscReal *basis = &T->T[0][r * Nq * Nb * Nc]; 254627f02ce8SMatthew G. Knepley const PetscReal *basisDer = &T->T[1][r * Nq * Nb * Nc * dE]; 254727f02ce8SMatthew G. Knepley 25480abb75b6SMatthew G. Knepley for (PetscInt q = 0; q < Nq; ++q) { 25490abb75b6SMatthew G. Knepley for (PetscInt b = 0; b < Nb; ++b) { 25500abb75b6SMatthew G. Knepley for (PetscInt c = 0; c < Nc; ++c) { 255127f02ce8SMatthew G. Knepley const PetscInt bcidx = b * Nc + c; 255227f02ce8SMatthew G. Knepley 255327f02ce8SMatthew G. Knepley tmpBasis[bcidx] = basis[q * Nb * Nc + bcidx]; 25540abb75b6SMatthew G. Knepley for (PetscInt d = 0; d < dE; ++d) tmpBasisDer[bcidx * dE + d] = basisDer[q * Nb * Nc * dE + bcidx * dE + d]; 255527f02ce8SMatthew G. Knepley } 255627f02ce8SMatthew G. Knepley } 25579566063dSJacob Faibussowitsch PetscCall(PetscFEPushforward(fe, fegeom, Nb, tmpBasis)); 25582b6f951bSStefano Zampini // TODO This is currently broken since we do not pull the geometry down to the lower dimension 25592b6f951bSStefano Zampini // PetscCall(PetscFEPushforwardGradient(fe, fegeom, Nb, tmpBasisDer)); 25600abb75b6SMatthew G. Knepley if (side == 2) { 25610abb75b6SMatthew G. Knepley // Integrating over whole cohesive cell, so insert for both sides 25620abb75b6SMatthew G. Knepley for (PetscInt s = 0; s < 2; ++s) { 25630abb75b6SMatthew G. Knepley for (PetscInt b = 0; b < Nb; ++b) { 25640abb75b6SMatthew G. Knepley for (PetscInt c = 0; c < Nc; ++c) { 25650abb75b6SMatthew G. Knepley const PetscInt bcidx = b * Nc + c; 25660abb75b6SMatthew G. Knepley const PetscInt qcidx = (q * 2 + s) * Nc + c; 25670abb75b6SMatthew G. Knepley 25680abb75b6SMatthew G. Knepley elemVec[Nb * s + b] += tmpBasis[bcidx] * f0[qcidx]; 25690abb75b6SMatthew G. Knepley for (PetscInt d = 0; d < dE; ++d) elemVec[Nb * s + b] += tmpBasisDer[bcidx * dE + d] * f1[qcidx * dE + d]; 25700abb75b6SMatthew G. Knepley } 25710abb75b6SMatthew G. Knepley } 25720abb75b6SMatthew G. Knepley } 25730abb75b6SMatthew G. Knepley } else { 25740abb75b6SMatthew G. Knepley // Integrating over endcaps of cohesive cell, so insert for correct side 25750abb75b6SMatthew G. Knepley for (PetscInt b = 0; b < Nb; ++b) { 25760abb75b6SMatthew G. Knepley for (PetscInt c = 0; c < Nc; ++c) { 257727f02ce8SMatthew G. Knepley const PetscInt bcidx = b * Nc + c; 2578c2b7495fSMatthew G. Knepley const PetscInt qcidx = q * Nc + c; 257927f02ce8SMatthew G. Knepley 25800abb75b6SMatthew G. Knepley elemVec[Nb * side + b] += tmpBasis[bcidx] * f0[qcidx]; 25810abb75b6SMatthew G. Knepley for (PetscInt d = 0; d < dE; ++d) elemVec[Nb * side + b] += tmpBasisDer[bcidx * dE + d] * f1[qcidx * dE + d]; 25820abb75b6SMatthew G. Knepley } 258327f02ce8SMatthew G. Knepley } 2584a8f1f9e5SMatthew G. Knepley } 2585a8f1f9e5SMatthew G. Knepley } 25863ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 2587a8f1f9e5SMatthew G. Knepley } 2588a8f1f9e5SMatthew G. Knepley 25891a768569SStefano Zampini #define petsc_elemmat_kernel_g1(_NbI, _NcI, _NbJ, _NcJ, _dE) \ 2590f102cd15SPierre Jolivet do { \ 25911a768569SStefano Zampini for (PetscInt fc = 0; fc < (_NcI); ++fc) { \ 25921a768569SStefano Zampini for (PetscInt gc = 0; gc < (_NcJ); ++gc) { \ 25931a768569SStefano Zampini const PetscScalar *G = g1 + (fc * (_NcJ) + gc) * _dE; \ 25941a768569SStefano Zampini for (PetscInt f = 0; f < (_NbI); ++f) { \ 25951a768569SStefano Zampini const PetscScalar tBIv = tmpBasisI[f * (_NcI) + fc]; \ 25961a768569SStefano Zampini for (PetscInt g = 0; g < (_NbJ); ++g) { \ 25971a768569SStefano Zampini const PetscScalar *tBDJ = tmpBasisDerJ + (g * (_NcJ) + gc) * (_dE); \ 25981a768569SStefano Zampini PetscScalar s = 0.0; \ 25990b36fe0aSPierre Jolivet for (PetscInt df = 0; df < _dE; ++df) s += G[df] * tBDJ[df]; \ 26001a768569SStefano Zampini elemMat[(offsetI + f) * totDim + (offsetJ + g)] += s * tBIv; \ 26011a768569SStefano Zampini } \ 26021a768569SStefano Zampini } \ 26031a768569SStefano Zampini } \ 2604f102cd15SPierre Jolivet } \ 2605f102cd15SPierre Jolivet } while (0) 26061a768569SStefano Zampini 26071a768569SStefano Zampini #define petsc_elemmat_kernel_g2(_NbI, _NcI, _NbJ, _NcJ, _dE) \ 2608f102cd15SPierre Jolivet do { \ 26091a768569SStefano Zampini for (PetscInt gc = 0; gc < (_NcJ); ++gc) { \ 26101a768569SStefano Zampini for (PetscInt fc = 0; fc < (_NcI); ++fc) { \ 26111a768569SStefano Zampini const PetscScalar *G = g2 + (fc * (_NcJ) + gc) * _dE; \ 26121a768569SStefano Zampini for (PetscInt g = 0; g < (_NbJ); ++g) { \ 26131a768569SStefano Zampini const PetscScalar tBJv = tmpBasisJ[g * (_NcJ) + gc]; \ 26141a768569SStefano Zampini for (PetscInt f = 0; f < (_NbI); ++f) { \ 26151a768569SStefano Zampini const PetscScalar *tBDI = tmpBasisDerI + (f * (_NcI) + fc) * (_dE); \ 26161a768569SStefano Zampini PetscScalar s = 0.0; \ 26170b36fe0aSPierre Jolivet for (PetscInt df = 0; df < _dE; ++df) s += tBDI[df] * G[df]; \ 26181a768569SStefano Zampini elemMat[(offsetI + f) * totDim + (offsetJ + g)] += s * tBJv; \ 26191a768569SStefano Zampini } \ 26201a768569SStefano Zampini } \ 26211a768569SStefano Zampini } \ 2622f102cd15SPierre Jolivet } \ 2623f102cd15SPierre Jolivet } while (0) 26241a768569SStefano Zampini 26251a768569SStefano Zampini #define petsc_elemmat_kernel_g3(_NbI, _NcI, _NbJ, _NcJ, _dE) \ 2626f102cd15SPierre Jolivet do { \ 26271a768569SStefano Zampini for (PetscInt fc = 0; fc < (_NcI); ++fc) { \ 26281a768569SStefano Zampini for (PetscInt gc = 0; gc < (_NcJ); ++gc) { \ 26291a768569SStefano Zampini const PetscScalar *G = g3 + (fc * (_NcJ) + gc) * (_dE) * (_dE); \ 26301a768569SStefano Zampini for (PetscInt f = 0; f < (_NbI); ++f) { \ 26311a768569SStefano Zampini const PetscScalar *tBDI = tmpBasisDerI + (f * (_NcI) + fc) * (_dE); \ 26321a768569SStefano Zampini for (PetscInt g = 0; g < (_NbJ); ++g) { \ 26331a768569SStefano Zampini PetscScalar s = 0.0; \ 26341a768569SStefano Zampini const PetscScalar *tBDJ = tmpBasisDerJ + (g * (_NcJ) + gc) * (_dE); \ 26351a768569SStefano Zampini for (PetscInt df = 0; df < (_dE); ++df) { \ 26360b36fe0aSPierre Jolivet for (PetscInt dg = 0; dg < (_dE); ++dg) s += tBDI[df] * G[df * (_dE) + dg] * tBDJ[dg]; \ 26371a768569SStefano Zampini } \ 26381a768569SStefano Zampini elemMat[(offsetI + f) * totDim + (offsetJ + g)] += s; \ 26391a768569SStefano Zampini } \ 26401a768569SStefano Zampini } \ 26411a768569SStefano Zampini } \ 2642f102cd15SPierre Jolivet } \ 2643f102cd15SPierre Jolivet } while (0) 26441a768569SStefano Zampini 26451a768569SStefano Zampini 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 totDim, PetscInt offsetI, PetscInt offsetJ, PetscScalar elemMat[]) 2646d71ae5a4SJacob Faibussowitsch { 26472b6f951bSStefano Zampini const PetscInt cdim = TI->cdim; 26482b6f951bSStefano Zampini const PetscInt dE = fegeom->dimEmbed; 2649ef0bb6c7SMatthew G. Knepley const PetscInt NqI = TI->Np; 2650ef0bb6c7SMatthew G. Knepley const PetscInt NbI = TI->Nb; 2651ef0bb6c7SMatthew G. Knepley const PetscInt NcI = TI->Nc; 2652ef0bb6c7SMatthew G. Knepley const PetscReal *basisI = &TI->T[0][(r * NqI + q) * NbI * NcI]; 26532b6f951bSStefano Zampini const PetscReal *basisDerI = &TI->T[1][(r * NqI + q) * NbI * NcI * cdim]; 2654ef0bb6c7SMatthew G. Knepley const PetscInt NqJ = TJ->Np; 2655ef0bb6c7SMatthew G. Knepley const PetscInt NbJ = TJ->Nb; 2656ef0bb6c7SMatthew G. Knepley const PetscInt NcJ = TJ->Nc; 2657ef0bb6c7SMatthew G. Knepley const PetscReal *basisJ = &TJ->T[0][(r * NqJ + q) * NbJ * NcJ]; 26582b6f951bSStefano Zampini const PetscReal *basisDerJ = &TJ->T[1][(r * NqJ + q) * NbJ * NcJ * cdim]; 2659a8f1f9e5SMatthew G. Knepley 26601a768569SStefano Zampini for (PetscInt f = 0; f < NbI; ++f) { 26611a768569SStefano Zampini for (PetscInt fc = 0; fc < NcI; ++fc) { 2662a8f1f9e5SMatthew G. Knepley const PetscInt fidx = f * NcI + fc; /* Test function basis index */ 2663a8f1f9e5SMatthew G. Knepley 2664a8f1f9e5SMatthew G. Knepley tmpBasisI[fidx] = basisI[fidx]; 26651a768569SStefano Zampini for (PetscInt df = 0; df < cdim; ++df) tmpBasisDerI[fidx * dE + df] = basisDerI[fidx * cdim + df]; 2666a8f1f9e5SMatthew G. Knepley } 2667a8f1f9e5SMatthew G. Knepley } 26689566063dSJacob Faibussowitsch PetscCall(PetscFEPushforward(feI, fegeom, NbI, tmpBasisI)); 26699566063dSJacob Faibussowitsch PetscCall(PetscFEPushforwardGradient(feI, fegeom, NbI, tmpBasisDerI)); 26701a768569SStefano Zampini if (feI != feJ) { 26711a768569SStefano Zampini for (PetscInt g = 0; g < NbJ; ++g) { 26721a768569SStefano Zampini for (PetscInt gc = 0; gc < NcJ; ++gc) { 2673a8f1f9e5SMatthew G. Knepley const PetscInt gidx = g * NcJ + gc; /* Trial function basis index */ 2674a8f1f9e5SMatthew G. Knepley 2675a8f1f9e5SMatthew G. Knepley tmpBasisJ[gidx] = basisJ[gidx]; 26761a768569SStefano Zampini for (PetscInt dg = 0; dg < cdim; ++dg) tmpBasisDerJ[gidx * dE + dg] = basisDerJ[gidx * cdim + dg]; 2677a8f1f9e5SMatthew G. Knepley } 2678a8f1f9e5SMatthew G. Knepley } 26799566063dSJacob Faibussowitsch PetscCall(PetscFEPushforward(feJ, fegeom, NbJ, tmpBasisJ)); 26809566063dSJacob Faibussowitsch PetscCall(PetscFEPushforwardGradient(feJ, fegeom, NbJ, tmpBasisDerJ)); 26811a768569SStefano Zampini } else { 26821a768569SStefano Zampini tmpBasisJ = tmpBasisI; 26831a768569SStefano Zampini tmpBasisDerJ = tmpBasisDerI; 26841a768569SStefano Zampini } 26851a768569SStefano Zampini if (PetscUnlikely(g0)) { 26861a768569SStefano Zampini for (PetscInt f = 0; f < NbI; ++f) { 2687a8f1f9e5SMatthew G. Knepley const PetscInt i = offsetI + f; /* Element matrix row */ 2688a8f1f9e5SMatthew G. Knepley 26891a768569SStefano Zampini for (PetscInt fc = 0; fc < NcI; ++fc) { 26901a768569SStefano Zampini const PetscScalar bI = tmpBasisI[f * NcI + fc]; /* Test function basis value */ 26911a768569SStefano Zampini 26921a768569SStefano Zampini for (PetscInt g = 0; g < NbJ; ++g) { 26931a768569SStefano Zampini const PetscInt j = offsetJ + g; /* Element matrix column */ 26941a768569SStefano Zampini const PetscInt fOff = i * totDim + j; 26951a768569SStefano Zampini 2696ac530a7eSPierre Jolivet for (PetscInt gc = 0; gc < NcJ; ++gc) elemMat[fOff] += bI * g0[fc * NcJ + gc] * tmpBasisJ[g * NcJ + gc]; 269727f02ce8SMatthew G. Knepley } 269827f02ce8SMatthew G. Knepley } 269927f02ce8SMatthew G. Knepley } 270027f02ce8SMatthew G. Knepley } 27011a768569SStefano Zampini if (PetscUnlikely(g1)) { 27021a768569SStefano Zampini #if 1 27031a768569SStefano Zampini if (dE == 2) { 27041a768569SStefano Zampini petsc_elemmat_kernel_g1(NbI, NcI, NbJ, NcJ, 2); 27051a768569SStefano Zampini } else if (dE == 3) { 27061a768569SStefano Zampini petsc_elemmat_kernel_g1(NbI, NcI, NbJ, NcJ, 3); 27071a768569SStefano Zampini } else { 27081a768569SStefano Zampini petsc_elemmat_kernel_g1(NbI, NcI, NbJ, NcJ, dE); 27091a768569SStefano Zampini } 27101a768569SStefano Zampini #else 27111a768569SStefano Zampini for (PetscInt f = 0; f < NbI; ++f) { 27121a768569SStefano Zampini const PetscInt i = offsetI + f; /* Element matrix row */ 27131a768569SStefano Zampini 27141a768569SStefano Zampini for (PetscInt fc = 0; fc < NcI; ++fc) { 27151a768569SStefano Zampini const PetscScalar bI = tmpBasisI[f * NcI + fc]; /* Test function basis value */ 27161a768569SStefano Zampini 27171a768569SStefano Zampini for (PetscInt g = 0; g < NbJ; ++g) { 27181a768569SStefano Zampini const PetscInt j = offsetJ + g; /* Element matrix column */ 27191a768569SStefano Zampini const PetscInt fOff = i * totDim + j; 27201a768569SStefano Zampini 27211a768569SStefano Zampini for (PetscInt gc = 0; gc < NcJ; ++gc) { 27221a768569SStefano Zampini const PetscInt gidx = g * NcJ + gc; /* Trial function basis index */ 27231a768569SStefano Zampini 2724ac530a7eSPierre Jolivet for (PetscInt df = 0; df < dE; ++df) elemMat[fOff] += bI * g1[(fc * NcJ + gc) * dE + df] * tmpBasisDerJ[gidx * dE + df]; 27251a768569SStefano Zampini } 27261a768569SStefano Zampini } 27271a768569SStefano Zampini } 27281a768569SStefano Zampini } 27291a768569SStefano Zampini #endif 27301a768569SStefano Zampini } 27311a768569SStefano Zampini if (PetscUnlikely(g2)) { 27321a768569SStefano Zampini #if 1 27331a768569SStefano Zampini if (dE == 2) { 27341a768569SStefano Zampini petsc_elemmat_kernel_g2(NbI, NcI, NbJ, NcJ, 2); 27351a768569SStefano Zampini } else if (dE == 3) { 27361a768569SStefano Zampini petsc_elemmat_kernel_g2(NbI, NcI, NbJ, NcJ, 3); 27371a768569SStefano Zampini } else { 27381a768569SStefano Zampini petsc_elemmat_kernel_g2(NbI, NcI, NbJ, NcJ, dE); 27391a768569SStefano Zampini } 27401a768569SStefano Zampini #else 27411a768569SStefano Zampini for (PetscInt g = 0; g < NbJ; ++g) { 27421a768569SStefano Zampini const PetscInt j = offsetJ + g; /* Element matrix column */ 27431a768569SStefano Zampini 27441a768569SStefano Zampini for (PetscInt gc = 0; gc < NcJ; ++gc) { 27451a768569SStefano Zampini const PetscScalar bJ = tmpBasisJ[g * NcJ + gc]; /* Trial function basis value */ 27461a768569SStefano Zampini 27471a768569SStefano Zampini for (PetscInt f = 0; f < NbI; ++f) { 27481a768569SStefano Zampini const PetscInt i = offsetI + f; /* Element matrix row */ 27491a768569SStefano Zampini const PetscInt fOff = i * totDim + j; 27501a768569SStefano Zampini 27511a768569SStefano Zampini for (PetscInt fc = 0; fc < NcI; ++fc) { 27521a768569SStefano Zampini const PetscInt fidx = f * NcI + fc; /* Test function basis index */ 27531a768569SStefano Zampini 2754ac530a7eSPierre Jolivet for (PetscInt df = 0; df < dE; ++df) elemMat[fOff] += tmpBasisDerI[fidx * dE + df] * g2[(fc * NcJ + gc) * dE + df] * bJ; 27551a768569SStefano Zampini } 27561a768569SStefano Zampini } 27571a768569SStefano Zampini } 27581a768569SStefano Zampini } 27591a768569SStefano Zampini #endif 27601a768569SStefano Zampini } 27611a768569SStefano Zampini if (PetscUnlikely(g3)) { 27621a768569SStefano Zampini #if 1 27631a768569SStefano Zampini if (dE == 2) { 27641a768569SStefano Zampini petsc_elemmat_kernel_g3(NbI, NcI, NbJ, NcJ, 2); 27651a768569SStefano Zampini } else if (dE == 3) { 27661a768569SStefano Zampini petsc_elemmat_kernel_g3(NbI, NcI, NbJ, NcJ, 3); 27671a768569SStefano Zampini } else { 27681a768569SStefano Zampini petsc_elemmat_kernel_g3(NbI, NcI, NbJ, NcJ, dE); 27691a768569SStefano Zampini } 27701a768569SStefano Zampini #else 27711a768569SStefano Zampini for (PetscInt f = 0; f < NbI; ++f) { 27721a768569SStefano Zampini const PetscInt i = offsetI + f; /* Element matrix row */ 27731a768569SStefano Zampini 27741a768569SStefano Zampini for (PetscInt fc = 0; fc < NcI; ++fc) { 27751a768569SStefano Zampini const PetscInt fidx = f * NcI + fc; /* Test function basis index */ 27761a768569SStefano Zampini 27771a768569SStefano Zampini for (PetscInt g = 0; g < NbJ; ++g) { 27781a768569SStefano Zampini const PetscInt j = offsetJ + g; /* Element matrix column */ 27791a768569SStefano Zampini const PetscInt fOff = i * totDim + j; 27801a768569SStefano Zampini 27811a768569SStefano Zampini for (PetscInt gc = 0; gc < NcJ; ++gc) { 27821a768569SStefano Zampini const PetscInt gidx = g * NcJ + gc; /* Trial function basis index */ 27831a768569SStefano Zampini 27841a768569SStefano Zampini for (PetscInt df = 0; df < dE; ++df) { 2785ac530a7eSPierre Jolivet for (PetscInt dg = 0; dg < dE; ++dg) elemMat[fOff] += tmpBasisDerI[fidx * dE + df] * g3[((fc * NcJ + gc) * dE + df) * dE + dg] * tmpBasisDerJ[gidx * dE + dg]; 27861a768569SStefano Zampini } 27871a768569SStefano Zampini } 27881a768569SStefano Zampini } 27891a768569SStefano Zampini } 27901a768569SStefano Zampini } 27911a768569SStefano Zampini #endif 279227f02ce8SMatthew G. Knepley } 27933ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 279427f02ce8SMatthew G. Knepley } 279527f02ce8SMatthew G. Knepley 27961a768569SStefano Zampini #undef petsc_elemmat_kernel_g1 27971a768569SStefano Zampini #undef petsc_elemmat_kernel_g2 27981a768569SStefano Zampini #undef petsc_elemmat_kernel_g3 27991a768569SStefano Zampini 28000abb75b6SMatthew 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[]) 2801d71ae5a4SJacob Faibussowitsch { 2802665f567fSMatthew G. Knepley const PetscInt dE = TI->cdim; 2803665f567fSMatthew G. Knepley const PetscInt NqI = TI->Np; 2804665f567fSMatthew G. Knepley const PetscInt NbI = TI->Nb; 2805665f567fSMatthew G. Knepley const PetscInt NcI = TI->Nc; 2806665f567fSMatthew G. Knepley const PetscReal *basisI = &TI->T[0][(r * NqI + q) * NbI * NcI]; 2807665f567fSMatthew G. Knepley const PetscReal *basisDerI = &TI->T[1][(r * NqI + q) * NbI * NcI * dE]; 2808665f567fSMatthew G. Knepley const PetscInt NqJ = TJ->Np; 2809665f567fSMatthew G. Knepley const PetscInt NbJ = TJ->Nb; 2810665f567fSMatthew G. Knepley const PetscInt NcJ = TJ->Nc; 2811665f567fSMatthew G. Knepley const PetscReal *basisJ = &TJ->T[0][(r * NqJ + q) * NbJ * NcJ]; 2812665f567fSMatthew G. Knepley const PetscReal *basisDerJ = &TJ->T[1][(r * NqJ + q) * NbJ * NcJ * dE]; 28135fedec97SMatthew G. Knepley const PetscInt so = isHybridI ? 0 : s; 28140abb75b6SMatthew G. Knepley const PetscInt to = isHybridJ ? 0 : t; 28155fedec97SMatthew G. Knepley PetscInt f, fc, g, gc, df, dg; 281627f02ce8SMatthew G. Knepley 281727f02ce8SMatthew G. Knepley for (f = 0; f < NbI; ++f) { 281827f02ce8SMatthew G. Knepley for (fc = 0; fc < NcI; ++fc) { 281927f02ce8SMatthew G. Knepley const PetscInt fidx = f * NcI + fc; /* Test function basis index */ 282027f02ce8SMatthew G. Knepley 282127f02ce8SMatthew G. Knepley tmpBasisI[fidx] = basisI[fidx]; 2822665f567fSMatthew G. Knepley for (df = 0; df < dE; ++df) tmpBasisDerI[fidx * dE + df] = basisDerI[fidx * dE + df]; 282327f02ce8SMatthew G. Knepley } 282427f02ce8SMatthew G. Knepley } 28259566063dSJacob Faibussowitsch PetscCall(PetscFEPushforward(feI, fegeom, NbI, tmpBasisI)); 28269566063dSJacob Faibussowitsch PetscCall(PetscFEPushforwardGradient(feI, fegeom, NbI, tmpBasisDerI)); 282727f02ce8SMatthew G. Knepley for (g = 0; g < NbJ; ++g) { 282827f02ce8SMatthew G. Knepley for (gc = 0; gc < NcJ; ++gc) { 282927f02ce8SMatthew G. Knepley const PetscInt gidx = g * NcJ + gc; /* Trial function basis index */ 283027f02ce8SMatthew G. Knepley 283127f02ce8SMatthew G. Knepley tmpBasisJ[gidx] = basisJ[gidx]; 2832665f567fSMatthew G. Knepley for (dg = 0; dg < dE; ++dg) tmpBasisDerJ[gidx * dE + dg] = basisDerJ[gidx * dE + dg]; 283327f02ce8SMatthew G. Knepley } 283427f02ce8SMatthew G. Knepley } 28359566063dSJacob Faibussowitsch PetscCall(PetscFEPushforward(feJ, fegeom, NbJ, tmpBasisJ)); 28362b6f951bSStefano Zampini // TODO This is currently broken since we do not pull the geometry down to the lower dimension 28372b6f951bSStefano Zampini // PetscCall(PetscFEPushforwardGradient(feJ, fegeom, NbJ, tmpBasisDerJ)); 283827f02ce8SMatthew G. Knepley for (f = 0; f < NbI; ++f) { 283927f02ce8SMatthew G. Knepley for (fc = 0; fc < NcI; ++fc) { 284027f02ce8SMatthew G. Knepley const PetscInt fidx = f * NcI + fc; /* Test function basis index */ 28415fedec97SMatthew G. Knepley const PetscInt i = offsetI + NbI * so + f; /* Element matrix row */ 284227f02ce8SMatthew G. Knepley for (g = 0; g < NbJ; ++g) { 284327f02ce8SMatthew G. Knepley for (gc = 0; gc < NcJ; ++gc) { 284427f02ce8SMatthew G. Knepley const PetscInt gidx = g * NcJ + gc; /* Trial function basis index */ 28455fedec97SMatthew G. Knepley const PetscInt j = offsetJ + NbJ * to + g; /* Element matrix column */ 284627f02ce8SMatthew G. Knepley const PetscInt fOff = eOffset + i * totDim + j; 284727f02ce8SMatthew G. Knepley 28485fedec97SMatthew G. Knepley elemMat[fOff] += tmpBasisI[fidx] * g0[fc * NcJ + gc] * tmpBasisJ[gidx]; 284927f02ce8SMatthew G. Knepley for (df = 0; df < dE; ++df) { 28505fedec97SMatthew G. Knepley elemMat[fOff] += tmpBasisI[fidx] * g1[(fc * NcJ + gc) * dE + df] * tmpBasisDerJ[gidx * dE + df]; 28515fedec97SMatthew G. Knepley elemMat[fOff] += tmpBasisDerI[fidx * dE + df] * g2[(fc * NcJ + gc) * dE + df] * tmpBasisJ[gidx]; 2852ad540459SPierre 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]; 2853a8f1f9e5SMatthew G. Knepley } 2854a8f1f9e5SMatthew G. Knepley } 2855a8f1f9e5SMatthew G. Knepley } 2856a8f1f9e5SMatthew G. Knepley } 2857a8f1f9e5SMatthew G. Knepley } 28583ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 2859a8f1f9e5SMatthew G. Knepley } 2860c9ba7969SMatthew G. Knepley 2861d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFECreateCellGeometry(PetscFE fe, PetscQuadrature quad, PetscFEGeom *cgeom) 2862d71ae5a4SJacob Faibussowitsch { 2863c9ba7969SMatthew G. Knepley PetscDualSpace dsp; 2864c9ba7969SMatthew G. Knepley DM dm; 2865c9ba7969SMatthew G. Knepley PetscQuadrature quadDef; 2866c9ba7969SMatthew G. Knepley PetscInt dim, cdim, Nq; 2867c9ba7969SMatthew G. Knepley 2868c9ba7969SMatthew G. Knepley PetscFunctionBegin; 28699566063dSJacob Faibussowitsch PetscCall(PetscFEGetDualSpace(fe, &dsp)); 28709566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetDM(dsp, &dm)); 28719566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &dim)); 28729566063dSJacob Faibussowitsch PetscCall(DMGetCoordinateDim(dm, &cdim)); 28739566063dSJacob Faibussowitsch PetscCall(PetscFEGetQuadrature(fe, &quadDef)); 2874c9ba7969SMatthew G. Knepley quad = quad ? quad : quadDef; 28759566063dSJacob Faibussowitsch PetscCall(PetscQuadratureGetData(quad, NULL, NULL, &Nq, NULL, NULL)); 28769566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(Nq * cdim, &cgeom->v)); 28779566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(Nq * cdim * cdim, &cgeom->J)); 28789566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(Nq * cdim * cdim, &cgeom->invJ)); 28799566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(Nq, &cgeom->detJ)); 2880c9ba7969SMatthew G. Knepley cgeom->dim = dim; 2881c9ba7969SMatthew G. Knepley cgeom->dimEmbed = cdim; 2882c9ba7969SMatthew G. Knepley cgeom->numCells = 1; 2883c9ba7969SMatthew G. Knepley cgeom->numPoints = Nq; 28849566063dSJacob Faibussowitsch PetscCall(DMPlexComputeCellGeometryFEM(dm, 0, quad, cgeom->v, cgeom->J, cgeom->invJ, cgeom->detJ)); 28853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2886c9ba7969SMatthew G. Knepley } 2887c9ba7969SMatthew G. Knepley 2888d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEDestroyCellGeometry(PetscFE fe, PetscFEGeom *cgeom) 2889d71ae5a4SJacob Faibussowitsch { 2890c9ba7969SMatthew G. Knepley PetscFunctionBegin; 28919566063dSJacob Faibussowitsch PetscCall(PetscFree(cgeom->v)); 28929566063dSJacob Faibussowitsch PetscCall(PetscFree(cgeom->J)); 28939566063dSJacob Faibussowitsch PetscCall(PetscFree(cgeom->invJ)); 28949566063dSJacob Faibussowitsch PetscCall(PetscFree(cgeom->detJ)); 28953ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2896c9ba7969SMatthew G. Knepley } 28971a768569SStefano Zampini 28981a768569SStefano Zampini #if 0 28991a768569SStefano Zampini PetscErrorCode PetscFEUpdateElementMat_Internal_SparseIndices(PetscTabulation TI, PetscTabulation TJ, PetscInt dimEmbed, const PetscInt g0[], const PetscInt g1[], const PetscInt g2[], const PetscInt g3[], PetscInt totDim, PetscInt offsetI, PetscInt offsetJ, PetscInt *n_g0, PetscInt **g0_idxs_out, PetscInt *n_g1, PetscInt **g1_idxs_out, PetscInt *n_g2, PetscInt **g2_idxs_out, PetscInt *n_g3, PetscInt **g3_idxs_out) 29001a768569SStefano Zampini { 29011a768569SStefano Zampini const PetscInt dE = dimEmbed; 29021a768569SStefano Zampini const PetscInt NbI = TI->Nb; 29031a768569SStefano Zampini const PetscInt NcI = TI->Nc; 29041a768569SStefano Zampini const PetscInt NbJ = TJ->Nb; 29051a768569SStefano Zampini const PetscInt NcJ = TJ->Nc; 29061a768569SStefano Zampini PetscBool has_g0 = g0 ? PETSC_TRUE : PETSC_FALSE; 29071a768569SStefano Zampini PetscBool has_g1 = g1 ? PETSC_TRUE : PETSC_FALSE; 29081a768569SStefano Zampini PetscBool has_g2 = g2 ? PETSC_TRUE : PETSC_FALSE; 29091a768569SStefano Zampini PetscBool has_g3 = g3 ? PETSC_TRUE : PETSC_FALSE; 29101a768569SStefano Zampini PetscInt *g0_idxs = NULL, *g1_idxs = NULL, *g2_idxs = NULL, *g3_idxs = NULL; 29111a768569SStefano Zampini PetscInt g0_i, g1_i, g2_i, g3_i; 29121a768569SStefano Zampini 29131a768569SStefano Zampini PetscFunctionBegin; 29141a768569SStefano Zampini g0_i = g1_i = g2_i = g3_i = 0; 29151a768569SStefano Zampini if (has_g0) 29161a768569SStefano Zampini for (PetscInt i = 0; i < NcI * NcJ; i++) 29171a768569SStefano Zampini if (g0[i]) g0_i += NbI * NbJ; 29181a768569SStefano Zampini if (has_g1) 29191a768569SStefano Zampini for (PetscInt i = 0; i < NcI * NcJ * dE; i++) 29201a768569SStefano Zampini if (g1[i]) g1_i += NbI * NbJ; 29211a768569SStefano Zampini if (has_g2) 29221a768569SStefano Zampini for (PetscInt i = 0; i < NcI * NcJ * dE; i++) 29231a768569SStefano Zampini if (g2[i]) g2_i += NbI * NbJ; 29241a768569SStefano Zampini if (has_g3) 29251a768569SStefano Zampini for (PetscInt i = 0; i < NcI * NcJ * dE * dE; i++) 29261a768569SStefano Zampini if (g3[i]) g3_i += NbI * NbJ; 29271a768569SStefano Zampini if (g0_i == NbI * NbJ * NcI * NcJ) g0_i = 0; 29281a768569SStefano Zampini if (g1_i == NbI * NbJ * NcI * NcJ * dE) g1_i = 0; 29291a768569SStefano Zampini if (g2_i == NbI * NbJ * NcI * NcJ * dE) g2_i = 0; 29301a768569SStefano Zampini if (g3_i == NbI * NbJ * NcI * NcJ * dE * dE) g3_i = 0; 29311a768569SStefano Zampini has_g0 = g0_i ? PETSC_TRUE : PETSC_FALSE; 29321a768569SStefano Zampini has_g1 = g1_i ? PETSC_TRUE : PETSC_FALSE; 29331a768569SStefano Zampini has_g2 = g2_i ? PETSC_TRUE : PETSC_FALSE; 29341a768569SStefano Zampini has_g3 = g3_i ? PETSC_TRUE : PETSC_FALSE; 29351a768569SStefano Zampini if (has_g0) PetscCall(PetscMalloc1(4 * g0_i, &g0_idxs)); 29361a768569SStefano Zampini if (has_g1) PetscCall(PetscMalloc1(4 * g1_i, &g1_idxs)); 29371a768569SStefano Zampini if (has_g2) PetscCall(PetscMalloc1(4 * g2_i, &g2_idxs)); 29381a768569SStefano Zampini if (has_g3) PetscCall(PetscMalloc1(4 * g3_i, &g3_idxs)); 29391a768569SStefano Zampini g0_i = g1_i = g2_i = g3_i = 0; 29401a768569SStefano Zampini 29411a768569SStefano Zampini for (PetscInt f = 0; f < NbI; ++f) { 29421a768569SStefano Zampini const PetscInt i = offsetI + f; /* Element matrix row */ 29431a768569SStefano Zampini for (PetscInt fc = 0; fc < NcI; ++fc) { 29441a768569SStefano Zampini const PetscInt fidx = f * NcI + fc; /* Test function basis index */ 29451a768569SStefano Zampini 29461a768569SStefano Zampini for (PetscInt g = 0; g < NbJ; ++g) { 29471a768569SStefano Zampini const PetscInt j = offsetJ + g; /* Element matrix column */ 29481a768569SStefano Zampini const PetscInt fOff = i * totDim + j; 29491a768569SStefano Zampini for (PetscInt gc = 0; gc < NcJ; ++gc) { 29501a768569SStefano Zampini const PetscInt gidx = g * NcJ + gc; /* Trial function basis index */ 29511a768569SStefano Zampini 29521a768569SStefano Zampini if (has_g0) { 29531a768569SStefano Zampini if (g0[fc * NcJ + gc]) { 29541a768569SStefano Zampini g0_idxs[4 * g0_i + 0] = fidx; 29551a768569SStefano Zampini g0_idxs[4 * g0_i + 1] = fc * NcJ + gc; 29561a768569SStefano Zampini g0_idxs[4 * g0_i + 2] = gidx; 29571a768569SStefano Zampini g0_idxs[4 * g0_i + 3] = fOff; 29581a768569SStefano Zampini g0_i++; 29591a768569SStefano Zampini } 29601a768569SStefano Zampini } 29611a768569SStefano Zampini 29621a768569SStefano Zampini for (PetscInt df = 0; df < dE; ++df) { 29631a768569SStefano Zampini if (has_g1) { 29641a768569SStefano Zampini if (g1[(fc * NcJ + gc) * dE + df]) { 29651a768569SStefano Zampini g1_idxs[4 * g1_i + 0] = fidx; 29661a768569SStefano Zampini g1_idxs[4 * g1_i + 1] = (fc * NcJ + gc) * dE + df; 29671a768569SStefano Zampini g1_idxs[4 * g1_i + 2] = gidx * dE + df; 29681a768569SStefano Zampini g1_idxs[4 * g1_i + 3] = fOff; 29691a768569SStefano Zampini g1_i++; 29701a768569SStefano Zampini } 29711a768569SStefano Zampini } 29721a768569SStefano Zampini if (has_g2) { 29731a768569SStefano Zampini if (g2[(fc * NcJ + gc) * dE + df]) { 29741a768569SStefano Zampini g2_idxs[4 * g2_i + 0] = fidx * dE + df; 29751a768569SStefano Zampini g2_idxs[4 * g2_i + 1] = (fc * NcJ + gc) * dE + df; 29761a768569SStefano Zampini g2_idxs[4 * g2_i + 2] = gidx; 29771a768569SStefano Zampini g2_idxs[4 * g2_i + 3] = fOff; 29781a768569SStefano Zampini g2_i++; 29791a768569SStefano Zampini } 29801a768569SStefano Zampini } 29811a768569SStefano Zampini if (has_g3) { 29821a768569SStefano Zampini for (PetscInt dg = 0; dg < dE; ++dg) { 29831a768569SStefano Zampini if (g3[((fc * NcJ + gc) * dE + df) * dE + dg]) { 29841a768569SStefano Zampini g3_idxs[4 * g3_i + 0] = fidx * dE + df; 29851a768569SStefano Zampini g3_idxs[4 * g3_i + 1] = ((fc * NcJ + gc) * dE + df) * dE + dg; 29861a768569SStefano Zampini g3_idxs[4 * g3_i + 2] = gidx * dE + dg; 29871a768569SStefano Zampini g3_idxs[4 * g3_i + 3] = fOff; 29881a768569SStefano Zampini g3_i++; 29891a768569SStefano Zampini } 29901a768569SStefano Zampini } 29911a768569SStefano Zampini } 29921a768569SStefano Zampini } 29931a768569SStefano Zampini } 29941a768569SStefano Zampini } 29951a768569SStefano Zampini } 29961a768569SStefano Zampini } 29971a768569SStefano Zampini *n_g0 = g0_i; 29981a768569SStefano Zampini *n_g1 = g1_i; 29991a768569SStefano Zampini *n_g2 = g2_i; 30001a768569SStefano Zampini *n_g3 = g3_i; 30011a768569SStefano Zampini 30021a768569SStefano Zampini *g0_idxs_out = g0_idxs; 30031a768569SStefano Zampini *g1_idxs_out = g1_idxs; 30041a768569SStefano Zampini *g2_idxs_out = g2_idxs; 30051a768569SStefano Zampini *g3_idxs_out = g3_idxs; 30061a768569SStefano Zampini PetscFunctionReturn(PETSC_SUCCESS); 30071a768569SStefano Zampini } 30081a768569SStefano Zampini 30091a768569SStefano Zampini //example HOW TO USE 30101a768569SStefano Zampini for (PetscInt i = 0; i < g0_sparse_n; i++) { 30111a768569SStefano Zampini PetscInt bM = g0_sparse_idxs[4 * i + 0]; 30121a768569SStefano Zampini PetscInt bN = g0_sparse_idxs[4 * i + 1]; 30131a768569SStefano Zampini PetscInt bK = g0_sparse_idxs[4 * i + 2]; 30141a768569SStefano Zampini PetscInt bO = g0_sparse_idxs[4 * i + 3]; 30151a768569SStefano Zampini elemMat[bO] += tmpBasisI[bM] * g0[bN] * tmpBasisJ[bK]; 30161a768569SStefano Zampini } 30171a768569SStefano Zampini #endif 3018