120cf1dd8SToby Isaac /* Basis Jet Tabulation 220cf1dd8SToby Isaac 320cf1dd8SToby Isaac We would like to tabulate the nodal basis functions and derivatives at a set of points, usually quadrature points. We 420cf1dd8SToby Isaac follow here the derviation in http://www.math.ttu.edu/~kirby/papers/fiat-toms-2004.pdf. The nodal basis $\psi_i$ can 520cf1dd8SToby Isaac be expressed in terms of a prime basis $\phi_i$ which can be stably evaluated. In PETSc, we will use the Legendre basis 620cf1dd8SToby Isaac as a prime basis. 720cf1dd8SToby Isaac 820cf1dd8SToby Isaac \psi_i = \sum_k \alpha_{ki} \phi_k 920cf1dd8SToby Isaac 1020cf1dd8SToby Isaac Our nodal basis is defined in terms of the dual basis $n_j$ 1120cf1dd8SToby Isaac 1220cf1dd8SToby Isaac n_j \cdot \psi_i = \delta_{ji} 1320cf1dd8SToby Isaac 1420cf1dd8SToby Isaac and we may act on the first equation to obtain 1520cf1dd8SToby Isaac 1620cf1dd8SToby Isaac n_j \cdot \psi_i = \sum_k \alpha_{ki} n_j \cdot \phi_k 1720cf1dd8SToby Isaac \delta_{ji} = \sum_k \alpha_{ki} V_{jk} 1820cf1dd8SToby Isaac I = V \alpha 1920cf1dd8SToby Isaac 2020cf1dd8SToby Isaac so the coefficients of the nodal basis in the prime basis are 2120cf1dd8SToby Isaac 2220cf1dd8SToby Isaac \alpha = V^{-1} 2320cf1dd8SToby Isaac 2420cf1dd8SToby Isaac We will define the dual basis vectors $n_j$ using a quadrature rule. 2520cf1dd8SToby Isaac 2620cf1dd8SToby Isaac Right now, we will just use the polynomial spaces P^k. I know some elements use the space of symmetric polynomials 2720cf1dd8SToby Isaac (I think Nedelec), but we will neglect this for now. Constraints in the space, e.g. Arnold-Winther elements, can 2820cf1dd8SToby Isaac be implemented exactly as in FIAT using functionals $L_j$. 2920cf1dd8SToby Isaac 3020cf1dd8SToby Isaac I will have to count the degrees correctly for the Legendre product when we are on simplices. 3120cf1dd8SToby Isaac 3220cf1dd8SToby Isaac We will have three objects: 3320cf1dd8SToby Isaac - Space, P: this just need point evaluation I think 3420cf1dd8SToby Isaac - Dual Space, P'+K: This looks like a set of functionals that can act on members of P, each n is defined by a Q 3520cf1dd8SToby Isaac - FEM: This keeps {P, P', Q} 3620cf1dd8SToby Isaac */ 3720cf1dd8SToby Isaac #include <petsc/private/petscfeimpl.h> /*I "petscfe.h" I*/ 3820cf1dd8SToby Isaac #include <petscdmplex.h> 3920cf1dd8SToby Isaac 4020cf1dd8SToby Isaac PetscBool FEcite = PETSC_FALSE; 4120cf1dd8SToby Isaac const char FECitation[] = "@article{kirby2004,\n" 4220cf1dd8SToby Isaac " title = {Algorithm 839: FIAT, a New Paradigm for Computing Finite Element Basis Functions},\n" 4320cf1dd8SToby Isaac " journal = {ACM Transactions on Mathematical Software},\n" 4420cf1dd8SToby Isaac " author = {Robert C. Kirby},\n" 4520cf1dd8SToby Isaac " volume = {30},\n" 4620cf1dd8SToby Isaac " number = {4},\n" 4720cf1dd8SToby Isaac " pages = {502--516},\n" 4820cf1dd8SToby Isaac " doi = {10.1145/1039813.1039820},\n" 4920cf1dd8SToby Isaac " year = {2004}\n}\n"; 5020cf1dd8SToby Isaac 5120cf1dd8SToby Isaac PetscClassId PETSCFE_CLASSID = 0; 5220cf1dd8SToby Isaac 53ead873ccSMatthew G. Knepley PetscLogEvent PETSCFE_SetUp; 54ead873ccSMatthew G. Knepley 5520cf1dd8SToby Isaac PetscFunctionList PetscFEList = NULL; 5620cf1dd8SToby Isaac PetscBool PetscFERegisterAllCalled = PETSC_FALSE; 5720cf1dd8SToby Isaac 5820cf1dd8SToby Isaac /*@C 5920cf1dd8SToby Isaac PetscFERegister - Adds a new PetscFE implementation 6020cf1dd8SToby Isaac 6120cf1dd8SToby Isaac Not Collective 6220cf1dd8SToby Isaac 6320cf1dd8SToby Isaac Input Parameters: 6420cf1dd8SToby Isaac + name - The name of a new user-defined creation routine 6520cf1dd8SToby Isaac - create_func - The creation routine itself 6620cf1dd8SToby Isaac 6720cf1dd8SToby Isaac Notes: 6820cf1dd8SToby Isaac PetscFERegister() may be called multiple times to add several user-defined PetscFEs 6920cf1dd8SToby Isaac 7020cf1dd8SToby Isaac Sample usage: 7120cf1dd8SToby Isaac .vb 7220cf1dd8SToby Isaac PetscFERegister("my_fe", MyPetscFECreate); 7320cf1dd8SToby Isaac .ve 7420cf1dd8SToby Isaac 7520cf1dd8SToby Isaac Then, your PetscFE type can be chosen with the procedural interface via 7620cf1dd8SToby Isaac .vb 7720cf1dd8SToby Isaac PetscFECreate(MPI_Comm, PetscFE *); 7820cf1dd8SToby Isaac PetscFESetType(PetscFE, "my_fe"); 7920cf1dd8SToby Isaac .ve 8020cf1dd8SToby Isaac or at runtime via the option 8120cf1dd8SToby Isaac .vb 8220cf1dd8SToby Isaac -petscfe_type my_fe 8320cf1dd8SToby Isaac .ve 8420cf1dd8SToby Isaac 8520cf1dd8SToby Isaac Level: advanced 8620cf1dd8SToby Isaac 8720cf1dd8SToby Isaac .seealso: PetscFERegisterAll(), PetscFERegisterDestroy() 8820cf1dd8SToby Isaac 8920cf1dd8SToby Isaac @*/ 9020cf1dd8SToby Isaac PetscErrorCode PetscFERegister(const char sname[], PetscErrorCode (*function)(PetscFE)) 9120cf1dd8SToby Isaac { 9220cf1dd8SToby Isaac PetscFunctionBegin; 935f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFunctionListAdd(&PetscFEList, sname, function)); 9420cf1dd8SToby Isaac PetscFunctionReturn(0); 9520cf1dd8SToby Isaac } 9620cf1dd8SToby Isaac 9720cf1dd8SToby Isaac /*@C 9820cf1dd8SToby Isaac PetscFESetType - Builds a particular PetscFE 9920cf1dd8SToby Isaac 100d083f849SBarry Smith Collective on fem 10120cf1dd8SToby Isaac 10220cf1dd8SToby Isaac Input Parameters: 10320cf1dd8SToby Isaac + fem - The PetscFE object 10420cf1dd8SToby Isaac - name - The kind of FEM space 10520cf1dd8SToby Isaac 10620cf1dd8SToby Isaac Options Database Key: 10720cf1dd8SToby Isaac . -petscfe_type <type> - Sets the PetscFE type; use -help for a list of available types 10820cf1dd8SToby Isaac 10920cf1dd8SToby Isaac Level: intermediate 11020cf1dd8SToby Isaac 11120cf1dd8SToby Isaac .seealso: PetscFEGetType(), PetscFECreate() 11220cf1dd8SToby Isaac @*/ 11320cf1dd8SToby Isaac PetscErrorCode PetscFESetType(PetscFE fem, PetscFEType name) 11420cf1dd8SToby Isaac { 11520cf1dd8SToby Isaac PetscErrorCode (*r)(PetscFE); 11620cf1dd8SToby Isaac PetscBool match; 11720cf1dd8SToby Isaac 11820cf1dd8SToby Isaac PetscFunctionBegin; 11920cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 1205f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectTypeCompare((PetscObject) fem, name, &match)); 12120cf1dd8SToby Isaac if (match) PetscFunctionReturn(0); 12220cf1dd8SToby Isaac 1235f80ce2aSJacob Faibussowitsch if (!PetscFERegisterAllCalled) CHKERRQ(PetscFERegisterAll()); 1245f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFunctionListFind(PetscFEList, name, &r)); 125*28b400f6SJacob Faibussowitsch PetscCheck(r,PetscObjectComm((PetscObject) fem), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown PetscFE type: %s", name); 12620cf1dd8SToby Isaac 12720cf1dd8SToby Isaac if (fem->ops->destroy) { 1285f80ce2aSJacob Faibussowitsch CHKERRQ((*fem->ops->destroy)(fem)); 12920cf1dd8SToby Isaac fem->ops->destroy = NULL; 13020cf1dd8SToby Isaac } 1315f80ce2aSJacob Faibussowitsch CHKERRQ((*r)(fem)); 1325f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectChangeTypeName((PetscObject) fem, name)); 13320cf1dd8SToby Isaac PetscFunctionReturn(0); 13420cf1dd8SToby Isaac } 13520cf1dd8SToby Isaac 13620cf1dd8SToby Isaac /*@C 13720cf1dd8SToby Isaac PetscFEGetType - Gets the PetscFE type name (as a string) from the object. 13820cf1dd8SToby Isaac 13920cf1dd8SToby Isaac Not Collective 14020cf1dd8SToby Isaac 14120cf1dd8SToby Isaac Input Parameter: 14220cf1dd8SToby Isaac . fem - The PetscFE 14320cf1dd8SToby Isaac 14420cf1dd8SToby Isaac Output Parameter: 14520cf1dd8SToby Isaac . name - The PetscFE type name 14620cf1dd8SToby Isaac 14720cf1dd8SToby Isaac Level: intermediate 14820cf1dd8SToby Isaac 14920cf1dd8SToby Isaac .seealso: PetscFESetType(), PetscFECreate() 15020cf1dd8SToby Isaac @*/ 15120cf1dd8SToby Isaac PetscErrorCode PetscFEGetType(PetscFE fem, PetscFEType *name) 15220cf1dd8SToby Isaac { 15320cf1dd8SToby Isaac PetscFunctionBegin; 15420cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 15520cf1dd8SToby Isaac PetscValidPointer(name, 2); 15620cf1dd8SToby Isaac if (!PetscFERegisterAllCalled) { 1575f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFERegisterAll()); 15820cf1dd8SToby Isaac } 15920cf1dd8SToby Isaac *name = ((PetscObject) fem)->type_name; 16020cf1dd8SToby Isaac PetscFunctionReturn(0); 16120cf1dd8SToby Isaac } 16220cf1dd8SToby Isaac 16320cf1dd8SToby Isaac /*@C 164fe2efc57SMark PetscFEViewFromOptions - View from Options 165fe2efc57SMark 166fe2efc57SMark Collective on PetscFE 167fe2efc57SMark 168fe2efc57SMark Input Parameters: 169fe2efc57SMark + A - the PetscFE object 170fe2efc57SMark . obj - Optional object 171fe2efc57SMark - name - command line option 172fe2efc57SMark 173fe2efc57SMark Level: intermediate 174fe2efc57SMark .seealso: PetscFE(), PetscFEView(), PetscObjectViewFromOptions(), PetscFECreate() 175fe2efc57SMark @*/ 176fe2efc57SMark PetscErrorCode PetscFEViewFromOptions(PetscFE A,PetscObject obj,const char name[]) 177fe2efc57SMark { 178fe2efc57SMark PetscFunctionBegin; 179fe2efc57SMark PetscValidHeaderSpecific(A,PETSCFE_CLASSID,1); 1805f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectViewFromOptions((PetscObject)A,obj,name)); 181fe2efc57SMark PetscFunctionReturn(0); 182fe2efc57SMark } 183fe2efc57SMark 184fe2efc57SMark /*@C 18520cf1dd8SToby Isaac PetscFEView - Views a PetscFE 18620cf1dd8SToby Isaac 187d083f849SBarry Smith Collective on fem 18820cf1dd8SToby Isaac 189d8d19677SJose E. Roman Input Parameters: 19020cf1dd8SToby Isaac + fem - the PetscFE object to view 191d9bac1caSLisandro Dalcin - viewer - the viewer 19220cf1dd8SToby Isaac 1932b99622eSMatthew G. Knepley Level: beginner 19420cf1dd8SToby Isaac 19520cf1dd8SToby Isaac .seealso PetscFEDestroy() 19620cf1dd8SToby Isaac @*/ 197d9bac1caSLisandro Dalcin PetscErrorCode PetscFEView(PetscFE fem, PetscViewer viewer) 19820cf1dd8SToby Isaac { 199d9bac1caSLisandro Dalcin PetscBool iascii; 20020cf1dd8SToby Isaac 20120cf1dd8SToby Isaac PetscFunctionBegin; 20220cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 203d9bac1caSLisandro Dalcin if (viewer) PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 2045f80ce2aSJacob Faibussowitsch if (!viewer) CHKERRQ(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject) fem), &viewer)); 2055f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectPrintClassNamePrefixType((PetscObject)fem, viewer)); 2065f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii)); 2075f80ce2aSJacob Faibussowitsch if (fem->ops->view) CHKERRQ((*fem->ops->view)(fem, viewer)); 20820cf1dd8SToby Isaac PetscFunctionReturn(0); 20920cf1dd8SToby Isaac } 21020cf1dd8SToby Isaac 21120cf1dd8SToby Isaac /*@ 21220cf1dd8SToby Isaac PetscFESetFromOptions - sets parameters in a PetscFE from the options database 21320cf1dd8SToby Isaac 214d083f849SBarry Smith Collective on fem 21520cf1dd8SToby Isaac 21620cf1dd8SToby Isaac Input Parameter: 21720cf1dd8SToby Isaac . fem - the PetscFE object to set options for 21820cf1dd8SToby Isaac 21920cf1dd8SToby Isaac Options Database: 220a2b725a8SWilliam Gropp + -petscfe_num_blocks - the number of cell blocks to integrate concurrently 221a2b725a8SWilliam Gropp - -petscfe_num_batches - the number of cell batches to integrate serially 22220cf1dd8SToby Isaac 2232b99622eSMatthew G. Knepley Level: intermediate 22420cf1dd8SToby Isaac 22520cf1dd8SToby Isaac .seealso PetscFEView() 22620cf1dd8SToby Isaac @*/ 22720cf1dd8SToby Isaac PetscErrorCode PetscFESetFromOptions(PetscFE fem) 22820cf1dd8SToby Isaac { 22920cf1dd8SToby Isaac const char *defaultType; 23020cf1dd8SToby Isaac char name[256]; 23120cf1dd8SToby Isaac PetscBool flg; 23220cf1dd8SToby Isaac PetscErrorCode ierr; 23320cf1dd8SToby Isaac 23420cf1dd8SToby Isaac PetscFunctionBegin; 23520cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 23620cf1dd8SToby Isaac if (!((PetscObject) fem)->type_name) { 23720cf1dd8SToby Isaac defaultType = PETSCFEBASIC; 23820cf1dd8SToby Isaac } else { 23920cf1dd8SToby Isaac defaultType = ((PetscObject) fem)->type_name; 24020cf1dd8SToby Isaac } 2415f80ce2aSJacob Faibussowitsch if (!PetscFERegisterAllCalled) CHKERRQ(PetscFERegisterAll()); 24220cf1dd8SToby Isaac 24320cf1dd8SToby Isaac ierr = PetscObjectOptionsBegin((PetscObject) fem);CHKERRQ(ierr); 2445f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsFList("-petscfe_type", "Finite element space", "PetscFESetType", PetscFEList, defaultType, name, 256, &flg)); 24520cf1dd8SToby Isaac if (flg) { 2465f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFESetType(fem, name)); 24720cf1dd8SToby Isaac } else if (!((PetscObject) fem)->type_name) { 2485f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFESetType(fem, defaultType)); 24920cf1dd8SToby Isaac } 2505f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsBoundedInt("-petscfe_num_blocks", "The number of cell blocks to integrate concurrently", "PetscSpaceSetTileSizes", fem->numBlocks, &fem->numBlocks, NULL,1)); 2515f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsBoundedInt("-petscfe_num_batches", "The number of cell batches to integrate serially", "PetscSpaceSetTileSizes", fem->numBatches, &fem->numBatches, NULL,1)); 25220cf1dd8SToby Isaac if (fem->ops->setfromoptions) { 2535f80ce2aSJacob Faibussowitsch CHKERRQ((*fem->ops->setfromoptions)(PetscOptionsObject,fem)); 25420cf1dd8SToby Isaac } 25520cf1dd8SToby Isaac /* process any options handlers added with PetscObjectAddOptionsHandler() */ 2565f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject) fem)); 25720cf1dd8SToby Isaac ierr = PetscOptionsEnd();CHKERRQ(ierr); 2585f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEViewFromOptions(fem, NULL, "-petscfe_view")); 25920cf1dd8SToby Isaac PetscFunctionReturn(0); 26020cf1dd8SToby Isaac } 26120cf1dd8SToby Isaac 26220cf1dd8SToby Isaac /*@C 26320cf1dd8SToby Isaac PetscFESetUp - Construct data structures for the PetscFE 26420cf1dd8SToby Isaac 265d083f849SBarry Smith Collective on fem 26620cf1dd8SToby Isaac 26720cf1dd8SToby Isaac Input Parameter: 26820cf1dd8SToby Isaac . fem - the PetscFE object to setup 26920cf1dd8SToby Isaac 2702b99622eSMatthew G. Knepley Level: intermediate 27120cf1dd8SToby Isaac 27220cf1dd8SToby Isaac .seealso PetscFEView(), PetscFEDestroy() 27320cf1dd8SToby Isaac @*/ 27420cf1dd8SToby Isaac PetscErrorCode PetscFESetUp(PetscFE fem) 27520cf1dd8SToby Isaac { 27620cf1dd8SToby Isaac PetscFunctionBegin; 27720cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 27820cf1dd8SToby Isaac if (fem->setupcalled) PetscFunctionReturn(0); 2795f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLogEventBegin(PETSCFE_SetUp, fem, 0, 0, 0)); 28020cf1dd8SToby Isaac fem->setupcalled = PETSC_TRUE; 2815f80ce2aSJacob Faibussowitsch if (fem->ops->setup) CHKERRQ((*fem->ops->setup)(fem)); 2825f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLogEventEnd(PETSCFE_SetUp, fem, 0, 0, 0)); 28320cf1dd8SToby Isaac PetscFunctionReturn(0); 28420cf1dd8SToby Isaac } 28520cf1dd8SToby Isaac 28620cf1dd8SToby Isaac /*@ 28720cf1dd8SToby Isaac PetscFEDestroy - Destroys a PetscFE object 28820cf1dd8SToby Isaac 289d083f849SBarry Smith Collective on fem 29020cf1dd8SToby Isaac 29120cf1dd8SToby Isaac Input Parameter: 29220cf1dd8SToby Isaac . fem - the PetscFE object to destroy 29320cf1dd8SToby Isaac 2942b99622eSMatthew G. Knepley Level: beginner 29520cf1dd8SToby Isaac 29620cf1dd8SToby Isaac .seealso PetscFEView() 29720cf1dd8SToby Isaac @*/ 29820cf1dd8SToby Isaac PetscErrorCode PetscFEDestroy(PetscFE *fem) 29920cf1dd8SToby Isaac { 30020cf1dd8SToby Isaac PetscFunctionBegin; 30120cf1dd8SToby Isaac if (!*fem) PetscFunctionReturn(0); 30220cf1dd8SToby Isaac PetscValidHeaderSpecific((*fem), PETSCFE_CLASSID, 1); 30320cf1dd8SToby Isaac 304ea78f98cSLisandro Dalcin if (--((PetscObject)(*fem))->refct > 0) {*fem = NULL; PetscFunctionReturn(0);} 30520cf1dd8SToby Isaac ((PetscObject) (*fem))->refct = 0; 30620cf1dd8SToby Isaac 30720cf1dd8SToby Isaac if ((*fem)->subspaces) { 30820cf1dd8SToby Isaac PetscInt dim, d; 30920cf1dd8SToby Isaac 3105f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceGetDimension((*fem)->dualSpace, &dim)); 3115f80ce2aSJacob Faibussowitsch for (d = 0; d < dim; ++d) CHKERRQ(PetscFEDestroy(&(*fem)->subspaces[d])); 31220cf1dd8SToby Isaac } 3135f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree((*fem)->subspaces)); 3145f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree((*fem)->invV)); 3155f80ce2aSJacob Faibussowitsch CHKERRQ(PetscTabulationDestroy(&(*fem)->T)); 3165f80ce2aSJacob Faibussowitsch CHKERRQ(PetscTabulationDestroy(&(*fem)->Tf)); 3175f80ce2aSJacob Faibussowitsch CHKERRQ(PetscTabulationDestroy(&(*fem)->Tc)); 3185f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceDestroy(&(*fem)->basisSpace)); 3195f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceDestroy(&(*fem)->dualSpace)); 3205f80ce2aSJacob Faibussowitsch CHKERRQ(PetscQuadratureDestroy(&(*fem)->quadrature)); 3215f80ce2aSJacob Faibussowitsch CHKERRQ(PetscQuadratureDestroy(&(*fem)->faceQuadrature)); 322f918ec44SMatthew G. Knepley #ifdef PETSC_HAVE_LIBCEED 3235f80ce2aSJacob Faibussowitsch CHKERRQ_CEED(CeedBasisDestroy(&(*fem)->ceedBasis)); 3245f80ce2aSJacob Faibussowitsch CHKERRQ_CEED(CeedDestroy(&(*fem)->ceed)); 325f918ec44SMatthew G. Knepley #endif 32620cf1dd8SToby Isaac 3275f80ce2aSJacob Faibussowitsch if ((*fem)->ops->destroy) CHKERRQ((*(*fem)->ops->destroy)(*fem)); 3285f80ce2aSJacob Faibussowitsch CHKERRQ(PetscHeaderDestroy(fem)); 32920cf1dd8SToby Isaac PetscFunctionReturn(0); 33020cf1dd8SToby Isaac } 33120cf1dd8SToby Isaac 33220cf1dd8SToby Isaac /*@ 33320cf1dd8SToby Isaac PetscFECreate - Creates an empty PetscFE object. The type can then be set with PetscFESetType(). 33420cf1dd8SToby Isaac 335d083f849SBarry Smith Collective 33620cf1dd8SToby Isaac 33720cf1dd8SToby Isaac Input Parameter: 33820cf1dd8SToby Isaac . comm - The communicator for the PetscFE object 33920cf1dd8SToby Isaac 34020cf1dd8SToby Isaac Output Parameter: 34120cf1dd8SToby Isaac . fem - The PetscFE object 34220cf1dd8SToby Isaac 34320cf1dd8SToby Isaac Level: beginner 34420cf1dd8SToby Isaac 34520cf1dd8SToby Isaac .seealso: PetscFESetType(), PETSCFEGALERKIN 34620cf1dd8SToby Isaac @*/ 34720cf1dd8SToby Isaac PetscErrorCode PetscFECreate(MPI_Comm comm, PetscFE *fem) 34820cf1dd8SToby Isaac { 34920cf1dd8SToby Isaac PetscFE f; 35020cf1dd8SToby Isaac 35120cf1dd8SToby Isaac PetscFunctionBegin; 35220cf1dd8SToby Isaac PetscValidPointer(fem, 2); 3535f80ce2aSJacob Faibussowitsch CHKERRQ(PetscCitationsRegister(FECitation,&FEcite)); 35420cf1dd8SToby Isaac *fem = NULL; 3555f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEInitializePackage()); 35620cf1dd8SToby Isaac 3575f80ce2aSJacob Faibussowitsch CHKERRQ(PetscHeaderCreate(f, PETSCFE_CLASSID, "PetscFE", "Finite Element", "PetscFE", comm, PetscFEDestroy, PetscFEView)); 35820cf1dd8SToby Isaac 35920cf1dd8SToby Isaac f->basisSpace = NULL; 36020cf1dd8SToby Isaac f->dualSpace = NULL; 36120cf1dd8SToby Isaac f->numComponents = 1; 36220cf1dd8SToby Isaac f->subspaces = NULL; 36320cf1dd8SToby Isaac f->invV = NULL; 364ef0bb6c7SMatthew G. Knepley f->T = NULL; 365ef0bb6c7SMatthew G. Knepley f->Tf = NULL; 366ef0bb6c7SMatthew G. Knepley f->Tc = NULL; 3675f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArrayzero(&f->quadrature, 1)); 3685f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArrayzero(&f->faceQuadrature, 1)); 36920cf1dd8SToby Isaac f->blockSize = 0; 37020cf1dd8SToby Isaac f->numBlocks = 1; 37120cf1dd8SToby Isaac f->batchSize = 0; 37220cf1dd8SToby Isaac f->numBatches = 1; 37320cf1dd8SToby Isaac 37420cf1dd8SToby Isaac *fem = f; 37520cf1dd8SToby Isaac PetscFunctionReturn(0); 37620cf1dd8SToby Isaac } 37720cf1dd8SToby Isaac 37820cf1dd8SToby Isaac /*@ 37920cf1dd8SToby Isaac PetscFEGetSpatialDimension - Returns the spatial dimension of the element 38020cf1dd8SToby Isaac 38120cf1dd8SToby Isaac Not collective 38220cf1dd8SToby Isaac 38320cf1dd8SToby Isaac Input Parameter: 38420cf1dd8SToby Isaac . fem - The PetscFE object 38520cf1dd8SToby Isaac 38620cf1dd8SToby Isaac Output Parameter: 38720cf1dd8SToby Isaac . dim - The spatial dimension 38820cf1dd8SToby Isaac 38920cf1dd8SToby Isaac Level: intermediate 39020cf1dd8SToby Isaac 39120cf1dd8SToby Isaac .seealso: PetscFECreate() 39220cf1dd8SToby Isaac @*/ 39320cf1dd8SToby Isaac PetscErrorCode PetscFEGetSpatialDimension(PetscFE fem, PetscInt *dim) 39420cf1dd8SToby Isaac { 39520cf1dd8SToby Isaac DM dm; 39620cf1dd8SToby Isaac 39720cf1dd8SToby Isaac PetscFunctionBegin; 39820cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 39920cf1dd8SToby Isaac PetscValidPointer(dim, 2); 4005f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceGetDM(fem->dualSpace, &dm)); 4015f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetDimension(dm, dim)); 40220cf1dd8SToby Isaac PetscFunctionReturn(0); 40320cf1dd8SToby Isaac } 40420cf1dd8SToby Isaac 40520cf1dd8SToby Isaac /*@ 40620cf1dd8SToby Isaac PetscFESetNumComponents - Sets the number of components in the element 40720cf1dd8SToby Isaac 40820cf1dd8SToby Isaac Not collective 40920cf1dd8SToby Isaac 41020cf1dd8SToby Isaac Input Parameters: 41120cf1dd8SToby Isaac + fem - The PetscFE object 41220cf1dd8SToby Isaac - comp - The number of field components 41320cf1dd8SToby Isaac 41420cf1dd8SToby Isaac Level: intermediate 41520cf1dd8SToby Isaac 41620cf1dd8SToby Isaac .seealso: PetscFECreate() 41720cf1dd8SToby Isaac @*/ 41820cf1dd8SToby Isaac PetscErrorCode PetscFESetNumComponents(PetscFE fem, PetscInt comp) 41920cf1dd8SToby Isaac { 42020cf1dd8SToby Isaac PetscFunctionBegin; 42120cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 42220cf1dd8SToby Isaac fem->numComponents = comp; 42320cf1dd8SToby Isaac PetscFunctionReturn(0); 42420cf1dd8SToby Isaac } 42520cf1dd8SToby Isaac 42620cf1dd8SToby Isaac /*@ 42720cf1dd8SToby Isaac PetscFEGetNumComponents - Returns the number of components in the element 42820cf1dd8SToby Isaac 42920cf1dd8SToby Isaac Not collective 43020cf1dd8SToby Isaac 43120cf1dd8SToby Isaac Input Parameter: 43220cf1dd8SToby Isaac . fem - The PetscFE object 43320cf1dd8SToby Isaac 43420cf1dd8SToby Isaac Output Parameter: 43520cf1dd8SToby Isaac . comp - The number of field components 43620cf1dd8SToby Isaac 43720cf1dd8SToby Isaac Level: intermediate 43820cf1dd8SToby Isaac 43920cf1dd8SToby Isaac .seealso: PetscFECreate() 44020cf1dd8SToby Isaac @*/ 44120cf1dd8SToby Isaac PetscErrorCode PetscFEGetNumComponents(PetscFE fem, PetscInt *comp) 44220cf1dd8SToby Isaac { 44320cf1dd8SToby Isaac PetscFunctionBegin; 44420cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 44520cf1dd8SToby Isaac PetscValidPointer(comp, 2); 44620cf1dd8SToby Isaac *comp = fem->numComponents; 44720cf1dd8SToby Isaac PetscFunctionReturn(0); 44820cf1dd8SToby Isaac } 44920cf1dd8SToby Isaac 45020cf1dd8SToby Isaac /*@ 45120cf1dd8SToby Isaac PetscFESetTileSizes - Sets the tile sizes for evaluation 45220cf1dd8SToby Isaac 45320cf1dd8SToby Isaac Not collective 45420cf1dd8SToby Isaac 45520cf1dd8SToby Isaac Input Parameters: 45620cf1dd8SToby Isaac + fem - The PetscFE object 45720cf1dd8SToby Isaac . blockSize - The number of elements in a block 45820cf1dd8SToby Isaac . numBlocks - The number of blocks in a batch 45920cf1dd8SToby Isaac . batchSize - The number of elements in a batch 46020cf1dd8SToby Isaac - numBatches - The number of batches in a chunk 46120cf1dd8SToby Isaac 46220cf1dd8SToby Isaac Level: intermediate 46320cf1dd8SToby Isaac 46420cf1dd8SToby Isaac .seealso: PetscFECreate() 46520cf1dd8SToby Isaac @*/ 46620cf1dd8SToby Isaac PetscErrorCode PetscFESetTileSizes(PetscFE fem, PetscInt blockSize, PetscInt numBlocks, PetscInt batchSize, PetscInt numBatches) 46720cf1dd8SToby Isaac { 46820cf1dd8SToby Isaac PetscFunctionBegin; 46920cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 47020cf1dd8SToby Isaac fem->blockSize = blockSize; 47120cf1dd8SToby Isaac fem->numBlocks = numBlocks; 47220cf1dd8SToby Isaac fem->batchSize = batchSize; 47320cf1dd8SToby Isaac fem->numBatches = numBatches; 47420cf1dd8SToby Isaac PetscFunctionReturn(0); 47520cf1dd8SToby Isaac } 47620cf1dd8SToby Isaac 47720cf1dd8SToby Isaac /*@ 47820cf1dd8SToby Isaac PetscFEGetTileSizes - Returns the tile sizes for evaluation 47920cf1dd8SToby Isaac 48020cf1dd8SToby Isaac Not collective 48120cf1dd8SToby Isaac 48220cf1dd8SToby Isaac Input Parameter: 48320cf1dd8SToby Isaac . fem - The PetscFE object 48420cf1dd8SToby Isaac 48520cf1dd8SToby Isaac Output Parameters: 48620cf1dd8SToby Isaac + blockSize - The number of elements in a block 48720cf1dd8SToby Isaac . numBlocks - The number of blocks in a batch 48820cf1dd8SToby Isaac . batchSize - The number of elements in a batch 48920cf1dd8SToby Isaac - numBatches - The number of batches in a chunk 49020cf1dd8SToby Isaac 49120cf1dd8SToby Isaac Level: intermediate 49220cf1dd8SToby Isaac 49320cf1dd8SToby Isaac .seealso: PetscFECreate() 49420cf1dd8SToby Isaac @*/ 49520cf1dd8SToby Isaac PetscErrorCode PetscFEGetTileSizes(PetscFE fem, PetscInt *blockSize, PetscInt *numBlocks, PetscInt *batchSize, PetscInt *numBatches) 49620cf1dd8SToby Isaac { 49720cf1dd8SToby Isaac PetscFunctionBegin; 49820cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 49920cf1dd8SToby Isaac if (blockSize) PetscValidPointer(blockSize, 2); 50020cf1dd8SToby Isaac if (numBlocks) PetscValidPointer(numBlocks, 3); 50120cf1dd8SToby Isaac if (batchSize) PetscValidPointer(batchSize, 4); 50220cf1dd8SToby Isaac if (numBatches) PetscValidPointer(numBatches, 5); 50320cf1dd8SToby Isaac if (blockSize) *blockSize = fem->blockSize; 50420cf1dd8SToby Isaac if (numBlocks) *numBlocks = fem->numBlocks; 50520cf1dd8SToby Isaac if (batchSize) *batchSize = fem->batchSize; 50620cf1dd8SToby Isaac if (numBatches) *numBatches = fem->numBatches; 50720cf1dd8SToby Isaac PetscFunctionReturn(0); 50820cf1dd8SToby Isaac } 50920cf1dd8SToby Isaac 51020cf1dd8SToby Isaac /*@ 51120cf1dd8SToby Isaac PetscFEGetBasisSpace - Returns the PetscSpace used for approximation of the solution 51220cf1dd8SToby Isaac 51320cf1dd8SToby Isaac Not collective 51420cf1dd8SToby Isaac 51520cf1dd8SToby Isaac Input Parameter: 51620cf1dd8SToby Isaac . fem - The PetscFE object 51720cf1dd8SToby Isaac 51820cf1dd8SToby Isaac Output Parameter: 51920cf1dd8SToby Isaac . sp - The PetscSpace object 52020cf1dd8SToby Isaac 52120cf1dd8SToby Isaac Level: intermediate 52220cf1dd8SToby Isaac 52320cf1dd8SToby Isaac .seealso: PetscFECreate() 52420cf1dd8SToby Isaac @*/ 52520cf1dd8SToby Isaac PetscErrorCode PetscFEGetBasisSpace(PetscFE fem, PetscSpace *sp) 52620cf1dd8SToby Isaac { 52720cf1dd8SToby Isaac PetscFunctionBegin; 52820cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 52920cf1dd8SToby Isaac PetscValidPointer(sp, 2); 53020cf1dd8SToby Isaac *sp = fem->basisSpace; 53120cf1dd8SToby Isaac PetscFunctionReturn(0); 53220cf1dd8SToby Isaac } 53320cf1dd8SToby Isaac 53420cf1dd8SToby Isaac /*@ 53520cf1dd8SToby Isaac PetscFESetBasisSpace - Sets the PetscSpace used for approximation of the solution 53620cf1dd8SToby Isaac 53720cf1dd8SToby Isaac Not collective 53820cf1dd8SToby Isaac 53920cf1dd8SToby Isaac Input Parameters: 54020cf1dd8SToby Isaac + fem - The PetscFE object 54120cf1dd8SToby Isaac - sp - The PetscSpace object 54220cf1dd8SToby Isaac 54320cf1dd8SToby Isaac Level: intermediate 54420cf1dd8SToby Isaac 54520cf1dd8SToby Isaac .seealso: PetscFECreate() 54620cf1dd8SToby Isaac @*/ 54720cf1dd8SToby Isaac PetscErrorCode PetscFESetBasisSpace(PetscFE fem, PetscSpace sp) 54820cf1dd8SToby Isaac { 54920cf1dd8SToby Isaac PetscFunctionBegin; 55020cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 55120cf1dd8SToby Isaac PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 2); 5525f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceDestroy(&fem->basisSpace)); 55320cf1dd8SToby Isaac fem->basisSpace = sp; 5545f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectReference((PetscObject) fem->basisSpace)); 55520cf1dd8SToby Isaac PetscFunctionReturn(0); 55620cf1dd8SToby Isaac } 55720cf1dd8SToby Isaac 55820cf1dd8SToby Isaac /*@ 55920cf1dd8SToby Isaac PetscFEGetDualSpace - Returns the PetscDualSpace used to define the inner product 56020cf1dd8SToby Isaac 56120cf1dd8SToby Isaac Not collective 56220cf1dd8SToby Isaac 56320cf1dd8SToby Isaac Input Parameter: 56420cf1dd8SToby Isaac . fem - The PetscFE object 56520cf1dd8SToby Isaac 56620cf1dd8SToby Isaac Output Parameter: 56720cf1dd8SToby Isaac . sp - The PetscDualSpace object 56820cf1dd8SToby Isaac 56920cf1dd8SToby Isaac Level: intermediate 57020cf1dd8SToby Isaac 57120cf1dd8SToby Isaac .seealso: PetscFECreate() 57220cf1dd8SToby Isaac @*/ 57320cf1dd8SToby Isaac PetscErrorCode PetscFEGetDualSpace(PetscFE fem, PetscDualSpace *sp) 57420cf1dd8SToby Isaac { 57520cf1dd8SToby Isaac PetscFunctionBegin; 57620cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 57720cf1dd8SToby Isaac PetscValidPointer(sp, 2); 57820cf1dd8SToby Isaac *sp = fem->dualSpace; 57920cf1dd8SToby Isaac PetscFunctionReturn(0); 58020cf1dd8SToby Isaac } 58120cf1dd8SToby Isaac 58220cf1dd8SToby Isaac /*@ 58320cf1dd8SToby Isaac PetscFESetDualSpace - Sets the PetscDualSpace used to define the inner product 58420cf1dd8SToby Isaac 58520cf1dd8SToby Isaac Not collective 58620cf1dd8SToby Isaac 58720cf1dd8SToby Isaac Input Parameters: 58820cf1dd8SToby Isaac + fem - The PetscFE object 58920cf1dd8SToby Isaac - sp - The PetscDualSpace object 59020cf1dd8SToby Isaac 59120cf1dd8SToby Isaac Level: intermediate 59220cf1dd8SToby Isaac 59320cf1dd8SToby Isaac .seealso: PetscFECreate() 59420cf1dd8SToby Isaac @*/ 59520cf1dd8SToby Isaac PetscErrorCode PetscFESetDualSpace(PetscFE fem, PetscDualSpace sp) 59620cf1dd8SToby Isaac { 59720cf1dd8SToby Isaac PetscFunctionBegin; 59820cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 59920cf1dd8SToby Isaac PetscValidHeaderSpecific(sp, PETSCDUALSPACE_CLASSID, 2); 6005f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceDestroy(&fem->dualSpace)); 60120cf1dd8SToby Isaac fem->dualSpace = sp; 6025f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectReference((PetscObject) fem->dualSpace)); 60320cf1dd8SToby Isaac PetscFunctionReturn(0); 60420cf1dd8SToby Isaac } 60520cf1dd8SToby Isaac 60620cf1dd8SToby Isaac /*@ 60720cf1dd8SToby Isaac PetscFEGetQuadrature - Returns the PetscQuadrature used to calculate inner products 60820cf1dd8SToby Isaac 60920cf1dd8SToby Isaac Not collective 61020cf1dd8SToby Isaac 61120cf1dd8SToby Isaac Input Parameter: 61220cf1dd8SToby Isaac . fem - The PetscFE object 61320cf1dd8SToby Isaac 61420cf1dd8SToby Isaac Output Parameter: 61520cf1dd8SToby Isaac . q - The PetscQuadrature object 61620cf1dd8SToby Isaac 61720cf1dd8SToby Isaac Level: intermediate 61820cf1dd8SToby Isaac 61920cf1dd8SToby Isaac .seealso: PetscFECreate() 62020cf1dd8SToby Isaac @*/ 62120cf1dd8SToby Isaac PetscErrorCode PetscFEGetQuadrature(PetscFE fem, PetscQuadrature *q) 62220cf1dd8SToby Isaac { 62320cf1dd8SToby Isaac PetscFunctionBegin; 62420cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 62520cf1dd8SToby Isaac PetscValidPointer(q, 2); 62620cf1dd8SToby Isaac *q = fem->quadrature; 62720cf1dd8SToby Isaac PetscFunctionReturn(0); 62820cf1dd8SToby Isaac } 62920cf1dd8SToby Isaac 63020cf1dd8SToby Isaac /*@ 63120cf1dd8SToby Isaac PetscFESetQuadrature - Sets the PetscQuadrature used to calculate inner products 63220cf1dd8SToby Isaac 63320cf1dd8SToby Isaac Not collective 63420cf1dd8SToby Isaac 63520cf1dd8SToby Isaac Input Parameters: 63620cf1dd8SToby Isaac + fem - The PetscFE object 63720cf1dd8SToby Isaac - q - The PetscQuadrature object 63820cf1dd8SToby Isaac 63920cf1dd8SToby Isaac Level: intermediate 64020cf1dd8SToby Isaac 64120cf1dd8SToby Isaac .seealso: PetscFECreate() 64220cf1dd8SToby Isaac @*/ 64320cf1dd8SToby Isaac PetscErrorCode PetscFESetQuadrature(PetscFE fem, PetscQuadrature q) 64420cf1dd8SToby Isaac { 64520cf1dd8SToby Isaac PetscInt Nc, qNc; 64620cf1dd8SToby Isaac 64720cf1dd8SToby Isaac PetscFunctionBegin; 64820cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 649fd2fdbddSMatthew G. Knepley if (q == fem->quadrature) PetscFunctionReturn(0); 6505f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEGetNumComponents(fem, &Nc)); 6515f80ce2aSJacob Faibussowitsch CHKERRQ(PetscQuadratureGetNumComponents(q, &qNc)); 6522c71b3e2SJacob Faibussowitsch PetscCheckFalse((qNc != 1) && (Nc != qNc),PetscObjectComm((PetscObject) fem), PETSC_ERR_ARG_SIZ, "FE components %D != Quadrature components %D and non-scalar quadrature", Nc, qNc); 6535f80ce2aSJacob Faibussowitsch CHKERRQ(PetscTabulationDestroy(&fem->T)); 6545f80ce2aSJacob Faibussowitsch CHKERRQ(PetscTabulationDestroy(&fem->Tc)); 6555f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectReference((PetscObject) q)); 6565f80ce2aSJacob Faibussowitsch CHKERRQ(PetscQuadratureDestroy(&fem->quadrature)); 65720cf1dd8SToby Isaac fem->quadrature = q; 65820cf1dd8SToby Isaac PetscFunctionReturn(0); 65920cf1dd8SToby Isaac } 66020cf1dd8SToby Isaac 66120cf1dd8SToby Isaac /*@ 66220cf1dd8SToby Isaac PetscFEGetFaceQuadrature - Returns the PetscQuadrature used to calculate inner products on faces 66320cf1dd8SToby Isaac 66420cf1dd8SToby Isaac Not collective 66520cf1dd8SToby Isaac 66620cf1dd8SToby Isaac Input Parameter: 66720cf1dd8SToby Isaac . fem - The PetscFE object 66820cf1dd8SToby Isaac 66920cf1dd8SToby Isaac Output Parameter: 67020cf1dd8SToby Isaac . q - The PetscQuadrature object 67120cf1dd8SToby Isaac 67220cf1dd8SToby Isaac Level: intermediate 67320cf1dd8SToby Isaac 67420cf1dd8SToby Isaac .seealso: PetscFECreate() 67520cf1dd8SToby Isaac @*/ 67620cf1dd8SToby Isaac PetscErrorCode PetscFEGetFaceQuadrature(PetscFE fem, PetscQuadrature *q) 67720cf1dd8SToby Isaac { 67820cf1dd8SToby Isaac PetscFunctionBegin; 67920cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 68020cf1dd8SToby Isaac PetscValidPointer(q, 2); 68120cf1dd8SToby Isaac *q = fem->faceQuadrature; 68220cf1dd8SToby Isaac PetscFunctionReturn(0); 68320cf1dd8SToby Isaac } 68420cf1dd8SToby Isaac 68520cf1dd8SToby Isaac /*@ 68620cf1dd8SToby Isaac PetscFESetFaceQuadrature - Sets the PetscQuadrature used to calculate inner products on faces 68720cf1dd8SToby Isaac 68820cf1dd8SToby Isaac Not collective 68920cf1dd8SToby Isaac 69020cf1dd8SToby Isaac Input Parameters: 69120cf1dd8SToby Isaac + fem - The PetscFE object 69220cf1dd8SToby Isaac - q - The PetscQuadrature object 69320cf1dd8SToby Isaac 69420cf1dd8SToby Isaac Level: intermediate 69520cf1dd8SToby Isaac 69620cf1dd8SToby Isaac .seealso: PetscFECreate() 69720cf1dd8SToby Isaac @*/ 69820cf1dd8SToby Isaac PetscErrorCode PetscFESetFaceQuadrature(PetscFE fem, PetscQuadrature q) 69920cf1dd8SToby Isaac { 700ef0bb6c7SMatthew G. Knepley PetscInt Nc, qNc; 70120cf1dd8SToby Isaac 70220cf1dd8SToby Isaac PetscFunctionBegin; 70320cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 7045f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEGetNumComponents(fem, &Nc)); 7055f80ce2aSJacob Faibussowitsch CHKERRQ(PetscQuadratureGetNumComponents(q, &qNc)); 7062c71b3e2SJacob Faibussowitsch PetscCheckFalse((qNc != 1) && (Nc != qNc),PetscObjectComm((PetscObject) fem), PETSC_ERR_ARG_SIZ, "FE components %D != Quadrature components %D and non-scalar quadrature", Nc, qNc); 7075f80ce2aSJacob Faibussowitsch CHKERRQ(PetscTabulationDestroy(&fem->Tf)); 7085f80ce2aSJacob Faibussowitsch CHKERRQ(PetscQuadratureDestroy(&fem->faceQuadrature)); 70920cf1dd8SToby Isaac fem->faceQuadrature = q; 7105f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectReference((PetscObject) q)); 71120cf1dd8SToby Isaac PetscFunctionReturn(0); 71220cf1dd8SToby Isaac } 71320cf1dd8SToby Isaac 7145dc5c000SMatthew G. Knepley /*@ 7155dc5c000SMatthew G. Knepley PetscFECopyQuadrature - Copy both volumetric and surface quadrature 7165dc5c000SMatthew G. Knepley 7175dc5c000SMatthew G. Knepley Not collective 7185dc5c000SMatthew G. Knepley 7195dc5c000SMatthew G. Knepley Input Parameters: 7205dc5c000SMatthew G. Knepley + sfe - The PetscFE source for the quadratures 7215dc5c000SMatthew G. Knepley - tfe - The PetscFE target for the quadratures 7225dc5c000SMatthew G. Knepley 7235dc5c000SMatthew G. Knepley Level: intermediate 7245dc5c000SMatthew G. Knepley 7255dc5c000SMatthew G. Knepley .seealso: PetscFECreate(), PetscFESetQuadrature(), PetscFESetFaceQuadrature() 7265dc5c000SMatthew G. Knepley @*/ 7275dc5c000SMatthew G. Knepley PetscErrorCode PetscFECopyQuadrature(PetscFE sfe, PetscFE tfe) 7285dc5c000SMatthew G. Knepley { 7295dc5c000SMatthew G. Knepley PetscQuadrature q; 7305dc5c000SMatthew G. Knepley 7315dc5c000SMatthew G. Knepley PetscFunctionBegin; 7325dc5c000SMatthew G. Knepley PetscValidHeaderSpecific(sfe, PETSCFE_CLASSID, 1); 7335dc5c000SMatthew G. Knepley PetscValidHeaderSpecific(tfe, PETSCFE_CLASSID, 2); 7345f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEGetQuadrature(sfe, &q)); 7355f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFESetQuadrature(tfe, q)); 7365f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEGetFaceQuadrature(sfe, &q)); 7375f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFESetFaceQuadrature(tfe, q)); 7385dc5c000SMatthew G. Knepley PetscFunctionReturn(0); 7395dc5c000SMatthew G. Knepley } 7405dc5c000SMatthew G. Knepley 74120cf1dd8SToby Isaac /*@C 74220cf1dd8SToby Isaac PetscFEGetNumDof - Returns the number of dofs (dual basis vectors) associated to mesh points on the reference cell of a given dimension 74320cf1dd8SToby Isaac 74420cf1dd8SToby Isaac Not collective 74520cf1dd8SToby Isaac 74620cf1dd8SToby Isaac Input Parameter: 74720cf1dd8SToby Isaac . fem - The PetscFE object 74820cf1dd8SToby Isaac 74920cf1dd8SToby Isaac Output Parameter: 75020cf1dd8SToby Isaac . numDof - Array with the number of dofs per dimension 75120cf1dd8SToby Isaac 75220cf1dd8SToby Isaac Level: intermediate 75320cf1dd8SToby Isaac 75420cf1dd8SToby Isaac .seealso: PetscFECreate() 75520cf1dd8SToby Isaac @*/ 75620cf1dd8SToby Isaac PetscErrorCode PetscFEGetNumDof(PetscFE fem, const PetscInt **numDof) 75720cf1dd8SToby Isaac { 75820cf1dd8SToby Isaac PetscFunctionBegin; 75920cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 76020cf1dd8SToby Isaac PetscValidPointer(numDof, 2); 7615f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceGetNumDof(fem->dualSpace, numDof)); 76220cf1dd8SToby Isaac PetscFunctionReturn(0); 76320cf1dd8SToby Isaac } 76420cf1dd8SToby Isaac 76520cf1dd8SToby Isaac /*@C 766ef0bb6c7SMatthew G. Knepley PetscFEGetCellTabulation - Returns the tabulation of the basis functions at the quadrature points on the reference cell 76720cf1dd8SToby Isaac 76820cf1dd8SToby Isaac Not collective 76920cf1dd8SToby Isaac 770d8d19677SJose E. Roman Input Parameters: 771f9244615SMatthew G. Knepley + fem - The PetscFE object 772f9244615SMatthew G. Knepley - k - The highest derivative we need to tabulate, very often 1 77320cf1dd8SToby Isaac 774ef0bb6c7SMatthew G. Knepley Output Parameter: 775ef0bb6c7SMatthew G. Knepley . T - The basis function values and derivatives at quadrature points 77620cf1dd8SToby Isaac 77720cf1dd8SToby Isaac Note: 778ef0bb6c7SMatthew G. Knepley $ T->T[0] = B[(p*pdim + i)*Nc + c] is the value at point p for basis function i and component c 779ef0bb6c7SMatthew G. Knepley $ T->T[1] = D[((p*pdim + i)*Nc + c)*dim + d] is the derivative value at point p for basis function i, component c, in direction d 780ef0bb6c7SMatthew G. Knepley $ T->T[2] = H[(((p*pdim + i)*Nc + c)*dim + d)*dim + e] is the value at point p for basis function i, component c, in directions d and e 78120cf1dd8SToby Isaac 78220cf1dd8SToby Isaac Level: intermediate 78320cf1dd8SToby Isaac 784ef0bb6c7SMatthew G. Knepley .seealso: PetscFECreateTabulation(), PetscTabulationDestroy() 78520cf1dd8SToby Isaac @*/ 786f9244615SMatthew G. Knepley PetscErrorCode PetscFEGetCellTabulation(PetscFE fem, PetscInt k, PetscTabulation *T) 78720cf1dd8SToby Isaac { 78820cf1dd8SToby Isaac PetscInt npoints; 78920cf1dd8SToby Isaac const PetscReal *points; 79020cf1dd8SToby Isaac 79120cf1dd8SToby Isaac PetscFunctionBegin; 79220cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 793064a246eSJacob Faibussowitsch PetscValidPointer(T, 3); 7945f80ce2aSJacob Faibussowitsch CHKERRQ(PetscQuadratureGetData(fem->quadrature, NULL, NULL, &npoints, &points, NULL)); 7955f80ce2aSJacob Faibussowitsch if (!fem->T) CHKERRQ(PetscFECreateTabulation(fem, 1, npoints, points, k, &fem->T)); 7962c71b3e2SJacob Faibussowitsch PetscCheckFalse(fem->T && k > fem->T->K,PetscObjectComm((PetscObject) fem), PETSC_ERR_ARG_OUTOFRANGE, "Requested %D derivatives, but only tabulated %D", k, fem->T->K); 797ef0bb6c7SMatthew G. Knepley *T = fem->T; 79820cf1dd8SToby Isaac PetscFunctionReturn(0); 79920cf1dd8SToby Isaac } 80020cf1dd8SToby Isaac 8012b99622eSMatthew G. Knepley /*@C 802ef0bb6c7SMatthew G. Knepley PetscFEGetFaceTabulation - Returns the tabulation of the basis functions at the face quadrature points for each face of the reference cell 8032b99622eSMatthew G. Knepley 8042b99622eSMatthew G. Knepley Not collective 8052b99622eSMatthew G. Knepley 806d8d19677SJose E. Roman Input Parameters: 807f9244615SMatthew G. Knepley + fem - The PetscFE object 808f9244615SMatthew G. Knepley - k - The highest derivative we need to tabulate, very often 1 8092b99622eSMatthew G. Knepley 8102b99622eSMatthew G. Knepley Output Parameters: 811a5b23f4aSJose E. Roman . Tf - The basis function values and derivatives at face quadrature points 8122b99622eSMatthew G. Knepley 8132b99622eSMatthew G. Knepley Note: 814ef0bb6c7SMatthew G. Knepley $ T->T[0] = Bf[((f*Nq + q)*pdim + i)*Nc + c] is the value at point f,q for basis function i and component c 815ef0bb6c7SMatthew G. Knepley $ T->T[1] = Df[(((f*Nq + q)*pdim + i)*Nc + c)*dim + d] is the derivative value at point f,q for basis function i, component c, in direction d 816ef0bb6c7SMatthew G. Knepley $ T->T[2] = Hf[((((f*Nq + q)*pdim + i)*Nc + c)*dim + d)*dim + e] is the value at point f,q for basis function i, component c, in directions d and e 8172b99622eSMatthew G. Knepley 8182b99622eSMatthew G. Knepley Level: intermediate 8192b99622eSMatthew G. Knepley 820ef0bb6c7SMatthew G. Knepley .seealso: PetscFEGetCellTabulation(), PetscFECreateTabulation(), PetscTabulationDestroy() 8212b99622eSMatthew G. Knepley @*/ 822f9244615SMatthew G. Knepley PetscErrorCode PetscFEGetFaceTabulation(PetscFE fem, PetscInt k, PetscTabulation *Tf) 82320cf1dd8SToby Isaac { 82420cf1dd8SToby Isaac PetscFunctionBegin; 82520cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 826064a246eSJacob Faibussowitsch PetscValidPointer(Tf, 3); 827ef0bb6c7SMatthew G. Knepley if (!fem->Tf) { 82820cf1dd8SToby Isaac const PetscReal xi0[3] = {-1., -1., -1.}; 82920cf1dd8SToby Isaac PetscReal v0[3], J[9], detJ; 83020cf1dd8SToby Isaac PetscQuadrature fq; 83120cf1dd8SToby Isaac PetscDualSpace sp; 83220cf1dd8SToby Isaac DM dm; 83320cf1dd8SToby Isaac const PetscInt *faces; 83420cf1dd8SToby Isaac PetscInt dim, numFaces, f, npoints, q; 83520cf1dd8SToby Isaac const PetscReal *points; 83620cf1dd8SToby Isaac PetscReal *facePoints; 83720cf1dd8SToby Isaac 8385f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEGetDualSpace(fem, &sp)); 8395f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceGetDM(sp, &dm)); 8405f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetDimension(dm, &dim)); 8415f80ce2aSJacob Faibussowitsch CHKERRQ(DMPlexGetConeSize(dm, 0, &numFaces)); 8425f80ce2aSJacob Faibussowitsch CHKERRQ(DMPlexGetCone(dm, 0, &faces)); 8435f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEGetFaceQuadrature(fem, &fq)); 84420cf1dd8SToby Isaac if (fq) { 8455f80ce2aSJacob Faibussowitsch CHKERRQ(PetscQuadratureGetData(fq, NULL, NULL, &npoints, &points, NULL)); 8465f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(numFaces*npoints*dim, &facePoints)); 84720cf1dd8SToby Isaac for (f = 0; f < numFaces; ++f) { 8485f80ce2aSJacob Faibussowitsch CHKERRQ(DMPlexComputeCellGeometryFEM(dm, faces[f], NULL, v0, J, NULL, &detJ)); 84920cf1dd8SToby Isaac for (q = 0; q < npoints; ++q) CoordinatesRefToReal(dim, dim-1, xi0, v0, J, &points[q*(dim-1)], &facePoints[(f*npoints+q)*dim]); 85020cf1dd8SToby Isaac } 8515f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFECreateTabulation(fem, numFaces, npoints, facePoints, k, &fem->Tf)); 8525f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(facePoints)); 85320cf1dd8SToby Isaac } 85420cf1dd8SToby Isaac } 8552c71b3e2SJacob Faibussowitsch PetscCheckFalse(fem->Tf && k > fem->Tf->K,PetscObjectComm((PetscObject) fem), PETSC_ERR_ARG_OUTOFRANGE, "Requested %D derivatives, but only tabulated %D", k, fem->Tf->K); 856ef0bb6c7SMatthew G. Knepley *Tf = fem->Tf; 85720cf1dd8SToby Isaac PetscFunctionReturn(0); 85820cf1dd8SToby Isaac } 85920cf1dd8SToby Isaac 8602b99622eSMatthew G. Knepley /*@C 861ef0bb6c7SMatthew G. Knepley PetscFEGetFaceCentroidTabulation - Returns the tabulation of the basis functions at the face centroid points 8622b99622eSMatthew G. Knepley 8632b99622eSMatthew G. Knepley Not collective 8642b99622eSMatthew G. Knepley 8652b99622eSMatthew G. Knepley Input Parameter: 8662b99622eSMatthew G. Knepley . fem - The PetscFE object 8672b99622eSMatthew G. Knepley 8682b99622eSMatthew G. Knepley Output Parameters: 869ef0bb6c7SMatthew G. Knepley . Tc - The basis function values at face centroid points 8702b99622eSMatthew G. Knepley 8712b99622eSMatthew G. Knepley Note: 872ef0bb6c7SMatthew G. Knepley $ T->T[0] = Bf[(f*pdim + i)*Nc + c] is the value at point f for basis function i and component c 8732b99622eSMatthew G. Knepley 8742b99622eSMatthew G. Knepley Level: intermediate 8752b99622eSMatthew G. Knepley 876ef0bb6c7SMatthew G. Knepley .seealso: PetscFEGetFaceTabulation(), PetscFEGetCellTabulation(), PetscFECreateTabulation(), PetscTabulationDestroy() 8772b99622eSMatthew G. Knepley @*/ 878ef0bb6c7SMatthew G. Knepley PetscErrorCode PetscFEGetFaceCentroidTabulation(PetscFE fem, PetscTabulation *Tc) 87920cf1dd8SToby Isaac { 88020cf1dd8SToby Isaac PetscFunctionBegin; 88120cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 882ef0bb6c7SMatthew G. Knepley PetscValidPointer(Tc, 2); 883ef0bb6c7SMatthew G. Knepley if (!fem->Tc) { 88420cf1dd8SToby Isaac PetscDualSpace sp; 88520cf1dd8SToby Isaac DM dm; 88620cf1dd8SToby Isaac const PetscInt *cone; 88720cf1dd8SToby Isaac PetscReal *centroids; 88820cf1dd8SToby Isaac PetscInt dim, numFaces, f; 88920cf1dd8SToby Isaac 8905f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEGetDualSpace(fem, &sp)); 8915f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceGetDM(sp, &dm)); 8925f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetDimension(dm, &dim)); 8935f80ce2aSJacob Faibussowitsch CHKERRQ(DMPlexGetConeSize(dm, 0, &numFaces)); 8945f80ce2aSJacob Faibussowitsch CHKERRQ(DMPlexGetCone(dm, 0, &cone)); 8955f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(numFaces*dim, ¢roids)); 8965f80ce2aSJacob Faibussowitsch for (f = 0; f < numFaces; ++f) CHKERRQ(DMPlexComputeCellGeometryFVM(dm, cone[f], NULL, ¢roids[f*dim], NULL)); 8975f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFECreateTabulation(fem, 1, numFaces, centroids, 0, &fem->Tc)); 8985f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(centroids)); 89920cf1dd8SToby Isaac } 900ef0bb6c7SMatthew G. Knepley *Tc = fem->Tc; 90120cf1dd8SToby Isaac PetscFunctionReturn(0); 90220cf1dd8SToby Isaac } 90320cf1dd8SToby Isaac 90420cf1dd8SToby Isaac /*@C 905ef0bb6c7SMatthew G. Knepley PetscFECreateTabulation - Tabulates the basis functions, and perhaps derivatives, at the points provided. 90620cf1dd8SToby Isaac 90720cf1dd8SToby Isaac Not collective 90820cf1dd8SToby Isaac 90920cf1dd8SToby Isaac Input Parameters: 91020cf1dd8SToby Isaac + fem - The PetscFE object 911ef0bb6c7SMatthew G. Knepley . nrepl - The number of replicas 912ef0bb6c7SMatthew G. Knepley . npoints - The number of tabulation points in a replica 913ef0bb6c7SMatthew G. Knepley . points - The tabulation point coordinates 914ef0bb6c7SMatthew G. Knepley - K - The number of derivatives calculated 91520cf1dd8SToby Isaac 916ef0bb6c7SMatthew G. Knepley Output Parameter: 917ef0bb6c7SMatthew G. Knepley . T - The basis function values and derivatives at tabulation points 91820cf1dd8SToby Isaac 91920cf1dd8SToby Isaac Note: 920ef0bb6c7SMatthew G. Knepley $ T->T[0] = B[(p*pdim + i)*Nc + c] is the value at point p for basis function i and component c 921ef0bb6c7SMatthew G. Knepley $ T->T[1] = D[((p*pdim + i)*Nc + c)*dim + d] is the derivative value at point p for basis function i, component c, in direction d 922ef0bb6c7SMatthew G. Knepley $ T->T[2] = H[(((p*pdim + i)*Nc + c)*dim + d)*dim + e] is the value at point p for basis function i, component c, in directions d and e 92320cf1dd8SToby Isaac 92420cf1dd8SToby Isaac Level: intermediate 92520cf1dd8SToby Isaac 926ef0bb6c7SMatthew G. Knepley .seealso: PetscFEGetCellTabulation(), PetscTabulationDestroy() 92720cf1dd8SToby Isaac @*/ 928ef0bb6c7SMatthew G. Knepley PetscErrorCode PetscFECreateTabulation(PetscFE fem, PetscInt nrepl, PetscInt npoints, const PetscReal points[], PetscInt K, PetscTabulation *T) 92920cf1dd8SToby Isaac { 93020cf1dd8SToby Isaac DM dm; 931ef0bb6c7SMatthew G. Knepley PetscDualSpace Q; 932ef0bb6c7SMatthew G. Knepley PetscInt Nb; /* Dimension of FE space P */ 933ef0bb6c7SMatthew G. Knepley PetscInt Nc; /* Field components */ 934ef0bb6c7SMatthew G. Knepley PetscInt cdim; /* Reference coordinate dimension */ 935ef0bb6c7SMatthew G. Knepley PetscInt k; 93620cf1dd8SToby Isaac 93720cf1dd8SToby Isaac PetscFunctionBegin; 938ef0bb6c7SMatthew G. Knepley if (!npoints || !fem->dualSpace || K < 0) { 939ef0bb6c7SMatthew G. Knepley *T = NULL; 94020cf1dd8SToby Isaac PetscFunctionReturn(0); 94120cf1dd8SToby Isaac } 94220cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 94340a2aa30SMatthew G. Knepley PetscValidPointer(points, 4); 94440a2aa30SMatthew G. Knepley PetscValidPointer(T, 6); 9455f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEGetDualSpace(fem, &Q)); 9465f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceGetDM(Q, &dm)); 9475f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetDimension(dm, &cdim)); 9485f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceGetDimension(Q, &Nb)); 9495f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEGetNumComponents(fem, &Nc)); 9505f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(1, T)); 951ef0bb6c7SMatthew G. Knepley (*T)->K = !cdim ? 0 : K; 952ef0bb6c7SMatthew G. Knepley (*T)->Nr = nrepl; 953ef0bb6c7SMatthew G. Knepley (*T)->Np = npoints; 954ef0bb6c7SMatthew G. Knepley (*T)->Nb = Nb; 955ef0bb6c7SMatthew G. Knepley (*T)->Nc = Nc; 956ef0bb6c7SMatthew G. Knepley (*T)->cdim = cdim; 9575f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1((*T)->K+1, &(*T)->T)); 958ef0bb6c7SMatthew G. Knepley for (k = 0; k <= (*T)->K; ++k) { 9595f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(nrepl*npoints*Nb*Nc*PetscPowInt(cdim, k), &(*T)->T[k])); 96020cf1dd8SToby Isaac } 9615f80ce2aSJacob Faibussowitsch CHKERRQ((*fem->ops->createtabulation)(fem, nrepl*npoints, points, K, *T)); 96220cf1dd8SToby Isaac PetscFunctionReturn(0); 96320cf1dd8SToby Isaac } 96420cf1dd8SToby Isaac 9652b99622eSMatthew G. Knepley /*@C 966ef0bb6c7SMatthew G. Knepley PetscFEComputeTabulation - Tabulates the basis functions, and perhaps derivatives, at the points provided. 9672b99622eSMatthew G. Knepley 9682b99622eSMatthew G. Knepley Not collective 9692b99622eSMatthew G. Knepley 9702b99622eSMatthew G. Knepley Input Parameters: 9712b99622eSMatthew G. Knepley + fem - The PetscFE object 9722b99622eSMatthew G. Knepley . npoints - The number of tabulation points 9732b99622eSMatthew G. Knepley . points - The tabulation point coordinates 974ef0bb6c7SMatthew G. Knepley . K - The number of derivatives calculated 975ef0bb6c7SMatthew G. Knepley - T - An existing tabulation object with enough allocated space 976ef0bb6c7SMatthew G. Knepley 977ef0bb6c7SMatthew G. Knepley Output Parameter: 978ef0bb6c7SMatthew G. Knepley . T - The basis function values and derivatives at tabulation points 9792b99622eSMatthew G. Knepley 9802b99622eSMatthew G. Knepley Note: 981ef0bb6c7SMatthew G. Knepley $ T->T[0] = B[(p*pdim + i)*Nc + c] is the value at point p for basis function i and component c 982ef0bb6c7SMatthew G. Knepley $ T->T[1] = D[((p*pdim + i)*Nc + c)*dim + d] is the derivative value at point p for basis function i, component c, in direction d 983ef0bb6c7SMatthew G. Knepley $ T->T[2] = H[(((p*pdim + i)*Nc + c)*dim + d)*dim + e] is the value at point p for basis function i, component c, in directions d and e 9842b99622eSMatthew G. Knepley 9852b99622eSMatthew G. Knepley Level: intermediate 9862b99622eSMatthew G. Knepley 987ef0bb6c7SMatthew G. Knepley .seealso: PetscFEGetCellTabulation(), PetscTabulationDestroy() 9882b99622eSMatthew G. Knepley @*/ 989ef0bb6c7SMatthew G. Knepley PetscErrorCode PetscFEComputeTabulation(PetscFE fem, PetscInt npoints, const PetscReal points[], PetscInt K, PetscTabulation T) 990ef0bb6c7SMatthew G. Knepley { 991ef0bb6c7SMatthew G. Knepley PetscFunctionBeginHot; 992ef0bb6c7SMatthew G. Knepley if (!npoints || !fem->dualSpace || K < 0) PetscFunctionReturn(0); 993ef0bb6c7SMatthew G. Knepley PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 994ef0bb6c7SMatthew G. Knepley PetscValidPointer(points, 3); 995ef0bb6c7SMatthew G. Knepley PetscValidPointer(T, 5); 99676bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 99720cf1dd8SToby Isaac DM dm; 998ef0bb6c7SMatthew G. Knepley PetscDualSpace Q; 999ef0bb6c7SMatthew G. Knepley PetscInt Nb; /* Dimension of FE space P */ 1000ef0bb6c7SMatthew G. Knepley PetscInt Nc; /* Field components */ 1001ef0bb6c7SMatthew G. Knepley PetscInt cdim; /* Reference coordinate dimension */ 1002ef0bb6c7SMatthew G. Knepley 10035f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEGetDualSpace(fem, &Q)); 10045f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceGetDM(Q, &dm)); 10055f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetDimension(dm, &cdim)); 10065f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceGetDimension(Q, &Nb)); 10075f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEGetNumComponents(fem, &Nc)); 10082c71b3e2SJacob Faibussowitsch PetscCheckFalse(T->K != (!cdim ? 0 : K),PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Tabulation K %D must match requested K %D", T->K, !cdim ? 0 : K); 10092c71b3e2SJacob Faibussowitsch PetscCheckFalse(T->Nb != Nb,PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Tabulation Nb %D must match requested Nb %D", T->Nb, Nb); 10102c71b3e2SJacob Faibussowitsch PetscCheckFalse(T->Nc != Nc,PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Tabulation Nc %D must match requested Nc %D", T->Nc, Nc); 10112c71b3e2SJacob Faibussowitsch PetscCheckFalse(T->cdim != cdim,PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Tabulation cdim %D must match requested cdim %D", T->cdim, cdim); 1012ef0bb6c7SMatthew G. Knepley } 1013ef0bb6c7SMatthew G. Knepley T->Nr = 1; 1014ef0bb6c7SMatthew G. Knepley T->Np = npoints; 10155f80ce2aSJacob Faibussowitsch CHKERRQ((*fem->ops->createtabulation)(fem, npoints, points, K, T)); 1016ef0bb6c7SMatthew G. Knepley PetscFunctionReturn(0); 1017ef0bb6c7SMatthew G. Knepley } 1018ef0bb6c7SMatthew G. Knepley 1019ef0bb6c7SMatthew G. Knepley /*@C 1020ef0bb6c7SMatthew G. Knepley PetscTabulationDestroy - Frees memory from the associated tabulation. 1021ef0bb6c7SMatthew G. Knepley 1022ef0bb6c7SMatthew G. Knepley Not collective 1023ef0bb6c7SMatthew G. Knepley 1024ef0bb6c7SMatthew G. Knepley Input Parameter: 1025ef0bb6c7SMatthew G. Knepley . T - The tabulation 1026ef0bb6c7SMatthew G. Knepley 1027ef0bb6c7SMatthew G. Knepley Level: intermediate 1028ef0bb6c7SMatthew G. Knepley 1029ef0bb6c7SMatthew G. Knepley .seealso: PetscFECreateTabulation(), PetscFEGetCellTabulation() 1030ef0bb6c7SMatthew G. Knepley @*/ 1031ef0bb6c7SMatthew G. Knepley PetscErrorCode PetscTabulationDestroy(PetscTabulation *T) 1032ef0bb6c7SMatthew G. Knepley { 1033ef0bb6c7SMatthew G. Knepley PetscInt k; 103420cf1dd8SToby Isaac 103520cf1dd8SToby Isaac PetscFunctionBegin; 1036ef0bb6c7SMatthew G. Knepley PetscValidPointer(T, 1); 1037ef0bb6c7SMatthew G. Knepley if (!T || !(*T)) PetscFunctionReturn(0); 10385f80ce2aSJacob Faibussowitsch for (k = 0; k <= (*T)->K; ++k) CHKERRQ(PetscFree((*T)->T[k])); 10395f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree((*T)->T)); 10405f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(*T)); 1041ef0bb6c7SMatthew G. Knepley *T = NULL; 104220cf1dd8SToby Isaac PetscFunctionReturn(0); 104320cf1dd8SToby Isaac } 104420cf1dd8SToby Isaac 104520cf1dd8SToby Isaac PETSC_EXTERN PetscErrorCode PetscFECreatePointTrace(PetscFE fe, PetscInt refPoint, PetscFE *trFE) 104620cf1dd8SToby Isaac { 104720cf1dd8SToby Isaac PetscSpace bsp, bsubsp; 104820cf1dd8SToby Isaac PetscDualSpace dsp, dsubsp; 104920cf1dd8SToby Isaac PetscInt dim, depth, numComp, i, j, coneSize, order; 105020cf1dd8SToby Isaac PetscFEType type; 105120cf1dd8SToby Isaac DM dm; 105220cf1dd8SToby Isaac DMLabel label; 105320cf1dd8SToby Isaac PetscReal *xi, *v, *J, detJ; 1054db11e2ebSMatthew G. Knepley const char *name; 105520cf1dd8SToby Isaac PetscQuadrature origin, fullQuad, subQuad; 105620cf1dd8SToby Isaac 105720cf1dd8SToby Isaac PetscFunctionBegin; 105820cf1dd8SToby Isaac PetscValidHeaderSpecific(fe,PETSCFE_CLASSID,1); 105920cf1dd8SToby Isaac PetscValidPointer(trFE,3); 10605f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEGetBasisSpace(fe,&bsp)); 10615f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEGetDualSpace(fe,&dsp)); 10625f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceGetDM(dsp,&dm)); 10635f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetDimension(dm,&dim)); 10645f80ce2aSJacob Faibussowitsch CHKERRQ(DMPlexGetDepthLabel(dm,&label)); 10655f80ce2aSJacob Faibussowitsch CHKERRQ(DMLabelGetValue(label,refPoint,&depth)); 10665f80ce2aSJacob Faibussowitsch CHKERRQ(PetscCalloc1(depth,&xi)); 10675f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(dim,&v)); 10685f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(dim*dim,&J)); 106920cf1dd8SToby Isaac for (i = 0; i < depth; i++) xi[i] = 0.; 10705f80ce2aSJacob Faibussowitsch CHKERRQ(PetscQuadratureCreate(PETSC_COMM_SELF,&origin)); 10715f80ce2aSJacob Faibussowitsch CHKERRQ(PetscQuadratureSetData(origin,depth,0,1,xi,NULL)); 10725f80ce2aSJacob Faibussowitsch CHKERRQ(DMPlexComputeCellGeometryFEM(dm,refPoint,origin,v,J,NULL,&detJ)); 107320cf1dd8SToby Isaac /* CellGeometryFEM computes the expanded Jacobian, we want the true jacobian */ 107420cf1dd8SToby Isaac for (i = 1; i < dim; i++) { 107520cf1dd8SToby Isaac for (j = 0; j < depth; j++) { 107620cf1dd8SToby Isaac J[i * depth + j] = J[i * dim + j]; 107720cf1dd8SToby Isaac } 107820cf1dd8SToby Isaac } 10795f80ce2aSJacob Faibussowitsch CHKERRQ(PetscQuadratureDestroy(&origin)); 10805f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceGetPointSubspace(dsp,refPoint,&dsubsp)); 10815f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceCreateSubspace(bsp,dsubsp,v,J,NULL,NULL,PETSC_OWN_POINTER,&bsubsp)); 10825f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceSetUp(bsubsp)); 10835f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFECreate(PetscObjectComm((PetscObject)fe),trFE)); 10845f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEGetType(fe,&type)); 10855f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFESetType(*trFE,type)); 10865f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEGetNumComponents(fe,&numComp)); 10875f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFESetNumComponents(*trFE,numComp)); 10885f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFESetBasisSpace(*trFE,bsubsp)); 10895f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFESetDualSpace(*trFE,dsubsp)); 10905f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectGetName((PetscObject) fe, &name)); 10915f80ce2aSJacob Faibussowitsch if (name) CHKERRQ(PetscFESetName(*trFE, name)); 10925f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEGetQuadrature(fe,&fullQuad)); 10935f80ce2aSJacob Faibussowitsch CHKERRQ(PetscQuadratureGetOrder(fullQuad,&order)); 10945f80ce2aSJacob Faibussowitsch CHKERRQ(DMPlexGetConeSize(dm,refPoint,&coneSize)); 109520cf1dd8SToby Isaac if (coneSize == 2 * depth) { 10965f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDTGaussTensorQuadrature(depth,1,(order + 1)/2,-1.,1.,&subQuad)); 109720cf1dd8SToby Isaac } else { 10985f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDTStroudConicalQuadrature(depth,1,(order + 1)/2,-1.,1.,&subQuad)); 109920cf1dd8SToby Isaac } 11005f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFESetQuadrature(*trFE,subQuad)); 11015f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFESetUp(*trFE)); 11025f80ce2aSJacob Faibussowitsch CHKERRQ(PetscQuadratureDestroy(&subQuad)); 11035f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceDestroy(&bsubsp)); 110420cf1dd8SToby Isaac PetscFunctionReturn(0); 110520cf1dd8SToby Isaac } 110620cf1dd8SToby Isaac 110720cf1dd8SToby Isaac PetscErrorCode PetscFECreateHeightTrace(PetscFE fe, PetscInt height, PetscFE *trFE) 110820cf1dd8SToby Isaac { 110920cf1dd8SToby Isaac PetscInt hStart, hEnd; 111020cf1dd8SToby Isaac PetscDualSpace dsp; 111120cf1dd8SToby Isaac DM dm; 111220cf1dd8SToby Isaac 111320cf1dd8SToby Isaac PetscFunctionBegin; 111420cf1dd8SToby Isaac PetscValidHeaderSpecific(fe,PETSCFE_CLASSID,1); 111520cf1dd8SToby Isaac PetscValidPointer(trFE,3); 111620cf1dd8SToby Isaac *trFE = NULL; 11175f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEGetDualSpace(fe,&dsp)); 11185f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceGetDM(dsp,&dm)); 11195f80ce2aSJacob Faibussowitsch CHKERRQ(DMPlexGetHeightStratum(dm,height,&hStart,&hEnd)); 112020cf1dd8SToby Isaac if (hEnd <= hStart) PetscFunctionReturn(0); 11215f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFECreatePointTrace(fe,hStart,trFE)); 112220cf1dd8SToby Isaac PetscFunctionReturn(0); 112320cf1dd8SToby Isaac } 112420cf1dd8SToby Isaac 112520cf1dd8SToby Isaac /*@ 112620cf1dd8SToby Isaac PetscFEGetDimension - Get the dimension of the finite element space on a cell 112720cf1dd8SToby Isaac 112820cf1dd8SToby Isaac Not collective 112920cf1dd8SToby Isaac 113020cf1dd8SToby Isaac Input Parameter: 113120cf1dd8SToby Isaac . fe - The PetscFE 113220cf1dd8SToby Isaac 113320cf1dd8SToby Isaac Output Parameter: 113420cf1dd8SToby Isaac . dim - The dimension 113520cf1dd8SToby Isaac 113620cf1dd8SToby Isaac Level: intermediate 113720cf1dd8SToby Isaac 113820cf1dd8SToby Isaac .seealso: PetscFECreate(), PetscSpaceGetDimension(), PetscDualSpaceGetDimension() 113920cf1dd8SToby Isaac @*/ 114020cf1dd8SToby Isaac PetscErrorCode PetscFEGetDimension(PetscFE fem, PetscInt *dim) 114120cf1dd8SToby Isaac { 114220cf1dd8SToby Isaac PetscFunctionBegin; 114320cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 114420cf1dd8SToby Isaac PetscValidPointer(dim, 2); 11455f80ce2aSJacob Faibussowitsch if (fem->ops->getdimension) CHKERRQ((*fem->ops->getdimension)(fem, dim)); 114620cf1dd8SToby Isaac PetscFunctionReturn(0); 114720cf1dd8SToby Isaac } 114820cf1dd8SToby Isaac 11494bee2e38SMatthew G. Knepley /*@C 11504bee2e38SMatthew G. Knepley PetscFEPushforward - Map the reference element function to real space 11514bee2e38SMatthew G. Knepley 11524bee2e38SMatthew G. Knepley Input Parameters: 11534bee2e38SMatthew G. Knepley + fe - The PetscFE 11544bee2e38SMatthew G. Knepley . fegeom - The cell geometry 11554bee2e38SMatthew G. Knepley . Nv - The number of function values 11564bee2e38SMatthew G. Knepley - vals - The function values 11574bee2e38SMatthew G. Knepley 11584bee2e38SMatthew G. Knepley Output Parameter: 11594bee2e38SMatthew G. Knepley . vals - The transformed function values 11604bee2e38SMatthew G. Knepley 11614bee2e38SMatthew G. Knepley Level: advanced 11624bee2e38SMatthew G. Knepley 11634bee2e38SMatthew G. Knepley Note: This just forwards the call onto PetscDualSpacePushforward(). 11644bee2e38SMatthew G. Knepley 1165f9244615SMatthew G. Knepley Note: This only handles transformations when the embedding dimension of the geometry in fegeom is the same as the reference dimension. 11662edcad52SToby Isaac 11674bee2e38SMatthew G. Knepley .seealso: PetscDualSpacePushforward() 11684bee2e38SMatthew G. Knepley @*/ 11692edcad52SToby Isaac PetscErrorCode PetscFEPushforward(PetscFE fe, PetscFEGeom *fegeom, PetscInt Nv, PetscScalar vals[]) 11704bee2e38SMatthew G. Knepley { 11712ae266adSMatthew G. Knepley PetscFunctionBeginHot; 11725f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpacePushforward(fe->dualSpace, fegeom, Nv, fe->numComponents, vals)); 11734bee2e38SMatthew G. Knepley PetscFunctionReturn(0); 11744bee2e38SMatthew G. Knepley } 11754bee2e38SMatthew G. Knepley 11764bee2e38SMatthew G. Knepley /*@C 11774bee2e38SMatthew G. Knepley PetscFEPushforwardGradient - Map the reference element function gradient to real space 11784bee2e38SMatthew G. Knepley 11794bee2e38SMatthew G. Knepley Input Parameters: 11804bee2e38SMatthew G. Knepley + fe - The PetscFE 11814bee2e38SMatthew G. Knepley . fegeom - The cell geometry 11824bee2e38SMatthew G. Knepley . Nv - The number of function gradient values 11834bee2e38SMatthew G. Knepley - vals - The function gradient values 11844bee2e38SMatthew G. Knepley 11854bee2e38SMatthew G. Knepley Output Parameter: 11864bee2e38SMatthew G. Knepley . vals - The transformed function gradient values 11874bee2e38SMatthew G. Knepley 11884bee2e38SMatthew G. Knepley Level: advanced 11894bee2e38SMatthew G. Knepley 11904bee2e38SMatthew G. Knepley Note: This just forwards the call onto PetscDualSpacePushforwardGradient(). 11914bee2e38SMatthew G. Knepley 1192f9244615SMatthew G. Knepley Note: This only handles transformations when the embedding dimension of the geometry in fegeom is the same as the reference dimension. 11932edcad52SToby Isaac 11944bee2e38SMatthew G. Knepley .seealso: PetscFEPushforward(), PetscDualSpacePushforwardGradient(), PetscDualSpacePushforward() 11954bee2e38SMatthew G. Knepley @*/ 11962edcad52SToby Isaac PetscErrorCode PetscFEPushforwardGradient(PetscFE fe, PetscFEGeom *fegeom, PetscInt Nv, PetscScalar vals[]) 11974bee2e38SMatthew G. Knepley { 11982ae266adSMatthew G. Knepley PetscFunctionBeginHot; 11995f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpacePushforwardGradient(fe->dualSpace, fegeom, Nv, fe->numComponents, vals)); 12004bee2e38SMatthew G. Knepley PetscFunctionReturn(0); 12014bee2e38SMatthew G. Knepley } 12024bee2e38SMatthew G. Knepley 1203f9244615SMatthew G. Knepley /*@C 1204f9244615SMatthew G. Knepley PetscFEPushforwardHessian - Map the reference element function Hessian to real space 1205f9244615SMatthew G. Knepley 1206f9244615SMatthew G. Knepley Input Parameters: 1207f9244615SMatthew G. Knepley + fe - The PetscFE 1208f9244615SMatthew G. Knepley . fegeom - The cell geometry 1209f9244615SMatthew G. Knepley . Nv - The number of function Hessian values 1210f9244615SMatthew G. Knepley - vals - The function Hessian values 1211f9244615SMatthew G. Knepley 1212f9244615SMatthew G. Knepley Output Parameter: 1213f9244615SMatthew G. Knepley . vals - The transformed function Hessian values 1214f9244615SMatthew G. Knepley 1215f9244615SMatthew G. Knepley Level: advanced 1216f9244615SMatthew G. Knepley 1217f9244615SMatthew G. Knepley Note: This just forwards the call onto PetscDualSpacePushforwardHessian(). 1218f9244615SMatthew G. Knepley 1219f9244615SMatthew G. Knepley Note: This only handles transformations when the embedding dimension of the geometry in fegeom is the same as the reference dimension. 1220f9244615SMatthew G. Knepley 1221f9244615SMatthew G. Knepley .seealso: PetscFEPushforward(), PetscDualSpacePushforwardHessian(), PetscDualSpacePushforward() 1222f9244615SMatthew G. Knepley @*/ 1223f9244615SMatthew G. Knepley PetscErrorCode PetscFEPushforwardHessian(PetscFE fe, PetscFEGeom *fegeom, PetscInt Nv, PetscScalar vals[]) 1224f9244615SMatthew G. Knepley { 1225f9244615SMatthew G. Knepley PetscFunctionBeginHot; 12265f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpacePushforwardHessian(fe->dualSpace, fegeom, Nv, fe->numComponents, vals)); 1227f9244615SMatthew G. Knepley PetscFunctionReturn(0); 1228f9244615SMatthew G. Knepley } 1229f9244615SMatthew G. Knepley 123020cf1dd8SToby Isaac /* 123120cf1dd8SToby Isaac Purpose: Compute element vector for chunk of elements 123220cf1dd8SToby Isaac 123320cf1dd8SToby Isaac Input: 123420cf1dd8SToby Isaac Sizes: 123520cf1dd8SToby Isaac Ne: number of elements 123620cf1dd8SToby Isaac Nf: number of fields 123720cf1dd8SToby Isaac PetscFE 123820cf1dd8SToby Isaac dim: spatial dimension 123920cf1dd8SToby Isaac Nb: number of basis functions 124020cf1dd8SToby Isaac Nc: number of field components 124120cf1dd8SToby Isaac PetscQuadrature 124220cf1dd8SToby Isaac Nq: number of quadrature points 124320cf1dd8SToby Isaac 124420cf1dd8SToby Isaac Geometry: 124520cf1dd8SToby Isaac PetscFEGeom[Ne] possibly *Nq 124620cf1dd8SToby Isaac PetscReal v0s[dim] 124720cf1dd8SToby Isaac PetscReal n[dim] 124820cf1dd8SToby Isaac PetscReal jacobians[dim*dim] 124920cf1dd8SToby Isaac PetscReal jacobianInverses[dim*dim] 125020cf1dd8SToby Isaac PetscReal jacobianDeterminants 125120cf1dd8SToby Isaac FEM: 125220cf1dd8SToby Isaac PetscFE 125320cf1dd8SToby Isaac PetscQuadrature 125420cf1dd8SToby Isaac PetscReal quadPoints[Nq*dim] 125520cf1dd8SToby Isaac PetscReal quadWeights[Nq] 125620cf1dd8SToby Isaac PetscReal basis[Nq*Nb*Nc] 125720cf1dd8SToby Isaac PetscReal basisDer[Nq*Nb*Nc*dim] 125820cf1dd8SToby Isaac PetscScalar coefficients[Ne*Nb*Nc] 125920cf1dd8SToby Isaac PetscScalar elemVec[Ne*Nb*Nc] 126020cf1dd8SToby Isaac 126120cf1dd8SToby Isaac Problem: 126220cf1dd8SToby Isaac PetscInt f: the active field 126320cf1dd8SToby Isaac f0, f1 126420cf1dd8SToby Isaac 126520cf1dd8SToby Isaac Work Space: 126620cf1dd8SToby Isaac PetscFE 126720cf1dd8SToby Isaac PetscScalar f0[Nq*dim]; 126820cf1dd8SToby Isaac PetscScalar f1[Nq*dim*dim]; 126920cf1dd8SToby Isaac PetscScalar u[Nc]; 127020cf1dd8SToby Isaac PetscScalar gradU[Nc*dim]; 127120cf1dd8SToby Isaac PetscReal x[dim]; 127220cf1dd8SToby Isaac PetscScalar realSpaceDer[dim]; 127320cf1dd8SToby Isaac 127420cf1dd8SToby Isaac Purpose: Compute element vector for N_cb batches of elements 127520cf1dd8SToby Isaac 127620cf1dd8SToby Isaac Input: 127720cf1dd8SToby Isaac Sizes: 127820cf1dd8SToby Isaac N_cb: Number of serial cell batches 127920cf1dd8SToby Isaac 128020cf1dd8SToby Isaac Geometry: 128120cf1dd8SToby Isaac PetscReal v0s[Ne*dim] 128220cf1dd8SToby Isaac PetscReal jacobians[Ne*dim*dim] possibly *Nq 128320cf1dd8SToby Isaac PetscReal jacobianInverses[Ne*dim*dim] possibly *Nq 128420cf1dd8SToby Isaac PetscReal jacobianDeterminants[Ne] possibly *Nq 128520cf1dd8SToby Isaac FEM: 128620cf1dd8SToby Isaac static PetscReal quadPoints[Nq*dim] 128720cf1dd8SToby Isaac static PetscReal quadWeights[Nq] 128820cf1dd8SToby Isaac static PetscReal basis[Nq*Nb*Nc] 128920cf1dd8SToby Isaac static PetscReal basisDer[Nq*Nb*Nc*dim] 129020cf1dd8SToby Isaac PetscScalar coefficients[Ne*Nb*Nc] 129120cf1dd8SToby Isaac PetscScalar elemVec[Ne*Nb*Nc] 129220cf1dd8SToby Isaac 129320cf1dd8SToby Isaac ex62.c: 129420cf1dd8SToby Isaac PetscErrorCode PetscFEIntegrateResidualBatch(PetscInt Ne, PetscInt numFields, PetscInt field, PetscQuadrature quad[], const PetscScalar coefficients[], 129520cf1dd8SToby Isaac const PetscReal v0s[], const PetscReal jacobians[], const PetscReal jacobianInverses[], const PetscReal jacobianDeterminants[], 129620cf1dd8SToby Isaac void (*f0_func)(const PetscScalar u[], const PetscScalar gradU[], const PetscReal x[], PetscScalar f0[]), 129720cf1dd8SToby Isaac void (*f1_func)(const PetscScalar u[], const PetscScalar gradU[], const PetscReal x[], PetscScalar f1[]), PetscScalar elemVec[]) 129820cf1dd8SToby Isaac 129920cf1dd8SToby Isaac ex52.c: 130020cf1dd8SToby 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) 130120cf1dd8SToby 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) 130220cf1dd8SToby Isaac 130320cf1dd8SToby Isaac ex52_integrateElement.cu 130420cf1dd8SToby Isaac __global__ void integrateElementQuadrature(int N_cb, realType *coefficients, realType *jacobianInverses, realType *jacobianDeterminants, realType *elemVec) 130520cf1dd8SToby Isaac 130620cf1dd8SToby Isaac PETSC_EXTERN PetscErrorCode IntegrateElementBatchGPU(PetscInt spatial_dim, PetscInt Ne, PetscInt Ncb, PetscInt Nbc, PetscInt Nbl, const PetscScalar coefficients[], 130720cf1dd8SToby Isaac const PetscReal jacobianInverses[], const PetscReal jacobianDeterminants[], PetscScalar elemVec[], 130820cf1dd8SToby Isaac PetscLogEvent event, PetscInt debug, PetscInt pde_op) 130920cf1dd8SToby Isaac 131020cf1dd8SToby Isaac ex52_integrateElementOpenCL.c: 131120cf1dd8SToby Isaac PETSC_EXTERN PetscErrorCode IntegrateElementBatchGPU(PetscInt spatial_dim, PetscInt Ne, PetscInt Ncb, PetscInt Nbc, PetscInt N_bl, const PetscScalar coefficients[], 131220cf1dd8SToby Isaac const PetscReal jacobianInverses[], const PetscReal jacobianDeterminants[], PetscScalar elemVec[], 131320cf1dd8SToby Isaac PetscLogEvent event, PetscInt debug, PetscInt pde_op) 131420cf1dd8SToby Isaac 131520cf1dd8SToby Isaac __kernel void integrateElementQuadrature(int N_cb, __global float *coefficients, __global float *jacobianInverses, __global float *jacobianDeterminants, __global float *elemVec) 131620cf1dd8SToby Isaac */ 131720cf1dd8SToby Isaac 131820cf1dd8SToby Isaac /*@C 131920cf1dd8SToby Isaac PetscFEIntegrate - Produce the integral for the given field for a chunk of elements by quadrature integration 132020cf1dd8SToby Isaac 132120cf1dd8SToby Isaac Not collective 132220cf1dd8SToby Isaac 132320cf1dd8SToby Isaac Input Parameters: 1324360cf244SMatthew G. Knepley + prob - The PetscDS specifying the discretizations and continuum functions 132520cf1dd8SToby Isaac . field - The field being integrated 132620cf1dd8SToby Isaac . Ne - The number of elements in the chunk 132720cf1dd8SToby Isaac . cgeom - The cell geometry for each cell in the chunk 132820cf1dd8SToby Isaac . coefficients - The array of FEM basis coefficients for the elements 132920cf1dd8SToby Isaac . probAux - The PetscDS specifying the auxiliary discretizations 133020cf1dd8SToby Isaac - coefficientsAux - The array of FEM auxiliary basis coefficients for the elements 133120cf1dd8SToby Isaac 13327a7aea1fSJed Brown Output Parameter: 133320cf1dd8SToby Isaac . integral - the integral for this field 133420cf1dd8SToby Isaac 13352b99622eSMatthew G. Knepley Level: intermediate 133620cf1dd8SToby Isaac 133720cf1dd8SToby Isaac .seealso: PetscFEIntegrateResidual() 133820cf1dd8SToby Isaac @*/ 13394bee2e38SMatthew G. Knepley PetscErrorCode PetscFEIntegrate(PetscDS prob, PetscInt field, PetscInt Ne, PetscFEGeom *cgeom, 134020cf1dd8SToby Isaac const PetscScalar coefficients[], PetscDS probAux, const PetscScalar coefficientsAux[], PetscScalar integral[]) 134120cf1dd8SToby Isaac { 13424bee2e38SMatthew G. Knepley PetscFE fe; 134320cf1dd8SToby Isaac 134420cf1dd8SToby Isaac PetscFunctionBegin; 13454bee2e38SMatthew G. Knepley PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 13465f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetDiscretization(prob, field, (PetscObject *) &fe)); 13475f80ce2aSJacob Faibussowitsch if (fe->ops->integrate) CHKERRQ((*fe->ops->integrate)(prob, field, Ne, cgeom, coefficients, probAux, coefficientsAux, integral)); 134820cf1dd8SToby Isaac PetscFunctionReturn(0); 134920cf1dd8SToby Isaac } 135020cf1dd8SToby Isaac 135120cf1dd8SToby Isaac /*@C 1352afe6d6adSToby Isaac PetscFEIntegrateBd - Produce the integral for the given field for a chunk of elements by quadrature integration 1353afe6d6adSToby Isaac 1354afe6d6adSToby Isaac Not collective 1355afe6d6adSToby Isaac 1356afe6d6adSToby Isaac Input Parameters: 1357360cf244SMatthew G. Knepley + prob - The PetscDS specifying the discretizations and continuum functions 1358afe6d6adSToby Isaac . field - The field being integrated 1359afe6d6adSToby Isaac . obj_func - The function to be integrated 1360afe6d6adSToby Isaac . Ne - The number of elements in the chunk 1361afe6d6adSToby Isaac . fgeom - The face geometry for each face in the chunk 1362afe6d6adSToby Isaac . coefficients - The array of FEM basis coefficients for the elements 1363afe6d6adSToby Isaac . probAux - The PetscDS specifying the auxiliary discretizations 1364afe6d6adSToby Isaac - coefficientsAux - The array of FEM auxiliary basis coefficients for the elements 1365afe6d6adSToby Isaac 13667a7aea1fSJed Brown Output Parameter: 1367afe6d6adSToby Isaac . integral - the integral for this field 1368afe6d6adSToby Isaac 13692b99622eSMatthew G. Knepley Level: intermediate 1370afe6d6adSToby Isaac 1371afe6d6adSToby Isaac .seealso: PetscFEIntegrateResidual() 1372afe6d6adSToby Isaac @*/ 13734bee2e38SMatthew G. Knepley PetscErrorCode PetscFEIntegrateBd(PetscDS prob, PetscInt field, 1374afe6d6adSToby Isaac void (*obj_func)(PetscInt, PetscInt, PetscInt, 1375afe6d6adSToby Isaac const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 1376afe6d6adSToby Isaac const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 1377afe6d6adSToby Isaac PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), 1378afe6d6adSToby Isaac PetscInt Ne, PetscFEGeom *geom, const PetscScalar coefficients[], PetscDS probAux, const PetscScalar coefficientsAux[], PetscScalar integral[]) 1379afe6d6adSToby Isaac { 13804bee2e38SMatthew G. Knepley PetscFE fe; 1381afe6d6adSToby Isaac 1382afe6d6adSToby Isaac PetscFunctionBegin; 13834bee2e38SMatthew G. Knepley PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 13845f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetDiscretization(prob, field, (PetscObject *) &fe)); 13855f80ce2aSJacob Faibussowitsch if (fe->ops->integratebd) CHKERRQ((*fe->ops->integratebd)(prob, field, obj_func, Ne, geom, coefficients, probAux, coefficientsAux, integral)); 1386afe6d6adSToby Isaac PetscFunctionReturn(0); 1387afe6d6adSToby Isaac } 1388afe6d6adSToby Isaac 1389afe6d6adSToby Isaac /*@C 139020cf1dd8SToby Isaac PetscFEIntegrateResidual - Produce the element residual vector for a chunk of elements by quadrature integration 139120cf1dd8SToby Isaac 139220cf1dd8SToby Isaac Not collective 139320cf1dd8SToby Isaac 139420cf1dd8SToby Isaac Input Parameters: 13956528b96dSMatthew G. Knepley + ds - The PetscDS specifying the discretizations and continuum functions 13966528b96dSMatthew G. Knepley . key - The (label+value, field) being integrated 139720cf1dd8SToby Isaac . Ne - The number of elements in the chunk 139820cf1dd8SToby Isaac . cgeom - The cell geometry for each cell in the chunk 139920cf1dd8SToby Isaac . coefficients - The array of FEM basis coefficients for the elements 140020cf1dd8SToby Isaac . coefficients_t - The array of FEM basis time derivative coefficients for the elements 140120cf1dd8SToby Isaac . probAux - The PetscDS specifying the auxiliary discretizations 140220cf1dd8SToby Isaac . coefficientsAux - The array of FEM auxiliary basis coefficients for the elements 140320cf1dd8SToby Isaac - t - The time 140420cf1dd8SToby Isaac 14057a7aea1fSJed Brown Output Parameter: 140620cf1dd8SToby Isaac . elemVec - the element residual vectors from each element 140720cf1dd8SToby Isaac 140820cf1dd8SToby Isaac Note: 140920cf1dd8SToby Isaac $ Loop over batch of elements (e): 141020cf1dd8SToby Isaac $ Loop over quadrature points (q): 141120cf1dd8SToby Isaac $ Make u_q and gradU_q (loops over fields,Nb,Ncomp) and x_q 141220cf1dd8SToby Isaac $ Call f_0 and f_1 141320cf1dd8SToby Isaac $ Loop over element vector entries (f,fc --> i): 141420cf1dd8SToby Isaac $ elemVec[i] += \psi^{fc}_f(q) f0_{fc}(u, \nabla u) + \nabla\psi^{fc}_f(q) \cdot f1_{fc,df}(u, \nabla u) 141520cf1dd8SToby Isaac 14162b99622eSMatthew G. Knepley Level: intermediate 141720cf1dd8SToby Isaac 141820cf1dd8SToby Isaac .seealso: PetscFEIntegrateResidual() 141920cf1dd8SToby Isaac @*/ 142006ad1575SMatthew G. Knepley PetscErrorCode PetscFEIntegrateResidual(PetscDS ds, PetscFormKey key, PetscInt Ne, PetscFEGeom *cgeom, 142120cf1dd8SToby Isaac const PetscScalar coefficients[], const PetscScalar coefficients_t[], PetscDS probAux, const PetscScalar coefficientsAux[], PetscReal t, PetscScalar elemVec[]) 142220cf1dd8SToby Isaac { 14234bee2e38SMatthew G. Knepley PetscFE fe; 142420cf1dd8SToby Isaac 14256528b96dSMatthew G. Knepley PetscFunctionBeginHot; 14266528b96dSMatthew G. Knepley PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1); 14275f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetDiscretization(ds, key.field, (PetscObject *) &fe)); 14285f80ce2aSJacob Faibussowitsch if (fe->ops->integrateresidual) CHKERRQ((*fe->ops->integrateresidual)(ds, key, Ne, cgeom, coefficients, coefficients_t, probAux, coefficientsAux, t, elemVec)); 142920cf1dd8SToby Isaac PetscFunctionReturn(0); 143020cf1dd8SToby Isaac } 143120cf1dd8SToby Isaac 143220cf1dd8SToby Isaac /*@C 143320cf1dd8SToby Isaac PetscFEIntegrateBdResidual - Produce the element residual vector for a chunk of elements by quadrature integration over a boundary 143420cf1dd8SToby Isaac 143520cf1dd8SToby Isaac Not collective 143620cf1dd8SToby Isaac 143720cf1dd8SToby Isaac Input Parameters: 143806d8a0d3SMatthew G. Knepley + ds - The PetscDS specifying the discretizations and continuum functions 143945480ffeSMatthew G. Knepley . wf - The PetscWeakForm object holding the pointwise functions 144006d8a0d3SMatthew G. Knepley . key - The (label+value, field) being integrated 144120cf1dd8SToby Isaac . Ne - The number of elements in the chunk 144220cf1dd8SToby Isaac . fgeom - The face geometry for each cell in the chunk 144320cf1dd8SToby Isaac . coefficients - The array of FEM basis coefficients for the elements 144420cf1dd8SToby Isaac . coefficients_t - The array of FEM basis time derivative coefficients for the elements 144520cf1dd8SToby Isaac . probAux - The PetscDS specifying the auxiliary discretizations 144620cf1dd8SToby Isaac . coefficientsAux - The array of FEM auxiliary basis coefficients for the elements 144720cf1dd8SToby Isaac - t - The time 144820cf1dd8SToby Isaac 14497a7aea1fSJed Brown Output Parameter: 145020cf1dd8SToby Isaac . elemVec - the element residual vectors from each element 145120cf1dd8SToby Isaac 14522b99622eSMatthew G. Knepley Level: intermediate 145320cf1dd8SToby Isaac 145420cf1dd8SToby Isaac .seealso: PetscFEIntegrateResidual() 145520cf1dd8SToby Isaac @*/ 145606ad1575SMatthew G. Knepley PetscErrorCode PetscFEIntegrateBdResidual(PetscDS ds, PetscWeakForm wf, PetscFormKey key, PetscInt Ne, PetscFEGeom *fgeom, 145720cf1dd8SToby Isaac const PetscScalar coefficients[], const PetscScalar coefficients_t[], PetscDS probAux, const PetscScalar coefficientsAux[], PetscReal t, PetscScalar elemVec[]) 145820cf1dd8SToby Isaac { 14594bee2e38SMatthew G. Knepley PetscFE fe; 146020cf1dd8SToby Isaac 146120cf1dd8SToby Isaac PetscFunctionBegin; 146206d8a0d3SMatthew G. Knepley PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1); 14635f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetDiscretization(ds, key.field, (PetscObject *) &fe)); 14645f80ce2aSJacob Faibussowitsch if (fe->ops->integratebdresidual) CHKERRQ((*fe->ops->integratebdresidual)(ds, wf, key, Ne, fgeom, coefficients, coefficients_t, probAux, coefficientsAux, t, elemVec)); 146520cf1dd8SToby Isaac PetscFunctionReturn(0); 146620cf1dd8SToby Isaac } 146720cf1dd8SToby Isaac 146820cf1dd8SToby Isaac /*@C 146927f02ce8SMatthew G. Knepley PetscFEIntegrateHybridResidual - Produce the element residual vector for a chunk of hybrid element faces by quadrature integration 147027f02ce8SMatthew G. Knepley 147127f02ce8SMatthew G. Knepley Not collective 147227f02ce8SMatthew G. Knepley 147327f02ce8SMatthew G. Knepley Input Parameters: 147427f02ce8SMatthew G. Knepley + prob - The PetscDS specifying the discretizations and continuum functions 14756528b96dSMatthew G. Knepley . key - The (label+value, field) being integrated 1476c2b7495fSMatthew G. Knepley . s - The side of the cell being integrated, 0 for negative and 1 for positive 147727f02ce8SMatthew G. Knepley . Ne - The number of elements in the chunk 147827f02ce8SMatthew G. Knepley . fgeom - The face geometry for each cell in the chunk 147927f02ce8SMatthew G. Knepley . coefficients - The array of FEM basis coefficients for the elements 148027f02ce8SMatthew G. Knepley . coefficients_t - The array of FEM basis time derivative coefficients for the elements 148127f02ce8SMatthew G. Knepley . probAux - The PetscDS specifying the auxiliary discretizations 148227f02ce8SMatthew G. Knepley . coefficientsAux - The array of FEM auxiliary basis coefficients for the elements 148327f02ce8SMatthew G. Knepley - t - The time 148427f02ce8SMatthew G. Knepley 148527f02ce8SMatthew G. Knepley Output Parameter 148627f02ce8SMatthew G. Knepley . elemVec - the element residual vectors from each element 148727f02ce8SMatthew G. Knepley 148827f02ce8SMatthew G. Knepley Level: developer 148927f02ce8SMatthew G. Knepley 149027f02ce8SMatthew G. Knepley .seealso: PetscFEIntegrateResidual() 149127f02ce8SMatthew G. Knepley @*/ 1492c2b7495fSMatthew G. Knepley PetscErrorCode PetscFEIntegrateHybridResidual(PetscDS prob, PetscFormKey key, PetscInt s, PetscInt Ne, PetscFEGeom *fgeom, 149327f02ce8SMatthew G. Knepley const PetscScalar coefficients[], const PetscScalar coefficients_t[], PetscDS probAux, const PetscScalar coefficientsAux[], PetscReal t, PetscScalar elemVec[]) 149427f02ce8SMatthew G. Knepley { 149527f02ce8SMatthew G. Knepley PetscFE fe; 149627f02ce8SMatthew G. Knepley 149727f02ce8SMatthew G. Knepley PetscFunctionBegin; 149827f02ce8SMatthew G. Knepley PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1); 14995f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetDiscretization(prob, key.field, (PetscObject *) &fe)); 15005f80ce2aSJacob Faibussowitsch if (fe->ops->integratehybridresidual) CHKERRQ((*fe->ops->integratehybridresidual)(prob, key, s, Ne, fgeom, coefficients, coefficients_t, probAux, coefficientsAux, t, elemVec)); 150127f02ce8SMatthew G. Knepley PetscFunctionReturn(0); 150227f02ce8SMatthew G. Knepley } 150327f02ce8SMatthew G. Knepley 150427f02ce8SMatthew G. Knepley /*@C 150520cf1dd8SToby Isaac PetscFEIntegrateJacobian - Produce the element Jacobian for a chunk of elements by quadrature integration 150620cf1dd8SToby Isaac 150720cf1dd8SToby Isaac Not collective 150820cf1dd8SToby Isaac 150920cf1dd8SToby Isaac Input Parameters: 15106528b96dSMatthew G. Knepley + ds - The PetscDS specifying the discretizations and continuum functions 151120cf1dd8SToby Isaac . jtype - The type of matrix pointwise functions that should be used 15126528b96dSMatthew G. Knepley . key - The (label+value, fieldI*Nf + fieldJ) being integrated 15135fedec97SMatthew G. Knepley . s - The side of the cell being integrated, 0 for negative and 1 for positive 151420cf1dd8SToby Isaac . Ne - The number of elements in the chunk 151520cf1dd8SToby Isaac . cgeom - The cell geometry for each cell in the chunk 151620cf1dd8SToby Isaac . coefficients - The array of FEM basis coefficients for the elements for the Jacobian evaluation point 151720cf1dd8SToby Isaac . coefficients_t - The array of FEM basis time derivative coefficients for the elements 151820cf1dd8SToby Isaac . probAux - The PetscDS specifying the auxiliary discretizations 151920cf1dd8SToby Isaac . coefficientsAux - The array of FEM auxiliary basis coefficients for the elements 152020cf1dd8SToby Isaac . t - The time 152120cf1dd8SToby Isaac - u_tShift - A multiplier for the dF/du_t term (as opposed to the dF/du term) 152220cf1dd8SToby Isaac 15237a7aea1fSJed Brown Output Parameter: 152420cf1dd8SToby Isaac . elemMat - the element matrices for the Jacobian from each element 152520cf1dd8SToby Isaac 152620cf1dd8SToby Isaac Note: 152720cf1dd8SToby Isaac $ Loop over batch of elements (e): 152820cf1dd8SToby Isaac $ Loop over element matrix entries (f,fc,g,gc --> i,j): 152920cf1dd8SToby Isaac $ Loop over quadrature points (q): 153020cf1dd8SToby Isaac $ Make u_q and gradU_q (loops over fields,Nb,Ncomp) 153120cf1dd8SToby Isaac $ elemMat[i,j] += \psi^{fc}_f(q) g0_{fc,gc}(u, \nabla u) \phi^{gc}_g(q) 153220cf1dd8SToby Isaac $ + \psi^{fc}_f(q) \cdot g1_{fc,gc,dg}(u, \nabla u) \nabla\phi^{gc}_g(q) 153320cf1dd8SToby Isaac $ + \nabla\psi^{fc}_f(q) \cdot g2_{fc,gc,df}(u, \nabla u) \phi^{gc}_g(q) 153420cf1dd8SToby Isaac $ + \nabla\psi^{fc}_f(q) \cdot g3_{fc,gc,df,dg}(u, \nabla u) \nabla\phi^{gc}_g(q) 15352b99622eSMatthew G. Knepley Level: intermediate 153620cf1dd8SToby Isaac 153720cf1dd8SToby Isaac .seealso: PetscFEIntegrateResidual() 153820cf1dd8SToby Isaac @*/ 153906ad1575SMatthew G. Knepley PetscErrorCode PetscFEIntegrateJacobian(PetscDS ds, PetscFEJacobianType jtype, PetscFormKey key, PetscInt Ne, PetscFEGeom *cgeom, 154020cf1dd8SToby Isaac const PetscScalar coefficients[], const PetscScalar coefficients_t[], PetscDS probAux, const PetscScalar coefficientsAux[], PetscReal t, PetscReal u_tshift, PetscScalar elemMat[]) 154120cf1dd8SToby Isaac { 15424bee2e38SMatthew G. Knepley PetscFE fe; 15436528b96dSMatthew G. Knepley PetscInt Nf; 154420cf1dd8SToby Isaac 154520cf1dd8SToby Isaac PetscFunctionBegin; 15466528b96dSMatthew G. Knepley PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1); 15475f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetNumFields(ds, &Nf)); 15485f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetDiscretization(ds, key.field / Nf, (PetscObject *) &fe)); 15495f80ce2aSJacob Faibussowitsch if (fe->ops->integratejacobian) CHKERRQ((*fe->ops->integratejacobian)(ds, jtype, key, Ne, cgeom, coefficients, coefficients_t, probAux, coefficientsAux, t, u_tshift, elemMat)); 155020cf1dd8SToby Isaac PetscFunctionReturn(0); 155120cf1dd8SToby Isaac } 155220cf1dd8SToby Isaac 155320cf1dd8SToby Isaac /*@C 155420cf1dd8SToby Isaac PetscFEIntegrateBdJacobian - Produce the boundary element Jacobian for a chunk of elements by quadrature integration 155520cf1dd8SToby Isaac 155620cf1dd8SToby Isaac Not collective 155720cf1dd8SToby Isaac 155820cf1dd8SToby Isaac Input Parameters: 155945480ffeSMatthew G. Knepley + ds - The PetscDS specifying the discretizations and continuum functions 156045480ffeSMatthew G. Knepley . wf - The PetscWeakForm holding the pointwise functions 156145480ffeSMatthew G. Knepley . key - The (label+value, fieldI*Nf + fieldJ) being integrated 156220cf1dd8SToby Isaac . Ne - The number of elements in the chunk 156320cf1dd8SToby Isaac . fgeom - The face geometry for each cell in the chunk 156420cf1dd8SToby Isaac . coefficients - The array of FEM basis coefficients for the elements for the Jacobian evaluation point 156520cf1dd8SToby Isaac . coefficients_t - The array of FEM basis time derivative coefficients for the elements 156620cf1dd8SToby Isaac . probAux - The PetscDS specifying the auxiliary discretizations 156720cf1dd8SToby Isaac . coefficientsAux - The array of FEM auxiliary basis coefficients for the elements 156820cf1dd8SToby Isaac . t - The time 156920cf1dd8SToby Isaac - u_tShift - A multiplier for the dF/du_t term (as opposed to the dF/du term) 157020cf1dd8SToby Isaac 15717a7aea1fSJed Brown Output Parameter: 157220cf1dd8SToby Isaac . elemMat - the element matrices for the Jacobian from each element 157320cf1dd8SToby Isaac 157420cf1dd8SToby Isaac Note: 157520cf1dd8SToby Isaac $ Loop over batch of elements (e): 157620cf1dd8SToby Isaac $ Loop over element matrix entries (f,fc,g,gc --> i,j): 157720cf1dd8SToby Isaac $ Loop over quadrature points (q): 157820cf1dd8SToby Isaac $ Make u_q and gradU_q (loops over fields,Nb,Ncomp) 157920cf1dd8SToby Isaac $ elemMat[i,j] += \psi^{fc}_f(q) g0_{fc,gc}(u, \nabla u) \phi^{gc}_g(q) 158020cf1dd8SToby Isaac $ + \psi^{fc}_f(q) \cdot g1_{fc,gc,dg}(u, \nabla u) \nabla\phi^{gc}_g(q) 158120cf1dd8SToby Isaac $ + \nabla\psi^{fc}_f(q) \cdot g2_{fc,gc,df}(u, \nabla u) \phi^{gc}_g(q) 158220cf1dd8SToby Isaac $ + \nabla\psi^{fc}_f(q) \cdot g3_{fc,gc,df,dg}(u, \nabla u) \nabla\phi^{gc}_g(q) 15832b99622eSMatthew G. Knepley Level: intermediate 158420cf1dd8SToby Isaac 158520cf1dd8SToby Isaac .seealso: PetscFEIntegrateJacobian(), PetscFEIntegrateResidual() 158620cf1dd8SToby Isaac @*/ 158706ad1575SMatthew G. Knepley PetscErrorCode PetscFEIntegrateBdJacobian(PetscDS ds, PetscWeakForm wf, PetscFormKey key, PetscInt Ne, PetscFEGeom *fgeom, 158820cf1dd8SToby Isaac const PetscScalar coefficients[], const PetscScalar coefficients_t[], PetscDS probAux, const PetscScalar coefficientsAux[], PetscReal t, PetscReal u_tshift, PetscScalar elemMat[]) 158920cf1dd8SToby Isaac { 15904bee2e38SMatthew G. Knepley PetscFE fe; 159145480ffeSMatthew G. Knepley PetscInt Nf; 159220cf1dd8SToby Isaac 159320cf1dd8SToby Isaac PetscFunctionBegin; 159445480ffeSMatthew G. Knepley PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1); 15955f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetNumFields(ds, &Nf)); 15965f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetDiscretization(ds, key.field / Nf, (PetscObject *) &fe)); 15975f80ce2aSJacob Faibussowitsch if (fe->ops->integratebdjacobian) CHKERRQ((*fe->ops->integratebdjacobian)(ds, wf, key, Ne, fgeom, coefficients, coefficients_t, probAux, coefficientsAux, t, u_tshift, elemMat)); 159820cf1dd8SToby Isaac PetscFunctionReturn(0); 159920cf1dd8SToby Isaac } 160020cf1dd8SToby Isaac 160127f02ce8SMatthew G. Knepley /*@C 160227f02ce8SMatthew G. Knepley PetscFEIntegrateHybridJacobian - Produce the boundary element Jacobian for a chunk of hybrid elements by quadrature integration 160327f02ce8SMatthew G. Knepley 160427f02ce8SMatthew G. Knepley Not collective 160527f02ce8SMatthew G. Knepley 160627f02ce8SMatthew G. Knepley Input Parameters: 160745480ffeSMatthew G. Knepley + ds - The PetscDS specifying the discretizations and continuum functions 160827f02ce8SMatthew G. Knepley . jtype - The type of matrix pointwise functions that should be used 160945480ffeSMatthew G. Knepley . key - The (label+value, fieldI*Nf + fieldJ) being integrated 16105fedec97SMatthew G. Knepley . s - The side of the cell being integrated, 0 for negative and 1 for positive 161127f02ce8SMatthew G. Knepley . Ne - The number of elements in the chunk 161227f02ce8SMatthew G. Knepley . fgeom - The face geometry for each cell in the chunk 161327f02ce8SMatthew G. Knepley . coefficients - The array of FEM basis coefficients for the elements for the Jacobian evaluation point 161427f02ce8SMatthew G. Knepley . coefficients_t - The array of FEM basis time derivative coefficients for the elements 161527f02ce8SMatthew G. Knepley . probAux - The PetscDS specifying the auxiliary discretizations 161627f02ce8SMatthew G. Knepley . coefficientsAux - The array of FEM auxiliary basis coefficients for the elements 161727f02ce8SMatthew G. Knepley . t - The time 161827f02ce8SMatthew G. Knepley - u_tShift - A multiplier for the dF/du_t term (as opposed to the dF/du term) 161927f02ce8SMatthew G. Knepley 162027f02ce8SMatthew G. Knepley Output Parameter 162127f02ce8SMatthew G. Knepley . elemMat - the element matrices for the Jacobian from each element 162227f02ce8SMatthew G. Knepley 162327f02ce8SMatthew G. Knepley Note: 162427f02ce8SMatthew G. Knepley $ Loop over batch of elements (e): 162527f02ce8SMatthew G. Knepley $ Loop over element matrix entries (f,fc,g,gc --> i,j): 162627f02ce8SMatthew G. Knepley $ Loop over quadrature points (q): 162727f02ce8SMatthew G. Knepley $ Make u_q and gradU_q (loops over fields,Nb,Ncomp) 162827f02ce8SMatthew G. Knepley $ elemMat[i,j] += \psi^{fc}_f(q) g0_{fc,gc}(u, \nabla u) \phi^{gc}_g(q) 162927f02ce8SMatthew G. Knepley $ + \psi^{fc}_f(q) \cdot g1_{fc,gc,dg}(u, \nabla u) \nabla\phi^{gc}_g(q) 163027f02ce8SMatthew G. Knepley $ + \nabla\psi^{fc}_f(q) \cdot g2_{fc,gc,df}(u, \nabla u) \phi^{gc}_g(q) 163127f02ce8SMatthew G. Knepley $ + \nabla\psi^{fc}_f(q) \cdot g3_{fc,gc,df,dg}(u, \nabla u) \nabla\phi^{gc}_g(q) 163227f02ce8SMatthew G. Knepley Level: developer 163327f02ce8SMatthew G. Knepley 163427f02ce8SMatthew G. Knepley .seealso: PetscFEIntegrateJacobian(), PetscFEIntegrateResidual() 163527f02ce8SMatthew G. Knepley @*/ 16365fedec97SMatthew G. Knepley PetscErrorCode PetscFEIntegrateHybridJacobian(PetscDS ds, PetscFEJacobianType jtype, PetscFormKey key, PetscInt s, PetscInt Ne, PetscFEGeom *fgeom, 163727f02ce8SMatthew G. Knepley const PetscScalar coefficients[], const PetscScalar coefficients_t[], PetscDS probAux, const PetscScalar coefficientsAux[], PetscReal t, PetscReal u_tshift, PetscScalar elemMat[]) 163827f02ce8SMatthew G. Knepley { 163927f02ce8SMatthew G. Knepley PetscFE fe; 164045480ffeSMatthew G. Knepley PetscInt Nf; 164127f02ce8SMatthew G. Knepley 164227f02ce8SMatthew G. Knepley PetscFunctionBegin; 164345480ffeSMatthew G. Knepley PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1); 16445f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetNumFields(ds, &Nf)); 16455f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetDiscretization(ds, key.field / Nf, (PetscObject *) &fe)); 16465f80ce2aSJacob Faibussowitsch if (fe->ops->integratehybridjacobian) CHKERRQ((*fe->ops->integratehybridjacobian)(ds, jtype, key, s, Ne, fgeom, coefficients, coefficients_t, probAux, coefficientsAux, t, u_tshift, elemMat)); 164727f02ce8SMatthew G. Knepley PetscFunctionReturn(0); 164827f02ce8SMatthew G. Knepley } 164927f02ce8SMatthew G. Knepley 16502b99622eSMatthew G. Knepley /*@ 16512b99622eSMatthew G. Knepley PetscFEGetHeightSubspace - Get the subspace of this space for a mesh point of a given height 16522b99622eSMatthew G. Knepley 16532b99622eSMatthew G. Knepley Input Parameters: 16542b99622eSMatthew G. Knepley + fe - The finite element space 16552b99622eSMatthew G. Knepley - height - The height of the Plex point 16562b99622eSMatthew G. Knepley 16572b99622eSMatthew G. Knepley Output Parameter: 16582b99622eSMatthew G. Knepley . subfe - The subspace of this FE space 16592b99622eSMatthew G. Knepley 16602b99622eSMatthew G. Knepley Note: For example, if we want the subspace of this space for a face, we would choose height = 1. 16612b99622eSMatthew G. Knepley 16622b99622eSMatthew G. Knepley Level: advanced 16632b99622eSMatthew G. Knepley 16642b99622eSMatthew G. Knepley .seealso: PetscFECreateDefault() 16652b99622eSMatthew G. Knepley @*/ 166620cf1dd8SToby Isaac PetscErrorCode PetscFEGetHeightSubspace(PetscFE fe, PetscInt height, PetscFE *subfe) 166720cf1dd8SToby Isaac { 166820cf1dd8SToby Isaac PetscSpace P, subP; 166920cf1dd8SToby Isaac PetscDualSpace Q, subQ; 167020cf1dd8SToby Isaac PetscQuadrature subq; 167120cf1dd8SToby Isaac PetscFEType fetype; 167220cf1dd8SToby Isaac PetscInt dim, Nc; 167320cf1dd8SToby Isaac 167420cf1dd8SToby Isaac PetscFunctionBegin; 167520cf1dd8SToby Isaac PetscValidHeaderSpecific(fe, PETSCFE_CLASSID, 1); 167620cf1dd8SToby Isaac PetscValidPointer(subfe, 3); 167720cf1dd8SToby Isaac if (height == 0) { 167820cf1dd8SToby Isaac *subfe = fe; 167920cf1dd8SToby Isaac PetscFunctionReturn(0); 168020cf1dd8SToby Isaac } 16815f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEGetBasisSpace(fe, &P)); 16825f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEGetDualSpace(fe, &Q)); 16835f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEGetNumComponents(fe, &Nc)); 16845f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEGetFaceQuadrature(fe, &subq)); 16855f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceGetDimension(Q, &dim)); 16862c71b3e2SJacob Faibussowitsch PetscCheckFalse(height > dim || height < 0,PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Asked for space at height %D for dimension %D space", height, dim); 16875f80ce2aSJacob Faibussowitsch if (!fe->subspaces) CHKERRQ(PetscCalloc1(dim, &fe->subspaces)); 168820cf1dd8SToby Isaac if (height <= dim) { 168920cf1dd8SToby Isaac if (!fe->subspaces[height-1]) { 1690665f567fSMatthew G. Knepley PetscFE sub = NULL; 16913f6b16c7SMatthew G. Knepley const char *name; 169220cf1dd8SToby Isaac 16935f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceGetHeightSubspace(P, height, &subP)); 16945f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceGetHeightSubspace(Q, height, &subQ)); 1695665f567fSMatthew G. Knepley if (subQ) { 16965f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFECreate(PetscObjectComm((PetscObject) fe), &sub)); 16975f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectGetName((PetscObject) fe, &name)); 16985f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectSetName((PetscObject) sub, name)); 16995f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEGetType(fe, &fetype)); 17005f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFESetType(sub, fetype)); 17015f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFESetBasisSpace(sub, subP)); 17025f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFESetDualSpace(sub, subQ)); 17035f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFESetNumComponents(sub, Nc)); 17045f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFESetUp(sub)); 17055f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFESetQuadrature(sub, subq)); 1706665f567fSMatthew G. Knepley } 170720cf1dd8SToby Isaac fe->subspaces[height-1] = sub; 170820cf1dd8SToby Isaac } 170920cf1dd8SToby Isaac *subfe = fe->subspaces[height-1]; 171020cf1dd8SToby Isaac } else { 171120cf1dd8SToby Isaac *subfe = NULL; 171220cf1dd8SToby Isaac } 171320cf1dd8SToby Isaac PetscFunctionReturn(0); 171420cf1dd8SToby Isaac } 171520cf1dd8SToby Isaac 171620cf1dd8SToby Isaac /*@ 171720cf1dd8SToby Isaac PetscFERefine - Create a "refined" PetscFE object that refines the reference cell into smaller copies. This is typically used 171820cf1dd8SToby Isaac to precondition a higher order method with a lower order method on a refined mesh having the same number of dofs (but more 171920cf1dd8SToby Isaac sparsity). It is also used to create an interpolation between regularly refined meshes. 172020cf1dd8SToby Isaac 1721d083f849SBarry Smith Collective on fem 172220cf1dd8SToby Isaac 172320cf1dd8SToby Isaac Input Parameter: 172420cf1dd8SToby Isaac . fe - The initial PetscFE 172520cf1dd8SToby Isaac 172620cf1dd8SToby Isaac Output Parameter: 172720cf1dd8SToby Isaac . feRef - The refined PetscFE 172820cf1dd8SToby Isaac 17292b99622eSMatthew G. Knepley Level: advanced 173020cf1dd8SToby Isaac 173120cf1dd8SToby Isaac .seealso: PetscFEType, PetscFECreate(), PetscFESetType() 173220cf1dd8SToby Isaac @*/ 173320cf1dd8SToby Isaac PetscErrorCode PetscFERefine(PetscFE fe, PetscFE *feRef) 173420cf1dd8SToby Isaac { 173520cf1dd8SToby Isaac PetscSpace P, Pref; 173620cf1dd8SToby Isaac PetscDualSpace Q, Qref; 173720cf1dd8SToby Isaac DM K, Kref; 173820cf1dd8SToby Isaac PetscQuadrature q, qref; 173920cf1dd8SToby Isaac const PetscReal *v0, *jac; 174020cf1dd8SToby Isaac PetscInt numComp, numSubelements; 17411ac17e89SToby Isaac PetscInt cStart, cEnd, c; 17421ac17e89SToby Isaac PetscDualSpace *cellSpaces; 174320cf1dd8SToby Isaac 174420cf1dd8SToby Isaac PetscFunctionBegin; 17455f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEGetBasisSpace(fe, &P)); 17465f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEGetDualSpace(fe, &Q)); 17475f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEGetQuadrature(fe, &q)); 17485f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceGetDM(Q, &K)); 174920cf1dd8SToby Isaac /* Create space */ 17505f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectReference((PetscObject) P)); 175120cf1dd8SToby Isaac Pref = P; 175220cf1dd8SToby Isaac /* Create dual space */ 17535f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceDuplicate(Q, &Qref)); 17545f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceSetType(Qref, PETSCDUALSPACEREFINED)); 17555f80ce2aSJacob Faibussowitsch CHKERRQ(DMRefine(K, PetscObjectComm((PetscObject) fe), &Kref)); 17565f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceSetDM(Qref, Kref)); 17575f80ce2aSJacob Faibussowitsch CHKERRQ(DMPlexGetHeightStratum(Kref, 0, &cStart, &cEnd)); 17585f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(cEnd - cStart, &cellSpaces)); 17591ac17e89SToby Isaac /* TODO: fix for non-uniform refinement */ 17601ac17e89SToby Isaac for (c = 0; c < cEnd - cStart; c++) cellSpaces[c] = Q; 17615f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceRefinedSetCellSpaces(Qref, cellSpaces)); 17625f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(cellSpaces)); 17635f80ce2aSJacob Faibussowitsch CHKERRQ(DMDestroy(&Kref)); 17645f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceSetUp(Qref)); 176520cf1dd8SToby Isaac /* Create element */ 17665f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFECreate(PetscObjectComm((PetscObject) fe), feRef)); 17675f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFESetType(*feRef, PETSCFECOMPOSITE)); 17685f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFESetBasisSpace(*feRef, Pref)); 17695f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFESetDualSpace(*feRef, Qref)); 17705f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEGetNumComponents(fe, &numComp)); 17715f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFESetNumComponents(*feRef, numComp)); 17725f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFESetUp(*feRef)); 17735f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceDestroy(&Pref)); 17745f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceDestroy(&Qref)); 177520cf1dd8SToby Isaac /* Create quadrature */ 17765f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFECompositeGetMapping(*feRef, &numSubelements, &v0, &jac, NULL)); 17775f80ce2aSJacob Faibussowitsch CHKERRQ(PetscQuadratureExpandComposite(q, numSubelements, v0, jac, &qref)); 17785f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFESetQuadrature(*feRef, qref)); 17795f80ce2aSJacob Faibussowitsch CHKERRQ(PetscQuadratureDestroy(&qref)); 178020cf1dd8SToby Isaac PetscFunctionReturn(0); 178120cf1dd8SToby Isaac } 178220cf1dd8SToby Isaac 17832df84da0SMatthew G. Knepley static PetscErrorCode PetscFECreate_Internal(MPI_Comm comm, PetscInt dim, PetscInt Nc, DMPolytopeType ct, const char prefix[], PetscInt degree, PetscInt qorder, PetscBool setFromOptions, PetscFE *fem) 17842df84da0SMatthew G. Knepley { 17852df84da0SMatthew G. Knepley PetscQuadrature q, fq; 17862df84da0SMatthew G. Knepley DM K; 17872df84da0SMatthew G. Knepley PetscSpace P; 17882df84da0SMatthew G. Knepley PetscDualSpace Q; 17892df84da0SMatthew G. Knepley PetscInt quadPointsPerEdge; 17902df84da0SMatthew G. Knepley PetscBool tensor; 17912df84da0SMatthew G. Knepley char name[64]; 17922df84da0SMatthew G. Knepley PetscErrorCode ierr; 17932df84da0SMatthew G. Knepley 17942df84da0SMatthew G. Knepley PetscFunctionBegin; 17952df84da0SMatthew G. Knepley if (prefix) PetscValidCharPointer(prefix, 5); 17962df84da0SMatthew G. Knepley PetscValidPointer(fem, 9); 17972df84da0SMatthew G. Knepley switch (ct) { 17982df84da0SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 17992df84da0SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: 18002df84da0SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 18012df84da0SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 18022df84da0SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 18032df84da0SMatthew G. Knepley case DM_POLYTOPE_QUAD_PRISM_TENSOR: 18042df84da0SMatthew G. Knepley tensor = PETSC_TRUE; 18052df84da0SMatthew G. Knepley break; 18062df84da0SMatthew G. Knepley default: tensor = PETSC_FALSE; 18072df84da0SMatthew G. Knepley } 18082df84da0SMatthew G. Knepley /* Create space */ 18095f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceCreate(comm, &P)); 18105f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceSetType(P, PETSCSPACEPOLYNOMIAL)); 18115f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectSetOptionsPrefix((PetscObject) P, prefix)); 18125f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpacePolynomialSetTensor(P, tensor)); 18135f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceSetNumComponents(P, Nc)); 18145f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceSetNumVariables(P, dim)); 18152df84da0SMatthew G. Knepley if (degree >= 0) { 18165f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceSetDegree(P, degree, PETSC_DETERMINE)); 1817cfd33b42SLisandro Dalcin if (ct == DM_POLYTOPE_TRI_PRISM || ct == DM_POLYTOPE_TRI_PRISM_TENSOR) { 18182df84da0SMatthew G. Knepley PetscSpace Pend, Pside; 18192df84da0SMatthew G. Knepley 18205f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceCreate(comm, &Pend)); 18215f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceSetType(Pend, PETSCSPACEPOLYNOMIAL)); 18225f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpacePolynomialSetTensor(Pend, PETSC_FALSE)); 18235f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceSetNumComponents(Pend, Nc)); 18245f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceSetNumVariables(Pend, dim-1)); 18255f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceSetDegree(Pend, degree, PETSC_DETERMINE)); 18265f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceCreate(comm, &Pside)); 18275f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceSetType(Pside, PETSCSPACEPOLYNOMIAL)); 18285f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpacePolynomialSetTensor(Pside, PETSC_FALSE)); 18295f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceSetNumComponents(Pside, 1)); 18305f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceSetNumVariables(Pside, 1)); 18315f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceSetDegree(Pside, degree, PETSC_DETERMINE)); 18325f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceSetType(P, PETSCSPACETENSOR)); 18335f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceTensorSetNumSubspaces(P, 2)); 18345f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceTensorSetSubspace(P, 0, Pend)); 18355f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceTensorSetSubspace(P, 1, Pside)); 18365f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceDestroy(&Pend)); 18375f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceDestroy(&Pside)); 18382df84da0SMatthew G. Knepley } 18392df84da0SMatthew G. Knepley } 18405f80ce2aSJacob Faibussowitsch if (setFromOptions) CHKERRQ(PetscSpaceSetFromOptions(P)); 18415f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceSetUp(P)); 18425f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceGetDegree(P, °ree, NULL)); 18435f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpacePolynomialGetTensor(P, &tensor)); 18445f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceGetNumComponents(P, &Nc)); 18452df84da0SMatthew G. Knepley /* Create dual space */ 18465f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceCreate(comm, &Q)); 18475f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceSetType(Q,PETSCDUALSPACELAGRANGE)); 18485f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectSetOptionsPrefix((PetscObject) Q, prefix)); 18495f80ce2aSJacob Faibussowitsch CHKERRQ(DMPlexCreateReferenceCell(PETSC_COMM_SELF, ct, &K)); 18505f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceSetDM(Q, K)); 18515f80ce2aSJacob Faibussowitsch CHKERRQ(DMDestroy(&K)); 18525f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceSetNumComponents(Q, Nc)); 18535f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceSetOrder(Q, degree)); 18542df84da0SMatthew G. Knepley /* TODO For some reason, we need a tensor dualspace with wedges */ 18555f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceLagrangeSetTensor(Q, (tensor || (ct == DM_POLYTOPE_TRI_PRISM)) ? PETSC_TRUE : PETSC_FALSE)); 18565f80ce2aSJacob Faibussowitsch if (setFromOptions) CHKERRQ(PetscDualSpaceSetFromOptions(Q)); 18575f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceSetUp(Q)); 18582df84da0SMatthew G. Knepley /* Create finite element */ 18595f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFECreate(comm, fem)); 18605f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectSetOptionsPrefix((PetscObject) *fem, prefix)); 18615f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFESetType(*fem, PETSCFEBASIC)); 18625f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFESetBasisSpace(*fem, P)); 18635f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFESetDualSpace(*fem, Q)); 18645f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFESetNumComponents(*fem, Nc)); 18655f80ce2aSJacob Faibussowitsch if (setFromOptions) CHKERRQ(PetscFESetFromOptions(*fem)); 18665f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFESetUp(*fem)); 18675f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceDestroy(&P)); 18685f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceDestroy(&Q)); 18692df84da0SMatthew G. Knepley /* Create quadrature (with specified order if given) */ 18702df84da0SMatthew G. Knepley qorder = qorder >= 0 ? qorder : degree; 18712df84da0SMatthew G. Knepley if (setFromOptions) { 18722df84da0SMatthew G. Knepley ierr = PetscObjectOptionsBegin((PetscObject)*fem);CHKERRQ(ierr); 18735f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsBoundedInt("-petscfe_default_quadrature_order","Quadrature order is one less than quadrature points per edge","PetscFECreateDefault",qorder,&qorder,NULL,0)); 18742df84da0SMatthew G. Knepley ierr = PetscOptionsEnd();CHKERRQ(ierr); 18752df84da0SMatthew G. Knepley } 18762df84da0SMatthew G. Knepley quadPointsPerEdge = PetscMax(qorder + 1,1); 18772df84da0SMatthew G. Knepley switch (ct) { 18782df84da0SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 18792df84da0SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: 18802df84da0SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 18812df84da0SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 18822df84da0SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 18832df84da0SMatthew G. Knepley case DM_POLYTOPE_QUAD_PRISM_TENSOR: 18845f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDTGaussTensorQuadrature(dim, 1, quadPointsPerEdge, -1.0, 1.0, &q)); 18855f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDTGaussTensorQuadrature(dim-1, 1, quadPointsPerEdge, -1.0, 1.0, &fq)); 18862df84da0SMatthew G. Knepley break; 18872df84da0SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 18882df84da0SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: 18895f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDTStroudConicalQuadrature(dim, 1, quadPointsPerEdge, -1.0, 1.0, &q)); 18905f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDTStroudConicalQuadrature(dim-1, 1, quadPointsPerEdge, -1.0, 1.0, &fq)); 18912df84da0SMatthew G. Knepley break; 18922df84da0SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM: 18932df84da0SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: 18942df84da0SMatthew G. Knepley { 18952df84da0SMatthew G. Knepley PetscQuadrature q1, q2; 18962df84da0SMatthew G. Knepley 18975f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDTStroudConicalQuadrature(2, 1, quadPointsPerEdge, -1.0, 1.0, &q1)); 18985f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDTGaussTensorQuadrature(1, 1, quadPointsPerEdge, -1.0, 1.0, &q2)); 18995f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDTTensorQuadratureCreate(q1, q2, &q)); 19005f80ce2aSJacob Faibussowitsch CHKERRQ(PetscQuadratureDestroy(&q1)); 19015f80ce2aSJacob Faibussowitsch CHKERRQ(PetscQuadratureDestroy(&q2)); 19022df84da0SMatthew G. Knepley } 19035f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDTStroudConicalQuadrature(dim-1, 1, quadPointsPerEdge, -1.0, 1.0, &fq)); 19042df84da0SMatthew G. Knepley /* TODO Need separate quadratures for each face */ 19052df84da0SMatthew G. Knepley break; 19062df84da0SMatthew G. Knepley default: SETERRQ(comm, PETSC_ERR_ARG_OUTOFRANGE, "No quadrature for celltype %s", DMPolytopeTypes[PetscMin(ct, DM_POLYTOPE_UNKNOWN)]); 19072df84da0SMatthew G. Knepley } 19085f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFESetQuadrature(*fem, q)); 19095f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFESetFaceQuadrature(*fem, fq)); 19105f80ce2aSJacob Faibussowitsch CHKERRQ(PetscQuadratureDestroy(&q)); 19115f80ce2aSJacob Faibussowitsch CHKERRQ(PetscQuadratureDestroy(&fq)); 19122df84da0SMatthew G. Knepley /* Set finite element name */ 19132df84da0SMatthew G. Knepley switch (ct) { 19142df84da0SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 19152df84da0SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: 19162df84da0SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 19172df84da0SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 19182df84da0SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 19192df84da0SMatthew G. Knepley case DM_POLYTOPE_QUAD_PRISM_TENSOR: 19205f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSNPrintf(name, sizeof(name), "Q%" PetscInt_FMT, degree)); 19212df84da0SMatthew G. Knepley break; 19222df84da0SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 19232df84da0SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: 19245f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSNPrintf(name, sizeof(name), "P%" PetscInt_FMT, degree)); 19252df84da0SMatthew G. Knepley break; 19262df84da0SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM: 19272df84da0SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: 19285f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSNPrintf(name, sizeof(name), "P%" PetscInt_FMT "xQ%" PetscInt_FMT, degree, degree)); 19292df84da0SMatthew G. Knepley break; 19302df84da0SMatthew G. Knepley default: 19315f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSNPrintf(name, sizeof(name), "FE")); 19322df84da0SMatthew G. Knepley } 19335f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFESetName(*fem, name)); 19342df84da0SMatthew G. Knepley PetscFunctionReturn(0); 19352df84da0SMatthew G. Knepley } 19362df84da0SMatthew G. Knepley 193720cf1dd8SToby Isaac /*@C 193820cf1dd8SToby Isaac PetscFECreateDefault - Create a PetscFE for basic FEM computation 193920cf1dd8SToby Isaac 1940d083f849SBarry Smith Collective 194120cf1dd8SToby Isaac 194220cf1dd8SToby Isaac Input Parameters: 19437be5e748SToby Isaac + comm - The MPI comm 194420cf1dd8SToby Isaac . dim - The spatial dimension 194520cf1dd8SToby Isaac . Nc - The number of components 194620cf1dd8SToby Isaac . isSimplex - Flag for simplex reference cell, otherwise its a tensor product 194720cf1dd8SToby Isaac . prefix - The options prefix, or NULL 1948727cddd5SJacob Faibussowitsch - qorder - The quadrature order or PETSC_DETERMINE to use PetscSpace polynomial degree 194920cf1dd8SToby Isaac 195020cf1dd8SToby Isaac Output Parameter: 195120cf1dd8SToby Isaac . fem - The PetscFE object 195220cf1dd8SToby Isaac 1953e703855dSMatthew G. Knepley Note: 19548f2aacc6SMatthew 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. 1955e703855dSMatthew G. Knepley 195620cf1dd8SToby Isaac Level: beginner 195720cf1dd8SToby Isaac 19582df84da0SMatthew G. Knepley .seealso: PetscFECreateLagrange(), PetscFECreateByCell(), PetscSpaceSetFromOptions(), PetscDualSpaceSetFromOptions(), PetscFESetFromOptions(), PetscFECreate(), PetscSpaceCreate(), PetscDualSpaceCreate() 195920cf1dd8SToby Isaac @*/ 19607be5e748SToby Isaac PetscErrorCode PetscFECreateDefault(MPI_Comm comm, PetscInt dim, PetscInt Nc, PetscBool isSimplex, const char prefix[], PetscInt qorder, PetscFE *fem) 196120cf1dd8SToby Isaac { 196220cf1dd8SToby Isaac PetscFunctionBegin; 19635f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFECreate_Internal(comm, dim, Nc, DMPolytopeTypeSimpleShape(dim, isSimplex), prefix, PETSC_DECIDE, qorder, PETSC_TRUE, fem)); 19642df84da0SMatthew G. Knepley PetscFunctionReturn(0); 196520cf1dd8SToby Isaac } 19662df84da0SMatthew G. Knepley 19672df84da0SMatthew G. Knepley /*@C 19682df84da0SMatthew G. Knepley PetscFECreateByCell - Create a PetscFE for basic FEM computation 19692df84da0SMatthew G. Knepley 19702df84da0SMatthew G. Knepley Collective 19712df84da0SMatthew G. Knepley 19722df84da0SMatthew G. Knepley Input Parameters: 19732df84da0SMatthew G. Knepley + comm - The MPI comm 19742df84da0SMatthew G. Knepley . dim - The spatial dimension 19752df84da0SMatthew G. Knepley . Nc - The number of components 19762df84da0SMatthew G. Knepley . ct - The celltype of the reference cell 19772df84da0SMatthew G. Knepley . prefix - The options prefix, or NULL 19782df84da0SMatthew G. Knepley - qorder - The quadrature order or PETSC_DETERMINE to use PetscSpace polynomial degree 19792df84da0SMatthew G. Knepley 19802df84da0SMatthew G. Knepley Output Parameter: 19812df84da0SMatthew G. Knepley . fem - The PetscFE object 19822df84da0SMatthew G. Knepley 19832df84da0SMatthew G. Knepley Note: 19842df84da0SMatthew 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. 19852df84da0SMatthew G. Knepley 19862df84da0SMatthew G. Knepley Level: beginner 19872df84da0SMatthew G. Knepley 19882df84da0SMatthew G. Knepley .seealso: PetscFECreateDefault(), PetscFECreateLagrange(), PetscSpaceSetFromOptions(), PetscDualSpaceSetFromOptions(), PetscFESetFromOptions(), PetscFECreate(), PetscSpaceCreate(), PetscDualSpaceCreate() 19892df84da0SMatthew G. Knepley @*/ 19902df84da0SMatthew G. Knepley PetscErrorCode PetscFECreateByCell(MPI_Comm comm, PetscInt dim, PetscInt Nc, DMPolytopeType ct, const char prefix[], PetscInt qorder, PetscFE *fem) 19912df84da0SMatthew G. Knepley { 19922df84da0SMatthew G. Knepley PetscFunctionBegin; 19935f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFECreate_Internal(comm, dim, Nc, ct, prefix, PETSC_DECIDE, qorder, PETSC_TRUE, fem)); 199420cf1dd8SToby Isaac PetscFunctionReturn(0); 199520cf1dd8SToby Isaac } 19963f6b16c7SMatthew G. Knepley 1997e703855dSMatthew G. Knepley /*@ 1998e703855dSMatthew G. Knepley PetscFECreateLagrange - Create a PetscFE for the basic Lagrange space of degree k 1999e703855dSMatthew G. Knepley 2000e703855dSMatthew G. Knepley Collective 2001e703855dSMatthew G. Knepley 2002e703855dSMatthew G. Knepley Input Parameters: 2003e703855dSMatthew G. Knepley + comm - The MPI comm 2004e703855dSMatthew G. Knepley . dim - The spatial dimension 2005e703855dSMatthew G. Knepley . Nc - The number of components 2006e703855dSMatthew G. Knepley . isSimplex - Flag for simplex reference cell, otherwise its a tensor product 2007e703855dSMatthew G. Knepley . k - The degree k of the space 2008e703855dSMatthew G. Knepley - qorder - The quadrature order or PETSC_DETERMINE to use PetscSpace polynomial degree 2009e703855dSMatthew G. Knepley 2010e703855dSMatthew G. Knepley Output Parameter: 2011e703855dSMatthew G. Knepley . fem - The PetscFE object 2012e703855dSMatthew G. Knepley 2013e703855dSMatthew G. Knepley Level: beginner 2014e703855dSMatthew G. Knepley 2015e703855dSMatthew G. Knepley Notes: 2016e703855dSMatthew 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. 2017e703855dSMatthew G. Knepley 20182df84da0SMatthew G. Knepley .seealso: PetscFECreateLagrangeByCell(), PetscFECreateDefault(), PetscFECreateByCell(), PetscFECreate(), PetscSpaceCreate(), PetscDualSpaceCreate() 2019e703855dSMatthew G. Knepley @*/ 2020e703855dSMatthew G. Knepley PetscErrorCode PetscFECreateLagrange(MPI_Comm comm, PetscInt dim, PetscInt Nc, PetscBool isSimplex, PetscInt k, PetscInt qorder, PetscFE *fem) 2021e703855dSMatthew G. Knepley { 2022e703855dSMatthew G. Knepley PetscFunctionBegin; 20235f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFECreate_Internal(comm, dim, Nc, DMPolytopeTypeSimpleShape(dim, isSimplex), NULL, k, qorder, PETSC_FALSE, fem)); 20242df84da0SMatthew G. Knepley PetscFunctionReturn(0); 2025e703855dSMatthew G. Knepley } 20262df84da0SMatthew G. Knepley 20272df84da0SMatthew G. Knepley /*@ 20282df84da0SMatthew G. Knepley PetscFECreateLagrangeByCell - Create a PetscFE for the basic Lagrange space of degree k 20292df84da0SMatthew G. Knepley 20302df84da0SMatthew G. Knepley Collective 20312df84da0SMatthew G. Knepley 20322df84da0SMatthew G. Knepley Input Parameters: 20332df84da0SMatthew G. Knepley + comm - The MPI comm 20342df84da0SMatthew G. Knepley . dim - The spatial dimension 20352df84da0SMatthew G. Knepley . Nc - The number of components 20362df84da0SMatthew G. Knepley . ct - The celltype of the reference cell 20372df84da0SMatthew G. Knepley . k - The degree k of the space 20382df84da0SMatthew G. Knepley - qorder - The quadrature order or PETSC_DETERMINE to use PetscSpace polynomial degree 20392df84da0SMatthew G. Knepley 20402df84da0SMatthew G. Knepley Output Parameter: 20412df84da0SMatthew G. Knepley . fem - The PetscFE object 20422df84da0SMatthew G. Knepley 20432df84da0SMatthew G. Knepley Level: beginner 20442df84da0SMatthew G. Knepley 20452df84da0SMatthew G. Knepley Notes: 20462df84da0SMatthew 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. 20472df84da0SMatthew G. Knepley 20482df84da0SMatthew G. Knepley .seealso: PetscFECreateLagrange(), PetscFECreateDefault(), PetscFECreateByCell(), PetscFECreate(), PetscSpaceCreate(), PetscDualSpaceCreate() 20492df84da0SMatthew G. Knepley @*/ 20502df84da0SMatthew G. Knepley PetscErrorCode PetscFECreateLagrangeByCell(MPI_Comm comm, PetscInt dim, PetscInt Nc, DMPolytopeType ct, PetscInt k, PetscInt qorder, PetscFE *fem) 20512df84da0SMatthew G. Knepley { 20522df84da0SMatthew G. Knepley PetscFunctionBegin; 20535f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFECreate_Internal(comm, dim, Nc, ct, NULL, k, qorder, PETSC_FALSE, fem)); 2054e703855dSMatthew G. Knepley PetscFunctionReturn(0); 2055e703855dSMatthew G. Knepley } 2056e703855dSMatthew G. Knepley 20573f6b16c7SMatthew G. Knepley /*@C 20583f6b16c7SMatthew G. Knepley PetscFESetName - Names the FE and its subobjects 20593f6b16c7SMatthew G. Knepley 20603f6b16c7SMatthew G. Knepley Not collective 20613f6b16c7SMatthew G. Knepley 20623f6b16c7SMatthew G. Knepley Input Parameters: 20633f6b16c7SMatthew G. Knepley + fe - The PetscFE 20643f6b16c7SMatthew G. Knepley - name - The name 20653f6b16c7SMatthew G. Knepley 20662b99622eSMatthew G. Knepley Level: intermediate 20673f6b16c7SMatthew G. Knepley 20683f6b16c7SMatthew G. Knepley .seealso: PetscFECreate(), PetscSpaceCreate(), PetscDualSpaceCreate() 20693f6b16c7SMatthew G. Knepley @*/ 20703f6b16c7SMatthew G. Knepley PetscErrorCode PetscFESetName(PetscFE fe, const char name[]) 20713f6b16c7SMatthew G. Knepley { 20723f6b16c7SMatthew G. Knepley PetscSpace P; 20733f6b16c7SMatthew G. Knepley PetscDualSpace Q; 20743f6b16c7SMatthew G. Knepley 20753f6b16c7SMatthew G. Knepley PetscFunctionBegin; 20765f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEGetBasisSpace(fe, &P)); 20775f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEGetDualSpace(fe, &Q)); 20785f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectSetName((PetscObject) fe, name)); 20795f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectSetName((PetscObject) P, name)); 20805f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectSetName((PetscObject) Q, name)); 20813f6b16c7SMatthew G. Knepley PetscFunctionReturn(0); 20823f6b16c7SMatthew G. Knepley } 2083a8f1f9e5SMatthew G. Knepley 2084ef0bb6c7SMatthew G. Knepley 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[]) 2085a8f1f9e5SMatthew G. Knepley { 2086f9244615SMatthew G. Knepley PetscInt dOffset = 0, fOffset = 0, f, g; 2087a8f1f9e5SMatthew G. Knepley 2088a8f1f9e5SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 2089a8f1f9e5SMatthew G. Knepley PetscFE fe; 2090f9244615SMatthew G. Knepley const PetscInt k = ds->jetDegree[f]; 2091ef0bb6c7SMatthew G. Knepley const PetscInt cdim = T[f]->cdim; 2092ef0bb6c7SMatthew G. Knepley const PetscInt Nq = T[f]->Np; 2093ef0bb6c7SMatthew G. Knepley const PetscInt Nbf = T[f]->Nb; 2094ef0bb6c7SMatthew G. Knepley const PetscInt Ncf = T[f]->Nc; 2095ef0bb6c7SMatthew G. Knepley const PetscReal *Bq = &T[f]->T[0][(r*Nq+q)*Nbf*Ncf]; 2096ef0bb6c7SMatthew G. Knepley const PetscReal *Dq = &T[f]->T[1][(r*Nq+q)*Nbf*Ncf*cdim]; 2097f9244615SMatthew G. Knepley const PetscReal *Hq = k > 1 ? &T[f]->T[2][(r*Nq+q)*Nbf*Ncf*cdim*cdim] : NULL; 2098f9244615SMatthew G. Knepley PetscInt hOffset = 0, b, c, d; 2099a8f1f9e5SMatthew G. Knepley 21005f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetDiscretization(ds, f, (PetscObject *) &fe)); 2101a8f1f9e5SMatthew G. Knepley for (c = 0; c < Ncf; ++c) u[fOffset+c] = 0.0; 2102ef0bb6c7SMatthew G. Knepley for (d = 0; d < cdim*Ncf; ++d) u_x[fOffset*cdim+d] = 0.0; 2103a8f1f9e5SMatthew G. Knepley for (b = 0; b < Nbf; ++b) { 2104a8f1f9e5SMatthew G. Knepley for (c = 0; c < Ncf; ++c) { 2105a8f1f9e5SMatthew G. Knepley const PetscInt cidx = b*Ncf+c; 2106a8f1f9e5SMatthew G. Knepley 2107a8f1f9e5SMatthew G. Knepley u[fOffset+c] += Bq[cidx]*coefficients[dOffset+b]; 2108ef0bb6c7SMatthew G. Knepley for (d = 0; d < cdim; ++d) u_x[(fOffset+c)*cdim+d] += Dq[cidx*cdim+d]*coefficients[dOffset+b]; 2109a8f1f9e5SMatthew G. Knepley } 2110a8f1f9e5SMatthew G. Knepley } 2111f9244615SMatthew G. Knepley if (k > 1) { 2112f9244615SMatthew G. Knepley for (g = 0; g < Nf; ++g) hOffset += T[g]->Nc*cdim; 2113f9244615SMatthew G. Knepley for (d = 0; d < cdim*cdim*Ncf; ++d) u_x[hOffset+fOffset*cdim*cdim+d] = 0.0; 2114f9244615SMatthew G. Knepley for (b = 0; b < Nbf; ++b) { 2115f9244615SMatthew G. Knepley for (c = 0; c < Ncf; ++c) { 2116f9244615SMatthew G. Knepley const PetscInt cidx = b*Ncf+c; 2117f9244615SMatthew G. Knepley 2118f9244615SMatthew G. Knepley for (d = 0; d < cdim*cdim; ++d) u_x[hOffset+(fOffset+c)*cdim*cdim+d] += Hq[cidx*cdim*cdim+d]*coefficients[dOffset+b]; 2119f9244615SMatthew G. Knepley } 2120f9244615SMatthew G. Knepley } 21215f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEPushforwardHessian(fe, fegeom, 1, &u_x[hOffset+fOffset*cdim*cdim])); 2122f9244615SMatthew G. Knepley } 21235f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEPushforward(fe, fegeom, 1, &u[fOffset])); 21245f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEPushforwardGradient(fe, fegeom, 1, &u_x[fOffset*cdim])); 2125a8f1f9e5SMatthew G. Knepley if (u_t) { 2126a8f1f9e5SMatthew G. Knepley for (c = 0; c < Ncf; ++c) u_t[fOffset+c] = 0.0; 2127a8f1f9e5SMatthew G. Knepley for (b = 0; b < Nbf; ++b) { 2128a8f1f9e5SMatthew G. Knepley for (c = 0; c < Ncf; ++c) { 2129a8f1f9e5SMatthew G. Knepley const PetscInt cidx = b*Ncf+c; 2130a8f1f9e5SMatthew G. Knepley 2131a8f1f9e5SMatthew G. Knepley u_t[fOffset+c] += Bq[cidx]*coefficients_t[dOffset+b]; 2132a8f1f9e5SMatthew G. Knepley } 2133a8f1f9e5SMatthew G. Knepley } 21345f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEPushforward(fe, fegeom, 1, &u_t[fOffset])); 2135a8f1f9e5SMatthew G. Knepley } 2136a8f1f9e5SMatthew G. Knepley fOffset += Ncf; 2137a8f1f9e5SMatthew G. Knepley dOffset += Nbf; 2138a8f1f9e5SMatthew G. Knepley } 2139a8f1f9e5SMatthew G. Knepley return 0; 2140a8f1f9e5SMatthew G. Knepley } 2141a8f1f9e5SMatthew G. Knepley 2142665f567fSMatthew G. Knepley PetscErrorCode PetscFEEvaluateFieldJets_Hybrid_Internal(PetscDS ds, PetscInt Nf, PetscInt r, PetscInt q, PetscTabulation T[], PetscFEGeom *fegeom, const PetscScalar coefficients[], const PetscScalar coefficients_t[], PetscScalar u[], PetscScalar u_x[], PetscScalar u_t[]) 214327f02ce8SMatthew G. Knepley { 21445fedec97SMatthew G. Knepley PetscInt dOffset = 0, fOffset = 0, f, g; 214527f02ce8SMatthew G. Knepley 21465fedec97SMatthew G. Knepley /* f is the field number in the DS, g is the field number in u[] */ 21475fedec97SMatthew G. Knepley for (f = 0, g = 0; f < Nf; ++f) { 21485fedec97SMatthew G. Knepley PetscFE fe = (PetscFE) ds->disc[f]; 21499ee2af8cSMatthew G. Knepley const PetscInt dEt = T[f]->cdim; 21509ee2af8cSMatthew G. Knepley const PetscInt dE = fegeom->dimEmbed; 2151665f567fSMatthew G. Knepley const PetscInt Nq = T[f]->Np; 2152665f567fSMatthew G. Knepley const PetscInt Nbf = T[f]->Nb; 2153665f567fSMatthew G. Knepley const PetscInt Ncf = T[f]->Nc; 2154665f567fSMatthew G. Knepley const PetscReal *Bq = &T[f]->T[0][(r*Nq+q)*Nbf*Ncf]; 21559ee2af8cSMatthew G. Knepley const PetscReal *Dq = &T[f]->T[1][(r*Nq+q)*Nbf*Ncf*dEt]; 21565fedec97SMatthew G. Knepley PetscBool isCohesive; 21575fedec97SMatthew G. Knepley PetscInt Ns, s; 21585fedec97SMatthew G. Knepley 21595fedec97SMatthew G. Knepley if (!T[f]) continue; 21605f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetCohesive(ds, f, &isCohesive)); 21615fedec97SMatthew G. Knepley Ns = isCohesive ? 1 : 2; 21625fedec97SMatthew G. Knepley for (s = 0; s < Ns; ++s, ++g) { 216327f02ce8SMatthew G. Knepley PetscInt b, c, d; 216427f02ce8SMatthew G. Knepley 216527f02ce8SMatthew G. Knepley for (c = 0; c < Ncf; ++c) u[fOffset+c] = 0.0; 21669ee2af8cSMatthew G. Knepley for (d = 0; d < dE*Ncf; ++d) u_x[fOffset*dE+d] = 0.0; 216727f02ce8SMatthew G. Knepley for (b = 0; b < Nbf; ++b) { 216827f02ce8SMatthew G. Knepley for (c = 0; c < Ncf; ++c) { 216927f02ce8SMatthew G. Knepley const PetscInt cidx = b*Ncf+c; 217027f02ce8SMatthew G. Knepley 217127f02ce8SMatthew G. Knepley u[fOffset+c] += Bq[cidx]*coefficients[dOffset+b]; 21729ee2af8cSMatthew G. Knepley for (d = 0; d < dEt; ++d) u_x[(fOffset+c)*dE+d] += Dq[cidx*dEt+d]*coefficients[dOffset+b]; 217327f02ce8SMatthew G. Knepley } 217427f02ce8SMatthew G. Knepley } 21755f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEPushforward(fe, fegeom, 1, &u[fOffset])); 21765f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEPushforwardGradient(fe, fegeom, 1, &u_x[fOffset*dE])); 217727f02ce8SMatthew G. Knepley if (u_t) { 217827f02ce8SMatthew G. Knepley for (c = 0; c < Ncf; ++c) u_t[fOffset+c] = 0.0; 217927f02ce8SMatthew G. Knepley for (b = 0; b < Nbf; ++b) { 218027f02ce8SMatthew G. Knepley for (c = 0; c < Ncf; ++c) { 218127f02ce8SMatthew G. Knepley const PetscInt cidx = b*Ncf+c; 218227f02ce8SMatthew G. Knepley 218327f02ce8SMatthew G. Knepley u_t[fOffset+c] += Bq[cidx]*coefficients_t[dOffset+b]; 218427f02ce8SMatthew G. Knepley } 218527f02ce8SMatthew G. Knepley } 21865f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEPushforward(fe, fegeom, 1, &u_t[fOffset])); 218727f02ce8SMatthew G. Knepley } 218827f02ce8SMatthew G. Knepley fOffset += Ncf; 218927f02ce8SMatthew G. Knepley dOffset += Nbf; 219027f02ce8SMatthew G. Knepley } 2191665f567fSMatthew G. Knepley } 219227f02ce8SMatthew G. Knepley return 0; 219327f02ce8SMatthew G. Knepley } 219427f02ce8SMatthew G. Knepley 2195a8f1f9e5SMatthew G. Knepley PetscErrorCode PetscFEEvaluateFaceFields_Internal(PetscDS prob, PetscInt field, PetscInt faceLoc, const PetscScalar coefficients[], PetscScalar u[]) 2196a8f1f9e5SMatthew G. Knepley { 2197a8f1f9e5SMatthew G. Knepley PetscFE fe; 2198ef0bb6c7SMatthew G. Knepley PetscTabulation Tc; 2199ef0bb6c7SMatthew G. Knepley PetscInt b, c; 2200a8f1f9e5SMatthew G. Knepley 2201a8f1f9e5SMatthew G. Knepley if (!prob) return 0; 22025f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetDiscretization(prob, field, (PetscObject *) &fe)); 22035f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEGetFaceCentroidTabulation(fe, &Tc)); 2204ef0bb6c7SMatthew G. Knepley { 2205ef0bb6c7SMatthew G. Knepley const PetscReal *faceBasis = Tc->T[0]; 2206ef0bb6c7SMatthew G. Knepley const PetscInt Nb = Tc->Nb; 2207ef0bb6c7SMatthew G. Knepley const PetscInt Nc = Tc->Nc; 2208ef0bb6c7SMatthew G. Knepley 2209a8f1f9e5SMatthew G. Knepley for (c = 0; c < Nc; ++c) {u[c] = 0.0;} 2210a8f1f9e5SMatthew G. Knepley for (b = 0; b < Nb; ++b) { 2211a8f1f9e5SMatthew G. Knepley for (c = 0; c < Nc; ++c) { 2212813a933aSJed Brown u[c] += coefficients[b] * faceBasis[(faceLoc*Nb + b)*Nc + c]; 2213a8f1f9e5SMatthew G. Knepley } 2214a8f1f9e5SMatthew G. Knepley } 2215ef0bb6c7SMatthew G. Knepley } 2216a8f1f9e5SMatthew G. Knepley return 0; 2217a8f1f9e5SMatthew G. Knepley } 2218a8f1f9e5SMatthew G. Knepley 22196587ee25SMatthew G. Knepley PetscErrorCode PetscFEUpdateElementVec_Internal(PetscFE fe, PetscTabulation T, PetscInt r, PetscScalar tmpBasis[], PetscScalar tmpBasisDer[], PetscInt e, PetscFEGeom *fegeom, PetscScalar f0[], PetscScalar f1[], PetscScalar elemVec[]) 2220a8f1f9e5SMatthew G. Knepley { 22216587ee25SMatthew G. Knepley PetscFEGeom pgeom; 2222bc3a64adSMatthew G. Knepley const PetscInt dEt = T->cdim; 2223bc3a64adSMatthew G. Knepley const PetscInt dE = fegeom->dimEmbed; 2224ef0bb6c7SMatthew G. Knepley const PetscInt Nq = T->Np; 2225ef0bb6c7SMatthew G. Knepley const PetscInt Nb = T->Nb; 2226ef0bb6c7SMatthew G. Knepley const PetscInt Nc = T->Nc; 2227ef0bb6c7SMatthew G. Knepley const PetscReal *basis = &T->T[0][r*Nq*Nb*Nc]; 2228bc3a64adSMatthew G. Knepley const PetscReal *basisDer = &T->T[1][r*Nq*Nb*Nc*dEt]; 2229a8f1f9e5SMatthew G. Knepley PetscInt q, b, c, d; 2230a8f1f9e5SMatthew G. Knepley 2231a8f1f9e5SMatthew G. Knepley for (q = 0; q < Nq; ++q) { 2232a8f1f9e5SMatthew G. Knepley for (b = 0; b < Nb; ++b) { 2233a8f1f9e5SMatthew G. Knepley for (c = 0; c < Nc; ++c) { 2234a8f1f9e5SMatthew G. Knepley const PetscInt bcidx = b*Nc+c; 2235a8f1f9e5SMatthew G. Knepley 2236a8f1f9e5SMatthew G. Knepley tmpBasis[bcidx] = basis[q*Nb*Nc+bcidx]; 2237bc3a64adSMatthew G. Knepley for (d = 0; d < dEt; ++d) tmpBasisDer[bcidx*dE+d] = basisDer[q*Nb*Nc*dEt+bcidx*dEt+d]; 22389ee2af8cSMatthew G. Knepley for (d = dEt; d < dE; ++d) tmpBasisDer[bcidx*dE+d] = 0.0; 2239a8f1f9e5SMatthew G. Knepley } 2240a8f1f9e5SMatthew G. Knepley } 22415f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEGeomGetCellPoint(fegeom, e, q, &pgeom)); 22425f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEPushforward(fe, &pgeom, Nb, tmpBasis)); 22435f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEPushforwardGradient(fe, &pgeom, Nb, tmpBasisDer)); 2244a8f1f9e5SMatthew G. Knepley for (b = 0; b < Nb; ++b) { 2245a8f1f9e5SMatthew G. Knepley for (c = 0; c < Nc; ++c) { 2246a8f1f9e5SMatthew G. Knepley const PetscInt bcidx = b*Nc+c; 2247a8f1f9e5SMatthew G. Knepley const PetscInt qcidx = q*Nc+c; 2248a8f1f9e5SMatthew G. Knepley 2249a8f1f9e5SMatthew G. Knepley elemVec[b] += tmpBasis[bcidx]*f0[qcidx]; 225027f02ce8SMatthew G. Knepley for (d = 0; d < dE; ++d) elemVec[b] += tmpBasisDer[bcidx*dE+d]*f1[qcidx*dE+d]; 225127f02ce8SMatthew G. Knepley } 225227f02ce8SMatthew G. Knepley } 225327f02ce8SMatthew G. Knepley } 225427f02ce8SMatthew G. Knepley return(0); 225527f02ce8SMatthew G. Knepley } 225627f02ce8SMatthew G. Knepley 2257c2b7495fSMatthew G. Knepley PetscErrorCode PetscFEUpdateElementVec_Hybrid_Internal(PetscFE fe, PetscTabulation T, PetscInt r, PetscInt s, PetscScalar tmpBasis[], PetscScalar tmpBasisDer[], PetscFEGeom *fegeom, PetscScalar f0[], PetscScalar f1[], PetscScalar elemVec[]) 225827f02ce8SMatthew G. Knepley { 225927f02ce8SMatthew G. Knepley const PetscInt dE = T->cdim; 226027f02ce8SMatthew G. Knepley const PetscInt Nq = T->Np; 226127f02ce8SMatthew G. Knepley const PetscInt Nb = T->Nb; 226227f02ce8SMatthew G. Knepley const PetscInt Nc = T->Nc; 226327f02ce8SMatthew G. Knepley const PetscReal *basis = &T->T[0][r*Nq*Nb*Nc]; 226427f02ce8SMatthew G. Knepley const PetscReal *basisDer = &T->T[1][r*Nq*Nb*Nc*dE]; 2265c2b7495fSMatthew G. Knepley PetscInt q, b, c, d; 226627f02ce8SMatthew G. Knepley 226727f02ce8SMatthew G. Knepley for (q = 0; q < Nq; ++q) { 226827f02ce8SMatthew G. Knepley for (b = 0; b < Nb; ++b) { 226927f02ce8SMatthew G. Knepley for (c = 0; c < Nc; ++c) { 227027f02ce8SMatthew G. Knepley const PetscInt bcidx = b*Nc+c; 227127f02ce8SMatthew G. Knepley 227227f02ce8SMatthew G. Knepley tmpBasis[bcidx] = basis[q*Nb*Nc+bcidx]; 227327f02ce8SMatthew G. Knepley for (d = 0; d < dE; ++d) tmpBasisDer[bcidx*dE+d] = basisDer[q*Nb*Nc*dE+bcidx*dE+d]; 227427f02ce8SMatthew G. Knepley } 227527f02ce8SMatthew G. Knepley } 22765f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEPushforward(fe, fegeom, Nb, tmpBasis)); 22775f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEPushforwardGradient(fe, fegeom, Nb, tmpBasisDer)); 227827f02ce8SMatthew G. Knepley for (b = 0; b < Nb; ++b) { 227927f02ce8SMatthew G. Knepley for (c = 0; c < Nc; ++c) { 228027f02ce8SMatthew G. Knepley const PetscInt bcidx = b*Nc+c; 2281c2b7495fSMatthew G. Knepley const PetscInt qcidx = q*Nc+c; 228227f02ce8SMatthew G. Knepley 228327f02ce8SMatthew G. Knepley elemVec[Nb*s+b] += tmpBasis[bcidx]*f0[qcidx]; 228427f02ce8SMatthew G. Knepley for (d = 0; d < dE; ++d) elemVec[Nb*s+b] += tmpBasisDer[bcidx*dE+d]*f1[qcidx*dE+d]; 228527f02ce8SMatthew G. Knepley } 2286a8f1f9e5SMatthew G. Knepley } 2287a8f1f9e5SMatthew G. Knepley } 2288a8f1f9e5SMatthew G. Knepley return(0); 2289a8f1f9e5SMatthew G. Knepley } 2290a8f1f9e5SMatthew G. Knepley 2291ef0bb6c7SMatthew G. Knepley PetscErrorCode PetscFEUpdateElementMat_Internal(PetscFE feI, PetscFE feJ, PetscInt r, PetscInt q, PetscTabulation TI, PetscScalar tmpBasisI[], PetscScalar tmpBasisDerI[], PetscTabulation TJ, PetscScalar tmpBasisJ[], PetscScalar tmpBasisDerJ[], PetscFEGeom *fegeom, const PetscScalar g0[], const PetscScalar g1[], const PetscScalar g2[], const PetscScalar g3[], PetscInt eOffset, PetscInt totDim, PetscInt offsetI, PetscInt offsetJ, PetscScalar elemMat[]) 2292a8f1f9e5SMatthew G. Knepley { 229327f02ce8SMatthew G. Knepley const PetscInt dE = TI->cdim; 2294ef0bb6c7SMatthew G. Knepley const PetscInt NqI = TI->Np; 2295ef0bb6c7SMatthew G. Knepley const PetscInt NbI = TI->Nb; 2296ef0bb6c7SMatthew G. Knepley const PetscInt NcI = TI->Nc; 2297ef0bb6c7SMatthew G. Knepley const PetscReal *basisI = &TI->T[0][(r*NqI+q)*NbI*NcI]; 2298665f567fSMatthew G. Knepley const PetscReal *basisDerI = &TI->T[1][(r*NqI+q)*NbI*NcI*dE]; 2299ef0bb6c7SMatthew G. Knepley const PetscInt NqJ = TJ->Np; 2300ef0bb6c7SMatthew G. Knepley const PetscInt NbJ = TJ->Nb; 2301ef0bb6c7SMatthew G. Knepley const PetscInt NcJ = TJ->Nc; 2302ef0bb6c7SMatthew G. Knepley const PetscReal *basisJ = &TJ->T[0][(r*NqJ+q)*NbJ*NcJ]; 2303665f567fSMatthew G. Knepley const PetscReal *basisDerJ = &TJ->T[1][(r*NqJ+q)*NbJ*NcJ*dE]; 2304a8f1f9e5SMatthew G. Knepley PetscInt f, fc, g, gc, df, dg; 2305a8f1f9e5SMatthew G. Knepley 2306a8f1f9e5SMatthew G. Knepley for (f = 0; f < NbI; ++f) { 2307a8f1f9e5SMatthew G. Knepley for (fc = 0; fc < NcI; ++fc) { 2308a8f1f9e5SMatthew G. Knepley const PetscInt fidx = f*NcI+fc; /* Test function basis index */ 2309a8f1f9e5SMatthew G. Knepley 2310a8f1f9e5SMatthew G. Knepley tmpBasisI[fidx] = basisI[fidx]; 231127f02ce8SMatthew G. Knepley for (df = 0; df < dE; ++df) tmpBasisDerI[fidx*dE+df] = basisDerI[fidx*dE+df]; 2312a8f1f9e5SMatthew G. Knepley } 2313a8f1f9e5SMatthew G. Knepley } 23145f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEPushforward(feI, fegeom, NbI, tmpBasisI)); 23155f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEPushforwardGradient(feI, fegeom, NbI, tmpBasisDerI)); 2316a8f1f9e5SMatthew G. Knepley for (g = 0; g < NbJ; ++g) { 2317a8f1f9e5SMatthew G. Knepley for (gc = 0; gc < NcJ; ++gc) { 2318a8f1f9e5SMatthew G. Knepley const PetscInt gidx = g*NcJ+gc; /* Trial function basis index */ 2319a8f1f9e5SMatthew G. Knepley 2320a8f1f9e5SMatthew G. Knepley tmpBasisJ[gidx] = basisJ[gidx]; 232127f02ce8SMatthew G. Knepley for (dg = 0; dg < dE; ++dg) tmpBasisDerJ[gidx*dE+dg] = basisDerJ[gidx*dE+dg]; 2322a8f1f9e5SMatthew G. Knepley } 2323a8f1f9e5SMatthew G. Knepley } 23245f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEPushforward(feJ, fegeom, NbJ, tmpBasisJ)); 23255f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEPushforwardGradient(feJ, fegeom, NbJ, tmpBasisDerJ)); 2326a8f1f9e5SMatthew G. Knepley for (f = 0; f < NbI; ++f) { 2327a8f1f9e5SMatthew G. Knepley for (fc = 0; fc < NcI; ++fc) { 2328a8f1f9e5SMatthew G. Knepley const PetscInt fidx = f*NcI+fc; /* Test function basis index */ 2329a8f1f9e5SMatthew G. Knepley const PetscInt i = offsetI+f; /* Element matrix row */ 2330a8f1f9e5SMatthew G. Knepley for (g = 0; g < NbJ; ++g) { 2331a8f1f9e5SMatthew G. Knepley for (gc = 0; gc < NcJ; ++gc) { 2332a8f1f9e5SMatthew G. Knepley const PetscInt gidx = g*NcJ+gc; /* Trial function basis index */ 2333a8f1f9e5SMatthew G. Knepley const PetscInt j = offsetJ+g; /* Element matrix column */ 2334a8f1f9e5SMatthew G. Knepley const PetscInt fOff = eOffset+i*totDim+j; 2335a8f1f9e5SMatthew G. Knepley 2336a8f1f9e5SMatthew G. Knepley elemMat[fOff] += tmpBasisI[fidx]*g0[fc*NcJ+gc]*tmpBasisJ[gidx]; 233727f02ce8SMatthew G. Knepley for (df = 0; df < dE; ++df) { 233827f02ce8SMatthew G. Knepley elemMat[fOff] += tmpBasisI[fidx]*g1[(fc*NcJ+gc)*dE+df]*tmpBasisDerJ[gidx*dE+df]; 233927f02ce8SMatthew G. Knepley elemMat[fOff] += tmpBasisDerI[fidx*dE+df]*g2[(fc*NcJ+gc)*dE+df]*tmpBasisJ[gidx]; 234027f02ce8SMatthew G. Knepley for (dg = 0; dg < dE; ++dg) { 234127f02ce8SMatthew G. Knepley elemMat[fOff] += tmpBasisDerI[fidx*dE+df]*g3[((fc*NcJ+gc)*dE+df)*dE+dg]*tmpBasisDerJ[gidx*dE+dg]; 234227f02ce8SMatthew G. Knepley } 234327f02ce8SMatthew G. Knepley } 234427f02ce8SMatthew G. Knepley } 234527f02ce8SMatthew G. Knepley } 234627f02ce8SMatthew G. Knepley } 234727f02ce8SMatthew G. Knepley } 234827f02ce8SMatthew G. Knepley return(0); 234927f02ce8SMatthew G. Knepley } 235027f02ce8SMatthew G. Knepley 23515fedec97SMatthew G. Knepley PetscErrorCode PetscFEUpdateElementMat_Hybrid_Internal(PetscFE feI, PetscBool isHybridI, PetscFE feJ, PetscBool isHybridJ, PetscInt r, PetscInt s, PetscInt q, PetscTabulation TI, PetscScalar tmpBasisI[], PetscScalar tmpBasisDerI[], PetscTabulation TJ, PetscScalar tmpBasisJ[], PetscScalar tmpBasisDerJ[], PetscFEGeom *fegeom, const PetscScalar g0[], const PetscScalar g1[], const PetscScalar g2[], const PetscScalar g3[], PetscInt eOffset, PetscInt totDim, PetscInt offsetI, PetscInt offsetJ, PetscScalar elemMat[]) 235227f02ce8SMatthew G. Knepley { 2353665f567fSMatthew G. Knepley const PetscInt dE = TI->cdim; 2354665f567fSMatthew G. Knepley const PetscInt NqI = TI->Np; 2355665f567fSMatthew G. Knepley const PetscInt NbI = TI->Nb; 2356665f567fSMatthew G. Knepley const PetscInt NcI = TI->Nc; 2357665f567fSMatthew G. Knepley const PetscReal *basisI = &TI->T[0][(r*NqI+q)*NbI*NcI]; 2358665f567fSMatthew G. Knepley const PetscReal *basisDerI = &TI->T[1][(r*NqI+q)*NbI*NcI*dE]; 2359665f567fSMatthew G. Knepley const PetscInt NqJ = TJ->Np; 2360665f567fSMatthew G. Knepley const PetscInt NbJ = TJ->Nb; 2361665f567fSMatthew G. Knepley const PetscInt NcJ = TJ->Nc; 2362665f567fSMatthew G. Knepley const PetscReal *basisJ = &TJ->T[0][(r*NqJ+q)*NbJ*NcJ]; 2363665f567fSMatthew G. Knepley const PetscReal *basisDerJ = &TJ->T[1][(r*NqJ+q)*NbJ*NcJ*dE]; 23645fedec97SMatthew G. Knepley const PetscInt so = isHybridI ? 0 : s; 23655fedec97SMatthew G. Knepley const PetscInt to = isHybridJ ? 0 : s; 23665fedec97SMatthew G. Knepley PetscInt f, fc, g, gc, df, dg; 236727f02ce8SMatthew G. Knepley 236827f02ce8SMatthew G. Knepley for (f = 0; f < NbI; ++f) { 236927f02ce8SMatthew G. Knepley for (fc = 0; fc < NcI; ++fc) { 237027f02ce8SMatthew G. Knepley const PetscInt fidx = f*NcI+fc; /* Test function basis index */ 237127f02ce8SMatthew G. Knepley 237227f02ce8SMatthew G. Knepley tmpBasisI[fidx] = basisI[fidx]; 2373665f567fSMatthew G. Knepley for (df = 0; df < dE; ++df) tmpBasisDerI[fidx*dE+df] = basisDerI[fidx*dE+df]; 237427f02ce8SMatthew G. Knepley } 237527f02ce8SMatthew G. Knepley } 23765f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEPushforward(feI, fegeom, NbI, tmpBasisI)); 23775f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEPushforwardGradient(feI, fegeom, NbI, tmpBasisDerI)); 237827f02ce8SMatthew G. Knepley for (g = 0; g < NbJ; ++g) { 237927f02ce8SMatthew G. Knepley for (gc = 0; gc < NcJ; ++gc) { 238027f02ce8SMatthew G. Knepley const PetscInt gidx = g*NcJ+gc; /* Trial function basis index */ 238127f02ce8SMatthew G. Knepley 238227f02ce8SMatthew G. Knepley tmpBasisJ[gidx] = basisJ[gidx]; 2383665f567fSMatthew G. Knepley for (dg = 0; dg < dE; ++dg) tmpBasisDerJ[gidx*dE+dg] = basisDerJ[gidx*dE+dg]; 238427f02ce8SMatthew G. Knepley } 238527f02ce8SMatthew G. Knepley } 23865f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEPushforward(feJ, fegeom, NbJ, tmpBasisJ)); 23875f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEPushforwardGradient(feJ, fegeom, NbJ, tmpBasisDerJ)); 238827f02ce8SMatthew G. Knepley for (f = 0; f < NbI; ++f) { 238927f02ce8SMatthew G. Knepley for (fc = 0; fc < NcI; ++fc) { 239027f02ce8SMatthew G. Knepley const PetscInt fidx = f*NcI+fc; /* Test function basis index */ 23915fedec97SMatthew G. Knepley const PetscInt i = offsetI+NbI*so+f; /* Element matrix row */ 239227f02ce8SMatthew G. Knepley for (g = 0; g < NbJ; ++g) { 239327f02ce8SMatthew G. Knepley for (gc = 0; gc < NcJ; ++gc) { 239427f02ce8SMatthew G. Knepley const PetscInt gidx = g*NcJ+gc; /* Trial function basis index */ 23955fedec97SMatthew G. Knepley const PetscInt j = offsetJ+NbJ*to+g; /* Element matrix column */ 239627f02ce8SMatthew G. Knepley const PetscInt fOff = eOffset+i*totDim+j; 239727f02ce8SMatthew G. Knepley 23985fedec97SMatthew G. Knepley elemMat[fOff] += tmpBasisI[fidx]*g0[fc*NcJ+gc]*tmpBasisJ[gidx]; 239927f02ce8SMatthew G. Knepley for (df = 0; df < dE; ++df) { 24005fedec97SMatthew G. Knepley elemMat[fOff] += tmpBasisI[fidx]*g1[(fc*NcJ+gc)*dE+df]*tmpBasisDerJ[gidx*dE+df]; 24015fedec97SMatthew G. Knepley elemMat[fOff] += tmpBasisDerI[fidx*dE+df]*g2[(fc*NcJ+gc)*dE+df]*tmpBasisJ[gidx]; 240227f02ce8SMatthew G. Knepley for (dg = 0; dg < dE; ++dg) { 24035fedec97SMatthew G. Knepley elemMat[fOff] += tmpBasisDerI[fidx*dE+df]*g3[((fc*NcJ+gc)*dE+df)*dE+dg]*tmpBasisDerJ[gidx*dE+dg]; 2404a8f1f9e5SMatthew G. Knepley } 2405a8f1f9e5SMatthew G. Knepley } 2406a8f1f9e5SMatthew G. Knepley } 2407a8f1f9e5SMatthew G. Knepley } 2408a8f1f9e5SMatthew G. Knepley } 2409a8f1f9e5SMatthew G. Knepley } 2410a8f1f9e5SMatthew G. Knepley return(0); 2411a8f1f9e5SMatthew G. Knepley } 2412c9ba7969SMatthew G. Knepley 2413c9ba7969SMatthew G. Knepley PetscErrorCode PetscFECreateCellGeometry(PetscFE fe, PetscQuadrature quad, PetscFEGeom *cgeom) 2414c9ba7969SMatthew G. Knepley { 2415c9ba7969SMatthew G. Knepley PetscDualSpace dsp; 2416c9ba7969SMatthew G. Knepley DM dm; 2417c9ba7969SMatthew G. Knepley PetscQuadrature quadDef; 2418c9ba7969SMatthew G. Knepley PetscInt dim, cdim, Nq; 2419c9ba7969SMatthew G. Knepley 2420c9ba7969SMatthew G. Knepley PetscFunctionBegin; 24215f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEGetDualSpace(fe, &dsp)); 24225f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceGetDM(dsp, &dm)); 24235f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetDimension(dm, &dim)); 24245f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetCoordinateDim(dm, &cdim)); 24255f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEGetQuadrature(fe, &quadDef)); 2426c9ba7969SMatthew G. Knepley quad = quad ? quad : quadDef; 24275f80ce2aSJacob Faibussowitsch CHKERRQ(PetscQuadratureGetData(quad, NULL, NULL, &Nq, NULL, NULL)); 24285f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(Nq*cdim, &cgeom->v)); 24295f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(Nq*cdim*cdim, &cgeom->J)); 24305f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(Nq*cdim*cdim, &cgeom->invJ)); 24315f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(Nq, &cgeom->detJ)); 2432c9ba7969SMatthew G. Knepley cgeom->dim = dim; 2433c9ba7969SMatthew G. Knepley cgeom->dimEmbed = cdim; 2434c9ba7969SMatthew G. Knepley cgeom->numCells = 1; 2435c9ba7969SMatthew G. Knepley cgeom->numPoints = Nq; 24365f80ce2aSJacob Faibussowitsch CHKERRQ(DMPlexComputeCellGeometryFEM(dm, 0, quad, cgeom->v, cgeom->J, cgeom->invJ, cgeom->detJ)); 2437c9ba7969SMatthew G. Knepley PetscFunctionReturn(0); 2438c9ba7969SMatthew G. Knepley } 2439c9ba7969SMatthew G. Knepley 2440c9ba7969SMatthew G. Knepley PetscErrorCode PetscFEDestroyCellGeometry(PetscFE fe, PetscFEGeom *cgeom) 2441c9ba7969SMatthew G. Knepley { 2442c9ba7969SMatthew G. Knepley PetscFunctionBegin; 24435f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(cgeom->v)); 24445f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(cgeom->J)); 24455f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(cgeom->invJ)); 24465f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(cgeom->detJ)); 2447c9ba7969SMatthew G. Knepley PetscFunctionReturn(0); 2448c9ba7969SMatthew G. Knepley } 2449