120cf1dd8SToby Isaac /* Basis Jet Tabulation
220cf1dd8SToby Isaac
320cf1dd8SToby Isaac We would like to tabulate the nodal basis functions and derivatives at a set of points, usually quadrature points. We
420cf1dd8SToby Isaac follow here the derviation in http://www.math.ttu.edu/~kirby/papers/fiat-toms-2004.pdf. The nodal basis $\psi_i$ can
520cf1dd8SToby Isaac be expressed in terms of a prime basis $\phi_i$ which can be stably evaluated. In PETSc, we will use the Legendre basis
620cf1dd8SToby Isaac as a prime basis.
720cf1dd8SToby Isaac
820cf1dd8SToby Isaac \psi_i = \sum_k \alpha_{ki} \phi_k
920cf1dd8SToby Isaac
1020cf1dd8SToby Isaac Our nodal basis is defined in terms of the dual basis $n_j$
1120cf1dd8SToby Isaac
1220cf1dd8SToby Isaac n_j \cdot \psi_i = \delta_{ji}
1320cf1dd8SToby Isaac
1420cf1dd8SToby Isaac and we may act on the first equation to obtain
1520cf1dd8SToby Isaac
1620cf1dd8SToby Isaac n_j \cdot \psi_i = \sum_k \alpha_{ki} n_j \cdot \phi_k
1720cf1dd8SToby Isaac \delta_{ji} = \sum_k \alpha_{ki} V_{jk}
1820cf1dd8SToby Isaac I = V \alpha
1920cf1dd8SToby Isaac
2020cf1dd8SToby Isaac so the coefficients of the nodal basis in the prime basis are
2120cf1dd8SToby Isaac
2220cf1dd8SToby Isaac \alpha = V^{-1}
2320cf1dd8SToby Isaac
2420cf1dd8SToby Isaac We will define the dual basis vectors $n_j$ using a quadrature rule.
2520cf1dd8SToby Isaac
2620cf1dd8SToby Isaac Right now, we will just use the polynomial spaces P^k. I know some elements use the space of symmetric polynomials
2720cf1dd8SToby Isaac (I think Nedelec), but we will neglect this for now. Constraints in the space, e.g. Arnold-Winther elements, can
2820cf1dd8SToby Isaac be implemented exactly as in FIAT using functionals $L_j$.
2920cf1dd8SToby Isaac
3020cf1dd8SToby Isaac I will have to count the degrees correctly for the Legendre product when we are on simplices.
3120cf1dd8SToby Isaac
3220cf1dd8SToby Isaac We will have three objects:
3320cf1dd8SToby Isaac - Space, P: this just need point evaluation I think
3420cf1dd8SToby Isaac - Dual Space, P'+K: This looks like a set of functionals that can act on members of P, each n is defined by a Q
3520cf1dd8SToby Isaac - FEM: This keeps {P, P', Q}
3620cf1dd8SToby Isaac */
3720cf1dd8SToby Isaac #include <petsc/private/petscfeimpl.h> /*I "petscfe.h" I*/
3820cf1dd8SToby Isaac #include <petscdmplex.h>
3920cf1dd8SToby Isaac
4020cf1dd8SToby Isaac PetscBool FEcite = PETSC_FALSE;
4120cf1dd8SToby Isaac const char FECitation[] = "@article{kirby2004,\n"
4220cf1dd8SToby Isaac " title = {Algorithm 839: FIAT, a New Paradigm for Computing Finite Element Basis Functions},\n"
4320cf1dd8SToby Isaac " journal = {ACM Transactions on Mathematical Software},\n"
4420cf1dd8SToby Isaac " author = {Robert C. Kirby},\n"
4520cf1dd8SToby Isaac " volume = {30},\n"
4620cf1dd8SToby Isaac " number = {4},\n"
4720cf1dd8SToby Isaac " pages = {502--516},\n"
4820cf1dd8SToby Isaac " doi = {10.1145/1039813.1039820},\n"
4920cf1dd8SToby Isaac " year = {2004}\n}\n";
5020cf1dd8SToby Isaac
5120cf1dd8SToby Isaac PetscClassId PETSCFE_CLASSID = 0;
5220cf1dd8SToby Isaac
53ead873ccSMatthew G. Knepley PetscLogEvent PETSCFE_SetUp;
54ead873ccSMatthew G. Knepley
5520cf1dd8SToby Isaac PetscFunctionList PetscFEList = NULL;
5620cf1dd8SToby Isaac PetscBool PetscFERegisterAllCalled = PETSC_FALSE;
5720cf1dd8SToby Isaac
5820cf1dd8SToby Isaac /*@C
59dce8aebaSBarry Smith PetscFERegister - Adds a new `PetscFEType`
6020cf1dd8SToby Isaac
61cc4c1da9SBarry Smith Not Collective, No Fortran Support
6220cf1dd8SToby Isaac
6320cf1dd8SToby Isaac Input Parameters:
642fe279fdSBarry Smith + sname - The name of a new user-defined creation routine
652fe279fdSBarry Smith - function - The creation routine
6620cf1dd8SToby Isaac
6760225df5SJacob Faibussowitsch Example Usage:
6820cf1dd8SToby Isaac .vb
6920cf1dd8SToby Isaac PetscFERegister("my_fe", MyPetscFECreate);
7020cf1dd8SToby Isaac .ve
7120cf1dd8SToby Isaac
7220cf1dd8SToby Isaac Then, your PetscFE type can be chosen with the procedural interface via
7320cf1dd8SToby Isaac .vb
7420cf1dd8SToby Isaac PetscFECreate(MPI_Comm, PetscFE *);
7520cf1dd8SToby Isaac PetscFESetType(PetscFE, "my_fe");
7620cf1dd8SToby Isaac .ve
7720cf1dd8SToby Isaac or at runtime via the option
7820cf1dd8SToby Isaac .vb
7920cf1dd8SToby Isaac -petscfe_type my_fe
8020cf1dd8SToby Isaac .ve
8120cf1dd8SToby Isaac
8220cf1dd8SToby Isaac Level: advanced
8320cf1dd8SToby Isaac
84dce8aebaSBarry Smith Note:
85dce8aebaSBarry Smith `PetscFERegister()` may be called multiple times to add several user-defined `PetscFE`s
8620cf1dd8SToby Isaac
87dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscFEType`, `PetscFERegisterAll()`, `PetscFERegisterDestroy()`
8820cf1dd8SToby Isaac @*/
PetscFERegister(const char sname[],PetscErrorCode (* function)(PetscFE))89d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFERegister(const char sname[], PetscErrorCode (*function)(PetscFE))
90d71ae5a4SJacob Faibussowitsch {
9120cf1dd8SToby Isaac PetscFunctionBegin;
929566063dSJacob Faibussowitsch PetscCall(PetscFunctionListAdd(&PetscFEList, sname, function));
933ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
9420cf1dd8SToby Isaac }
9520cf1dd8SToby Isaac
96cc4c1da9SBarry Smith /*@
97dce8aebaSBarry Smith PetscFESetType - Builds a particular `PetscFE`
9820cf1dd8SToby Isaac
9920f4b53cSBarry Smith Collective
10020cf1dd8SToby Isaac
10120cf1dd8SToby Isaac Input Parameters:
102dce8aebaSBarry Smith + fem - The `PetscFE` object
10320cf1dd8SToby Isaac - name - The kind of FEM space
10420cf1dd8SToby Isaac
10520cf1dd8SToby Isaac Options Database Key:
10620f4b53cSBarry Smith . -petscfe_type <type> - Sets the `PetscFE` type; use -help for a list of available types
10720cf1dd8SToby Isaac
10820cf1dd8SToby Isaac Level: intermediate
10920cf1dd8SToby Isaac
110dce8aebaSBarry Smith .seealso: `PetscFEType`, `PetscFE`, `PetscFEGetType()`, `PetscFECreate()`
11120cf1dd8SToby Isaac @*/
PetscFESetType(PetscFE fem,PetscFEType name)112d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFESetType(PetscFE fem, PetscFEType name)
113d71ae5a4SJacob Faibussowitsch {
11420cf1dd8SToby Isaac PetscErrorCode (*r)(PetscFE);
11520cf1dd8SToby Isaac PetscBool match;
11620cf1dd8SToby Isaac
11720cf1dd8SToby Isaac PetscFunctionBegin;
11820cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1);
1199566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)fem, name, &match));
1203ba16761SJacob Faibussowitsch if (match) PetscFunctionReturn(PETSC_SUCCESS);
12120cf1dd8SToby Isaac
1229566063dSJacob Faibussowitsch if (!PetscFERegisterAllCalled) PetscCall(PetscFERegisterAll());
1239566063dSJacob Faibussowitsch PetscCall(PetscFunctionListFind(PetscFEList, name, &r));
12428b400f6SJacob Faibussowitsch PetscCheck(r, PetscObjectComm((PetscObject)fem), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown PetscFE type: %s", name);
12520cf1dd8SToby Isaac
126dbbe0bcdSBarry Smith PetscTryTypeMethod(fem, destroy);
12720cf1dd8SToby Isaac fem->ops->destroy = NULL;
128dbbe0bcdSBarry Smith
1299566063dSJacob Faibussowitsch PetscCall((*r)(fem));
1309566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)fem, name));
1313ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
13220cf1dd8SToby Isaac }
13320cf1dd8SToby Isaac
134cc4c1da9SBarry Smith /*@
135dce8aebaSBarry Smith PetscFEGetType - Gets the `PetscFEType` (as a string) from the `PetscFE` object.
13620cf1dd8SToby Isaac
13720cf1dd8SToby Isaac Not Collective
13820cf1dd8SToby Isaac
13920cf1dd8SToby Isaac Input Parameter:
140dce8aebaSBarry Smith . fem - The `PetscFE`
14120cf1dd8SToby Isaac
14220cf1dd8SToby Isaac Output Parameter:
143dce8aebaSBarry Smith . name - The `PetscFEType` name
14420cf1dd8SToby Isaac
14520cf1dd8SToby Isaac Level: intermediate
14620cf1dd8SToby Isaac
147dce8aebaSBarry Smith .seealso: `PetscFEType`, `PetscFE`, `PetscFESetType()`, `PetscFECreate()`
14820cf1dd8SToby Isaac @*/
PetscFEGetType(PetscFE fem,PetscFEType * name)149d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEGetType(PetscFE fem, PetscFEType *name)
150d71ae5a4SJacob Faibussowitsch {
15120cf1dd8SToby Isaac PetscFunctionBegin;
15220cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1);
1534f572ea9SToby Isaac PetscAssertPointer(name, 2);
15448a46eb9SPierre Jolivet if (!PetscFERegisterAllCalled) PetscCall(PetscFERegisterAll());
15520cf1dd8SToby Isaac *name = ((PetscObject)fem)->type_name;
1563ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
15720cf1dd8SToby Isaac }
15820cf1dd8SToby Isaac
159ffeef943SBarry Smith /*@
160dce8aebaSBarry Smith PetscFEViewFromOptions - View from a `PetscFE` based on values in the options database
161fe2efc57SMark
16220f4b53cSBarry Smith Collective
163fe2efc57SMark
164fe2efc57SMark Input Parameters:
165dce8aebaSBarry Smith + A - the `PetscFE` object
166ce78bad3SBarry Smith . obj - Optional object that provides the options prefix, pass `NULL` to use the options prefix of `A`
167dce8aebaSBarry Smith - name - command line option name
168fe2efc57SMark
169fe2efc57SMark Level: intermediate
170dce8aebaSBarry Smith
171dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscFEView()`, `PetscObjectViewFromOptions()`, `PetscFECreate()`
172fe2efc57SMark @*/
PetscFEViewFromOptions(PetscFE A,PeOp PetscObject obj,const char name[])173ce78bad3SBarry Smith PetscErrorCode PetscFEViewFromOptions(PetscFE A, PeOp PetscObject obj, const char name[])
174d71ae5a4SJacob Faibussowitsch {
175fe2efc57SMark PetscFunctionBegin;
176fe2efc57SMark PetscValidHeaderSpecific(A, PETSCFE_CLASSID, 1);
1779566063dSJacob Faibussowitsch PetscCall(PetscObjectViewFromOptions((PetscObject)A, obj, name));
1783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
179fe2efc57SMark }
180fe2efc57SMark
181ffeef943SBarry Smith /*@
182dce8aebaSBarry Smith PetscFEView - Views a `PetscFE`
18320cf1dd8SToby Isaac
18420f4b53cSBarry Smith Collective
18520cf1dd8SToby Isaac
186d8d19677SJose E. Roman Input Parameters:
187dce8aebaSBarry Smith + fem - the `PetscFE` object to view
188d9bac1caSLisandro Dalcin - viewer - the viewer
18920cf1dd8SToby Isaac
1902b99622eSMatthew G. Knepley Level: beginner
19120cf1dd8SToby Isaac
192dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscViewer`, `PetscFEDestroy()`, `PetscFEViewFromOptions()`
19320cf1dd8SToby Isaac @*/
PetscFEView(PetscFE fem,PetscViewer viewer)194d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEView(PetscFE fem, PetscViewer viewer)
195d71ae5a4SJacob Faibussowitsch {
1969f196a02SMartin Diehl PetscBool isascii;
19720cf1dd8SToby Isaac
19820cf1dd8SToby Isaac PetscFunctionBegin;
19920cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1);
200d9bac1caSLisandro Dalcin if (viewer) PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
2019566063dSJacob Faibussowitsch if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)fem), &viewer));
2029566063dSJacob Faibussowitsch PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)fem, viewer));
2039f196a02SMartin Diehl PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
204dbbe0bcdSBarry Smith PetscTryTypeMethod(fem, view, viewer);
2053ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
20620cf1dd8SToby Isaac }
20720cf1dd8SToby Isaac
20820cf1dd8SToby Isaac /*@
209dce8aebaSBarry Smith PetscFESetFromOptions - sets parameters in a `PetscFE` from the options database
21020cf1dd8SToby Isaac
21120f4b53cSBarry Smith Collective
21220cf1dd8SToby Isaac
21320cf1dd8SToby Isaac Input Parameter:
214dce8aebaSBarry Smith . fem - the `PetscFE` object to set options for
21520cf1dd8SToby Isaac
216dce8aebaSBarry Smith Options Database Keys:
217a2b725a8SWilliam Gropp + -petscfe_num_blocks - the number of cell blocks to integrate concurrently
218a2b725a8SWilliam Gropp - -petscfe_num_batches - the number of cell batches to integrate serially
21920cf1dd8SToby Isaac
2202b99622eSMatthew G. Knepley Level: intermediate
22120cf1dd8SToby Isaac
222bfe80ac4SPierre Jolivet .seealso: `PetscFE`, `PetscFEView()`
22320cf1dd8SToby Isaac @*/
PetscFESetFromOptions(PetscFE fem)224d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFESetFromOptions(PetscFE fem)
225d71ae5a4SJacob Faibussowitsch {
22620cf1dd8SToby Isaac const char *defaultType;
22720cf1dd8SToby Isaac char name[256];
22820cf1dd8SToby Isaac PetscBool flg;
22920cf1dd8SToby Isaac
23020cf1dd8SToby Isaac PetscFunctionBegin;
23120cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1);
23220cf1dd8SToby Isaac if (!((PetscObject)fem)->type_name) {
23320cf1dd8SToby Isaac defaultType = PETSCFEBASIC;
23420cf1dd8SToby Isaac } else {
23520cf1dd8SToby Isaac defaultType = ((PetscObject)fem)->type_name;
23620cf1dd8SToby Isaac }
2379566063dSJacob Faibussowitsch if (!PetscFERegisterAllCalled) PetscCall(PetscFERegisterAll());
23820cf1dd8SToby Isaac
239d0609cedSBarry Smith PetscObjectOptionsBegin((PetscObject)fem);
2409566063dSJacob Faibussowitsch PetscCall(PetscOptionsFList("-petscfe_type", "Finite element space", "PetscFESetType", PetscFEList, defaultType, name, 256, &flg));
24120cf1dd8SToby Isaac if (flg) {
2429566063dSJacob Faibussowitsch PetscCall(PetscFESetType(fem, name));
24320cf1dd8SToby Isaac } else if (!((PetscObject)fem)->type_name) {
2449566063dSJacob Faibussowitsch PetscCall(PetscFESetType(fem, defaultType));
24520cf1dd8SToby Isaac }
2469566063dSJacob Faibussowitsch PetscCall(PetscOptionsBoundedInt("-petscfe_num_blocks", "The number of cell blocks to integrate concurrently", "PetscSpaceSetTileSizes", fem->numBlocks, &fem->numBlocks, NULL, 1));
2479566063dSJacob Faibussowitsch PetscCall(PetscOptionsBoundedInt("-petscfe_num_batches", "The number of cell batches to integrate serially", "PetscSpaceSetTileSizes", fem->numBatches, &fem->numBatches, NULL, 1));
248dbbe0bcdSBarry Smith PetscTryTypeMethod(fem, setfromoptions, PetscOptionsObject);
24920cf1dd8SToby Isaac /* process any options handlers added with PetscObjectAddOptionsHandler() */
250dbbe0bcdSBarry Smith PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)fem, PetscOptionsObject));
251d0609cedSBarry Smith PetscOptionsEnd();
2529566063dSJacob Faibussowitsch PetscCall(PetscFEViewFromOptions(fem, NULL, "-petscfe_view"));
2533ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
25420cf1dd8SToby Isaac }
25520cf1dd8SToby Isaac
256cc4c1da9SBarry Smith /*@
257dce8aebaSBarry Smith PetscFESetUp - Construct data structures for the `PetscFE` after the `PetscFEType` has been set
25820cf1dd8SToby Isaac
25920f4b53cSBarry Smith Collective
26020cf1dd8SToby Isaac
26120cf1dd8SToby Isaac Input Parameter:
262dce8aebaSBarry Smith . fem - the `PetscFE` object to setup
26320cf1dd8SToby Isaac
2642b99622eSMatthew G. Knepley Level: intermediate
26520cf1dd8SToby Isaac
266dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscFEView()`, `PetscFEDestroy()`
26720cf1dd8SToby Isaac @*/
PetscFESetUp(PetscFE fem)268d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFESetUp(PetscFE fem)
269d71ae5a4SJacob Faibussowitsch {
27020cf1dd8SToby Isaac PetscFunctionBegin;
27120cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1);
2723ba16761SJacob Faibussowitsch if (fem->setupcalled) PetscFunctionReturn(PETSC_SUCCESS);
2739566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(PETSCFE_SetUp, fem, 0, 0, 0));
27420cf1dd8SToby Isaac fem->setupcalled = PETSC_TRUE;
275dbbe0bcdSBarry Smith PetscTryTypeMethod(fem, setup);
2769566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(PETSCFE_SetUp, fem, 0, 0, 0));
2773ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
27820cf1dd8SToby Isaac }
27920cf1dd8SToby Isaac
28020cf1dd8SToby Isaac /*@
281dce8aebaSBarry Smith PetscFEDestroy - Destroys a `PetscFE` object
28220cf1dd8SToby Isaac
28320f4b53cSBarry Smith Collective
28420cf1dd8SToby Isaac
28520cf1dd8SToby Isaac Input Parameter:
286dce8aebaSBarry Smith . fem - the `PetscFE` object to destroy
28720cf1dd8SToby Isaac
2882b99622eSMatthew G. Knepley Level: beginner
28920cf1dd8SToby Isaac
290dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscFEView()`
29120cf1dd8SToby Isaac @*/
PetscFEDestroy(PetscFE * fem)292d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEDestroy(PetscFE *fem)
293d71ae5a4SJacob Faibussowitsch {
29420cf1dd8SToby Isaac PetscFunctionBegin;
2953ba16761SJacob Faibussowitsch if (!*fem) PetscFunctionReturn(PETSC_SUCCESS);
296f4f49eeaSPierre Jolivet PetscValidHeaderSpecific(*fem, PETSCFE_CLASSID, 1);
29720cf1dd8SToby Isaac
298f4f49eeaSPierre Jolivet if (--((PetscObject)*fem)->refct > 0) {
2999371c9d4SSatish Balay *fem = NULL;
3003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
3019371c9d4SSatish Balay }
302f4f49eeaSPierre Jolivet ((PetscObject)*fem)->refct = 0;
30320cf1dd8SToby Isaac
30420cf1dd8SToby Isaac if ((*fem)->subspaces) {
30520cf1dd8SToby Isaac PetscInt dim, d;
30620cf1dd8SToby Isaac
3079566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetDimension((*fem)->dualSpace, &dim));
3089566063dSJacob Faibussowitsch for (d = 0; d < dim; ++d) PetscCall(PetscFEDestroy(&(*fem)->subspaces[d]));
30920cf1dd8SToby Isaac }
3109566063dSJacob Faibussowitsch PetscCall(PetscFree((*fem)->subspaces));
3119566063dSJacob Faibussowitsch PetscCall(PetscFree((*fem)->invV));
3129566063dSJacob Faibussowitsch PetscCall(PetscTabulationDestroy(&(*fem)->T));
3139566063dSJacob Faibussowitsch PetscCall(PetscTabulationDestroy(&(*fem)->Tf));
3149566063dSJacob Faibussowitsch PetscCall(PetscTabulationDestroy(&(*fem)->Tc));
3159566063dSJacob Faibussowitsch PetscCall(PetscSpaceDestroy(&(*fem)->basisSpace));
3169566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceDestroy(&(*fem)->dualSpace));
3179566063dSJacob Faibussowitsch PetscCall(PetscQuadratureDestroy(&(*fem)->quadrature));
3189566063dSJacob Faibussowitsch PetscCall(PetscQuadratureDestroy(&(*fem)->faceQuadrature));
319f918ec44SMatthew G. Knepley #ifdef PETSC_HAVE_LIBCEED
3209566063dSJacob Faibussowitsch PetscCallCEED(CeedBasisDestroy(&(*fem)->ceedBasis));
3219566063dSJacob Faibussowitsch PetscCallCEED(CeedDestroy(&(*fem)->ceed));
322f918ec44SMatthew G. Knepley #endif
32320cf1dd8SToby Isaac
324f4f49eeaSPierre Jolivet PetscTryTypeMethod(*fem, destroy);
3259566063dSJacob Faibussowitsch PetscCall(PetscHeaderDestroy(fem));
3263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
32720cf1dd8SToby Isaac }
32820cf1dd8SToby Isaac
32920cf1dd8SToby Isaac /*@
330dce8aebaSBarry Smith PetscFECreate - Creates an empty `PetscFE` object. The type can then be set with `PetscFESetType()`.
33120cf1dd8SToby Isaac
332d083f849SBarry Smith Collective
33320cf1dd8SToby Isaac
33420cf1dd8SToby Isaac Input Parameter:
335dce8aebaSBarry Smith . comm - The communicator for the `PetscFE` object
33620cf1dd8SToby Isaac
33720cf1dd8SToby Isaac Output Parameter:
338dce8aebaSBarry Smith . fem - The `PetscFE` object
33920cf1dd8SToby Isaac
34020cf1dd8SToby Isaac Level: beginner
34120cf1dd8SToby Isaac
342a01caf64Smarkadams4 .seealso: `PetscFE`, `PetscFEType`, `PetscFESetType()`, `PetscFECreateDefault()`, `PETSCFEGALERKIN`
34320cf1dd8SToby Isaac @*/
PetscFECreate(MPI_Comm comm,PetscFE * fem)344d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFECreate(MPI_Comm comm, PetscFE *fem)
345d71ae5a4SJacob Faibussowitsch {
34620cf1dd8SToby Isaac PetscFE f;
34720cf1dd8SToby Isaac
34820cf1dd8SToby Isaac PetscFunctionBegin;
3494f572ea9SToby Isaac PetscAssertPointer(fem, 2);
3509566063dSJacob Faibussowitsch PetscCall(PetscCitationsRegister(FECitation, &FEcite));
3519566063dSJacob Faibussowitsch PetscCall(PetscFEInitializePackage());
35220cf1dd8SToby Isaac
3539566063dSJacob Faibussowitsch PetscCall(PetscHeaderCreate(f, PETSCFE_CLASSID, "PetscFE", "Finite Element", "PetscFE", comm, PetscFEDestroy, PetscFEView));
35420cf1dd8SToby Isaac
35520cf1dd8SToby Isaac f->basisSpace = NULL;
35620cf1dd8SToby Isaac f->dualSpace = NULL;
35720cf1dd8SToby Isaac f->numComponents = 1;
35820cf1dd8SToby Isaac f->subspaces = NULL;
35920cf1dd8SToby Isaac f->invV = NULL;
360ef0bb6c7SMatthew G. Knepley f->T = NULL;
361ef0bb6c7SMatthew G. Knepley f->Tf = NULL;
362ef0bb6c7SMatthew G. Knepley f->Tc = NULL;
3639566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(&f->quadrature, 1));
3649566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(&f->faceQuadrature, 1));
36520cf1dd8SToby Isaac f->blockSize = 0;
36620cf1dd8SToby Isaac f->numBlocks = 1;
36720cf1dd8SToby Isaac f->batchSize = 0;
36820cf1dd8SToby Isaac f->numBatches = 1;
36920cf1dd8SToby Isaac
37020cf1dd8SToby Isaac *fem = f;
3713ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
37220cf1dd8SToby Isaac }
37320cf1dd8SToby Isaac
37420cf1dd8SToby Isaac /*@
37520cf1dd8SToby Isaac PetscFEGetSpatialDimension - Returns the spatial dimension of the element
37620cf1dd8SToby Isaac
37720f4b53cSBarry Smith Not Collective
37820cf1dd8SToby Isaac
37920cf1dd8SToby Isaac Input Parameter:
380dce8aebaSBarry Smith . fem - The `PetscFE` object
38120cf1dd8SToby Isaac
38220cf1dd8SToby Isaac Output Parameter:
38320cf1dd8SToby Isaac . dim - The spatial dimension
38420cf1dd8SToby Isaac
38520cf1dd8SToby Isaac Level: intermediate
38620cf1dd8SToby Isaac
387dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscFECreate()`
38820cf1dd8SToby Isaac @*/
PetscFEGetSpatialDimension(PetscFE fem,PetscInt * dim)389d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEGetSpatialDimension(PetscFE fem, PetscInt *dim)
390d71ae5a4SJacob Faibussowitsch {
39120cf1dd8SToby Isaac DM dm;
39220cf1dd8SToby Isaac
39320cf1dd8SToby Isaac PetscFunctionBegin;
39420cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1);
3954f572ea9SToby Isaac PetscAssertPointer(dim, 2);
3969566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetDM(fem->dualSpace, &dm));
3979566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, dim));
3983ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
39920cf1dd8SToby Isaac }
40020cf1dd8SToby Isaac
40120cf1dd8SToby Isaac /*@
402dce8aebaSBarry Smith PetscFESetNumComponents - Sets the number of field components in the element
40320cf1dd8SToby Isaac
40420f4b53cSBarry Smith Not Collective
40520cf1dd8SToby Isaac
40620cf1dd8SToby Isaac Input Parameters:
407dce8aebaSBarry Smith + fem - The `PetscFE` object
40820cf1dd8SToby Isaac - comp - The number of field components
40920cf1dd8SToby Isaac
41020cf1dd8SToby Isaac Level: intermediate
41120cf1dd8SToby Isaac
412dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscFECreate()`, `PetscFEGetSpatialDimension()`, `PetscFEGetNumComponents()`
41320cf1dd8SToby Isaac @*/
PetscFESetNumComponents(PetscFE fem,PetscInt comp)414d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFESetNumComponents(PetscFE fem, PetscInt comp)
415d71ae5a4SJacob Faibussowitsch {
41620cf1dd8SToby Isaac PetscFunctionBegin;
41720cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1);
41820cf1dd8SToby Isaac fem->numComponents = comp;
4193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
42020cf1dd8SToby Isaac }
42120cf1dd8SToby Isaac
42220cf1dd8SToby Isaac /*@
42320cf1dd8SToby Isaac PetscFEGetNumComponents - Returns the number of components in the element
42420cf1dd8SToby Isaac
42520f4b53cSBarry Smith Not Collective
42620cf1dd8SToby Isaac
42720cf1dd8SToby Isaac Input Parameter:
428dce8aebaSBarry Smith . fem - The `PetscFE` object
42920cf1dd8SToby Isaac
43020cf1dd8SToby Isaac Output Parameter:
43120cf1dd8SToby Isaac . comp - The number of field components
43220cf1dd8SToby Isaac
43320cf1dd8SToby Isaac Level: intermediate
43420cf1dd8SToby Isaac
43542747ad1SJacob Faibussowitsch .seealso: `PetscFE`, `PetscFECreate()`, `PetscFEGetSpatialDimension()`
43620cf1dd8SToby Isaac @*/
PetscFEGetNumComponents(PetscFE fem,PetscInt * comp)437d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEGetNumComponents(PetscFE fem, PetscInt *comp)
438d71ae5a4SJacob Faibussowitsch {
43920cf1dd8SToby Isaac PetscFunctionBegin;
44020cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1);
4414f572ea9SToby Isaac PetscAssertPointer(comp, 2);
44220cf1dd8SToby Isaac *comp = fem->numComponents;
4433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
44420cf1dd8SToby Isaac }
44520cf1dd8SToby Isaac
44620cf1dd8SToby Isaac /*@
44720cf1dd8SToby Isaac PetscFESetTileSizes - Sets the tile sizes for evaluation
44820cf1dd8SToby Isaac
44920f4b53cSBarry Smith Not Collective
45020cf1dd8SToby Isaac
45120cf1dd8SToby Isaac Input Parameters:
452dce8aebaSBarry Smith + fem - The `PetscFE` object
45320cf1dd8SToby Isaac . blockSize - The number of elements in a block
45420cf1dd8SToby Isaac . numBlocks - The number of blocks in a batch
45520cf1dd8SToby Isaac . batchSize - The number of elements in a batch
45620cf1dd8SToby Isaac - numBatches - The number of batches in a chunk
45720cf1dd8SToby Isaac
45820cf1dd8SToby Isaac Level: intermediate
45920cf1dd8SToby Isaac
460dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscFECreate()`, `PetscFEGetTileSizes()`
46120cf1dd8SToby Isaac @*/
PetscFESetTileSizes(PetscFE fem,PetscInt blockSize,PetscInt numBlocks,PetscInt batchSize,PetscInt numBatches)462d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFESetTileSizes(PetscFE fem, PetscInt blockSize, PetscInt numBlocks, PetscInt batchSize, PetscInt numBatches)
463d71ae5a4SJacob Faibussowitsch {
46420cf1dd8SToby Isaac PetscFunctionBegin;
46520cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1);
46620cf1dd8SToby Isaac fem->blockSize = blockSize;
46720cf1dd8SToby Isaac fem->numBlocks = numBlocks;
46820cf1dd8SToby Isaac fem->batchSize = batchSize;
46920cf1dd8SToby Isaac fem->numBatches = numBatches;
4703ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
47120cf1dd8SToby Isaac }
47220cf1dd8SToby Isaac
47320cf1dd8SToby Isaac /*@
47420cf1dd8SToby Isaac PetscFEGetTileSizes - Returns the tile sizes for evaluation
47520cf1dd8SToby Isaac
47620f4b53cSBarry Smith Not Collective
47720cf1dd8SToby Isaac
47820cf1dd8SToby Isaac Input Parameter:
479dce8aebaSBarry Smith . fem - The `PetscFE` object
48020cf1dd8SToby Isaac
48120cf1dd8SToby Isaac Output Parameters:
482ce78bad3SBarry Smith + blockSize - The number of elements in a block, pass `NULL` if not needed
483ce78bad3SBarry Smith . numBlocks - The number of blocks in a batch, pass `NULL` if not needed
484ce78bad3SBarry Smith . batchSize - The number of elements in a batch, pass `NULL` if not needed
485ce78bad3SBarry Smith - numBatches - The number of batches in a chunk, pass `NULL` if not needed
48620cf1dd8SToby Isaac
48720cf1dd8SToby Isaac Level: intermediate
48820cf1dd8SToby Isaac
489dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscFECreate()`, `PetscFESetTileSizes()`
49020cf1dd8SToby Isaac @*/
PetscFEGetTileSizes(PetscFE fem,PeOp PetscInt * blockSize,PeOp PetscInt * numBlocks,PeOp PetscInt * batchSize,PeOp PetscInt * numBatches)491ce78bad3SBarry Smith PetscErrorCode PetscFEGetTileSizes(PetscFE fem, PeOp PetscInt *blockSize, PeOp PetscInt *numBlocks, PeOp PetscInt *batchSize, PeOp PetscInt *numBatches)
492d71ae5a4SJacob Faibussowitsch {
49320cf1dd8SToby Isaac PetscFunctionBegin;
49420cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1);
4954f572ea9SToby Isaac if (blockSize) PetscAssertPointer(blockSize, 2);
4964f572ea9SToby Isaac if (numBlocks) PetscAssertPointer(numBlocks, 3);
4974f572ea9SToby Isaac if (batchSize) PetscAssertPointer(batchSize, 4);
4984f572ea9SToby Isaac if (numBatches) PetscAssertPointer(numBatches, 5);
49920cf1dd8SToby Isaac if (blockSize) *blockSize = fem->blockSize;
50020cf1dd8SToby Isaac if (numBlocks) *numBlocks = fem->numBlocks;
50120cf1dd8SToby Isaac if (batchSize) *batchSize = fem->batchSize;
50220cf1dd8SToby Isaac if (numBatches) *numBatches = fem->numBatches;
5033ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
50420cf1dd8SToby Isaac }
50520cf1dd8SToby Isaac
50620cf1dd8SToby Isaac /*@
507dce8aebaSBarry Smith PetscFEGetBasisSpace - Returns the `PetscSpace` used for the approximation of the solution for the `PetscFE`
50820cf1dd8SToby Isaac
50920f4b53cSBarry Smith Not Collective
51020cf1dd8SToby Isaac
51120cf1dd8SToby Isaac Input Parameter:
512dce8aebaSBarry Smith . fem - The `PetscFE` object
51320cf1dd8SToby Isaac
51420cf1dd8SToby Isaac Output Parameter:
515dce8aebaSBarry Smith . sp - The `PetscSpace` object
51620cf1dd8SToby Isaac
51720cf1dd8SToby Isaac Level: intermediate
51820cf1dd8SToby Isaac
519dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscSpace`, `PetscFECreate()`
52020cf1dd8SToby Isaac @*/
PetscFEGetBasisSpace(PetscFE fem,PetscSpace * sp)521d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEGetBasisSpace(PetscFE fem, PetscSpace *sp)
522d71ae5a4SJacob Faibussowitsch {
52320cf1dd8SToby Isaac PetscFunctionBegin;
52420cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1);
5254f572ea9SToby Isaac PetscAssertPointer(sp, 2);
52620cf1dd8SToby Isaac *sp = fem->basisSpace;
5273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
52820cf1dd8SToby Isaac }
52920cf1dd8SToby Isaac
53020cf1dd8SToby Isaac /*@
531dce8aebaSBarry Smith PetscFESetBasisSpace - Sets the `PetscSpace` used for the approximation of the solution
53220cf1dd8SToby Isaac
53320f4b53cSBarry Smith Not Collective
53420cf1dd8SToby Isaac
53520cf1dd8SToby Isaac Input Parameters:
536dce8aebaSBarry Smith + fem - The `PetscFE` object
537dce8aebaSBarry Smith - sp - The `PetscSpace` object
53820cf1dd8SToby Isaac
53920cf1dd8SToby Isaac Level: intermediate
54020cf1dd8SToby Isaac
54160225df5SJacob Faibussowitsch Developer Notes:
542dce8aebaSBarry Smith There is `PetscFESetBasisSpace()` but the `PetscFESetDualSpace()`, likely the Basis is unneeded in the function name
543dce8aebaSBarry Smith
544dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscSpace`, `PetscDualSpace`, `PetscFECreate()`, `PetscFESetDualSpace()`
54520cf1dd8SToby Isaac @*/
PetscFESetBasisSpace(PetscFE fem,PetscSpace sp)546d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFESetBasisSpace(PetscFE fem, PetscSpace sp)
547d71ae5a4SJacob Faibussowitsch {
54820cf1dd8SToby Isaac PetscFunctionBegin;
54920cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1);
55020cf1dd8SToby Isaac PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 2);
5519566063dSJacob Faibussowitsch PetscCall(PetscSpaceDestroy(&fem->basisSpace));
55220cf1dd8SToby Isaac fem->basisSpace = sp;
5539566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)fem->basisSpace));
5543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
55520cf1dd8SToby Isaac }
55620cf1dd8SToby Isaac
55720cf1dd8SToby Isaac /*@
558dce8aebaSBarry Smith PetscFEGetDualSpace - Returns the `PetscDualSpace` used to define the inner product for a `PetscFE`
55920cf1dd8SToby Isaac
56020f4b53cSBarry Smith Not Collective
56120cf1dd8SToby Isaac
56220cf1dd8SToby Isaac Input Parameter:
563dce8aebaSBarry Smith . fem - The `PetscFE` object
56420cf1dd8SToby Isaac
56520cf1dd8SToby Isaac Output Parameter:
566dce8aebaSBarry Smith . sp - The `PetscDualSpace` object
56720cf1dd8SToby Isaac
56820cf1dd8SToby Isaac Level: intermediate
56920cf1dd8SToby Isaac
570dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscSpace`, `PetscDualSpace`, `PetscFECreate()`
57120cf1dd8SToby Isaac @*/
PetscFEGetDualSpace(PetscFE fem,PetscDualSpace * sp)572d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEGetDualSpace(PetscFE fem, PetscDualSpace *sp)
573d71ae5a4SJacob Faibussowitsch {
57420cf1dd8SToby Isaac PetscFunctionBegin;
57520cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1);
5764f572ea9SToby Isaac PetscAssertPointer(sp, 2);
57720cf1dd8SToby Isaac *sp = fem->dualSpace;
5783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
57920cf1dd8SToby Isaac }
58020cf1dd8SToby Isaac
58120cf1dd8SToby Isaac /*@
582dce8aebaSBarry Smith PetscFESetDualSpace - Sets the `PetscDualSpace` used to define the inner product
58320cf1dd8SToby Isaac
58420f4b53cSBarry Smith Not Collective
58520cf1dd8SToby Isaac
58620cf1dd8SToby Isaac Input Parameters:
587dce8aebaSBarry Smith + fem - The `PetscFE` object
588dce8aebaSBarry Smith - sp - The `PetscDualSpace` object
58920cf1dd8SToby Isaac
59020cf1dd8SToby Isaac Level: intermediate
59120cf1dd8SToby Isaac
592dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscSpace`, `PetscDualSpace`, `PetscFECreate()`, `PetscFESetBasisSpace()`
59320cf1dd8SToby Isaac @*/
PetscFESetDualSpace(PetscFE fem,PetscDualSpace sp)594d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFESetDualSpace(PetscFE fem, PetscDualSpace sp)
595d71ae5a4SJacob Faibussowitsch {
59620cf1dd8SToby Isaac PetscFunctionBegin;
59720cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1);
59820cf1dd8SToby Isaac PetscValidHeaderSpecific(sp, PETSCDUALSPACE_CLASSID, 2);
5999566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceDestroy(&fem->dualSpace));
60020cf1dd8SToby Isaac fem->dualSpace = sp;
6019566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)fem->dualSpace));
6023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
60320cf1dd8SToby Isaac }
60420cf1dd8SToby Isaac
60520cf1dd8SToby Isaac /*@
606dce8aebaSBarry Smith PetscFEGetQuadrature - Returns the `PetscQuadrature` used to calculate inner products
60720cf1dd8SToby Isaac
60820f4b53cSBarry Smith Not Collective
60920cf1dd8SToby Isaac
61020cf1dd8SToby Isaac Input Parameter:
611dce8aebaSBarry Smith . fem - The `PetscFE` object
61220cf1dd8SToby Isaac
61320cf1dd8SToby Isaac Output Parameter:
614dce8aebaSBarry Smith . q - The `PetscQuadrature` object
61520cf1dd8SToby Isaac
61620cf1dd8SToby Isaac Level: intermediate
61720cf1dd8SToby Isaac
618dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscSpace`, `PetscDualSpace`, `PetscQuadrature`, `PetscFECreate()`
61920cf1dd8SToby Isaac @*/
PetscFEGetQuadrature(PetscFE fem,PetscQuadrature * q)620d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEGetQuadrature(PetscFE fem, PetscQuadrature *q)
621d71ae5a4SJacob Faibussowitsch {
62220cf1dd8SToby Isaac PetscFunctionBegin;
62320cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1);
6244f572ea9SToby Isaac PetscAssertPointer(q, 2);
62520cf1dd8SToby Isaac *q = fem->quadrature;
6263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
62720cf1dd8SToby Isaac }
62820cf1dd8SToby Isaac
62920cf1dd8SToby Isaac /*@
630dce8aebaSBarry Smith PetscFESetQuadrature - Sets the `PetscQuadrature` used to calculate inner products
63120cf1dd8SToby Isaac
63220f4b53cSBarry Smith Not Collective
63320cf1dd8SToby Isaac
63420cf1dd8SToby Isaac Input Parameters:
635dce8aebaSBarry Smith + fem - The `PetscFE` object
636dce8aebaSBarry Smith - q - The `PetscQuadrature` object
63720cf1dd8SToby Isaac
63820cf1dd8SToby Isaac Level: intermediate
63920cf1dd8SToby Isaac
640dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscSpace`, `PetscDualSpace`, `PetscQuadrature`, `PetscFECreate()`, `PetscFEGetFaceQuadrature()`
64120cf1dd8SToby Isaac @*/
PetscFESetQuadrature(PetscFE fem,PetscQuadrature q)642d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFESetQuadrature(PetscFE fem, PetscQuadrature q)
643d71ae5a4SJacob Faibussowitsch {
64420cf1dd8SToby Isaac PetscInt Nc, qNc;
64520cf1dd8SToby Isaac
64620cf1dd8SToby Isaac PetscFunctionBegin;
64720cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1);
6483ba16761SJacob Faibussowitsch if (q == fem->quadrature) PetscFunctionReturn(PETSC_SUCCESS);
6499566063dSJacob Faibussowitsch PetscCall(PetscFEGetNumComponents(fem, &Nc));
6509566063dSJacob Faibussowitsch PetscCall(PetscQuadratureGetNumComponents(q, &qNc));
65163a3b9bcSJacob Faibussowitsch PetscCheck(!(qNc != 1) || !(Nc != qNc), PetscObjectComm((PetscObject)fem), PETSC_ERR_ARG_SIZ, "FE components %" PetscInt_FMT " != Quadrature components %" PetscInt_FMT " and non-scalar quadrature", Nc, qNc);
6529566063dSJacob Faibussowitsch PetscCall(PetscTabulationDestroy(&fem->T));
6539566063dSJacob Faibussowitsch PetscCall(PetscTabulationDestroy(&fem->Tc));
6549566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)q));
6559566063dSJacob Faibussowitsch PetscCall(PetscQuadratureDestroy(&fem->quadrature));
65620cf1dd8SToby Isaac fem->quadrature = q;
6573ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
65820cf1dd8SToby Isaac }
65920cf1dd8SToby Isaac
66020cf1dd8SToby Isaac /*@
661dce8aebaSBarry Smith PetscFEGetFaceQuadrature - Returns the `PetscQuadrature` used to calculate inner products on faces
66220cf1dd8SToby Isaac
66320f4b53cSBarry Smith Not Collective
66420cf1dd8SToby Isaac
66520cf1dd8SToby Isaac Input Parameter:
666dce8aebaSBarry Smith . fem - The `PetscFE` object
66720cf1dd8SToby Isaac
66820cf1dd8SToby Isaac Output Parameter:
669dce8aebaSBarry Smith . q - The `PetscQuadrature` object
67020cf1dd8SToby Isaac
67120cf1dd8SToby Isaac Level: intermediate
67220cf1dd8SToby Isaac
67360225df5SJacob Faibussowitsch Developer Notes:
67435cb6cd3SPierre Jolivet There is a special face quadrature but not edge, likely this API would benefit from a refactorization
675dce8aebaSBarry Smith
676dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscSpace`, `PetscDualSpace`, `PetscQuadrature`, `PetscFECreate()`, `PetscFESetQuadrature()`, `PetscFESetFaceQuadrature()`
67720cf1dd8SToby Isaac @*/
PetscFEGetFaceQuadrature(PetscFE fem,PetscQuadrature * q)678d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEGetFaceQuadrature(PetscFE fem, PetscQuadrature *q)
679d71ae5a4SJacob Faibussowitsch {
68020cf1dd8SToby Isaac PetscFunctionBegin;
68120cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1);
6824f572ea9SToby Isaac PetscAssertPointer(q, 2);
68320cf1dd8SToby Isaac *q = fem->faceQuadrature;
6843ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
68520cf1dd8SToby Isaac }
68620cf1dd8SToby Isaac
68720cf1dd8SToby Isaac /*@
688dce8aebaSBarry Smith PetscFESetFaceQuadrature - Sets the `PetscQuadrature` used to calculate inner products on faces
68920cf1dd8SToby Isaac
69020f4b53cSBarry Smith Not Collective
69120cf1dd8SToby Isaac
69220cf1dd8SToby Isaac Input Parameters:
693dce8aebaSBarry Smith + fem - The `PetscFE` object
694dce8aebaSBarry Smith - q - The `PetscQuadrature` object
69520cf1dd8SToby Isaac
69620cf1dd8SToby Isaac Level: intermediate
69720cf1dd8SToby Isaac
69842747ad1SJacob Faibussowitsch .seealso: `PetscFE`, `PetscSpace`, `PetscDualSpace`, `PetscQuadrature`, `PetscFECreate()`, `PetscFESetQuadrature()`
69920cf1dd8SToby Isaac @*/
PetscFESetFaceQuadrature(PetscFE fem,PetscQuadrature q)700d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFESetFaceQuadrature(PetscFE fem, PetscQuadrature q)
701d71ae5a4SJacob Faibussowitsch {
702ef0bb6c7SMatthew G. Knepley PetscInt Nc, qNc;
70320cf1dd8SToby Isaac
70420cf1dd8SToby Isaac PetscFunctionBegin;
70520cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1);
70626add6b9SMatthew G. Knepley if (q == fem->faceQuadrature) PetscFunctionReturn(PETSC_SUCCESS);
7079566063dSJacob Faibussowitsch PetscCall(PetscFEGetNumComponents(fem, &Nc));
7089566063dSJacob Faibussowitsch PetscCall(PetscQuadratureGetNumComponents(q, &qNc));
70963a3b9bcSJacob Faibussowitsch PetscCheck(!(qNc != 1) || !(Nc != qNc), PetscObjectComm((PetscObject)fem), PETSC_ERR_ARG_SIZ, "FE components %" PetscInt_FMT " != Quadrature components %" PetscInt_FMT " and non-scalar quadrature", Nc, qNc);
7109566063dSJacob Faibussowitsch PetscCall(PetscTabulationDestroy(&fem->Tf));
71126add6b9SMatthew G. Knepley PetscCall(PetscObjectReference((PetscObject)q));
7129566063dSJacob Faibussowitsch PetscCall(PetscQuadratureDestroy(&fem->faceQuadrature));
71320cf1dd8SToby Isaac fem->faceQuadrature = q;
7143ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
71520cf1dd8SToby Isaac }
71620cf1dd8SToby Isaac
7175dc5c000SMatthew G. Knepley /*@
718dce8aebaSBarry Smith PetscFECopyQuadrature - Copy both volumetric and surface quadrature to a new `PetscFE`
7195dc5c000SMatthew G. Knepley
72020f4b53cSBarry Smith Not Collective
7215dc5c000SMatthew G. Knepley
7225dc5c000SMatthew G. Knepley Input Parameters:
723dce8aebaSBarry Smith + sfe - The `PetscFE` source for the quadratures
724dce8aebaSBarry Smith - tfe - The `PetscFE` target for the quadratures
7255dc5c000SMatthew G. Knepley
7265dc5c000SMatthew G. Knepley Level: intermediate
7275dc5c000SMatthew G. Knepley
728dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscSpace`, `PetscDualSpace`, `PetscQuadrature`, `PetscFECreate()`, `PetscFESetQuadrature()`, `PetscFESetFaceQuadrature()`
7295dc5c000SMatthew G. Knepley @*/
PetscFECopyQuadrature(PetscFE sfe,PetscFE tfe)730d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFECopyQuadrature(PetscFE sfe, PetscFE tfe)
731d71ae5a4SJacob Faibussowitsch {
7325dc5c000SMatthew G. Knepley PetscQuadrature q;
7335dc5c000SMatthew G. Knepley
7345dc5c000SMatthew G. Knepley PetscFunctionBegin;
7355dc5c000SMatthew G. Knepley PetscValidHeaderSpecific(sfe, PETSCFE_CLASSID, 1);
7365dc5c000SMatthew G. Knepley PetscValidHeaderSpecific(tfe, PETSCFE_CLASSID, 2);
7379566063dSJacob Faibussowitsch PetscCall(PetscFEGetQuadrature(sfe, &q));
7389566063dSJacob Faibussowitsch PetscCall(PetscFESetQuadrature(tfe, q));
7399566063dSJacob Faibussowitsch PetscCall(PetscFEGetFaceQuadrature(sfe, &q));
7409566063dSJacob Faibussowitsch PetscCall(PetscFESetFaceQuadrature(tfe, q));
7413ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
7425dc5c000SMatthew G. Knepley }
7435dc5c000SMatthew G. Knepley
74420cf1dd8SToby Isaac /*@C
74520cf1dd8SToby Isaac PetscFEGetNumDof - Returns the number of dofs (dual basis vectors) associated to mesh points on the reference cell of a given dimension
74620cf1dd8SToby Isaac
74720f4b53cSBarry Smith Not Collective
74820cf1dd8SToby Isaac
74920cf1dd8SToby Isaac Input Parameter:
750dce8aebaSBarry Smith . fem - The `PetscFE` object
75120cf1dd8SToby Isaac
75220cf1dd8SToby Isaac Output Parameter:
753f13dfd9eSBarry Smith . numDof - Array of length `dim` with the number of dofs in each dimension
75420cf1dd8SToby Isaac
75520cf1dd8SToby Isaac Level: intermediate
75620cf1dd8SToby Isaac
757dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscSpace`, `PetscDualSpace`, `PetscFECreate()`
75820cf1dd8SToby Isaac @*/
PetscFEGetNumDof(PetscFE fem,const PetscInt * numDof[])759f13dfd9eSBarry Smith PetscErrorCode PetscFEGetNumDof(PetscFE fem, const PetscInt *numDof[])
760d71ae5a4SJacob Faibussowitsch {
76120cf1dd8SToby Isaac PetscFunctionBegin;
76220cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1);
7634f572ea9SToby Isaac PetscAssertPointer(numDof, 2);
7649566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetNumDof(fem->dualSpace, numDof));
7653ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
76620cf1dd8SToby Isaac }
76720cf1dd8SToby Isaac
76820cf1dd8SToby Isaac /*@C
769ef0bb6c7SMatthew G. Knepley PetscFEGetCellTabulation - Returns the tabulation of the basis functions at the quadrature points on the reference cell
77020cf1dd8SToby Isaac
77120f4b53cSBarry Smith Not Collective
77220cf1dd8SToby Isaac
773d8d19677SJose E. Roman Input Parameters:
774dce8aebaSBarry Smith + fem - The `PetscFE` object
775f9244615SMatthew G. Knepley - k - The highest derivative we need to tabulate, very often 1
77620cf1dd8SToby Isaac
777ef0bb6c7SMatthew G. Knepley Output Parameter:
778ef0bb6c7SMatthew G. Knepley . T - The basis function values and derivatives at quadrature points
77920cf1dd8SToby Isaac
78020cf1dd8SToby Isaac Level: intermediate
78120cf1dd8SToby Isaac
782dce8aebaSBarry Smith Note:
783dce8aebaSBarry Smith .vb
784dce8aebaSBarry Smith T->T[0] = B[(p*pdim + i)*Nc + c] is the value at point p for basis function i and component c
785dce8aebaSBarry Smith T->T[1] = D[((p*pdim + i)*Nc + c)*dim + d] is the derivative value at point p for basis function i, component c, in direction d
786dce8aebaSBarry Smith T->T[2] = H[(((p*pdim + i)*Nc + c)*dim + d)*dim + e] is the value at point p for basis function i, component c, in directions d and e
787dce8aebaSBarry Smith .ve
788dce8aebaSBarry Smith
789dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscSpace`, `PetscDualSpace`, `PetscTabulation`, `PetscFECreateTabulation()`, `PetscTabulationDestroy()`
79020cf1dd8SToby Isaac @*/
PetscFEGetCellTabulation(PetscFE fem,PetscInt k,PetscTabulation * T)791d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEGetCellTabulation(PetscFE fem, PetscInt k, PetscTabulation *T)
792d71ae5a4SJacob Faibussowitsch {
79320cf1dd8SToby Isaac PetscInt npoints;
79420cf1dd8SToby Isaac const PetscReal *points;
79520cf1dd8SToby Isaac
79620cf1dd8SToby Isaac PetscFunctionBegin;
79720cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1);
7984f572ea9SToby Isaac PetscAssertPointer(T, 3);
7999566063dSJacob Faibussowitsch PetscCall(PetscQuadratureGetData(fem->quadrature, NULL, NULL, &npoints, &points, NULL));
8009566063dSJacob Faibussowitsch if (!fem->T) PetscCall(PetscFECreateTabulation(fem, 1, npoints, points, k, &fem->T));
801aa9788aaSMatthew G. Knepley PetscCheck(!fem->T || k <= fem->T->K || (!fem->T->cdim && !fem->T->K), PetscObjectComm((PetscObject)fem), PETSC_ERR_ARG_OUTOFRANGE, "Requested %" PetscInt_FMT " derivatives, but only tabulated %" PetscInt_FMT, k, fem->T->K);
802ef0bb6c7SMatthew G. Knepley *T = fem->T;
8033ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
80420cf1dd8SToby Isaac }
80520cf1dd8SToby Isaac
PetscFEExpandFaceQuadrature(PetscFE fe,PetscQuadrature fq,PetscQuadrature * efq)806989fa639SBrad Aagaard PetscErrorCode PetscFEExpandFaceQuadrature(PetscFE fe, PetscQuadrature fq, PetscQuadrature *efq)
807989fa639SBrad Aagaard {
808989fa639SBrad Aagaard DM dm;
809989fa639SBrad Aagaard PetscDualSpace sp;
810989fa639SBrad Aagaard const PetscInt *faces;
811989fa639SBrad Aagaard const PetscReal *points, *weights;
812989fa639SBrad Aagaard DMPolytopeType ct;
813989fa639SBrad Aagaard PetscReal *facePoints, *faceWeights;
814989fa639SBrad Aagaard PetscInt dim, cStart, Nf, Nc, Np, order;
815989fa639SBrad Aagaard
816989fa639SBrad Aagaard PetscFunctionBegin;
817989fa639SBrad Aagaard PetscCall(PetscFEGetDualSpace(fe, &sp));
818989fa639SBrad Aagaard PetscCall(PetscDualSpaceGetDM(sp, &dm));
819989fa639SBrad Aagaard PetscCall(DMGetDimension(dm, &dim));
820989fa639SBrad Aagaard PetscCall(DMPlexGetHeightStratum(dm, 0, &cStart, NULL));
821989fa639SBrad Aagaard PetscCall(DMPlexGetConeSize(dm, cStart, &Nf));
822989fa639SBrad Aagaard PetscCall(DMPlexGetCone(dm, cStart, &faces));
823989fa639SBrad Aagaard PetscCall(PetscQuadratureGetData(fq, NULL, &Nc, &Np, &points, &weights));
824989fa639SBrad Aagaard PetscCall(PetscMalloc1(Nf * Np * dim, &facePoints));
825989fa639SBrad Aagaard PetscCall(PetscMalloc1(Nf * Np * Nc, &faceWeights));
826989fa639SBrad Aagaard for (PetscInt f = 0; f < Nf; ++f) {
827989fa639SBrad Aagaard const PetscReal xi0[3] = {-1., -1., -1.};
828989fa639SBrad Aagaard PetscReal v0[3], J[9], detJ;
829989fa639SBrad Aagaard
830989fa639SBrad Aagaard PetscCall(DMPlexComputeCellGeometryFEM(dm, faces[f], NULL, v0, J, NULL, &detJ));
831989fa639SBrad Aagaard for (PetscInt q = 0; q < Np; ++q) {
832989fa639SBrad Aagaard CoordinatesRefToReal(dim, dim - 1, xi0, v0, J, &points[q * (dim - 1)], &facePoints[(f * Np + q) * dim]);
833989fa639SBrad Aagaard for (PetscInt c = 0; c < Nc; ++c) faceWeights[(f * Np + q) * Nc + c] = weights[q * Nc + c];
834989fa639SBrad Aagaard }
835989fa639SBrad Aagaard }
836989fa639SBrad Aagaard PetscCall(PetscQuadratureCreate(PetscObjectComm((PetscObject)fq), efq));
837989fa639SBrad Aagaard PetscCall(PetscQuadratureGetCellType(fq, &ct));
838989fa639SBrad Aagaard PetscCall(PetscQuadratureSetCellType(*efq, ct));
839989fa639SBrad Aagaard PetscCall(PetscQuadratureGetOrder(fq, &order));
840989fa639SBrad Aagaard PetscCall(PetscQuadratureSetOrder(*efq, order));
841989fa639SBrad Aagaard PetscCall(PetscQuadratureSetData(*efq, dim, Nc, Nf * Np, facePoints, faceWeights));
842989fa639SBrad Aagaard PetscFunctionReturn(PETSC_SUCCESS);
843989fa639SBrad Aagaard }
844989fa639SBrad Aagaard
8452b99622eSMatthew G. Knepley /*@C
846ef0bb6c7SMatthew G. Knepley PetscFEGetFaceTabulation - Returns the tabulation of the basis functions at the face quadrature points for each face of the reference cell
8472b99622eSMatthew G. Knepley
84820f4b53cSBarry Smith Not Collective
8492b99622eSMatthew G. Knepley
850d8d19677SJose E. Roman Input Parameters:
851dce8aebaSBarry Smith + fem - The `PetscFE` object
852f9244615SMatthew G. Knepley - k - The highest derivative we need to tabulate, very often 1
8532b99622eSMatthew G. Knepley
8542fe279fdSBarry Smith Output Parameter:
855a5b23f4aSJose E. Roman . Tf - The basis function values and derivatives at face quadrature points
8562b99622eSMatthew G. Knepley
8572b99622eSMatthew G. Knepley Level: intermediate
8582b99622eSMatthew G. Knepley
859dce8aebaSBarry Smith Note:
860dce8aebaSBarry Smith .vb
861dce8aebaSBarry Smith T->T[0] = Bf[((f*Nq + q)*pdim + i)*Nc + c] is the value at point f,q for basis function i and component c
862dce8aebaSBarry Smith T->T[1] = Df[(((f*Nq + q)*pdim + i)*Nc + c)*dim + d] is the derivative value at point f,q for basis function i, component c, in direction d
863dce8aebaSBarry Smith T->T[2] = Hf[((((f*Nq + q)*pdim + i)*Nc + c)*dim + d)*dim + e] is the value at point f,q for basis function i, component c, in directions d and e
864dce8aebaSBarry Smith .ve
865dce8aebaSBarry Smith
866dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscSpace`, `PetscDualSpace`, `PetscTabulation`, `PetscFEGetCellTabulation()`, `PetscFECreateTabulation()`, `PetscTabulationDestroy()`
8672b99622eSMatthew G. Knepley @*/
PetscFEGetFaceTabulation(PetscFE fem,PetscInt k,PetscTabulation * Tf)868d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEGetFaceTabulation(PetscFE fem, PetscInt k, PetscTabulation *Tf)
869d71ae5a4SJacob Faibussowitsch {
87020cf1dd8SToby Isaac PetscFunctionBegin;
87120cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1);
8724f572ea9SToby Isaac PetscAssertPointer(Tf, 3);
873ef0bb6c7SMatthew G. Knepley if (!fem->Tf) {
87420cf1dd8SToby Isaac PetscQuadrature fq;
875989fa639SBrad Aagaard
876989fa639SBrad Aagaard PetscCall(PetscFEGetFaceQuadrature(fem, &fq));
877989fa639SBrad Aagaard if (fq) {
878989fa639SBrad Aagaard PetscQuadrature efq;
879989fa639SBrad Aagaard const PetscReal *facePoints;
880989fa639SBrad Aagaard PetscInt Np, eNp;
881989fa639SBrad Aagaard
882989fa639SBrad Aagaard PetscCall(PetscFEExpandFaceQuadrature(fem, fq, &efq));
883989fa639SBrad Aagaard PetscCall(PetscQuadratureGetData(fq, NULL, NULL, &Np, NULL, NULL));
884989fa639SBrad Aagaard PetscCall(PetscQuadratureGetData(efq, NULL, NULL, &eNp, &facePoints, NULL));
885989fa639SBrad Aagaard if (PetscDefined(USE_DEBUG)) {
88620cf1dd8SToby Isaac PetscDualSpace sp;
88720cf1dd8SToby Isaac DM dm;
888989fa639SBrad Aagaard PetscInt cStart, Nf;
88920cf1dd8SToby Isaac
8909566063dSJacob Faibussowitsch PetscCall(PetscFEGetDualSpace(fem, &sp));
8919566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetDM(sp, &dm));
892989fa639SBrad Aagaard PetscCall(DMPlexGetHeightStratum(dm, 0, &cStart, NULL));
893989fa639SBrad Aagaard PetscCall(DMPlexGetConeSize(dm, cStart, &Nf));
894989fa639SBrad Aagaard PetscCheck(Nf == eNp / Np, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Number of faces %" PetscInt_FMT " != %" PetscInt_FMT " number of quadrature replicas", Nf, eNp / Np);
89520cf1dd8SToby Isaac }
896989fa639SBrad Aagaard PetscCall(PetscFECreateTabulation(fem, eNp / Np, Np, facePoints, k, &fem->Tf));
897989fa639SBrad Aagaard PetscCall(PetscQuadratureDestroy(&efq));
89820cf1dd8SToby Isaac }
89920cf1dd8SToby Isaac }
9001dca8a05SBarry Smith PetscCheck(!fem->Tf || k <= fem->Tf->K, PetscObjectComm((PetscObject)fem), PETSC_ERR_ARG_OUTOFRANGE, "Requested %" PetscInt_FMT " derivatives, but only tabulated %" PetscInt_FMT, k, fem->Tf->K);
901ef0bb6c7SMatthew G. Knepley *Tf = fem->Tf;
9023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
90320cf1dd8SToby Isaac }
90420cf1dd8SToby Isaac
9052b99622eSMatthew G. Knepley /*@C
906ef0bb6c7SMatthew G. Knepley PetscFEGetFaceCentroidTabulation - Returns the tabulation of the basis functions at the face centroid points
9072b99622eSMatthew G. Knepley
90820f4b53cSBarry Smith Not Collective
9092b99622eSMatthew G. Knepley
9102b99622eSMatthew G. Knepley Input Parameter:
911dce8aebaSBarry Smith . fem - The `PetscFE` object
9122b99622eSMatthew G. Knepley
9132fe279fdSBarry Smith Output Parameter:
914ef0bb6c7SMatthew G. Knepley . Tc - The basis function values at face centroid points
9152b99622eSMatthew G. Knepley
9162b99622eSMatthew G. Knepley Level: intermediate
9172b99622eSMatthew G. Knepley
918dce8aebaSBarry Smith Note:
919dce8aebaSBarry Smith .vb
920dce8aebaSBarry Smith T->T[0] = Bf[(f*pdim + i)*Nc + c] is the value at point f for basis function i and component c
921dce8aebaSBarry Smith .ve
922dce8aebaSBarry Smith
923dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscSpace`, `PetscDualSpace`, `PetscTabulation`, `PetscFEGetFaceTabulation()`, `PetscFEGetCellTabulation()`, `PetscFECreateTabulation()`, `PetscTabulationDestroy()`
9242b99622eSMatthew G. Knepley @*/
PetscFEGetFaceCentroidTabulation(PetscFE fem,PetscTabulation * Tc)925d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEGetFaceCentroidTabulation(PetscFE fem, PetscTabulation *Tc)
926d71ae5a4SJacob Faibussowitsch {
92720cf1dd8SToby Isaac PetscFunctionBegin;
92820cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1);
9294f572ea9SToby Isaac PetscAssertPointer(Tc, 2);
930ef0bb6c7SMatthew G. Knepley if (!fem->Tc) {
93120cf1dd8SToby Isaac PetscDualSpace sp;
93220cf1dd8SToby Isaac DM dm;
93320cf1dd8SToby Isaac const PetscInt *cone;
93420cf1dd8SToby Isaac PetscReal *centroids;
93520cf1dd8SToby Isaac PetscInt dim, numFaces, f;
93620cf1dd8SToby Isaac
9379566063dSJacob Faibussowitsch PetscCall(PetscFEGetDualSpace(fem, &sp));
9389566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetDM(sp, &dm));
9399566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &dim));
9409566063dSJacob Faibussowitsch PetscCall(DMPlexGetConeSize(dm, 0, &numFaces));
9419566063dSJacob Faibussowitsch PetscCall(DMPlexGetCone(dm, 0, &cone));
9429566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(numFaces * dim, ¢roids));
9439566063dSJacob Faibussowitsch for (f = 0; f < numFaces; ++f) PetscCall(DMPlexComputeCellGeometryFVM(dm, cone[f], NULL, ¢roids[f * dim], NULL));
9449566063dSJacob Faibussowitsch PetscCall(PetscFECreateTabulation(fem, 1, numFaces, centroids, 0, &fem->Tc));
9459566063dSJacob Faibussowitsch PetscCall(PetscFree(centroids));
94620cf1dd8SToby Isaac }
947ef0bb6c7SMatthew G. Knepley *Tc = fem->Tc;
9483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
94920cf1dd8SToby Isaac }
95020cf1dd8SToby Isaac
95120cf1dd8SToby Isaac /*@C
952ef0bb6c7SMatthew G. Knepley PetscFECreateTabulation - Tabulates the basis functions, and perhaps derivatives, at the points provided.
95320cf1dd8SToby Isaac
95420f4b53cSBarry Smith Not Collective
95520cf1dd8SToby Isaac
95620cf1dd8SToby Isaac Input Parameters:
957dce8aebaSBarry Smith + fem - The `PetscFE` object
958ef0bb6c7SMatthew G. Knepley . nrepl - The number of replicas
959ef0bb6c7SMatthew G. Knepley . npoints - The number of tabulation points in a replica
960ef0bb6c7SMatthew G. Knepley . points - The tabulation point coordinates
961ef0bb6c7SMatthew G. Knepley - K - The number of derivatives calculated
96220cf1dd8SToby Isaac
963ef0bb6c7SMatthew G. Knepley Output Parameter:
964ef0bb6c7SMatthew G. Knepley . T - The basis function values and derivatives at tabulation points
96520cf1dd8SToby Isaac
96620cf1dd8SToby Isaac Level: intermediate
96720cf1dd8SToby Isaac
968dce8aebaSBarry Smith Note:
969dce8aebaSBarry Smith .vb
970dce8aebaSBarry Smith T->T[0] = B[(p*pdim + i)*Nc + c] is the value at point p for basis function i and component c
971dce8aebaSBarry Smith T->T[1] = D[((p*pdim + i)*Nc + c)*dim + d] is the derivative value at point p for basis function i, component c, in direction d
972a4e35b19SJacob Faibussowitsch T->T[2] = H[(((p*pdim + i)*Nc + c)*dim + d)*dim + e] is the value at point p for basis
973a4e35b19SJacob Faibussowitsch T->function i, component c, in directions d and e
974a4e35b19SJacob Faibussowitsch .ve
975dce8aebaSBarry Smith
976dce8aebaSBarry Smith .seealso: `PetscTabulation`, `PetscFEGetCellTabulation()`, `PetscTabulationDestroy()`
97720cf1dd8SToby Isaac @*/
PetscFECreateTabulation(PetscFE fem,PetscInt nrepl,PetscInt npoints,const PetscReal points[],PetscInt K,PetscTabulation * T)978d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFECreateTabulation(PetscFE fem, PetscInt nrepl, PetscInt npoints, const PetscReal points[], PetscInt K, PetscTabulation *T)
979d71ae5a4SJacob Faibussowitsch {
98020cf1dd8SToby Isaac DM dm;
981ef0bb6c7SMatthew G. Knepley PetscDualSpace Q;
982ef0bb6c7SMatthew G. Knepley PetscInt Nb; /* Dimension of FE space P */
983ef0bb6c7SMatthew G. Knepley PetscInt Nc; /* Field components */
984ef0bb6c7SMatthew G. Knepley PetscInt cdim; /* Reference coordinate dimension */
985ef0bb6c7SMatthew G. Knepley PetscInt k;
98620cf1dd8SToby Isaac
98720cf1dd8SToby Isaac PetscFunctionBegin;
988ef0bb6c7SMatthew G. Knepley if (!npoints || !fem->dualSpace || K < 0) {
989ef0bb6c7SMatthew G. Knepley *T = NULL;
9903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
99120cf1dd8SToby Isaac }
99220cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1);
9934f572ea9SToby Isaac PetscAssertPointer(points, 4);
9944f572ea9SToby Isaac PetscAssertPointer(T, 6);
9959566063dSJacob Faibussowitsch PetscCall(PetscFEGetDualSpace(fem, &Q));
9969566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetDM(Q, &dm));
9979566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &cdim));
9989566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetDimension(Q, &Nb));
9999566063dSJacob Faibussowitsch PetscCall(PetscFEGetNumComponents(fem, &Nc));
10009566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(1, T));
1001ef0bb6c7SMatthew G. Knepley (*T)->K = !cdim ? 0 : K;
1002ef0bb6c7SMatthew G. Knepley (*T)->Nr = nrepl;
1003ef0bb6c7SMatthew G. Knepley (*T)->Np = npoints;
1004ef0bb6c7SMatthew G. Knepley (*T)->Nb = Nb;
1005ef0bb6c7SMatthew G. Knepley (*T)->Nc = Nc;
1006ef0bb6c7SMatthew G. Knepley (*T)->cdim = cdim;
10079566063dSJacob Faibussowitsch PetscCall(PetscMalloc1((*T)->K + 1, &(*T)->T));
10082dce792eSToby Isaac for (k = 0; k <= (*T)->K; ++k) PetscCall(PetscCalloc1(nrepl * npoints * Nb * Nc * PetscPowInt(cdim, k), &(*T)->T[k]));
1009ce78bad3SBarry Smith PetscUseTypeMethod(fem, computetabulation, nrepl * npoints, points, K, *T);
10103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
101120cf1dd8SToby Isaac }
101220cf1dd8SToby Isaac
10132b99622eSMatthew G. Knepley /*@C
1014ef0bb6c7SMatthew G. Knepley PetscFEComputeTabulation - Tabulates the basis functions, and perhaps derivatives, at the points provided.
10152b99622eSMatthew G. Knepley
101620f4b53cSBarry Smith Not Collective
10172b99622eSMatthew G. Knepley
10182b99622eSMatthew G. Knepley Input Parameters:
1019dce8aebaSBarry Smith + fem - The `PetscFE` object
10202b99622eSMatthew G. Knepley . npoints - The number of tabulation points
10212b99622eSMatthew G. Knepley . points - The tabulation point coordinates
1022ef0bb6c7SMatthew G. Knepley . K - The number of derivatives calculated
1023ef0bb6c7SMatthew G. Knepley - T - An existing tabulation object with enough allocated space
1024ef0bb6c7SMatthew G. Knepley
1025ef0bb6c7SMatthew G. Knepley Output Parameter:
1026ef0bb6c7SMatthew G. Knepley . T - The basis function values and derivatives at tabulation points
10272b99622eSMatthew G. Knepley
10282b99622eSMatthew G. Knepley Level: intermediate
10292b99622eSMatthew G. Knepley
1030dce8aebaSBarry Smith Note:
1031dce8aebaSBarry Smith .vb
1032dce8aebaSBarry Smith T->T[0] = B[(p*pdim + i)*Nc + c] is the value at point p for basis function i and component c
1033dce8aebaSBarry Smith T->T[1] = D[((p*pdim + i)*Nc + c)*dim + d] is the derivative value at point p for basis function i, component c, in direction d
1034dce8aebaSBarry Smith T->T[2] = H[(((p*pdim + i)*Nc + c)*dim + d)*dim + e] is the value at point p for basis function i, component c, in directions d and e
1035dce8aebaSBarry Smith .ve
1036dce8aebaSBarry Smith
1037dce8aebaSBarry Smith .seealso: `PetscTabulation`, `PetscFEGetCellTabulation()`, `PetscTabulationDestroy()`
10382b99622eSMatthew G. Knepley @*/
PetscFEComputeTabulation(PetscFE fem,PetscInt npoints,const PetscReal points[],PetscInt K,PetscTabulation T)1039d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEComputeTabulation(PetscFE fem, PetscInt npoints, const PetscReal points[], PetscInt K, PetscTabulation T)
1040d71ae5a4SJacob Faibussowitsch {
1041ef0bb6c7SMatthew G. Knepley PetscFunctionBeginHot;
10423ba16761SJacob Faibussowitsch if (!npoints || !fem->dualSpace || K < 0) PetscFunctionReturn(PETSC_SUCCESS);
1043ef0bb6c7SMatthew G. Knepley PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1);
10444f572ea9SToby Isaac PetscAssertPointer(points, 3);
10454f572ea9SToby Isaac PetscAssertPointer(T, 5);
104676bd3646SJed Brown if (PetscDefined(USE_DEBUG)) {
104720cf1dd8SToby Isaac DM dm;
1048ef0bb6c7SMatthew G. Knepley PetscDualSpace Q;
1049ef0bb6c7SMatthew G. Knepley PetscInt Nb; /* Dimension of FE space P */
1050ef0bb6c7SMatthew G. Knepley PetscInt Nc; /* Field components */
1051ef0bb6c7SMatthew G. Knepley PetscInt cdim; /* Reference coordinate dimension */
1052ef0bb6c7SMatthew G. Knepley
10539566063dSJacob Faibussowitsch PetscCall(PetscFEGetDualSpace(fem, &Q));
10549566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetDM(Q, &dm));
10559566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &cdim));
10569566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetDimension(Q, &Nb));
10579566063dSJacob Faibussowitsch PetscCall(PetscFEGetNumComponents(fem, &Nc));
105863a3b9bcSJacob Faibussowitsch PetscCheck(T->K == (!cdim ? 0 : K), PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Tabulation K %" PetscInt_FMT " must match requested K %" PetscInt_FMT, T->K, !cdim ? 0 : K);
105963a3b9bcSJacob Faibussowitsch PetscCheck(T->Nb == Nb, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Tabulation Nb %" PetscInt_FMT " must match requested Nb %" PetscInt_FMT, T->Nb, Nb);
106063a3b9bcSJacob Faibussowitsch PetscCheck(T->Nc == Nc, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Tabulation Nc %" PetscInt_FMT " must match requested Nc %" PetscInt_FMT, T->Nc, Nc);
106163a3b9bcSJacob Faibussowitsch PetscCheck(T->cdim == cdim, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Tabulation cdim %" PetscInt_FMT " must match requested cdim %" PetscInt_FMT, T->cdim, cdim);
1062ef0bb6c7SMatthew G. Knepley }
1063ef0bb6c7SMatthew G. Knepley T->Nr = 1;
1064ef0bb6c7SMatthew G. Knepley T->Np = npoints;
1065ce78bad3SBarry Smith PetscUseTypeMethod(fem, computetabulation, npoints, points, K, T);
10663ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1067ef0bb6c7SMatthew G. Knepley }
1068ef0bb6c7SMatthew G. Knepley
1069cc4c1da9SBarry Smith /*@
1070ef0bb6c7SMatthew G. Knepley PetscTabulationDestroy - Frees memory from the associated tabulation.
1071ef0bb6c7SMatthew G. Knepley
107220f4b53cSBarry Smith Not Collective
1073ef0bb6c7SMatthew G. Knepley
1074ef0bb6c7SMatthew G. Knepley Input Parameter:
1075ef0bb6c7SMatthew G. Knepley . T - The tabulation
1076ef0bb6c7SMatthew G. Knepley
1077ef0bb6c7SMatthew G. Knepley Level: intermediate
1078ef0bb6c7SMatthew G. Knepley
1079dce8aebaSBarry Smith .seealso: `PetscTabulation`, `PetscFECreateTabulation()`, `PetscFEGetCellTabulation()`
1080ef0bb6c7SMatthew G. Knepley @*/
PetscTabulationDestroy(PetscTabulation * T)1081d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscTabulationDestroy(PetscTabulation *T)
1082d71ae5a4SJacob Faibussowitsch {
1083ef0bb6c7SMatthew G. Knepley PetscInt k;
108420cf1dd8SToby Isaac
108520cf1dd8SToby Isaac PetscFunctionBegin;
10864f572ea9SToby Isaac PetscAssertPointer(T, 1);
108757508eceSPierre Jolivet if (!T || !*T) PetscFunctionReturn(PETSC_SUCCESS);
10889566063dSJacob Faibussowitsch for (k = 0; k <= (*T)->K; ++k) PetscCall(PetscFree((*T)->T[k]));
10899566063dSJacob Faibussowitsch PetscCall(PetscFree((*T)->T));
10909566063dSJacob Faibussowitsch PetscCall(PetscFree(*T));
1091ef0bb6c7SMatthew G. Knepley *T = NULL;
10923ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
109320cf1dd8SToby Isaac }
109420cf1dd8SToby Isaac
PetscFECreatePointTraceDefault_Internal(PetscFE fe,PetscInt refPoint,PetscFE * trFE)10952dce792eSToby Isaac static PetscErrorCode PetscFECreatePointTraceDefault_Internal(PetscFE fe, PetscInt refPoint, PetscFE *trFE)
1096d71ae5a4SJacob Faibussowitsch {
109720cf1dd8SToby Isaac PetscSpace bsp, bsubsp;
109820cf1dd8SToby Isaac PetscDualSpace dsp, dsubsp;
109920cf1dd8SToby Isaac PetscInt dim, depth, numComp, i, j, coneSize, order;
110020cf1dd8SToby Isaac DM dm;
110120cf1dd8SToby Isaac DMLabel label;
110220cf1dd8SToby Isaac PetscReal *xi, *v, *J, detJ;
1103db11e2ebSMatthew G. Knepley const char *name;
110420cf1dd8SToby Isaac PetscQuadrature origin, fullQuad, subQuad;
110520cf1dd8SToby Isaac
110620cf1dd8SToby Isaac PetscFunctionBegin;
11079566063dSJacob Faibussowitsch PetscCall(PetscFEGetBasisSpace(fe, &bsp));
11089566063dSJacob Faibussowitsch PetscCall(PetscFEGetDualSpace(fe, &dsp));
11099566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetDM(dsp, &dm));
11109566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &dim));
11119566063dSJacob Faibussowitsch PetscCall(DMPlexGetDepthLabel(dm, &label));
11129566063dSJacob Faibussowitsch PetscCall(DMLabelGetValue(label, refPoint, &depth));
11139566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(depth, &xi));
11149566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(dim, &v));
11159566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(dim * dim, &J));
111620cf1dd8SToby Isaac for (i = 0; i < depth; i++) xi[i] = 0.;
11179566063dSJacob Faibussowitsch PetscCall(PetscQuadratureCreate(PETSC_COMM_SELF, &origin));
11189566063dSJacob Faibussowitsch PetscCall(PetscQuadratureSetData(origin, depth, 0, 1, xi, NULL));
11199566063dSJacob Faibussowitsch PetscCall(DMPlexComputeCellGeometryFEM(dm, refPoint, origin, v, J, NULL, &detJ));
112020cf1dd8SToby Isaac /* CellGeometryFEM computes the expanded Jacobian, we want the true jacobian */
112120cf1dd8SToby Isaac for (i = 1; i < dim; i++) {
1122ad540459SPierre Jolivet for (j = 0; j < depth; j++) J[i * depth + j] = J[i * dim + j];
112320cf1dd8SToby Isaac }
11249566063dSJacob Faibussowitsch PetscCall(PetscQuadratureDestroy(&origin));
11259566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetPointSubspace(dsp, refPoint, &dsubsp));
11269566063dSJacob Faibussowitsch PetscCall(PetscSpaceCreateSubspace(bsp, dsubsp, v, J, NULL, NULL, PETSC_OWN_POINTER, &bsubsp));
11279566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetUp(bsubsp));
11289566063dSJacob Faibussowitsch PetscCall(PetscFECreate(PetscObjectComm((PetscObject)fe), trFE));
11292dce792eSToby Isaac PetscCall(PetscFESetType(*trFE, PETSCFEBASIC));
11309566063dSJacob Faibussowitsch PetscCall(PetscFEGetNumComponents(fe, &numComp));
11319566063dSJacob Faibussowitsch PetscCall(PetscFESetNumComponents(*trFE, numComp));
11329566063dSJacob Faibussowitsch PetscCall(PetscFESetBasisSpace(*trFE, bsubsp));
11339566063dSJacob Faibussowitsch PetscCall(PetscFESetDualSpace(*trFE, dsubsp));
11349566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)fe, &name));
11359566063dSJacob Faibussowitsch if (name) PetscCall(PetscFESetName(*trFE, name));
11369566063dSJacob Faibussowitsch PetscCall(PetscFEGetQuadrature(fe, &fullQuad));
11379566063dSJacob Faibussowitsch PetscCall(PetscQuadratureGetOrder(fullQuad, &order));
11389566063dSJacob Faibussowitsch PetscCall(DMPlexGetConeSize(dm, refPoint, &coneSize));
11398b6ef6a4SJed Brown if (coneSize == 2 * depth) PetscCall(PetscDTGaussTensorQuadrature(depth, 1, (order + 2) / 2, -1., 1., &subQuad));
11408b6ef6a4SJed Brown else PetscCall(PetscDTSimplexQuadrature(depth, order, PETSCDTSIMPLEXQUAD_DEFAULT, &subQuad));
11419566063dSJacob Faibussowitsch PetscCall(PetscFESetQuadrature(*trFE, subQuad));
11429566063dSJacob Faibussowitsch PetscCall(PetscFESetUp(*trFE));
11439566063dSJacob Faibussowitsch PetscCall(PetscQuadratureDestroy(&subQuad));
11449566063dSJacob Faibussowitsch PetscCall(PetscSpaceDestroy(&bsubsp));
11453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
114620cf1dd8SToby Isaac }
114720cf1dd8SToby Isaac
PetscFECreatePointTrace(PetscFE fe,PetscInt refPoint,PetscFE * trFE)11482dce792eSToby Isaac PETSC_EXTERN PetscErrorCode PetscFECreatePointTrace(PetscFE fe, PetscInt refPoint, PetscFE *trFE)
11492dce792eSToby Isaac {
11502dce792eSToby Isaac PetscFunctionBegin;
11512dce792eSToby Isaac PetscValidHeaderSpecific(fe, PETSCFE_CLASSID, 1);
11522dce792eSToby Isaac PetscAssertPointer(trFE, 3);
11539927e4dfSBarry Smith if (fe->ops->createpointtrace) PetscUseTypeMethod(fe, createpointtrace, refPoint, trFE);
11549927e4dfSBarry Smith else PetscCall(PetscFECreatePointTraceDefault_Internal(fe, refPoint, trFE));
11552dce792eSToby Isaac PetscFunctionReturn(PETSC_SUCCESS);
11562dce792eSToby Isaac }
11572dce792eSToby Isaac
PetscFECreateHeightTrace(PetscFE fe,PetscInt height,PetscFE * trFE)1158d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFECreateHeightTrace(PetscFE fe, PetscInt height, PetscFE *trFE)
1159d71ae5a4SJacob Faibussowitsch {
116020cf1dd8SToby Isaac PetscInt hStart, hEnd;
116120cf1dd8SToby Isaac PetscDualSpace dsp;
116220cf1dd8SToby Isaac DM dm;
116320cf1dd8SToby Isaac
116420cf1dd8SToby Isaac PetscFunctionBegin;
116520cf1dd8SToby Isaac PetscValidHeaderSpecific(fe, PETSCFE_CLASSID, 1);
11664f572ea9SToby Isaac PetscAssertPointer(trFE, 3);
116720cf1dd8SToby Isaac *trFE = NULL;
11689566063dSJacob Faibussowitsch PetscCall(PetscFEGetDualSpace(fe, &dsp));
11699566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetDM(dsp, &dm));
11709566063dSJacob Faibussowitsch PetscCall(DMPlexGetHeightStratum(dm, height, &hStart, &hEnd));
11713ba16761SJacob Faibussowitsch if (hEnd <= hStart) PetscFunctionReturn(PETSC_SUCCESS);
11729566063dSJacob Faibussowitsch PetscCall(PetscFECreatePointTrace(fe, hStart, trFE));
11733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
117420cf1dd8SToby Isaac }
117520cf1dd8SToby Isaac
117620cf1dd8SToby Isaac /*@
117720cf1dd8SToby Isaac PetscFEGetDimension - Get the dimension of the finite element space on a cell
117820cf1dd8SToby Isaac
117920f4b53cSBarry Smith Not Collective
118020cf1dd8SToby Isaac
118120cf1dd8SToby Isaac Input Parameter:
118260225df5SJacob Faibussowitsch . fem - The `PetscFE`
118320cf1dd8SToby Isaac
118420cf1dd8SToby Isaac Output Parameter:
118520cf1dd8SToby Isaac . dim - The dimension
118620cf1dd8SToby Isaac
118720cf1dd8SToby Isaac Level: intermediate
118820cf1dd8SToby Isaac
1189dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscFECreate()`, `PetscSpaceGetDimension()`, `PetscDualSpaceGetDimension()`
119020cf1dd8SToby Isaac @*/
PetscFEGetDimension(PetscFE fem,PetscInt * dim)1191d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEGetDimension(PetscFE fem, PetscInt *dim)
1192d71ae5a4SJacob Faibussowitsch {
119320cf1dd8SToby Isaac PetscFunctionBegin;
119420cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1);
11954f572ea9SToby Isaac PetscAssertPointer(dim, 2);
1196dbbe0bcdSBarry Smith PetscTryTypeMethod(fem, getdimension, dim);
11973ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
119820cf1dd8SToby Isaac }
119920cf1dd8SToby Isaac
1200cc4c1da9SBarry Smith /*@
12014bee2e38SMatthew G. Knepley PetscFEPushforward - Map the reference element function to real space
12024bee2e38SMatthew G. Knepley
12034bee2e38SMatthew G. Knepley Input Parameters:
1204dce8aebaSBarry Smith + fe - The `PetscFE`
12054bee2e38SMatthew G. Knepley . fegeom - The cell geometry
12064bee2e38SMatthew G. Knepley . Nv - The number of function values
12074bee2e38SMatthew G. Knepley - vals - The function values
12084bee2e38SMatthew G. Knepley
12094bee2e38SMatthew G. Knepley Output Parameter:
12104bee2e38SMatthew G. Knepley . vals - The transformed function values
12114bee2e38SMatthew G. Knepley
12124bee2e38SMatthew G. Knepley Level: advanced
12134bee2e38SMatthew G. Knepley
1214dce8aebaSBarry Smith Notes:
1215dce8aebaSBarry Smith This just forwards the call onto `PetscDualSpacePushforward()`.
12164bee2e38SMatthew G. Knepley
1217dce8aebaSBarry Smith It only handles transformations when the embedding dimension of the geometry in fegeom is the same as the reference dimension.
12182edcad52SToby Isaac
1219dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscFEGeom`, `PetscDualSpace`, `PetscDualSpacePushforward()`
12204bee2e38SMatthew G. Knepley @*/
PetscFEPushforward(PetscFE fe,PetscFEGeom * fegeom,PetscInt Nv,PetscScalar vals[])1221d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEPushforward(PetscFE fe, PetscFEGeom *fegeom, PetscInt Nv, PetscScalar vals[])
1222d71ae5a4SJacob Faibussowitsch {
12232ae266adSMatthew G. Knepley PetscFunctionBeginHot;
12249566063dSJacob Faibussowitsch PetscCall(PetscDualSpacePushforward(fe->dualSpace, fegeom, Nv, fe->numComponents, vals));
12253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
12264bee2e38SMatthew G. Knepley }
12274bee2e38SMatthew G. Knepley
1228cc4c1da9SBarry Smith /*@
12294bee2e38SMatthew G. Knepley PetscFEPushforwardGradient - Map the reference element function gradient to real space
12304bee2e38SMatthew G. Knepley
12314bee2e38SMatthew G. Knepley Input Parameters:
1232dce8aebaSBarry Smith + fe - The `PetscFE`
12334bee2e38SMatthew G. Knepley . fegeom - The cell geometry
12344bee2e38SMatthew G. Knepley . Nv - The number of function gradient values
12354bee2e38SMatthew G. Knepley - vals - The function gradient values
12364bee2e38SMatthew G. Knepley
12374bee2e38SMatthew G. Knepley Output Parameter:
12384bee2e38SMatthew G. Knepley . vals - The transformed function gradient values
12394bee2e38SMatthew G. Knepley
12404bee2e38SMatthew G. Knepley Level: advanced
12414bee2e38SMatthew G. Knepley
1242dce8aebaSBarry Smith Notes:
1243dce8aebaSBarry Smith This just forwards the call onto `PetscDualSpacePushforwardGradient()`.
12444bee2e38SMatthew G. Knepley
1245dce8aebaSBarry Smith It only handles transformations when the embedding dimension of the geometry in fegeom is the same as the reference dimension.
12462edcad52SToby Isaac
1247dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscFEGeom`, `PetscDualSpace`, `PetscFEPushforward()`, `PetscDualSpacePushforwardGradient()`, `PetscDualSpacePushforward()`
12484bee2e38SMatthew G. Knepley @*/
PetscFEPushforwardGradient(PetscFE fe,PetscFEGeom * fegeom,PetscInt Nv,PetscScalar vals[])1249d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEPushforwardGradient(PetscFE fe, PetscFEGeom *fegeom, PetscInt Nv, PetscScalar vals[])
1250d71ae5a4SJacob Faibussowitsch {
12512ae266adSMatthew G. Knepley PetscFunctionBeginHot;
12529566063dSJacob Faibussowitsch PetscCall(PetscDualSpacePushforwardGradient(fe->dualSpace, fegeom, Nv, fe->numComponents, vals));
12533ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
12544bee2e38SMatthew G. Knepley }
12554bee2e38SMatthew G. Knepley
1256cc4c1da9SBarry Smith /*@
1257f9244615SMatthew G. Knepley PetscFEPushforwardHessian - Map the reference element function Hessian to real space
1258f9244615SMatthew G. Knepley
1259f9244615SMatthew G. Knepley Input Parameters:
1260dce8aebaSBarry Smith + fe - The `PetscFE`
1261f9244615SMatthew G. Knepley . fegeom - The cell geometry
1262f9244615SMatthew G. Knepley . Nv - The number of function Hessian values
1263f9244615SMatthew G. Knepley - vals - The function Hessian values
1264f9244615SMatthew G. Knepley
1265f9244615SMatthew G. Knepley Output Parameter:
1266f9244615SMatthew G. Knepley . vals - The transformed function Hessian values
1267f9244615SMatthew G. Knepley
1268f9244615SMatthew G. Knepley Level: advanced
1269f9244615SMatthew G. Knepley
1270dce8aebaSBarry Smith Notes:
1271dce8aebaSBarry Smith This just forwards the call onto `PetscDualSpacePushforwardHessian()`.
1272f9244615SMatthew G. Knepley
1273dce8aebaSBarry Smith It only handles transformations when the embedding dimension of the geometry in fegeom is the same as the reference dimension.
1274f9244615SMatthew G. Knepley
127560225df5SJacob Faibussowitsch Developer Notes:
1276dce8aebaSBarry Smith It is unclear why all these one line convenience routines are desirable
1277dce8aebaSBarry Smith
1278dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscFEGeom`, `PetscDualSpace`, `PetscFEPushforward()`, `PetscDualSpacePushforwardHessian()`, `PetscDualSpacePushforward()`
1279f9244615SMatthew G. Knepley @*/
PetscFEPushforwardHessian(PetscFE fe,PetscFEGeom * fegeom,PetscInt Nv,PetscScalar vals[])1280d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEPushforwardHessian(PetscFE fe, PetscFEGeom *fegeom, PetscInt Nv, PetscScalar vals[])
1281d71ae5a4SJacob Faibussowitsch {
1282f9244615SMatthew G. Knepley PetscFunctionBeginHot;
12839566063dSJacob Faibussowitsch PetscCall(PetscDualSpacePushforwardHessian(fe->dualSpace, fegeom, Nv, fe->numComponents, vals));
12843ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1285f9244615SMatthew G. Knepley }
1286f9244615SMatthew G. Knepley
128720cf1dd8SToby Isaac /*
128820cf1dd8SToby Isaac Purpose: Compute element vector for chunk of elements
128920cf1dd8SToby Isaac
129020cf1dd8SToby Isaac Input:
129120cf1dd8SToby Isaac Sizes:
129220cf1dd8SToby Isaac Ne: number of elements
129320cf1dd8SToby Isaac Nf: number of fields
129420cf1dd8SToby Isaac PetscFE
129520cf1dd8SToby Isaac dim: spatial dimension
129620cf1dd8SToby Isaac Nb: number of basis functions
129720cf1dd8SToby Isaac Nc: number of field components
129820cf1dd8SToby Isaac PetscQuadrature
129920cf1dd8SToby Isaac Nq: number of quadrature points
130020cf1dd8SToby Isaac
130120cf1dd8SToby Isaac Geometry:
130220cf1dd8SToby Isaac PetscFEGeom[Ne] possibly *Nq
130320cf1dd8SToby Isaac PetscReal v0s[dim]
130420cf1dd8SToby Isaac PetscReal n[dim]
130520cf1dd8SToby Isaac PetscReal jacobians[dim*dim]
130620cf1dd8SToby Isaac PetscReal jacobianInverses[dim*dim]
130720cf1dd8SToby Isaac PetscReal jacobianDeterminants
130820cf1dd8SToby Isaac FEM:
130920cf1dd8SToby Isaac PetscFE
131020cf1dd8SToby Isaac PetscQuadrature
131120cf1dd8SToby Isaac PetscReal quadPoints[Nq*dim]
131220cf1dd8SToby Isaac PetscReal quadWeights[Nq]
131320cf1dd8SToby Isaac PetscReal basis[Nq*Nb*Nc]
131420cf1dd8SToby Isaac PetscReal basisDer[Nq*Nb*Nc*dim]
131520cf1dd8SToby Isaac PetscScalar coefficients[Ne*Nb*Nc]
131620cf1dd8SToby Isaac PetscScalar elemVec[Ne*Nb*Nc]
131720cf1dd8SToby Isaac
131820cf1dd8SToby Isaac Problem:
131920cf1dd8SToby Isaac PetscInt f: the active field
132020cf1dd8SToby Isaac f0, f1
132120cf1dd8SToby Isaac
132220cf1dd8SToby Isaac Work Space:
132320cf1dd8SToby Isaac PetscFE
132420cf1dd8SToby Isaac PetscScalar f0[Nq*dim];
132520cf1dd8SToby Isaac PetscScalar f1[Nq*dim*dim];
132620cf1dd8SToby Isaac PetscScalar u[Nc];
132720cf1dd8SToby Isaac PetscScalar gradU[Nc*dim];
132820cf1dd8SToby Isaac PetscReal x[dim];
132920cf1dd8SToby Isaac PetscScalar realSpaceDer[dim];
133020cf1dd8SToby Isaac
133120cf1dd8SToby Isaac Purpose: Compute element vector for N_cb batches of elements
133220cf1dd8SToby Isaac
133320cf1dd8SToby Isaac Input:
133420cf1dd8SToby Isaac Sizes:
133520cf1dd8SToby Isaac N_cb: Number of serial cell batches
133620cf1dd8SToby Isaac
133720cf1dd8SToby Isaac Geometry:
133820cf1dd8SToby Isaac PetscReal v0s[Ne*dim]
133920cf1dd8SToby Isaac PetscReal jacobians[Ne*dim*dim] possibly *Nq
134020cf1dd8SToby Isaac PetscReal jacobianInverses[Ne*dim*dim] possibly *Nq
134120cf1dd8SToby Isaac PetscReal jacobianDeterminants[Ne] possibly *Nq
134220cf1dd8SToby Isaac FEM:
134320cf1dd8SToby Isaac static PetscReal quadPoints[Nq*dim]
134420cf1dd8SToby Isaac static PetscReal quadWeights[Nq]
134520cf1dd8SToby Isaac static PetscReal basis[Nq*Nb*Nc]
134620cf1dd8SToby Isaac static PetscReal basisDer[Nq*Nb*Nc*dim]
134720cf1dd8SToby Isaac PetscScalar coefficients[Ne*Nb*Nc]
134820cf1dd8SToby Isaac PetscScalar elemVec[Ne*Nb*Nc]
134920cf1dd8SToby Isaac
135020cf1dd8SToby Isaac ex62.c:
135120cf1dd8SToby Isaac PetscErrorCode PetscFEIntegrateResidualBatch(PetscInt Ne, PetscInt numFields, PetscInt field, PetscQuadrature quad[], const PetscScalar coefficients[],
135220cf1dd8SToby Isaac const PetscReal v0s[], const PetscReal jacobians[], const PetscReal jacobianInverses[], const PetscReal jacobianDeterminants[],
135320cf1dd8SToby Isaac void (*f0_func)(const PetscScalar u[], const PetscScalar gradU[], const PetscReal x[], PetscScalar f0[]),
135420cf1dd8SToby Isaac void (*f1_func)(const PetscScalar u[], const PetscScalar gradU[], const PetscReal x[], PetscScalar f1[]), PetscScalar elemVec[])
135520cf1dd8SToby Isaac
135620cf1dd8SToby Isaac ex52.c:
135720cf1dd8SToby Isaac PetscErrorCode IntegrateLaplacianBatchCPU(PetscInt Ne, PetscInt Nb, const PetscScalar coefficients[], const PetscReal jacobianInverses[], const PetscReal jacobianDeterminants[], PetscInt Nq, const PetscReal quadPoints[], const PetscReal quadWeights[], const PetscReal basisTabulation[], const PetscReal basisDerTabulation[], PetscScalar elemVec[], AppCtx *user)
135820cf1dd8SToby Isaac PetscErrorCode IntegrateElasticityBatchCPU(PetscInt Ne, PetscInt Nb, PetscInt Ncomp, const PetscScalar coefficients[], const PetscReal jacobianInverses[], const PetscReal jacobianDeterminants[], PetscInt Nq, const PetscReal quadPoints[], const PetscReal quadWeights[], const PetscReal basisTabulation[], const PetscReal basisDerTabulation[], PetscScalar elemVec[], AppCtx *user)
135920cf1dd8SToby Isaac
136020cf1dd8SToby Isaac ex52_integrateElement.cu
136120cf1dd8SToby Isaac __global__ void integrateElementQuadrature(int N_cb, realType *coefficients, realType *jacobianInverses, realType *jacobianDeterminants, realType *elemVec)
136220cf1dd8SToby Isaac
136320cf1dd8SToby Isaac PETSC_EXTERN PetscErrorCode IntegrateElementBatchGPU(PetscInt spatial_dim, PetscInt Ne, PetscInt Ncb, PetscInt Nbc, PetscInt Nbl, const PetscScalar coefficients[],
136420cf1dd8SToby Isaac const PetscReal jacobianInverses[], const PetscReal jacobianDeterminants[], PetscScalar elemVec[],
136520cf1dd8SToby Isaac PetscLogEvent event, PetscInt debug, PetscInt pde_op)
136620cf1dd8SToby Isaac
136720cf1dd8SToby Isaac ex52_integrateElementOpenCL.c:
136820cf1dd8SToby Isaac PETSC_EXTERN PetscErrorCode IntegrateElementBatchGPU(PetscInt spatial_dim, PetscInt Ne, PetscInt Ncb, PetscInt Nbc, PetscInt N_bl, const PetscScalar coefficients[],
136920cf1dd8SToby Isaac const PetscReal jacobianInverses[], const PetscReal jacobianDeterminants[], PetscScalar elemVec[],
137020cf1dd8SToby Isaac PetscLogEvent event, PetscInt debug, PetscInt pde_op)
137120cf1dd8SToby Isaac
137220cf1dd8SToby Isaac __kernel void integrateElementQuadrature(int N_cb, __global float *coefficients, __global float *jacobianInverses, __global float *jacobianDeterminants, __global float *elemVec)
137320cf1dd8SToby Isaac */
137420cf1dd8SToby Isaac
1375cc4c1da9SBarry Smith /*@
137620cf1dd8SToby Isaac PetscFEIntegrate - Produce the integral for the given field for a chunk of elements by quadrature integration
137720cf1dd8SToby Isaac
137820f4b53cSBarry Smith Not Collective
137920cf1dd8SToby Isaac
138020cf1dd8SToby Isaac Input Parameters:
1381dce8aebaSBarry Smith + prob - The `PetscDS` specifying the discretizations and continuum functions
138220cf1dd8SToby Isaac . field - The field being integrated
138320cf1dd8SToby Isaac . Ne - The number of elements in the chunk
138420cf1dd8SToby Isaac . cgeom - The cell geometry for each cell in the chunk
138520cf1dd8SToby Isaac . coefficients - The array of FEM basis coefficients for the elements
1386dce8aebaSBarry Smith . probAux - The `PetscDS` specifying the auxiliary discretizations
138720cf1dd8SToby Isaac - coefficientsAux - The array of FEM auxiliary basis coefficients for the elements
138820cf1dd8SToby Isaac
13897a7aea1fSJed Brown Output Parameter:
139020cf1dd8SToby Isaac . integral - the integral for this field
139120cf1dd8SToby Isaac
13922b99622eSMatthew G. Knepley Level: intermediate
139320cf1dd8SToby Isaac
139460225df5SJacob Faibussowitsch Developer Notes:
1395dce8aebaSBarry Smith The function name begins with `PetscFE` and yet the first argument is `PetscDS` and it has no `PetscFE` arguments.
1396dce8aebaSBarry Smith
1397dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscDS`, `PetscFEIntegrateResidual()`, `PetscFEIntegrateBd()`
139820cf1dd8SToby Isaac @*/
PetscFEIntegrate(PetscDS prob,PetscInt field,PetscInt Ne,PetscFEGeom * cgeom,const PetscScalar coefficients[],PetscDS probAux,const PetscScalar coefficientsAux[],PetscScalar integral[])1399d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEIntegrate(PetscDS prob, PetscInt field, PetscInt Ne, PetscFEGeom *cgeom, const PetscScalar coefficients[], PetscDS probAux, const PetscScalar coefficientsAux[], PetscScalar integral[])
1400d71ae5a4SJacob Faibussowitsch {
14014bee2e38SMatthew G. Knepley PetscFE fe;
140220cf1dd8SToby Isaac
140320cf1dd8SToby Isaac PetscFunctionBegin;
14044bee2e38SMatthew G. Knepley PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
14059566063dSJacob Faibussowitsch PetscCall(PetscDSGetDiscretization(prob, field, (PetscObject *)&fe));
14069566063dSJacob Faibussowitsch if (fe->ops->integrate) PetscCall((*fe->ops->integrate)(prob, field, Ne, cgeom, coefficients, probAux, coefficientsAux, integral));
14073ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
140820cf1dd8SToby Isaac }
140920cf1dd8SToby Isaac
141020cf1dd8SToby Isaac /*@C
1411afe6d6adSToby Isaac PetscFEIntegrateBd - Produce the integral for the given field for a chunk of elements by quadrature integration
1412afe6d6adSToby Isaac
141320f4b53cSBarry Smith Not Collective
1414afe6d6adSToby Isaac
1415afe6d6adSToby Isaac Input Parameters:
1416dce8aebaSBarry Smith + prob - The `PetscDS` specifying the discretizations and continuum functions
1417afe6d6adSToby Isaac . field - The field being integrated
1418afe6d6adSToby Isaac . obj_func - The function to be integrated
1419afe6d6adSToby Isaac . Ne - The number of elements in the chunk
142060225df5SJacob Faibussowitsch . geom - The face geometry for each face in the chunk
1421afe6d6adSToby Isaac . coefficients - The array of FEM basis coefficients for the elements
1422dce8aebaSBarry Smith . probAux - The `PetscDS` specifying the auxiliary discretizations
1423afe6d6adSToby Isaac - coefficientsAux - The array of FEM auxiliary basis coefficients for the elements
1424afe6d6adSToby Isaac
14257a7aea1fSJed Brown Output Parameter:
1426afe6d6adSToby Isaac . integral - the integral for this field
1427afe6d6adSToby Isaac
14282b99622eSMatthew G. Knepley Level: intermediate
1429afe6d6adSToby Isaac
143060225df5SJacob Faibussowitsch Developer Notes:
1431dce8aebaSBarry Smith The function name begins with `PetscFE` and yet the first argument is `PetscDS` and it has no `PetscFE` arguments.
1432dce8aebaSBarry Smith
1433dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscDS`, `PetscFEIntegrateResidual()`, `PetscFEIntegrate()`
1434afe6d6adSToby Isaac @*/
PetscFEIntegrateBd(PetscDS prob,PetscInt field,void (* obj_func)(PetscInt,PetscInt,PetscInt,const PetscInt[],const PetscInt[],const PetscScalar[],const PetscScalar[],const PetscScalar[],const PetscInt[],const PetscInt[],const PetscScalar[],const PetscScalar[],const PetscScalar[],PetscReal,const PetscReal[],const PetscReal[],PetscInt,const PetscScalar[],PetscScalar[]),PetscInt Ne,PetscFEGeom * geom,const PetscScalar coefficients[],PetscDS probAux,const PetscScalar coefficientsAux[],PetscScalar integral[])1435d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEIntegrateBd(PetscDS prob, PetscInt field, void (*obj_func)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), PetscInt Ne, PetscFEGeom *geom, const PetscScalar coefficients[], PetscDS probAux, const PetscScalar coefficientsAux[], PetscScalar integral[])
1436d71ae5a4SJacob Faibussowitsch {
14374bee2e38SMatthew G. Knepley PetscFE fe;
1438afe6d6adSToby Isaac
1439afe6d6adSToby Isaac PetscFunctionBegin;
14404bee2e38SMatthew G. Knepley PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
14419566063dSJacob Faibussowitsch PetscCall(PetscDSGetDiscretization(prob, field, (PetscObject *)&fe));
14429566063dSJacob Faibussowitsch if (fe->ops->integratebd) PetscCall((*fe->ops->integratebd)(prob, field, obj_func, Ne, geom, coefficients, probAux, coefficientsAux, integral));
14433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1444afe6d6adSToby Isaac }
1445afe6d6adSToby Isaac
1446cc4c1da9SBarry Smith /*@
144720cf1dd8SToby Isaac PetscFEIntegrateResidual - Produce the element residual vector for a chunk of elements by quadrature integration
144820cf1dd8SToby Isaac
144920f4b53cSBarry Smith Not Collective
145020cf1dd8SToby Isaac
145120cf1dd8SToby Isaac Input Parameters:
145220f4b53cSBarry Smith + ds - The `PetscDS` specifying the discretizations and continuum functions
14536528b96dSMatthew G. Knepley . key - The (label+value, field) being integrated
145420cf1dd8SToby Isaac . Ne - The number of elements in the chunk
145520cf1dd8SToby Isaac . cgeom - The cell geometry for each cell in the chunk
145620cf1dd8SToby Isaac . coefficients - The array of FEM basis coefficients for the elements
145720cf1dd8SToby Isaac . coefficients_t - The array of FEM basis time derivative coefficients for the elements
145820f4b53cSBarry Smith . probAux - The `PetscDS` specifying the auxiliary discretizations
145920cf1dd8SToby Isaac . coefficientsAux - The array of FEM auxiliary basis coefficients for the elements
146020cf1dd8SToby Isaac - t - The time
146120cf1dd8SToby Isaac
14627a7aea1fSJed Brown Output Parameter:
146320cf1dd8SToby Isaac . elemVec - the element residual vectors from each element
146420cf1dd8SToby Isaac
14652b99622eSMatthew G. Knepley Level: intermediate
146620cf1dd8SToby Isaac
1467dce8aebaSBarry Smith Note:
1468dce8aebaSBarry Smith .vb
1469dce8aebaSBarry Smith Loop over batch of elements (e):
1470dce8aebaSBarry Smith Loop over quadrature points (q):
1471dce8aebaSBarry Smith Make u_q and gradU_q (loops over fields,Nb,Ncomp) and x_q
1472dce8aebaSBarry Smith Call f_0 and f_1
1473dce8aebaSBarry Smith Loop over element vector entries (f,fc --> i):
1474dce8aebaSBarry Smith elemVec[i] += \psi^{fc}_f(q) f0_{fc}(u, \nabla u) + \nabla\psi^{fc}_f(q) \cdot f1_{fc,df}(u, \nabla u)
1475dce8aebaSBarry Smith .ve
1476dce8aebaSBarry Smith
147742747ad1SJacob Faibussowitsch .seealso: `PetscFEIntegrateBdResidual()`
147820cf1dd8SToby Isaac @*/
PetscFEIntegrateResidual(PetscDS ds,PetscFormKey key,PetscInt Ne,PetscFEGeom * cgeom,const PetscScalar coefficients[],const PetscScalar coefficients_t[],PetscDS probAux,const PetscScalar coefficientsAux[],PetscReal t,PetscScalar elemVec[])1479d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEIntegrateResidual(PetscDS ds, PetscFormKey key, PetscInt Ne, PetscFEGeom *cgeom, const PetscScalar coefficients[], const PetscScalar coefficients_t[], PetscDS probAux, const PetscScalar coefficientsAux[], PetscReal t, PetscScalar elemVec[])
1480d71ae5a4SJacob Faibussowitsch {
14814bee2e38SMatthew G. Knepley PetscFE fe;
148220cf1dd8SToby Isaac
14836528b96dSMatthew G. Knepley PetscFunctionBeginHot;
14846528b96dSMatthew G. Knepley PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
14859566063dSJacob Faibussowitsch PetscCall(PetscDSGetDiscretization(ds, key.field, (PetscObject *)&fe));
14869566063dSJacob Faibussowitsch if (fe->ops->integrateresidual) PetscCall((*fe->ops->integrateresidual)(ds, key, Ne, cgeom, coefficients, coefficients_t, probAux, coefficientsAux, t, elemVec));
14873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
148820cf1dd8SToby Isaac }
148920cf1dd8SToby Isaac
1490cc4c1da9SBarry Smith /*@
149120cf1dd8SToby Isaac PetscFEIntegrateBdResidual - Produce the element residual vector for a chunk of elements by quadrature integration over a boundary
149220cf1dd8SToby Isaac
149320f4b53cSBarry Smith Not Collective
149420cf1dd8SToby Isaac
149520cf1dd8SToby Isaac Input Parameters:
149620f4b53cSBarry Smith + ds - The `PetscDS` specifying the discretizations and continuum functions
149745480ffeSMatthew G. Knepley . wf - The PetscWeakForm object holding the pointwise functions
149806d8a0d3SMatthew G. Knepley . key - The (label+value, field) being integrated
149920cf1dd8SToby Isaac . Ne - The number of elements in the chunk
150020cf1dd8SToby Isaac . fgeom - The face geometry for each cell in the chunk
150120cf1dd8SToby Isaac . coefficients - The array of FEM basis coefficients for the elements
150220cf1dd8SToby Isaac . coefficients_t - The array of FEM basis time derivative coefficients for the elements
150320f4b53cSBarry Smith . probAux - The `PetscDS` specifying the auxiliary discretizations
150420cf1dd8SToby Isaac . coefficientsAux - The array of FEM auxiliary basis coefficients for the elements
150520cf1dd8SToby Isaac - t - The time
150620cf1dd8SToby Isaac
15077a7aea1fSJed Brown Output Parameter:
150820cf1dd8SToby Isaac . elemVec - the element residual vectors from each element
150920cf1dd8SToby Isaac
15102b99622eSMatthew G. Knepley Level: intermediate
151120cf1dd8SToby Isaac
1512db781477SPatrick Sanan .seealso: `PetscFEIntegrateResidual()`
151320cf1dd8SToby Isaac @*/
PetscFEIntegrateBdResidual(PetscDS ds,PetscWeakForm wf,PetscFormKey key,PetscInt Ne,PetscFEGeom * fgeom,const PetscScalar coefficients[],const PetscScalar coefficients_t[],PetscDS probAux,const PetscScalar coefficientsAux[],PetscReal t,PetscScalar elemVec[])1514d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEIntegrateBdResidual(PetscDS ds, PetscWeakForm wf, PetscFormKey key, PetscInt Ne, PetscFEGeom *fgeom, const PetscScalar coefficients[], const PetscScalar coefficients_t[], PetscDS probAux, const PetscScalar coefficientsAux[], PetscReal t, PetscScalar elemVec[])
1515d71ae5a4SJacob Faibussowitsch {
15164bee2e38SMatthew G. Knepley PetscFE fe;
151720cf1dd8SToby Isaac
151820cf1dd8SToby Isaac PetscFunctionBegin;
151906d8a0d3SMatthew G. Knepley PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
15209566063dSJacob Faibussowitsch PetscCall(PetscDSGetDiscretization(ds, key.field, (PetscObject *)&fe));
15219566063dSJacob Faibussowitsch if (fe->ops->integratebdresidual) PetscCall((*fe->ops->integratebdresidual)(ds, wf, key, Ne, fgeom, coefficients, coefficients_t, probAux, coefficientsAux, t, elemVec));
15223ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
152320cf1dd8SToby Isaac }
152420cf1dd8SToby Isaac
1525cc4c1da9SBarry Smith /*@
152627f02ce8SMatthew G. Knepley PetscFEIntegrateHybridResidual - Produce the element residual vector for a chunk of hybrid element faces by quadrature integration
152727f02ce8SMatthew G. Knepley
152820f4b53cSBarry Smith Not Collective
152927f02ce8SMatthew G. Knepley
153027f02ce8SMatthew G. Knepley Input Parameters:
153107218a29SMatthew G. Knepley + ds - The `PetscDS` specifying the discretizations and continuum functions
153207218a29SMatthew G. Knepley . dsIn - The `PetscDS` specifying the discretizations and continuum functions for input
15336528b96dSMatthew G. Knepley . key - The (label+value, field) being integrated
1534c2b7495fSMatthew G. Knepley . s - The side of the cell being integrated, 0 for negative and 1 for positive
153527f02ce8SMatthew G. Knepley . Ne - The number of elements in the chunk
153627f02ce8SMatthew G. Knepley . fgeom - The face geometry for each cell in the chunk
1537989fa639SBrad Aagaard . cgeom - The cell geometry for each neighbor cell in the chunk
153827f02ce8SMatthew G. Knepley . coefficients - The array of FEM basis coefficients for the elements
153927f02ce8SMatthew G. Knepley . coefficients_t - The array of FEM basis time derivative coefficients for the elements
154020f4b53cSBarry Smith . probAux - The `PetscDS` specifying the auxiliary discretizations
154127f02ce8SMatthew G. Knepley . coefficientsAux - The array of FEM auxiliary basis coefficients for the elements
154227f02ce8SMatthew G. Knepley - t - The time
154327f02ce8SMatthew G. Knepley
1544a4e35b19SJacob Faibussowitsch Output Parameter:
154527f02ce8SMatthew G. Knepley . elemVec - the element residual vectors from each element
154627f02ce8SMatthew G. Knepley
154727f02ce8SMatthew G. Knepley Level: developer
154827f02ce8SMatthew G. Knepley
1549db781477SPatrick Sanan .seealso: `PetscFEIntegrateResidual()`
155027f02ce8SMatthew G. Knepley @*/
PetscFEIntegrateHybridResidual(PetscDS ds,PetscDS dsIn,PetscFormKey key,PetscInt s,PetscInt Ne,PetscFEGeom * fgeom,PetscFEGeom * cgeom,const PetscScalar coefficients[],const PetscScalar coefficients_t[],PetscDS probAux,const PetscScalar coefficientsAux[],PetscReal t,PetscScalar elemVec[])1551989fa639SBrad Aagaard PetscErrorCode PetscFEIntegrateHybridResidual(PetscDS ds, PetscDS dsIn, PetscFormKey key, PetscInt s, PetscInt Ne, PetscFEGeom *fgeom, PetscFEGeom *cgeom, const PetscScalar coefficients[], const PetscScalar coefficients_t[], PetscDS probAux, const PetscScalar coefficientsAux[], PetscReal t, PetscScalar elemVec[])
1552d71ae5a4SJacob Faibussowitsch {
155327f02ce8SMatthew G. Knepley PetscFE fe;
155427f02ce8SMatthew G. Knepley
155527f02ce8SMatthew G. Knepley PetscFunctionBegin;
155607218a29SMatthew G. Knepley PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
155707218a29SMatthew G. Knepley PetscValidHeaderSpecific(dsIn, PETSCDS_CLASSID, 2);
155807218a29SMatthew G. Knepley PetscCall(PetscDSGetDiscretization(ds, key.field, (PetscObject *)&fe));
1559989fa639SBrad Aagaard if (fe->ops->integratehybridresidual) PetscCall((*fe->ops->integratehybridresidual)(ds, dsIn, key, s, Ne, fgeom, cgeom, coefficients, coefficients_t, probAux, coefficientsAux, t, elemVec));
15603ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
156127f02ce8SMatthew G. Knepley }
156227f02ce8SMatthew G. Knepley
1563cc4c1da9SBarry Smith /*@
156420cf1dd8SToby Isaac PetscFEIntegrateJacobian - Produce the element Jacobian for a chunk of elements by quadrature integration
156520cf1dd8SToby Isaac
156620f4b53cSBarry Smith Not Collective
156720cf1dd8SToby Isaac
156820cf1dd8SToby Isaac Input Parameters:
15694561e6c9SMatthew G. Knepley + rds - The `PetscDS` specifying the row discretizations and continuum functions
15704561e6c9SMatthew G. Knepley . cds - The `PetscDS` specifying the column discretizations
157120cf1dd8SToby Isaac . jtype - The type of matrix pointwise functions that should be used
15726528b96dSMatthew G. Knepley . key - The (label+value, fieldI*Nf + fieldJ) being integrated
157320cf1dd8SToby Isaac . Ne - The number of elements in the chunk
157420cf1dd8SToby Isaac . cgeom - The cell geometry for each cell in the chunk
157520cf1dd8SToby Isaac . coefficients - The array of FEM basis coefficients for the elements for the Jacobian evaluation point
157620cf1dd8SToby Isaac . coefficients_t - The array of FEM basis time derivative coefficients for the elements
15774561e6c9SMatthew G. Knepley . dsAux - The `PetscDS` specifying the auxiliary discretizations
157820cf1dd8SToby Isaac . coefficientsAux - The array of FEM auxiliary basis coefficients for the elements
157920cf1dd8SToby Isaac . t - The time
158060225df5SJacob Faibussowitsch - u_tshift - A multiplier for the dF/du_t term (as opposed to the dF/du term)
158120cf1dd8SToby Isaac
15827a7aea1fSJed Brown Output Parameter:
158320cf1dd8SToby Isaac . elemMat - the element matrices for the Jacobian from each element
158420cf1dd8SToby Isaac
15852b99622eSMatthew G. Knepley Level: intermediate
158620cf1dd8SToby Isaac
1587dce8aebaSBarry Smith Note:
1588dce8aebaSBarry Smith .vb
1589dce8aebaSBarry Smith Loop over batch of elements (e):
1590dce8aebaSBarry Smith Loop over element matrix entries (f,fc,g,gc --> i,j):
1591dce8aebaSBarry Smith Loop over quadrature points (q):
1592dce8aebaSBarry Smith Make u_q and gradU_q (loops over fields,Nb,Ncomp)
1593dce8aebaSBarry Smith elemMat[i,j] += \psi^{fc}_f(q) g0_{fc,gc}(u, \nabla u) \phi^{gc}_g(q)
1594dce8aebaSBarry Smith + \psi^{fc}_f(q) \cdot g1_{fc,gc,dg}(u, \nabla u) \nabla\phi^{gc}_g(q)
1595dce8aebaSBarry Smith + \nabla\psi^{fc}_f(q) \cdot g2_{fc,gc,df}(u, \nabla u) \phi^{gc}_g(q)
1596dce8aebaSBarry Smith + \nabla\psi^{fc}_f(q) \cdot g3_{fc,gc,df,dg}(u, \nabla u) \nabla\phi^{gc}_g(q)
1597dce8aebaSBarry Smith .ve
1598dce8aebaSBarry Smith
1599db781477SPatrick Sanan .seealso: `PetscFEIntegrateResidual()`
160020cf1dd8SToby Isaac @*/
PetscFEIntegrateJacobian(PetscDS rds,PetscDS cds,PetscFEJacobianType jtype,PetscFormKey key,PetscInt Ne,PetscFEGeom * cgeom,const PetscScalar coefficients[],const PetscScalar coefficients_t[],PetscDS dsAux,const PetscScalar coefficientsAux[],PetscReal t,PetscReal u_tshift,PetscScalar elemMat[])16014561e6c9SMatthew G. Knepley PetscErrorCode PetscFEIntegrateJacobian(PetscDS rds, PetscDS cds, PetscFEJacobianType jtype, PetscFormKey key, PetscInt Ne, PetscFEGeom *cgeom, const PetscScalar coefficients[], const PetscScalar coefficients_t[], PetscDS dsAux, const PetscScalar coefficientsAux[], PetscReal t, PetscReal u_tshift, PetscScalar elemMat[])
1602d71ae5a4SJacob Faibussowitsch {
16034bee2e38SMatthew G. Knepley PetscFE fe;
16046528b96dSMatthew G. Knepley PetscInt Nf;
160520cf1dd8SToby Isaac
160620cf1dd8SToby Isaac PetscFunctionBegin;
16074561e6c9SMatthew G. Knepley PetscValidHeaderSpecific(rds, PETSCDS_CLASSID, 1);
16084561e6c9SMatthew G. Knepley PetscValidHeaderSpecific(cds, PETSCDS_CLASSID, 2);
16094561e6c9SMatthew G. Knepley PetscCall(PetscDSGetNumFields(rds, &Nf));
16104561e6c9SMatthew G. Knepley PetscCall(PetscDSGetDiscretization(rds, key.field / Nf, (PetscObject *)&fe));
16114561e6c9SMatthew G. Knepley if (fe->ops->integratejacobian) PetscCall((*fe->ops->integratejacobian)(rds, cds, jtype, key, Ne, cgeom, coefficients, coefficients_t, dsAux, coefficientsAux, t, u_tshift, elemMat));
16123ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
161320cf1dd8SToby Isaac }
161420cf1dd8SToby Isaac
1615cc4c1da9SBarry Smith /*@
161620cf1dd8SToby Isaac PetscFEIntegrateBdJacobian - Produce the boundary element Jacobian for a chunk of elements by quadrature integration
161720cf1dd8SToby Isaac
161820f4b53cSBarry Smith Not Collective
161920cf1dd8SToby Isaac
162020cf1dd8SToby Isaac Input Parameters:
162120f4b53cSBarry Smith + ds - The `PetscDS` specifying the discretizations and continuum functions
162245480ffeSMatthew G. Knepley . wf - The PetscWeakForm holding the pointwise functions
1623e3d591f2SMatthew G. Knepley . jtype - The type of matrix pointwise functions that should be used
162445480ffeSMatthew G. Knepley . key - The (label+value, fieldI*Nf + fieldJ) being integrated
162520cf1dd8SToby Isaac . Ne - The number of elements in the chunk
162620cf1dd8SToby Isaac . fgeom - The face geometry for each cell in the chunk
162720cf1dd8SToby Isaac . coefficients - The array of FEM basis coefficients for the elements for the Jacobian evaluation point
162820cf1dd8SToby Isaac . coefficients_t - The array of FEM basis time derivative coefficients for the elements
162920f4b53cSBarry Smith . probAux - The `PetscDS` specifying the auxiliary discretizations
163020cf1dd8SToby Isaac . coefficientsAux - The array of FEM auxiliary basis coefficients for the elements
163120cf1dd8SToby Isaac . t - The time
163260225df5SJacob Faibussowitsch - u_tshift - A multiplier for the dF/du_t term (as opposed to the dF/du term)
163320cf1dd8SToby Isaac
16347a7aea1fSJed Brown Output Parameter:
163520cf1dd8SToby Isaac . elemMat - the element matrices for the Jacobian from each element
163620cf1dd8SToby Isaac
16372b99622eSMatthew G. Knepley Level: intermediate
163820cf1dd8SToby Isaac
1639dce8aebaSBarry Smith Note:
1640dce8aebaSBarry Smith .vb
1641dce8aebaSBarry Smith Loop over batch of elements (e):
1642dce8aebaSBarry Smith Loop over element matrix entries (f,fc,g,gc --> i,j):
1643dce8aebaSBarry Smith Loop over quadrature points (q):
1644dce8aebaSBarry Smith Make u_q and gradU_q (loops over fields,Nb,Ncomp)
1645dce8aebaSBarry Smith elemMat[i,j] += \psi^{fc}_f(q) g0_{fc,gc}(u, \nabla u) \phi^{gc}_g(q)
1646dce8aebaSBarry Smith + \psi^{fc}_f(q) \cdot g1_{fc,gc,dg}(u, \nabla u) \nabla\phi^{gc}_g(q)
1647dce8aebaSBarry Smith + \nabla\psi^{fc}_f(q) \cdot g2_{fc,gc,df}(u, \nabla u) \phi^{gc}_g(q)
1648dce8aebaSBarry Smith + \nabla\psi^{fc}_f(q) \cdot g3_{fc,gc,df,dg}(u, \nabla u) \nabla\phi^{gc}_g(q)
1649dce8aebaSBarry Smith .ve
1650dce8aebaSBarry Smith
1651db781477SPatrick Sanan .seealso: `PetscFEIntegrateJacobian()`, `PetscFEIntegrateResidual()`
165220cf1dd8SToby Isaac @*/
PetscFEIntegrateBdJacobian(PetscDS ds,PetscWeakForm wf,PetscFEJacobianType jtype,PetscFormKey key,PetscInt Ne,PetscFEGeom * fgeom,const PetscScalar coefficients[],const PetscScalar coefficients_t[],PetscDS probAux,const PetscScalar coefficientsAux[],PetscReal t,PetscReal u_tshift,PetscScalar elemMat[])1653e3d591f2SMatthew G. Knepley PetscErrorCode PetscFEIntegrateBdJacobian(PetscDS ds, PetscWeakForm wf, PetscFEJacobianType jtype, PetscFormKey key, PetscInt Ne, PetscFEGeom *fgeom, const PetscScalar coefficients[], const PetscScalar coefficients_t[], PetscDS probAux, const PetscScalar coefficientsAux[], PetscReal t, PetscReal u_tshift, PetscScalar elemMat[])
1654d71ae5a4SJacob Faibussowitsch {
16554bee2e38SMatthew G. Knepley PetscFE fe;
165645480ffeSMatthew G. Knepley PetscInt Nf;
165720cf1dd8SToby Isaac
165820cf1dd8SToby Isaac PetscFunctionBegin;
165945480ffeSMatthew G. Knepley PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
16609566063dSJacob Faibussowitsch PetscCall(PetscDSGetNumFields(ds, &Nf));
16619566063dSJacob Faibussowitsch PetscCall(PetscDSGetDiscretization(ds, key.field / Nf, (PetscObject *)&fe));
1662e3d591f2SMatthew G. Knepley if (fe->ops->integratebdjacobian) PetscCall((*fe->ops->integratebdjacobian)(ds, wf, jtype, key, Ne, fgeom, coefficients, coefficients_t, probAux, coefficientsAux, t, u_tshift, elemMat));
16633ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
166420cf1dd8SToby Isaac }
166520cf1dd8SToby Isaac
1666cc4c1da9SBarry Smith /*@
166727f02ce8SMatthew G. Knepley PetscFEIntegrateHybridJacobian - Produce the boundary element Jacobian for a chunk of hybrid elements by quadrature integration
166827f02ce8SMatthew G. Knepley
166920f4b53cSBarry Smith Not Collective
167027f02ce8SMatthew G. Knepley
167127f02ce8SMatthew G. Knepley Input Parameters:
167207218a29SMatthew G. Knepley + ds - The `PetscDS` specifying the discretizations and continuum functions for the output
167307218a29SMatthew G. Knepley . dsIn - The `PetscDS` specifying the discretizations and continuum functions for the input
167427f02ce8SMatthew G. Knepley . jtype - The type of matrix pointwise functions that should be used
167545480ffeSMatthew G. Knepley . key - The (label+value, fieldI*Nf + fieldJ) being integrated
16765fedec97SMatthew G. Knepley . s - The side of the cell being integrated, 0 for negative and 1 for positive
167727f02ce8SMatthew G. Knepley . Ne - The number of elements in the chunk
167827f02ce8SMatthew G. Knepley . fgeom - The face geometry for each cell in the chunk
1679989fa639SBrad Aagaard . cgeom - The cell geometry for each neighbor cell in the chunk
168027f02ce8SMatthew G. Knepley . coefficients - The array of FEM basis coefficients for the elements for the Jacobian evaluation point
168127f02ce8SMatthew G. Knepley . coefficients_t - The array of FEM basis time derivative coefficients for the elements
168220f4b53cSBarry Smith . probAux - The `PetscDS` specifying the auxiliary discretizations
168327f02ce8SMatthew G. Knepley . coefficientsAux - The array of FEM auxiliary basis coefficients for the elements
168427f02ce8SMatthew G. Knepley . t - The time
168560225df5SJacob Faibussowitsch - u_tshift - A multiplier for the dF/du_t term (as opposed to the dF/du term)
168627f02ce8SMatthew G. Knepley
1687a4e35b19SJacob Faibussowitsch Output Parameter:
168827f02ce8SMatthew G. Knepley . elemMat - the element matrices for the Jacobian from each element
168927f02ce8SMatthew G. Knepley
169027f02ce8SMatthew G. Knepley Level: developer
169127f02ce8SMatthew G. Knepley
1692dce8aebaSBarry Smith Note:
1693dce8aebaSBarry Smith .vb
1694dce8aebaSBarry Smith Loop over batch of elements (e):
1695dce8aebaSBarry Smith Loop over element matrix entries (f,fc,g,gc --> i,j):
1696dce8aebaSBarry Smith Loop over quadrature points (q):
1697dce8aebaSBarry Smith Make u_q and gradU_q (loops over fields,Nb,Ncomp)
1698dce8aebaSBarry Smith elemMat[i,j] += \psi^{fc}_f(q) g0_{fc,gc}(u, \nabla u) \phi^{gc}_g(q)
1699dce8aebaSBarry Smith + \psi^{fc}_f(q) \cdot g1_{fc,gc,dg}(u, \nabla u) \nabla\phi^{gc}_g(q)
1700dce8aebaSBarry Smith + \nabla\psi^{fc}_f(q) \cdot g2_{fc,gc,df}(u, \nabla u) \phi^{gc}_g(q)
1701dce8aebaSBarry Smith + \nabla\psi^{fc}_f(q) \cdot g3_{fc,gc,df,dg}(u, \nabla u) \nabla\phi^{gc}_g(q)
1702dce8aebaSBarry Smith .ve
1703dce8aebaSBarry Smith
1704db781477SPatrick Sanan .seealso: `PetscFEIntegrateJacobian()`, `PetscFEIntegrateResidual()`
170527f02ce8SMatthew G. Knepley @*/
PetscFEIntegrateHybridJacobian(PetscDS ds,PetscDS dsIn,PetscFEJacobianType jtype,PetscFormKey key,PetscInt s,PetscInt Ne,PetscFEGeom * fgeom,PetscFEGeom * cgeom,const PetscScalar coefficients[],const PetscScalar coefficients_t[],PetscDS probAux,const PetscScalar coefficientsAux[],PetscReal t,PetscReal u_tshift,PetscScalar elemMat[])1706989fa639SBrad Aagaard PetscErrorCode PetscFEIntegrateHybridJacobian(PetscDS ds, PetscDS dsIn, PetscFEJacobianType jtype, PetscFormKey key, PetscInt s, PetscInt Ne, PetscFEGeom *fgeom, PetscFEGeom *cgeom, const PetscScalar coefficients[], const PetscScalar coefficients_t[], PetscDS probAux, const PetscScalar coefficientsAux[], PetscReal t, PetscReal u_tshift, PetscScalar elemMat[])
1707d71ae5a4SJacob Faibussowitsch {
170827f02ce8SMatthew G. Knepley PetscFE fe;
170945480ffeSMatthew G. Knepley PetscInt Nf;
171027f02ce8SMatthew G. Knepley
171127f02ce8SMatthew G. Knepley PetscFunctionBegin;
171245480ffeSMatthew G. Knepley PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
17139566063dSJacob Faibussowitsch PetscCall(PetscDSGetNumFields(ds, &Nf));
17149566063dSJacob Faibussowitsch PetscCall(PetscDSGetDiscretization(ds, key.field / Nf, (PetscObject *)&fe));
1715989fa639SBrad Aagaard if (fe->ops->integratehybridjacobian) PetscCall((*fe->ops->integratehybridjacobian)(ds, dsIn, jtype, key, s, Ne, fgeom, cgeom, coefficients, coefficients_t, probAux, coefficientsAux, t, u_tshift, elemMat));
17163ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
171727f02ce8SMatthew G. Knepley }
171827f02ce8SMatthew G. Knepley
17192b99622eSMatthew G. Knepley /*@
17202b99622eSMatthew G. Knepley PetscFEGetHeightSubspace - Get the subspace of this space for a mesh point of a given height
17212b99622eSMatthew G. Knepley
17222b99622eSMatthew G. Knepley Input Parameters:
17232b99622eSMatthew G. Knepley + fe - The finite element space
172420f4b53cSBarry Smith - height - The height of the `DMPLEX` point
17252b99622eSMatthew G. Knepley
17262b99622eSMatthew G. Knepley Output Parameter:
172720f4b53cSBarry Smith . subfe - The subspace of this `PetscFE` space
17282b99622eSMatthew G. Knepley
17292b99622eSMatthew G. Knepley Level: advanced
17302b99622eSMatthew G. Knepley
1731dce8aebaSBarry Smith Note:
1732dce8aebaSBarry Smith For example, if we want the subspace of this space for a face, we would choose height = 1.
1733dce8aebaSBarry Smith
1734db781477SPatrick Sanan .seealso: `PetscFECreateDefault()`
17352b99622eSMatthew G. Knepley @*/
PetscFEGetHeightSubspace(PetscFE fe,PetscInt height,PetscFE * subfe)1736d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEGetHeightSubspace(PetscFE fe, PetscInt height, PetscFE *subfe)
1737d71ae5a4SJacob Faibussowitsch {
173820cf1dd8SToby Isaac PetscSpace P, subP;
173920cf1dd8SToby Isaac PetscDualSpace Q, subQ;
174020cf1dd8SToby Isaac PetscQuadrature subq;
174120cf1dd8SToby Isaac PetscInt dim, Nc;
174220cf1dd8SToby Isaac
174320cf1dd8SToby Isaac PetscFunctionBegin;
174420cf1dd8SToby Isaac PetscValidHeaderSpecific(fe, PETSCFE_CLASSID, 1);
17454f572ea9SToby Isaac PetscAssertPointer(subfe, 3);
174620cf1dd8SToby Isaac if (height == 0) {
174720cf1dd8SToby Isaac *subfe = fe;
17483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
174920cf1dd8SToby Isaac }
17509566063dSJacob Faibussowitsch PetscCall(PetscFEGetBasisSpace(fe, &P));
17519566063dSJacob Faibussowitsch PetscCall(PetscFEGetDualSpace(fe, &Q));
17529566063dSJacob Faibussowitsch PetscCall(PetscFEGetNumComponents(fe, &Nc));
17539566063dSJacob Faibussowitsch PetscCall(PetscFEGetFaceQuadrature(fe, &subq));
17549566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetDimension(Q, &dim));
17551dca8a05SBarry Smith PetscCheck(height <= dim && height >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Asked for space at height %" PetscInt_FMT " for dimension %" PetscInt_FMT " space", height, dim);
17569566063dSJacob Faibussowitsch if (!fe->subspaces) PetscCall(PetscCalloc1(dim, &fe->subspaces));
175720cf1dd8SToby Isaac if (height <= dim) {
175820cf1dd8SToby Isaac if (!fe->subspaces[height - 1]) {
1759665f567fSMatthew G. Knepley PetscFE sub = NULL;
17603f6b16c7SMatthew G. Knepley const char *name;
176120cf1dd8SToby Isaac
17629566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetHeightSubspace(P, height, &subP));
17639566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetHeightSubspace(Q, height, &subQ));
1764665f567fSMatthew G. Knepley if (subQ) {
17652dce792eSToby Isaac PetscCall(PetscObjectReference((PetscObject)subP));
17662dce792eSToby Isaac PetscCall(PetscObjectReference((PetscObject)subQ));
17672dce792eSToby Isaac PetscCall(PetscObjectReference((PetscObject)subq));
17682dce792eSToby Isaac PetscCall(PetscFECreateFromSpaces(subP, subQ, subq, NULL, &sub));
17692dce792eSToby Isaac }
17702dce792eSToby Isaac if (sub) {
17719566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)fe, &name));
17722dce792eSToby Isaac if (name) PetscCall(PetscFESetName(sub, name));
1773665f567fSMatthew G. Knepley }
177420cf1dd8SToby Isaac fe->subspaces[height - 1] = sub;
177520cf1dd8SToby Isaac }
177620cf1dd8SToby Isaac *subfe = fe->subspaces[height - 1];
177720cf1dd8SToby Isaac } else {
177820cf1dd8SToby Isaac *subfe = NULL;
177920cf1dd8SToby Isaac }
17803ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
178120cf1dd8SToby Isaac }
178220cf1dd8SToby Isaac
178320cf1dd8SToby Isaac /*@
1784a4e35b19SJacob Faibussowitsch PetscFERefine - Create a "refined" `PetscFE` object that refines the reference cell into
1785a4e35b19SJacob Faibussowitsch smaller copies.
178620cf1dd8SToby Isaac
178720f4b53cSBarry Smith Collective
178820cf1dd8SToby Isaac
178920cf1dd8SToby Isaac Input Parameter:
179020f4b53cSBarry Smith . fe - The initial `PetscFE`
179120cf1dd8SToby Isaac
179220cf1dd8SToby Isaac Output Parameter:
179320f4b53cSBarry Smith . feRef - The refined `PetscFE`
179420cf1dd8SToby Isaac
17952b99622eSMatthew G. Knepley Level: advanced
179620cf1dd8SToby Isaac
1797a4e35b19SJacob Faibussowitsch Notes:
1798a4e35b19SJacob Faibussowitsch This is typically used to generate a preconditioner for a higher order method from a lower order method on a
1799a4e35b19SJacob Faibussowitsch refined mesh having the same number of dofs (but more sparsity). It is also used to create an
1800a4e35b19SJacob Faibussowitsch interpolation between regularly refined meshes.
1801a4e35b19SJacob Faibussowitsch
1802db781477SPatrick Sanan .seealso: `PetscFEType`, `PetscFECreate()`, `PetscFESetType()`
180320cf1dd8SToby Isaac @*/
PetscFERefine(PetscFE fe,PetscFE * feRef)1804d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFERefine(PetscFE fe, PetscFE *feRef)
1805d71ae5a4SJacob Faibussowitsch {
180620cf1dd8SToby Isaac PetscSpace P, Pref;
180720cf1dd8SToby Isaac PetscDualSpace Q, Qref;
180820cf1dd8SToby Isaac DM K, Kref;
180920cf1dd8SToby Isaac PetscQuadrature q, qref;
181020cf1dd8SToby Isaac const PetscReal *v0, *jac;
181120cf1dd8SToby Isaac PetscInt numComp, numSubelements;
18121ac17e89SToby Isaac PetscInt cStart, cEnd, c;
18131ac17e89SToby Isaac PetscDualSpace *cellSpaces;
181420cf1dd8SToby Isaac
181520cf1dd8SToby Isaac PetscFunctionBegin;
18169566063dSJacob Faibussowitsch PetscCall(PetscFEGetBasisSpace(fe, &P));
18179566063dSJacob Faibussowitsch PetscCall(PetscFEGetDualSpace(fe, &Q));
18189566063dSJacob Faibussowitsch PetscCall(PetscFEGetQuadrature(fe, &q));
18199566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetDM(Q, &K));
182020cf1dd8SToby Isaac /* Create space */
18219566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)P));
182220cf1dd8SToby Isaac Pref = P;
182320cf1dd8SToby Isaac /* Create dual space */
18249566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceDuplicate(Q, &Qref));
18259566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetType(Qref, PETSCDUALSPACEREFINED));
18269566063dSJacob Faibussowitsch PetscCall(DMRefine(K, PetscObjectComm((PetscObject)fe), &Kref));
1827e44f6aebSMatthew G. Knepley PetscCall(DMGetCoordinatesLocalSetUp(Kref));
18289566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetDM(Qref, Kref));
18299566063dSJacob Faibussowitsch PetscCall(DMPlexGetHeightStratum(Kref, 0, &cStart, &cEnd));
18309566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(cEnd - cStart, &cellSpaces));
18311ac17e89SToby Isaac /* TODO: fix for non-uniform refinement */
18321ac17e89SToby Isaac for (c = 0; c < cEnd - cStart; c++) cellSpaces[c] = Q;
18339566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceRefinedSetCellSpaces(Qref, cellSpaces));
18349566063dSJacob Faibussowitsch PetscCall(PetscFree(cellSpaces));
18359566063dSJacob Faibussowitsch PetscCall(DMDestroy(&Kref));
18369566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetUp(Qref));
183720cf1dd8SToby Isaac /* Create element */
18389566063dSJacob Faibussowitsch PetscCall(PetscFECreate(PetscObjectComm((PetscObject)fe), feRef));
18399566063dSJacob Faibussowitsch PetscCall(PetscFESetType(*feRef, PETSCFECOMPOSITE));
18409566063dSJacob Faibussowitsch PetscCall(PetscFESetBasisSpace(*feRef, Pref));
18419566063dSJacob Faibussowitsch PetscCall(PetscFESetDualSpace(*feRef, Qref));
18429566063dSJacob Faibussowitsch PetscCall(PetscFEGetNumComponents(fe, &numComp));
18439566063dSJacob Faibussowitsch PetscCall(PetscFESetNumComponents(*feRef, numComp));
18449566063dSJacob Faibussowitsch PetscCall(PetscFESetUp(*feRef));
18459566063dSJacob Faibussowitsch PetscCall(PetscSpaceDestroy(&Pref));
18469566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceDestroy(&Qref));
184720cf1dd8SToby Isaac /* Create quadrature */
18489566063dSJacob Faibussowitsch PetscCall(PetscFECompositeGetMapping(*feRef, &numSubelements, &v0, &jac, NULL));
18499566063dSJacob Faibussowitsch PetscCall(PetscQuadratureExpandComposite(q, numSubelements, v0, jac, &qref));
18509566063dSJacob Faibussowitsch PetscCall(PetscFESetQuadrature(*feRef, qref));
18519566063dSJacob Faibussowitsch PetscCall(PetscQuadratureDestroy(&qref));
18523ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
185320cf1dd8SToby Isaac }
185420cf1dd8SToby Isaac
PetscFESetDefaultName_Private(PetscFE fe)1855d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFESetDefaultName_Private(PetscFE fe)
1856d71ae5a4SJacob Faibussowitsch {
18577c48043bSMatthew G. Knepley PetscSpace P;
18587c48043bSMatthew G. Knepley PetscDualSpace Q;
18597c48043bSMatthew G. Knepley DM K;
18607c48043bSMatthew G. Knepley DMPolytopeType ct;
18617c48043bSMatthew G. Knepley PetscInt degree;
18627c48043bSMatthew G. Knepley char name[64];
18637c48043bSMatthew G. Knepley
18647c48043bSMatthew G. Knepley PetscFunctionBegin;
18657c48043bSMatthew G. Knepley PetscCall(PetscFEGetBasisSpace(fe, &P));
18667c48043bSMatthew G. Knepley PetscCall(PetscSpaceGetDegree(P, °ree, NULL));
18677c48043bSMatthew G. Knepley PetscCall(PetscFEGetDualSpace(fe, &Q));
18687c48043bSMatthew G. Knepley PetscCall(PetscDualSpaceGetDM(Q, &K));
18697c48043bSMatthew G. Knepley PetscCall(DMPlexGetCellType(K, 0, &ct));
18707c48043bSMatthew G. Knepley switch (ct) {
18717c48043bSMatthew G. Knepley case DM_POLYTOPE_SEGMENT:
18727c48043bSMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR:
18737c48043bSMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL:
18747c48043bSMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR:
18757c48043bSMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON:
1876d71ae5a4SJacob Faibussowitsch case DM_POLYTOPE_QUAD_PRISM_TENSOR:
1877d71ae5a4SJacob Faibussowitsch PetscCall(PetscSNPrintf(name, sizeof(name), "Q%" PetscInt_FMT, degree));
1878d71ae5a4SJacob Faibussowitsch break;
18797c48043bSMatthew G. Knepley case DM_POLYTOPE_TRIANGLE:
1880d71ae5a4SJacob Faibussowitsch case DM_POLYTOPE_TETRAHEDRON:
1881d71ae5a4SJacob Faibussowitsch PetscCall(PetscSNPrintf(name, sizeof(name), "P%" PetscInt_FMT, degree));
1882d71ae5a4SJacob Faibussowitsch break;
18837c48043bSMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM:
1884d71ae5a4SJacob Faibussowitsch case DM_POLYTOPE_TRI_PRISM_TENSOR:
1885d71ae5a4SJacob Faibussowitsch PetscCall(PetscSNPrintf(name, sizeof(name), "P%" PetscInt_FMT "xQ%" PetscInt_FMT, degree, degree));
1886d71ae5a4SJacob Faibussowitsch break;
1887d71ae5a4SJacob Faibussowitsch default:
1888d71ae5a4SJacob Faibussowitsch PetscCall(PetscSNPrintf(name, sizeof(name), "FE"));
18897c48043bSMatthew G. Knepley }
18907c48043bSMatthew G. Knepley PetscCall(PetscFESetName(fe, name));
18913ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
18927c48043bSMatthew G. Knepley }
18937c48043bSMatthew G. Knepley
18947c48043bSMatthew G. Knepley /*@
1895dce8aebaSBarry Smith PetscFECreateFromSpaces - Create a `PetscFE` from the basis and dual spaces
18967c48043bSMatthew G. Knepley
18977c48043bSMatthew G. Knepley Collective
18987c48043bSMatthew G. Knepley
18997c48043bSMatthew G. Knepley Input Parameters:
19007c48043bSMatthew G. Knepley + P - The basis space
19017c48043bSMatthew G. Knepley . Q - The dual space
19027c48043bSMatthew G. Knepley . q - The cell quadrature
19037c48043bSMatthew G. Knepley - fq - The face quadrature
19047c48043bSMatthew G. Knepley
19057c48043bSMatthew G. Knepley Output Parameter:
190620f4b53cSBarry Smith . fem - The `PetscFE` object
19077c48043bSMatthew G. Knepley
19087c48043bSMatthew G. Knepley Level: beginner
19097c48043bSMatthew G. Knepley
1910dce8aebaSBarry Smith Note:
1911dce8aebaSBarry Smith The `PetscFE` takes ownership of these spaces by calling destroy on each. They should not be used after this call, and for borrowed references from `PetscFEGetSpace()` and the like, the caller must use `PetscObjectReference` before this call.
1912dce8aebaSBarry Smith
1913dce8aebaSBarry Smith .seealso: `PetscFE`, `PetscSpace`, `PetscDualSpace`, `PetscQuadrature`,
1914dce8aebaSBarry Smith `PetscFECreateLagrangeByCell()`, `PetscFECreateDefault()`, `PetscFECreateByCell()`, `PetscFECreate()`, `PetscSpaceCreate()`, `PetscDualSpaceCreate()`
19157c48043bSMatthew G. Knepley @*/
PetscFECreateFromSpaces(PetscSpace P,PetscDualSpace Q,PetscQuadrature q,PetscQuadrature fq,PetscFE * fem)1916d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFECreateFromSpaces(PetscSpace P, PetscDualSpace Q, PetscQuadrature q, PetscQuadrature fq, PetscFE *fem)
1917d71ae5a4SJacob Faibussowitsch {
19187c48043bSMatthew G. Knepley PetscInt Nc;
19192dce792eSToby Isaac PetscInt p_Ns = -1, p_Nc = -1, q_Ns = -1, q_Nc = -1;
19202dce792eSToby Isaac PetscBool p_is_uniform_sum = PETSC_FALSE, p_interleave_basis = PETSC_FALSE, p_interleave_components = PETSC_FALSE;
19212dce792eSToby Isaac PetscBool q_is_uniform_sum = PETSC_FALSE, q_interleave_basis = PETSC_FALSE, q_interleave_components = PETSC_FALSE;
19227c48043bSMatthew G. Knepley const char *prefix;
19237c48043bSMatthew G. Knepley
19247c48043bSMatthew G. Knepley PetscFunctionBegin;
19252dce792eSToby Isaac PetscCall(PetscObjectTypeCompare((PetscObject)P, PETSCSPACESUM, &p_is_uniform_sum));
19262dce792eSToby Isaac if (p_is_uniform_sum) {
19272dce792eSToby Isaac PetscSpace subsp_0 = NULL;
19282dce792eSToby Isaac PetscCall(PetscSpaceSumGetNumSubspaces(P, &p_Ns));
19292dce792eSToby Isaac PetscCall(PetscSpaceGetNumComponents(P, &p_Nc));
19302dce792eSToby Isaac PetscCall(PetscSpaceSumGetConcatenate(P, &p_is_uniform_sum));
19312dce792eSToby Isaac PetscCall(PetscSpaceSumGetInterleave(P, &p_interleave_basis, &p_interleave_components));
19322dce792eSToby Isaac for (PetscInt s = 0; s < p_Ns; s++) {
19332dce792eSToby Isaac PetscSpace subsp;
19342dce792eSToby Isaac
19352dce792eSToby Isaac PetscCall(PetscSpaceSumGetSubspace(P, s, &subsp));
19362dce792eSToby Isaac if (!s) {
19372dce792eSToby Isaac subsp_0 = subsp;
19382dce792eSToby Isaac } else if (subsp != subsp_0) {
19392dce792eSToby Isaac p_is_uniform_sum = PETSC_FALSE;
19402dce792eSToby Isaac }
19412dce792eSToby Isaac }
19422dce792eSToby Isaac }
19432dce792eSToby Isaac PetscCall(PetscObjectTypeCompare((PetscObject)Q, PETSCDUALSPACESUM, &q_is_uniform_sum));
19442dce792eSToby Isaac if (q_is_uniform_sum) {
19452dce792eSToby Isaac PetscDualSpace subsp_0 = NULL;
19462dce792eSToby Isaac PetscCall(PetscDualSpaceSumGetNumSubspaces(Q, &q_Ns));
19472dce792eSToby Isaac PetscCall(PetscDualSpaceGetNumComponents(Q, &q_Nc));
19482dce792eSToby Isaac PetscCall(PetscDualSpaceSumGetConcatenate(Q, &q_is_uniform_sum));
19492dce792eSToby Isaac PetscCall(PetscDualSpaceSumGetInterleave(Q, &q_interleave_basis, &q_interleave_components));
19502dce792eSToby Isaac for (PetscInt s = 0; s < q_Ns; s++) {
19512dce792eSToby Isaac PetscDualSpace subsp;
19522dce792eSToby Isaac
19532dce792eSToby Isaac PetscCall(PetscDualSpaceSumGetSubspace(Q, s, &subsp));
19542dce792eSToby Isaac if (!s) {
19552dce792eSToby Isaac subsp_0 = subsp;
19562dce792eSToby Isaac } else if (subsp != subsp_0) {
19572dce792eSToby Isaac q_is_uniform_sum = PETSC_FALSE;
19582dce792eSToby Isaac }
19592dce792eSToby Isaac }
19602dce792eSToby Isaac }
19612dce792eSToby Isaac if (p_is_uniform_sum && q_is_uniform_sum && (p_interleave_basis == q_interleave_basis) && (p_interleave_components == q_interleave_components) && (p_Ns == q_Ns) && (p_Nc == q_Nc)) {
19622dce792eSToby Isaac PetscSpace scalar_space;
19632dce792eSToby Isaac PetscDualSpace scalar_dspace;
19642dce792eSToby Isaac PetscFE scalar_fe;
19652dce792eSToby Isaac
19662dce792eSToby Isaac PetscCall(PetscSpaceSumGetSubspace(P, 0, &scalar_space));
19672dce792eSToby Isaac PetscCall(PetscDualSpaceSumGetSubspace(Q, 0, &scalar_dspace));
19682dce792eSToby Isaac PetscCall(PetscObjectReference((PetscObject)scalar_space));
19692dce792eSToby Isaac PetscCall(PetscObjectReference((PetscObject)scalar_dspace));
19702dce792eSToby Isaac PetscCall(PetscObjectReference((PetscObject)q));
19712dce792eSToby Isaac PetscCall(PetscObjectReference((PetscObject)fq));
19722dce792eSToby Isaac PetscCall(PetscFECreateFromSpaces(scalar_space, scalar_dspace, q, fq, &scalar_fe));
19732dce792eSToby Isaac PetscCall(PetscFECreateVector(scalar_fe, p_Ns, p_interleave_basis, p_interleave_components, fem));
19742dce792eSToby Isaac PetscCall(PetscFEDestroy(&scalar_fe));
19752dce792eSToby Isaac } else {
19767c48043bSMatthew G. Knepley PetscCall(PetscFECreate(PetscObjectComm((PetscObject)P), fem));
19777c48043bSMatthew G. Knepley PetscCall(PetscFESetType(*fem, PETSCFEBASIC));
19782dce792eSToby Isaac }
19797c48043bSMatthew G. Knepley PetscCall(PetscSpaceGetNumComponents(P, &Nc));
19807c48043bSMatthew G. Knepley PetscCall(PetscFESetNumComponents(*fem, Nc));
19812dce792eSToby Isaac PetscCall(PetscFESetBasisSpace(*fem, P));
19822dce792eSToby Isaac PetscCall(PetscFESetDualSpace(*fem, Q));
19832dce792eSToby Isaac PetscCall(PetscObjectGetOptionsPrefix((PetscObject)P, &prefix));
19842dce792eSToby Isaac PetscCall(PetscObjectSetOptionsPrefix((PetscObject)*fem, prefix));
19857c48043bSMatthew G. Knepley PetscCall(PetscFESetUp(*fem));
19867c48043bSMatthew G. Knepley PetscCall(PetscSpaceDestroy(&P));
19877c48043bSMatthew G. Knepley PetscCall(PetscDualSpaceDestroy(&Q));
19887c48043bSMatthew G. Knepley PetscCall(PetscFESetQuadrature(*fem, q));
19897c48043bSMatthew G. Knepley PetscCall(PetscFESetFaceQuadrature(*fem, fq));
19907c48043bSMatthew G. Knepley PetscCall(PetscQuadratureDestroy(&q));
19917c48043bSMatthew G. Knepley PetscCall(PetscQuadratureDestroy(&fq));
19927c48043bSMatthew G. Knepley PetscCall(PetscFESetDefaultName_Private(*fem));
19933ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
19947c48043bSMatthew G. Knepley }
19957c48043bSMatthew G. Knepley
PetscFECreate_Internal(MPI_Comm comm,PetscInt dim,PetscInt Nc,DMPolytopeType ct,const char prefix[],PetscInt degree,PetscInt qorder,PetscBool setFromOptions,PetscFE * fem)1996d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscFECreate_Internal(MPI_Comm comm, PetscInt dim, PetscInt Nc, DMPolytopeType ct, const char prefix[], PetscInt degree, PetscInt qorder, PetscBool setFromOptions, PetscFE *fem)
1997d71ae5a4SJacob Faibussowitsch {
19982df84da0SMatthew G. Knepley DM K;
19992df84da0SMatthew G. Knepley PetscSpace P;
20002df84da0SMatthew G. Knepley PetscDualSpace Q;
20017c48043bSMatthew G. Knepley PetscQuadrature q, fq;
20022df84da0SMatthew G. Knepley PetscBool tensor;
20032df84da0SMatthew G. Knepley
20042df84da0SMatthew G. Knepley PetscFunctionBegin;
20054f572ea9SToby Isaac if (prefix) PetscAssertPointer(prefix, 5);
20064f572ea9SToby Isaac PetscAssertPointer(fem, 9);
20072df84da0SMatthew G. Knepley switch (ct) {
20082df84da0SMatthew G. Knepley case DM_POLYTOPE_SEGMENT:
20092df84da0SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR:
20102df84da0SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL:
20112df84da0SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR:
20122df84da0SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON:
2013d71ae5a4SJacob Faibussowitsch case DM_POLYTOPE_QUAD_PRISM_TENSOR:
2014d71ae5a4SJacob Faibussowitsch tensor = PETSC_TRUE;
2015d71ae5a4SJacob Faibussowitsch break;
2016d71ae5a4SJacob Faibussowitsch default:
2017d71ae5a4SJacob Faibussowitsch tensor = PETSC_FALSE;
20182df84da0SMatthew G. Knepley }
20192df84da0SMatthew G. Knepley /* Create space */
20209566063dSJacob Faibussowitsch PetscCall(PetscSpaceCreate(comm, &P));
20219566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetType(P, PETSCSPACEPOLYNOMIAL));
20229566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)P, prefix));
20239566063dSJacob Faibussowitsch PetscCall(PetscSpacePolynomialSetTensor(P, tensor));
20249566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetNumComponents(P, Nc));
20259566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetNumVariables(P, dim));
20262df84da0SMatthew G. Knepley if (degree >= 0) {
20279566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetDegree(P, degree, PETSC_DETERMINE));
2028cfd33b42SLisandro Dalcin if (ct == DM_POLYTOPE_TRI_PRISM || ct == DM_POLYTOPE_TRI_PRISM_TENSOR) {
20292df84da0SMatthew G. Knepley PetscSpace Pend, Pside;
20302df84da0SMatthew G. Knepley
20312dce792eSToby Isaac PetscCall(PetscSpaceSetNumComponents(P, 1));
20329566063dSJacob Faibussowitsch PetscCall(PetscSpaceCreate(comm, &Pend));
20339566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetType(Pend, PETSCSPACEPOLYNOMIAL));
20349566063dSJacob Faibussowitsch PetscCall(PetscSpacePolynomialSetTensor(Pend, PETSC_FALSE));
20352dce792eSToby Isaac PetscCall(PetscSpaceSetNumComponents(Pend, 1));
20369566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetNumVariables(Pend, dim - 1));
20379566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetDegree(Pend, degree, PETSC_DETERMINE));
20389566063dSJacob Faibussowitsch PetscCall(PetscSpaceCreate(comm, &Pside));
20399566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetType(Pside, PETSCSPACEPOLYNOMIAL));
20409566063dSJacob Faibussowitsch PetscCall(PetscSpacePolynomialSetTensor(Pside, PETSC_FALSE));
20419566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetNumComponents(Pside, 1));
20429566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetNumVariables(Pside, 1));
20439566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetDegree(Pside, degree, PETSC_DETERMINE));
20449566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetType(P, PETSCSPACETENSOR));
20459566063dSJacob Faibussowitsch PetscCall(PetscSpaceTensorSetNumSubspaces(P, 2));
20469566063dSJacob Faibussowitsch PetscCall(PetscSpaceTensorSetSubspace(P, 0, Pend));
20479566063dSJacob Faibussowitsch PetscCall(PetscSpaceTensorSetSubspace(P, 1, Pside));
20489566063dSJacob Faibussowitsch PetscCall(PetscSpaceDestroy(&Pend));
20499566063dSJacob Faibussowitsch PetscCall(PetscSpaceDestroy(&Pside));
20502dce792eSToby Isaac
20512dce792eSToby Isaac if (Nc > 1) {
20522dce792eSToby Isaac PetscSpace scalar_P = P;
20532dce792eSToby Isaac
20542dce792eSToby Isaac PetscCall(PetscSpaceCreate(comm, &P));
20552dce792eSToby Isaac PetscCall(PetscSpaceSetNumVariables(P, dim));
20562dce792eSToby Isaac PetscCall(PetscSpaceSetNumComponents(P, Nc));
20572dce792eSToby Isaac PetscCall(PetscSpaceSetType(P, PETSCSPACESUM));
20582dce792eSToby Isaac PetscCall(PetscSpaceSumSetNumSubspaces(P, Nc));
20592dce792eSToby Isaac PetscCall(PetscSpaceSumSetConcatenate(P, PETSC_TRUE));
20602dce792eSToby Isaac PetscCall(PetscSpaceSumSetInterleave(P, PETSC_TRUE, PETSC_FALSE));
20612dce792eSToby Isaac for (PetscInt i = 0; i < Nc; i++) PetscCall(PetscSpaceSumSetSubspace(P, i, scalar_P));
20622dce792eSToby Isaac PetscCall(PetscSpaceDestroy(&scalar_P));
20632dce792eSToby Isaac }
20642df84da0SMatthew G. Knepley }
20652df84da0SMatthew G. Knepley }
20669566063dSJacob Faibussowitsch if (setFromOptions) PetscCall(PetscSpaceSetFromOptions(P));
20679566063dSJacob Faibussowitsch PetscCall(PetscSpaceSetUp(P));
20689566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetDegree(P, °ree, NULL));
20699566063dSJacob Faibussowitsch PetscCall(PetscSpacePolynomialGetTensor(P, &tensor));
20709566063dSJacob Faibussowitsch PetscCall(PetscSpaceGetNumComponents(P, &Nc));
20712df84da0SMatthew G. Knepley /* Create dual space */
20729566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceCreate(comm, &Q));
20739566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetType(Q, PETSCDUALSPACELAGRANGE));
20749566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)Q, prefix));
20759566063dSJacob Faibussowitsch PetscCall(DMPlexCreateReferenceCell(PETSC_COMM_SELF, ct, &K));
20769566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetDM(Q, K));
20779566063dSJacob Faibussowitsch PetscCall(DMDestroy(&K));
20789566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetNumComponents(Q, Nc));
20799566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetOrder(Q, degree));
20809566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceLagrangeSetTensor(Q, (tensor || (ct == DM_POLYTOPE_TRI_PRISM)) ? PETSC_TRUE : PETSC_FALSE));
20819566063dSJacob Faibussowitsch if (setFromOptions) PetscCall(PetscDualSpaceSetFromOptions(Q));
20829566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceSetUp(Q));
20837c48043bSMatthew G. Knepley /* Create quadrature */
2084f2c64c88SMatthew G. Knepley PetscDTSimplexQuadratureType qtype = PETSCDTSIMPLEXQUAD_DEFAULT;
2085f2c64c88SMatthew G. Knepley
20862df84da0SMatthew G. Knepley qorder = qorder >= 0 ? qorder : degree;
20872df84da0SMatthew G. Knepley if (setFromOptions) {
20887c48043bSMatthew G. Knepley PetscObjectOptionsBegin((PetscObject)P);
20899566063dSJacob Faibussowitsch PetscCall(PetscOptionsBoundedInt("-petscfe_default_quadrature_order", "Quadrature order is one less than quadrature points per edge", "PetscFECreateDefault", qorder, &qorder, NULL, 0));
2090f2c64c88SMatthew G. Knepley PetscCall(PetscOptionsEnum("-petscfe_default_quadrature_type", "Simplex quadrature type", "PetscDTSimplexQuadratureType", PetscDTSimplexQuadratureTypes, (PetscEnum)qtype, (PetscEnum *)&qtype, NULL));
2091d0609cedSBarry Smith PetscOptionsEnd();
20922df84da0SMatthew G. Knepley }
2093f2c64c88SMatthew G. Knepley PetscCall(PetscDTCreateQuadratureByCell(ct, qorder, qtype, &q, &fq));
20947c48043bSMatthew G. Knepley /* Create finite element */
20957c48043bSMatthew G. Knepley PetscCall(PetscFECreateFromSpaces(P, Q, q, fq, fem));
20967c48043bSMatthew G. Knepley if (setFromOptions) PetscCall(PetscFESetFromOptions(*fem));
20973ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
20982df84da0SMatthew G. Knepley }
20992df84da0SMatthew G. Knepley
2100cc4c1da9SBarry Smith /*@
210120f4b53cSBarry Smith PetscFECreateDefault - Create a `PetscFE` for basic FEM computation
210220cf1dd8SToby Isaac
2103d083f849SBarry Smith Collective
210420cf1dd8SToby Isaac
210520cf1dd8SToby Isaac Input Parameters:
21067be5e748SToby Isaac + comm - The MPI comm
210720cf1dd8SToby Isaac . dim - The spatial dimension
210820cf1dd8SToby Isaac . Nc - The number of components
210920cf1dd8SToby Isaac . isSimplex - Flag for simplex reference cell, otherwise its a tensor product
211020f4b53cSBarry Smith . prefix - The options prefix, or `NULL`
211120f4b53cSBarry Smith - qorder - The quadrature order or `PETSC_DETERMINE` to use `PetscSpace` polynomial degree
211220cf1dd8SToby Isaac
211320cf1dd8SToby Isaac Output Parameter:
211420f4b53cSBarry Smith . fem - The `PetscFE` object
211520cf1dd8SToby Isaac
2116dce8aebaSBarry Smith Level: beginner
2117dce8aebaSBarry Smith
2118e703855dSMatthew G. Knepley Note:
21198f2aacc6SMatthew G. Knepley Each subobject is SetFromOption() during creation, so that the object may be customized from the command line, using the prefix specified above. See the links below for the particular options available.
2120e703855dSMatthew G. Knepley
2121db781477SPatrick Sanan .seealso: `PetscFECreateLagrange()`, `PetscFECreateByCell()`, `PetscSpaceSetFromOptions()`, `PetscDualSpaceSetFromOptions()`, `PetscFESetFromOptions()`, `PetscFECreate()`, `PetscSpaceCreate()`, `PetscDualSpaceCreate()`
212220cf1dd8SToby Isaac @*/
PetscFECreateDefault(MPI_Comm comm,PetscInt dim,PetscInt Nc,PetscBool isSimplex,const char prefix[],PetscInt qorder,PetscFE * fem)2123d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFECreateDefault(MPI_Comm comm, PetscInt dim, PetscInt Nc, PetscBool isSimplex, const char prefix[], PetscInt qorder, PetscFE *fem)
2124d71ae5a4SJacob Faibussowitsch {
212520cf1dd8SToby Isaac PetscFunctionBegin;
21269566063dSJacob Faibussowitsch PetscCall(PetscFECreate_Internal(comm, dim, Nc, DMPolytopeTypeSimpleShape(dim, isSimplex), prefix, PETSC_DECIDE, qorder, PETSC_TRUE, fem));
21273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
212820cf1dd8SToby Isaac }
21292df84da0SMatthew G. Knepley
2130cc4c1da9SBarry Smith /*@
213120f4b53cSBarry Smith PetscFECreateByCell - Create a `PetscFE` for basic FEM computation
21322df84da0SMatthew G. Knepley
21332df84da0SMatthew G. Knepley Collective
21342df84da0SMatthew G. Knepley
21352df84da0SMatthew G. Knepley Input Parameters:
21362df84da0SMatthew G. Knepley + comm - The MPI comm
21372df84da0SMatthew G. Knepley . dim - The spatial dimension
21382df84da0SMatthew G. Knepley . Nc - The number of components
21392df84da0SMatthew G. Knepley . ct - The celltype of the reference cell
214020f4b53cSBarry Smith . prefix - The options prefix, or `NULL`
214120f4b53cSBarry Smith - qorder - The quadrature order or `PETSC_DETERMINE` to use `PetscSpace` polynomial degree
21422df84da0SMatthew G. Knepley
21432df84da0SMatthew G. Knepley Output Parameter:
214420f4b53cSBarry Smith . fem - The `PetscFE` object
21452df84da0SMatthew G. Knepley
2146dce8aebaSBarry Smith Level: beginner
2147dce8aebaSBarry Smith
21482df84da0SMatthew G. Knepley Note:
21492df84da0SMatthew G. Knepley Each subobject is SetFromOption() during creation, so that the object may be customized from the command line, using the prefix specified above. See the links below for the particular options available.
21502df84da0SMatthew G. Knepley
2151db781477SPatrick Sanan .seealso: `PetscFECreateDefault()`, `PetscFECreateLagrange()`, `PetscSpaceSetFromOptions()`, `PetscDualSpaceSetFromOptions()`, `PetscFESetFromOptions()`, `PetscFECreate()`, `PetscSpaceCreate()`, `PetscDualSpaceCreate()`
21522df84da0SMatthew G. Knepley @*/
PetscFECreateByCell(MPI_Comm comm,PetscInt dim,PetscInt Nc,DMPolytopeType ct,const char prefix[],PetscInt qorder,PetscFE * fem)2153d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFECreateByCell(MPI_Comm comm, PetscInt dim, PetscInt Nc, DMPolytopeType ct, const char prefix[], PetscInt qorder, PetscFE *fem)
2154d71ae5a4SJacob Faibussowitsch {
21552df84da0SMatthew G. Knepley PetscFunctionBegin;
21569566063dSJacob Faibussowitsch PetscCall(PetscFECreate_Internal(comm, dim, Nc, ct, prefix, PETSC_DECIDE, qorder, PETSC_TRUE, fem));
21573ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
215820cf1dd8SToby Isaac }
21593f6b16c7SMatthew G. Knepley
2160e703855dSMatthew G. Knepley /*@
216120f4b53cSBarry Smith PetscFECreateLagrange - Create a `PetscFE` for the basic Lagrange space of degree k
2162e703855dSMatthew G. Knepley
2163e703855dSMatthew G. Knepley Collective
2164e703855dSMatthew G. Knepley
2165e703855dSMatthew G. Knepley Input Parameters:
2166e703855dSMatthew G. Knepley + comm - The MPI comm
2167e703855dSMatthew G. Knepley . dim - The spatial dimension
2168e703855dSMatthew G. Knepley . Nc - The number of components
2169e703855dSMatthew G. Knepley . isSimplex - Flag for simplex reference cell, otherwise its a tensor product
2170e703855dSMatthew G. Knepley . k - The degree k of the space
217120f4b53cSBarry Smith - qorder - The quadrature order or `PETSC_DETERMINE` to use `PetscSpace` polynomial degree
2172e703855dSMatthew G. Knepley
2173e703855dSMatthew G. Knepley Output Parameter:
217420f4b53cSBarry Smith . fem - The `PetscFE` object
2175e703855dSMatthew G. Knepley
2176e703855dSMatthew G. Knepley Level: beginner
2177e703855dSMatthew G. Knepley
2178dce8aebaSBarry Smith Note:
2179e703855dSMatthew G. Knepley For simplices, this element is the space of maximum polynomial degree k, otherwise it is a tensor product of 1D polynomials, each with maximal degree k.
2180e703855dSMatthew G. Knepley
2181db781477SPatrick Sanan .seealso: `PetscFECreateLagrangeByCell()`, `PetscFECreateDefault()`, `PetscFECreateByCell()`, `PetscFECreate()`, `PetscSpaceCreate()`, `PetscDualSpaceCreate()`
2182e703855dSMatthew G. Knepley @*/
PetscFECreateLagrange(MPI_Comm comm,PetscInt dim,PetscInt Nc,PetscBool isSimplex,PetscInt k,PetscInt qorder,PetscFE * fem)2183d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFECreateLagrange(MPI_Comm comm, PetscInt dim, PetscInt Nc, PetscBool isSimplex, PetscInt k, PetscInt qorder, PetscFE *fem)
2184d71ae5a4SJacob Faibussowitsch {
2185e703855dSMatthew G. Knepley PetscFunctionBegin;
21869566063dSJacob Faibussowitsch PetscCall(PetscFECreate_Internal(comm, dim, Nc, DMPolytopeTypeSimpleShape(dim, isSimplex), NULL, k, qorder, PETSC_FALSE, fem));
21873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
2188e703855dSMatthew G. Knepley }
21892df84da0SMatthew G. Knepley
21902df84da0SMatthew G. Knepley /*@
219120f4b53cSBarry Smith PetscFECreateLagrangeByCell - Create a `PetscFE` for the basic Lagrange space of degree k
21922df84da0SMatthew G. Knepley
21932df84da0SMatthew G. Knepley Collective
21942df84da0SMatthew G. Knepley
21952df84da0SMatthew G. Knepley Input Parameters:
21962df84da0SMatthew G. Knepley + comm - The MPI comm
21972df84da0SMatthew G. Knepley . dim - The spatial dimension
21982df84da0SMatthew G. Knepley . Nc - The number of components
21992df84da0SMatthew G. Knepley . ct - The celltype of the reference cell
22002df84da0SMatthew G. Knepley . k - The degree k of the space
220120f4b53cSBarry Smith - qorder - The quadrature order or `PETSC_DETERMINE` to use `PetscSpace` polynomial degree
22022df84da0SMatthew G. Knepley
22032df84da0SMatthew G. Knepley Output Parameter:
220420f4b53cSBarry Smith . fem - The `PetscFE` object
22052df84da0SMatthew G. Knepley
22062df84da0SMatthew G. Knepley Level: beginner
22072df84da0SMatthew G. Knepley
2208dce8aebaSBarry Smith Note:
22092df84da0SMatthew G. Knepley For simplices, this element is the space of maximum polynomial degree k, otherwise it is a tensor product of 1D polynomials, each with maximal degree k.
22102df84da0SMatthew G. Knepley
2211db781477SPatrick Sanan .seealso: `PetscFECreateLagrange()`, `PetscFECreateDefault()`, `PetscFECreateByCell()`, `PetscFECreate()`, `PetscSpaceCreate()`, `PetscDualSpaceCreate()`
22122df84da0SMatthew G. Knepley @*/
PetscFECreateLagrangeByCell(MPI_Comm comm,PetscInt dim,PetscInt Nc,DMPolytopeType ct,PetscInt k,PetscInt qorder,PetscFE * fem)2213d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFECreateLagrangeByCell(MPI_Comm comm, PetscInt dim, PetscInt Nc, DMPolytopeType ct, PetscInt k, PetscInt qorder, PetscFE *fem)
2214d71ae5a4SJacob Faibussowitsch {
22152df84da0SMatthew G. Knepley PetscFunctionBegin;
22169566063dSJacob Faibussowitsch PetscCall(PetscFECreate_Internal(comm, dim, Nc, ct, NULL, k, qorder, PETSC_FALSE, fem));
22173ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
2218e703855dSMatthew G. Knepley }
2219e703855dSMatthew G. Knepley
2220cc4c1da9SBarry Smith /*@
2221bb4b53efSMatthew G. Knepley PetscFELimitDegree - Copy a `PetscFE` but limit the degree to be in the given range
2222bb4b53efSMatthew G. Knepley
2223bb4b53efSMatthew G. Knepley Collective
2224bb4b53efSMatthew G. Knepley
2225bb4b53efSMatthew G. Knepley Input Parameters:
2226bb4b53efSMatthew G. Knepley + fe - The `PetscFE`
2227bb4b53efSMatthew G. Knepley . minDegree - The minimum degree, or `PETSC_DETERMINE` for no limit
2228bb4b53efSMatthew G. Knepley - maxDegree - The maximum degree, or `PETSC_DETERMINE` for no limit
2229bb4b53efSMatthew G. Knepley
2230bb4b53efSMatthew G. Knepley Output Parameter:
2231bb4b53efSMatthew G. Knepley . newfe - The `PetscFE` object
2232bb4b53efSMatthew G. Knepley
2233bb4b53efSMatthew G. Knepley Level: advanced
2234bb4b53efSMatthew G. Knepley
2235bb4b53efSMatthew G. Knepley Note:
2236bb4b53efSMatthew G. Knepley This currently only works for Lagrange elements.
2237bb4b53efSMatthew G. Knepley
2238bb4b53efSMatthew G. Knepley .seealso: `PetscFECreateLagrange()`, `PetscFECreateDefault()`, `PetscFECreateByCell()`, `PetscFECreate()`, `PetscSpaceCreate()`, `PetscDualSpaceCreate()`
2239bb4b53efSMatthew G. Knepley @*/
PetscFELimitDegree(PetscFE fe,PetscInt minDegree,PetscInt maxDegree,PetscFE * newfe)2240bb4b53efSMatthew G. Knepley PetscErrorCode PetscFELimitDegree(PetscFE fe, PetscInt minDegree, PetscInt maxDegree, PetscFE *newfe)
2241bb4b53efSMatthew G. Knepley {
2242bb4b53efSMatthew G. Knepley PetscDualSpace Q;
2243bb4b53efSMatthew G. Knepley PetscBool islag, issum;
2244bb4b53efSMatthew G. Knepley PetscInt oldk = 0, k;
2245bb4b53efSMatthew G. Knepley
2246bb4b53efSMatthew G. Knepley PetscFunctionBegin;
2247bb4b53efSMatthew G. Knepley PetscCall(PetscFEGetDualSpace(fe, &Q));
2248bb4b53efSMatthew G. Knepley PetscCall(PetscObjectTypeCompare((PetscObject)Q, PETSCDUALSPACELAGRANGE, &islag));
2249bb4b53efSMatthew G. Knepley PetscCall(PetscObjectTypeCompare((PetscObject)Q, PETSCDUALSPACESUM, &issum));
2250bb4b53efSMatthew G. Knepley if (islag) {
2251bb4b53efSMatthew G. Knepley PetscCall(PetscDualSpaceGetOrder(Q, &oldk));
2252bb4b53efSMatthew G. Knepley } else if (issum) {
2253bb4b53efSMatthew G. Knepley PetscDualSpace subQ;
2254bb4b53efSMatthew G. Knepley
2255bb4b53efSMatthew G. Knepley PetscCall(PetscDualSpaceSumGetSubspace(Q, 0, &subQ));
2256bb4b53efSMatthew G. Knepley PetscCall(PetscDualSpaceGetOrder(subQ, &oldk));
2257bb4b53efSMatthew G. Knepley } else {
2258bb4b53efSMatthew G. Knepley PetscCall(PetscObjectReference((PetscObject)fe));
2259bb4b53efSMatthew G. Knepley *newfe = fe;
2260bb4b53efSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS);
2261bb4b53efSMatthew G. Knepley }
2262bb4b53efSMatthew G. Knepley k = oldk;
2263bb4b53efSMatthew G. Knepley if (minDegree >= 0) k = PetscMax(k, minDegree);
2264bb4b53efSMatthew G. Knepley if (maxDegree >= 0) k = PetscMin(k, maxDegree);
2265bb4b53efSMatthew G. Knepley if (k != oldk) {
2266bb4b53efSMatthew G. Knepley DM K;
2267bb4b53efSMatthew G. Knepley PetscSpace P;
2268bb4b53efSMatthew G. Knepley PetscQuadrature q;
2269bb4b53efSMatthew G. Knepley DMPolytopeType ct;
2270bb4b53efSMatthew G. Knepley PetscInt dim, Nc;
2271bb4b53efSMatthew G. Knepley
2272bb4b53efSMatthew G. Knepley PetscCall(PetscFEGetBasisSpace(fe, &P));
2273bb4b53efSMatthew G. Knepley PetscCall(PetscSpaceGetNumVariables(P, &dim));
2274bb4b53efSMatthew G. Knepley PetscCall(PetscSpaceGetNumComponents(P, &Nc));
2275bb4b53efSMatthew G. Knepley PetscCall(PetscDualSpaceGetDM(Q, &K));
2276bb4b53efSMatthew G. Knepley PetscCall(DMPlexGetCellType(K, 0, &ct));
2277bb4b53efSMatthew G. Knepley PetscCall(PetscFECreateLagrangeByCell(PetscObjectComm((PetscObject)fe), dim, Nc, ct, k, PETSC_DETERMINE, newfe));
2278bb4b53efSMatthew G. Knepley PetscCall(PetscFEGetQuadrature(fe, &q));
2279bb4b53efSMatthew G. Knepley PetscCall(PetscFESetQuadrature(*newfe, q));
2280bb4b53efSMatthew G. Knepley } else {
2281bb4b53efSMatthew G. Knepley PetscCall(PetscObjectReference((PetscObject)fe));
2282bb4b53efSMatthew G. Knepley *newfe = fe;
2283bb4b53efSMatthew G. Knepley }
2284bb4b53efSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS);
2285bb4b53efSMatthew G. Knepley }
2286bb4b53efSMatthew G. Knepley
2287bb4b53efSMatthew G. Knepley /*@
22884c712d99Sksagiyam PetscFECreateBrokenElement - Create a discontinuous version of the input `PetscFE`
22894c712d99Sksagiyam
22904c712d99Sksagiyam Collective
22914c712d99Sksagiyam
22924c712d99Sksagiyam Input Parameters:
22934c712d99Sksagiyam . cgfe - The continuous `PetscFE` object
22944c712d99Sksagiyam
22954c712d99Sksagiyam Output Parameter:
22964c712d99Sksagiyam . dgfe - The discontinuous `PetscFE` object
22974c712d99Sksagiyam
22984c712d99Sksagiyam Level: advanced
22994c712d99Sksagiyam
23004c712d99Sksagiyam Note:
23014c712d99Sksagiyam This only works for Lagrange elements.
23024c712d99Sksagiyam
23034c712d99Sksagiyam .seealso: `PetscFECreate()`, `PetscSpaceCreate()`, `PetscDualSpaceCreate()`, `PetscFECreateLagrange()`, `PetscFECreateLagrangeByCell()`, `PetscDualSpaceLagrangeSetContinuity()`
23044c712d99Sksagiyam @*/
PetscFECreateBrokenElement(PetscFE cgfe,PetscFE * dgfe)23054c712d99Sksagiyam PetscErrorCode PetscFECreateBrokenElement(PetscFE cgfe, PetscFE *dgfe)
23064c712d99Sksagiyam {
23074c712d99Sksagiyam PetscSpace P;
23084c712d99Sksagiyam PetscDualSpace Q, dgQ;
23094c712d99Sksagiyam PetscQuadrature q, fq;
23104c712d99Sksagiyam PetscBool is_lagrange, is_sum;
23114c712d99Sksagiyam
23124c712d99Sksagiyam PetscFunctionBegin;
23134c712d99Sksagiyam PetscCall(PetscFEGetBasisSpace(cgfe, &P));
23144c712d99Sksagiyam PetscCall(PetscObjectReference((PetscObject)P));
23154c712d99Sksagiyam PetscCall(PetscFEGetDualSpace(cgfe, &Q));
23164c712d99Sksagiyam PetscCall(PetscObjectTypeCompare((PetscObject)Q, PETSCDUALSPACELAGRANGE, &is_lagrange));
23174c712d99Sksagiyam PetscCall(PetscObjectTypeCompare((PetscObject)Q, PETSCDUALSPACESUM, &is_sum));
23184c712d99Sksagiyam PetscCheck(is_lagrange || is_sum, PETSC_COMM_SELF, PETSC_ERR_SUP, "Can only create broken elements of Lagrange elements");
23194c712d99Sksagiyam PetscCall(PetscDualSpaceDuplicate(Q, &dgQ));
23204c712d99Sksagiyam PetscCall(PetscDualSpaceLagrangeSetContinuity(dgQ, PETSC_FALSE));
23214c712d99Sksagiyam PetscCall(PetscDualSpaceSetUp(dgQ));
23224c712d99Sksagiyam PetscCall(PetscFEGetQuadrature(cgfe, &q));
23234c712d99Sksagiyam PetscCall(PetscObjectReference((PetscObject)q));
23244c712d99Sksagiyam PetscCall(PetscFEGetFaceQuadrature(cgfe, &fq));
23254c712d99Sksagiyam PetscCall(PetscObjectReference((PetscObject)fq));
23264c712d99Sksagiyam PetscCall(PetscFECreateFromSpaces(P, dgQ, q, fq, dgfe));
23274c712d99Sksagiyam PetscFunctionReturn(PETSC_SUCCESS);
23284c712d99Sksagiyam }
23294c712d99Sksagiyam
23304c712d99Sksagiyam /*@
233120f4b53cSBarry Smith PetscFESetName - Names the `PetscFE` and its subobjects
23323f6b16c7SMatthew G. Knepley
233320f4b53cSBarry Smith Not Collective
23343f6b16c7SMatthew G. Knepley
23353f6b16c7SMatthew G. Knepley Input Parameters:
233620f4b53cSBarry Smith + fe - The `PetscFE`
23373f6b16c7SMatthew G. Knepley - name - The name
23383f6b16c7SMatthew G. Knepley
23392b99622eSMatthew G. Knepley Level: intermediate
23403f6b16c7SMatthew G. Knepley
2341db781477SPatrick Sanan .seealso: `PetscFECreate()`, `PetscSpaceCreate()`, `PetscDualSpaceCreate()`
23423f6b16c7SMatthew G. Knepley @*/
PetscFESetName(PetscFE fe,const char name[])2343d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFESetName(PetscFE fe, const char name[])
2344d71ae5a4SJacob Faibussowitsch {
23453f6b16c7SMatthew G. Knepley PetscSpace P;
23463f6b16c7SMatthew G. Knepley PetscDualSpace Q;
23473f6b16c7SMatthew G. Knepley
23483f6b16c7SMatthew G. Knepley PetscFunctionBegin;
23499566063dSJacob Faibussowitsch PetscCall(PetscFEGetBasisSpace(fe, &P));
23509566063dSJacob Faibussowitsch PetscCall(PetscFEGetDualSpace(fe, &Q));
23519566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)fe, name));
23529566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)P, name));
23539566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)Q, name));
23543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
23553f6b16c7SMatthew G. Knepley }
2356a8f1f9e5SMatthew G. Knepley
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[])2357d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEEvaluateFieldJets_Internal(PetscDS ds, PetscInt Nf, PetscInt r, PetscInt q, PetscTabulation T[], PetscFEGeom *fegeom, const PetscScalar coefficients[], const PetscScalar coefficients_t[], PetscScalar u[], PetscScalar u_x[], PetscScalar u_t[])
2358d71ae5a4SJacob Faibussowitsch {
2359f9244615SMatthew G. Knepley PetscInt dOffset = 0, fOffset = 0, f, g;
2360a8f1f9e5SMatthew G. Knepley
2361a8f1f9e5SMatthew G. Knepley for (f = 0; f < Nf; ++f) {
236226add6b9SMatthew G. Knepley PetscCheck(r < T[f]->Nr, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Replica number %" PetscInt_FMT " should be in [0, %" PetscInt_FMT ")", r, T[f]->Nr);
236326add6b9SMatthew G. Knepley PetscCheck(q < T[f]->Np, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Point number %" PetscInt_FMT " should be in [0, %" PetscInt_FMT ")", q, T[f]->Np);
2364a8f1f9e5SMatthew G. Knepley PetscFE fe;
2365f9244615SMatthew G. Knepley const PetscInt k = ds->jetDegree[f];
2366ef0bb6c7SMatthew G. Knepley const PetscInt cdim = T[f]->cdim;
23672b6f951bSStefano Zampini const PetscInt dE = fegeom->dimEmbed;
2368ef0bb6c7SMatthew G. Knepley const PetscInt Nq = T[f]->Np;
2369ef0bb6c7SMatthew G. Knepley const PetscInt Nbf = T[f]->Nb;
2370ef0bb6c7SMatthew G. Knepley const PetscInt Ncf = T[f]->Nc;
2371ef0bb6c7SMatthew G. Knepley const PetscReal *Bq = &T[f]->T[0][(r * Nq + q) * Nbf * Ncf];
2372ef0bb6c7SMatthew G. Knepley const PetscReal *Dq = &T[f]->T[1][(r * Nq + q) * Nbf * Ncf * cdim];
2373f9244615SMatthew G. Knepley const PetscReal *Hq = k > 1 ? &T[f]->T[2][(r * Nq + q) * Nbf * Ncf * cdim * cdim] : NULL;
2374f9244615SMatthew G. Knepley PetscInt hOffset = 0, b, c, d;
2375a8f1f9e5SMatthew G. Knepley
23769566063dSJacob Faibussowitsch PetscCall(PetscDSGetDiscretization(ds, f, (PetscObject *)&fe));
2377a8f1f9e5SMatthew G. Knepley for (c = 0; c < Ncf; ++c) u[fOffset + c] = 0.0;
23782b6f951bSStefano Zampini for (d = 0; d < dE * Ncf; ++d) u_x[fOffset * dE + d] = 0.0;
2379a8f1f9e5SMatthew G. Knepley for (b = 0; b < Nbf; ++b) {
2380a8f1f9e5SMatthew G. Knepley for (c = 0; c < Ncf; ++c) {
2381a8f1f9e5SMatthew G. Knepley const PetscInt cidx = b * Ncf + c;
2382a8f1f9e5SMatthew G. Knepley
2383a8f1f9e5SMatthew G. Knepley u[fOffset + c] += Bq[cidx] * coefficients[dOffset + b];
23842b6f951bSStefano Zampini for (d = 0; d < cdim; ++d) u_x[(fOffset + c) * dE + d] += Dq[cidx * cdim + d] * coefficients[dOffset + b];
2385a8f1f9e5SMatthew G. Knepley }
2386a8f1f9e5SMatthew G. Knepley }
2387f9244615SMatthew G. Knepley if (k > 1) {
23882b6f951bSStefano Zampini for (g = 0; g < Nf; ++g) hOffset += T[g]->Nc * dE;
23892b6f951bSStefano Zampini for (d = 0; d < dE * dE * Ncf; ++d) u_x[hOffset + fOffset * dE * dE + d] = 0.0;
2390f9244615SMatthew G. Knepley for (b = 0; b < Nbf; ++b) {
2391f9244615SMatthew G. Knepley for (c = 0; c < Ncf; ++c) {
2392f9244615SMatthew G. Knepley const PetscInt cidx = b * Ncf + c;
2393f9244615SMatthew G. Knepley
23942b6f951bSStefano Zampini for (d = 0; d < cdim * cdim; ++d) u_x[hOffset + (fOffset + c) * dE * dE + d] += Hq[cidx * cdim * cdim + d] * coefficients[dOffset + b];
2395f9244615SMatthew G. Knepley }
2396f9244615SMatthew G. Knepley }
23972b6f951bSStefano Zampini PetscCall(PetscFEPushforwardHessian(fe, fegeom, 1, &u_x[hOffset + fOffset * dE * dE]));
2398f9244615SMatthew G. Knepley }
23999566063dSJacob Faibussowitsch PetscCall(PetscFEPushforward(fe, fegeom, 1, &u[fOffset]));
24002b6f951bSStefano Zampini PetscCall(PetscFEPushforwardGradient(fe, fegeom, 1, &u_x[fOffset * dE]));
2401a8f1f9e5SMatthew G. Knepley if (u_t) {
2402a8f1f9e5SMatthew G. Knepley for (c = 0; c < Ncf; ++c) u_t[fOffset + c] = 0.0;
2403a8f1f9e5SMatthew G. Knepley for (b = 0; b < Nbf; ++b) {
2404a8f1f9e5SMatthew G. Knepley for (c = 0; c < Ncf; ++c) {
2405a8f1f9e5SMatthew G. Knepley const PetscInt cidx = b * Ncf + c;
2406a8f1f9e5SMatthew G. Knepley
2407a8f1f9e5SMatthew G. Knepley u_t[fOffset + c] += Bq[cidx] * coefficients_t[dOffset + b];
2408a8f1f9e5SMatthew G. Knepley }
2409a8f1f9e5SMatthew G. Knepley }
24109566063dSJacob Faibussowitsch PetscCall(PetscFEPushforward(fe, fegeom, 1, &u_t[fOffset]));
2411a8f1f9e5SMatthew G. Knepley }
2412a8f1f9e5SMatthew G. Knepley fOffset += Ncf;
2413a8f1f9e5SMatthew G. Knepley dOffset += Nbf;
2414a8f1f9e5SMatthew G. Knepley }
24153ba16761SJacob Faibussowitsch return PETSC_SUCCESS;
2416a8f1f9e5SMatthew G. Knepley }
2417a8f1f9e5SMatthew G. Knepley
PetscFEEvaluateFieldJets_Hybrid_Internal(PetscDS ds,PetscInt Nf,PetscInt rc,PetscInt qc,PetscTabulation Tab[],const PetscInt rf[],const PetscInt qf[],PetscTabulation Tabf[],PetscFEGeom * fegeom,PetscFEGeom * fegeomNbr,const PetscScalar coefficients[],const PetscScalar coefficients_t[],PetscScalar u[],PetscScalar u_x[],PetscScalar u_t[])2418989fa639SBrad Aagaard PetscErrorCode PetscFEEvaluateFieldJets_Hybrid_Internal(PetscDS ds, PetscInt Nf, PetscInt rc, PetscInt qc, PetscTabulation Tab[], const PetscInt rf[], const PetscInt qf[], PetscTabulation Tabf[], PetscFEGeom *fegeom, PetscFEGeom *fegeomNbr, const PetscScalar coefficients[], const PetscScalar coefficients_t[], PetscScalar u[], PetscScalar u_x[], PetscScalar u_t[])
2419d71ae5a4SJacob Faibussowitsch {
2420*e60de12fSPierre Jolivet PetscInt dOffset = 0, fOffset = 0, f;
242127f02ce8SMatthew G. Knepley
2422*e60de12fSPierre Jolivet /* f is the field number in the DS */
2423*e60de12fSPierre Jolivet for (f = 0; f < Nf; ++f) {
24245fedec97SMatthew G. Knepley PetscBool isCohesive;
24255fedec97SMatthew G. Knepley PetscInt Ns, s;
24265fedec97SMatthew G. Knepley
242707218a29SMatthew G. Knepley if (!Tab[f]) continue;
24289566063dSJacob Faibussowitsch PetscCall(PetscDSGetCohesive(ds, f, &isCohesive));
24295fedec97SMatthew G. Knepley Ns = isCohesive ? 1 : 2;
243007218a29SMatthew G. Knepley {
243107218a29SMatthew G. Knepley PetscTabulation T = isCohesive ? Tab[f] : Tabf[f];
243207218a29SMatthew G. Knepley PetscFE fe = (PetscFE)ds->disc[f];
243307218a29SMatthew G. Knepley const PetscInt dEt = T->cdim;
243407218a29SMatthew G. Knepley const PetscInt dE = fegeom->dimEmbed;
243507218a29SMatthew G. Knepley const PetscInt Nq = T->Np;
243607218a29SMatthew G. Knepley const PetscInt Nbf = T->Nb;
243707218a29SMatthew G. Knepley const PetscInt Ncf = T->Nc;
243807218a29SMatthew G. Knepley
2439*e60de12fSPierre Jolivet for (s = 0; s < Ns; ++s) {
244007218a29SMatthew G. Knepley const PetscInt r = isCohesive ? rc : rf[s];
244107218a29SMatthew G. Knepley const PetscInt q = isCohesive ? qc : qf[s];
244207218a29SMatthew G. Knepley const PetscReal *Bq = &T->T[0][(r * Nq + q) * Nbf * Ncf];
244307218a29SMatthew G. Knepley const PetscReal *Dq = &T->T[1][(r * Nq + q) * Nbf * Ncf * dEt];
244427f02ce8SMatthew G. Knepley PetscInt b, c, d;
244527f02ce8SMatthew G. Knepley
244607218a29SMatthew G. Knepley PetscCheck(r < T->Nr, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field %" PetscInt_FMT " Side %" PetscInt_FMT " Replica number %" PetscInt_FMT " should be in [0, %" PetscInt_FMT ")", f, s, r, T->Nr);
244707218a29SMatthew G. Knepley PetscCheck(q < T->Np, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field %" PetscInt_FMT " Side %" PetscInt_FMT " Point number %" PetscInt_FMT " should be in [0, %" PetscInt_FMT ")", f, s, q, T->Np);
244827f02ce8SMatthew G. Knepley for (c = 0; c < Ncf; ++c) u[fOffset + c] = 0.0;
24499ee2af8cSMatthew G. Knepley for (d = 0; d < dE * Ncf; ++d) u_x[fOffset * dE + d] = 0.0;
245027f02ce8SMatthew G. Knepley for (b = 0; b < Nbf; ++b) {
245127f02ce8SMatthew G. Knepley for (c = 0; c < Ncf; ++c) {
245227f02ce8SMatthew G. Knepley const PetscInt cidx = b * Ncf + c;
245327f02ce8SMatthew G. Knepley
245427f02ce8SMatthew G. Knepley u[fOffset + c] += Bq[cidx] * coefficients[dOffset + b];
24559ee2af8cSMatthew G. Knepley for (d = 0; d < dEt; ++d) u_x[(fOffset + c) * dE + d] += Dq[cidx * dEt + d] * coefficients[dOffset + b];
245627f02ce8SMatthew G. Knepley }
245727f02ce8SMatthew G. Knepley }
2458989fa639SBrad Aagaard PetscCall(PetscFEPushforward(fe, isCohesive ? fegeom : &fegeomNbr[s], 1, &u[fOffset]));
2459989fa639SBrad Aagaard PetscCall(PetscFEPushforwardGradient(fe, isCohesive ? fegeom : &fegeomNbr[s], 1, &u_x[fOffset * dE]));
246027f02ce8SMatthew G. Knepley if (u_t) {
246127f02ce8SMatthew G. Knepley for (c = 0; c < Ncf; ++c) u_t[fOffset + c] = 0.0;
246227f02ce8SMatthew G. Knepley for (b = 0; b < Nbf; ++b) {
246327f02ce8SMatthew G. Knepley for (c = 0; c < Ncf; ++c) {
246427f02ce8SMatthew G. Knepley const PetscInt cidx = b * Ncf + c;
246527f02ce8SMatthew G. Knepley
246627f02ce8SMatthew G. Knepley u_t[fOffset + c] += Bq[cidx] * coefficients_t[dOffset + b];
246727f02ce8SMatthew G. Knepley }
246827f02ce8SMatthew G. Knepley }
24699566063dSJacob Faibussowitsch PetscCall(PetscFEPushforward(fe, fegeom, 1, &u_t[fOffset]));
247027f02ce8SMatthew G. Knepley }
247127f02ce8SMatthew G. Knepley fOffset += Ncf;
247227f02ce8SMatthew G. Knepley dOffset += Nbf;
247327f02ce8SMatthew G. Knepley }
2474665f567fSMatthew G. Knepley }
247507218a29SMatthew G. Knepley }
24763ba16761SJacob Faibussowitsch return PETSC_SUCCESS;
247727f02ce8SMatthew G. Knepley }
247827f02ce8SMatthew G. Knepley
PetscFEEvaluateFaceFields_Internal(PetscDS prob,PetscInt field,PetscInt faceLoc,const PetscScalar coefficients[],PetscScalar u[])2479d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEEvaluateFaceFields_Internal(PetscDS prob, PetscInt field, PetscInt faceLoc, const PetscScalar coefficients[], PetscScalar u[])
2480d71ae5a4SJacob Faibussowitsch {
2481a8f1f9e5SMatthew G. Knepley PetscFE fe;
2482ef0bb6c7SMatthew G. Knepley PetscTabulation Tc;
2483ef0bb6c7SMatthew G. Knepley PetscInt b, c;
2484a8f1f9e5SMatthew G. Knepley
24853ba16761SJacob Faibussowitsch if (!prob) return PETSC_SUCCESS;
24869566063dSJacob Faibussowitsch PetscCall(PetscDSGetDiscretization(prob, field, (PetscObject *)&fe));
24879566063dSJacob Faibussowitsch PetscCall(PetscFEGetFaceCentroidTabulation(fe, &Tc));
2488ef0bb6c7SMatthew G. Knepley {
2489ef0bb6c7SMatthew G. Knepley const PetscReal *faceBasis = Tc->T[0];
2490ef0bb6c7SMatthew G. Knepley const PetscInt Nb = Tc->Nb;
2491ef0bb6c7SMatthew G. Knepley const PetscInt Nc = Tc->Nc;
2492ef0bb6c7SMatthew G. Knepley
2493ad540459SPierre Jolivet for (c = 0; c < Nc; ++c) u[c] = 0.0;
2494a8f1f9e5SMatthew G. Knepley for (b = 0; b < Nb; ++b) {
2495ad540459SPierre Jolivet for (c = 0; c < Nc; ++c) u[c] += coefficients[b] * faceBasis[(faceLoc * Nb + b) * Nc + c];
2496a8f1f9e5SMatthew G. Knepley }
2497ef0bb6c7SMatthew G. Knepley }
24983ba16761SJacob Faibussowitsch return PETSC_SUCCESS;
2499a8f1f9e5SMatthew G. Knepley }
2500a8f1f9e5SMatthew G. Knepley
PetscFEUpdateElementVec_Internal(PetscFE fe,PetscTabulation T,PetscInt r,PetscScalar tmpBasis[],PetscScalar tmpBasisDer[],PetscInt e,PetscFEGeom * fegeom,PetscScalar f0[],PetscScalar f1[],PetscScalar elemVec[])2501d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEUpdateElementVec_Internal(PetscFE fe, PetscTabulation T, PetscInt r, PetscScalar tmpBasis[], PetscScalar tmpBasisDer[], PetscInt e, PetscFEGeom *fegeom, PetscScalar f0[], PetscScalar f1[], PetscScalar elemVec[])
2502d71ae5a4SJacob Faibussowitsch {
25036587ee25SMatthew G. Knepley PetscFEGeom pgeom;
2504bc3a64adSMatthew G. Knepley const PetscInt dEt = T->cdim;
2505bc3a64adSMatthew G. Knepley const PetscInt dE = fegeom->dimEmbed;
2506ef0bb6c7SMatthew G. Knepley const PetscInt Nq = T->Np;
2507ef0bb6c7SMatthew G. Knepley const PetscInt Nb = T->Nb;
2508ef0bb6c7SMatthew G. Knepley const PetscInt Nc = T->Nc;
2509ef0bb6c7SMatthew G. Knepley const PetscReal *basis = &T->T[0][r * Nq * Nb * Nc];
2510bc3a64adSMatthew G. Knepley const PetscReal *basisDer = &T->T[1][r * Nq * Nb * Nc * dEt];
2511a8f1f9e5SMatthew G. Knepley PetscInt q, b, c, d;
2512a8f1f9e5SMatthew G. Knepley
2513a8f1f9e5SMatthew G. Knepley for (q = 0; q < Nq; ++q) {
2514a8f1f9e5SMatthew G. Knepley for (b = 0; b < Nb; ++b) {
2515a8f1f9e5SMatthew G. Knepley for (c = 0; c < Nc; ++c) {
2516a8f1f9e5SMatthew G. Knepley const PetscInt bcidx = b * Nc + c;
2517a8f1f9e5SMatthew G. Knepley
2518a8f1f9e5SMatthew G. Knepley tmpBasis[bcidx] = basis[q * Nb * Nc + bcidx];
2519bc3a64adSMatthew G. Knepley for (d = 0; d < dEt; ++d) tmpBasisDer[bcidx * dE + d] = basisDer[q * Nb * Nc * dEt + bcidx * dEt + d];
25209ee2af8cSMatthew G. Knepley for (d = dEt; d < dE; ++d) tmpBasisDer[bcidx * dE + d] = 0.0;
2521a8f1f9e5SMatthew G. Knepley }
2522a8f1f9e5SMatthew G. Knepley }
25239566063dSJacob Faibussowitsch PetscCall(PetscFEGeomGetCellPoint(fegeom, e, q, &pgeom));
25249566063dSJacob Faibussowitsch PetscCall(PetscFEPushforward(fe, &pgeom, Nb, tmpBasis));
25259566063dSJacob Faibussowitsch PetscCall(PetscFEPushforwardGradient(fe, &pgeom, Nb, tmpBasisDer));
2526a8f1f9e5SMatthew G. Knepley for (b = 0; b < Nb; ++b) {
2527a8f1f9e5SMatthew G. Knepley for (c = 0; c < Nc; ++c) {
2528a8f1f9e5SMatthew G. Knepley const PetscInt bcidx = b * Nc + c;
2529a8f1f9e5SMatthew G. Knepley const PetscInt qcidx = q * Nc + c;
2530a8f1f9e5SMatthew G. Knepley
2531a8f1f9e5SMatthew G. Knepley elemVec[b] += tmpBasis[bcidx] * f0[qcidx];
253227f02ce8SMatthew G. Knepley for (d = 0; d < dE; ++d) elemVec[b] += tmpBasisDer[bcidx * dE + d] * f1[qcidx * dE + d];
253327f02ce8SMatthew G. Knepley }
253427f02ce8SMatthew G. Knepley }
253527f02ce8SMatthew G. Knepley }
25363ba16761SJacob Faibussowitsch return PETSC_SUCCESS;
253727f02ce8SMatthew G. Knepley }
253827f02ce8SMatthew G. Knepley
PetscFEUpdateElementVec_Hybrid_Internal(PetscFE fe,PetscTabulation T,PetscInt r,PetscInt side,PetscScalar tmpBasis[],PetscScalar tmpBasisDer[],PetscFEGeom * fegeom,PetscScalar f0[],PetscScalar f1[],PetscScalar elemVec[])25390abb75b6SMatthew G. Knepley PetscErrorCode PetscFEUpdateElementVec_Hybrid_Internal(PetscFE fe, PetscTabulation T, PetscInt r, PetscInt side, PetscScalar tmpBasis[], PetscScalar tmpBasisDer[], PetscFEGeom *fegeom, PetscScalar f0[], PetscScalar f1[], PetscScalar elemVec[])
2540d71ae5a4SJacob Faibussowitsch {
254127f02ce8SMatthew G. Knepley const PetscInt dE = T->cdim;
254227f02ce8SMatthew G. Knepley const PetscInt Nq = T->Np;
254327f02ce8SMatthew G. Knepley const PetscInt Nb = T->Nb;
254427f02ce8SMatthew G. Knepley const PetscInt Nc = T->Nc;
254527f02ce8SMatthew G. Knepley const PetscReal *basis = &T->T[0][r * Nq * Nb * Nc];
254627f02ce8SMatthew G. Knepley const PetscReal *basisDer = &T->T[1][r * Nq * Nb * Nc * dE];
254727f02ce8SMatthew G. Knepley
25480abb75b6SMatthew G. Knepley for (PetscInt q = 0; q < Nq; ++q) {
25490abb75b6SMatthew G. Knepley for (PetscInt b = 0; b < Nb; ++b) {
25500abb75b6SMatthew G. Knepley for (PetscInt c = 0; c < Nc; ++c) {
255127f02ce8SMatthew G. Knepley const PetscInt bcidx = b * Nc + c;
255227f02ce8SMatthew G. Knepley
255327f02ce8SMatthew G. Knepley tmpBasis[bcidx] = basis[q * Nb * Nc + bcidx];
25540abb75b6SMatthew G. Knepley for (PetscInt d = 0; d < dE; ++d) tmpBasisDer[bcidx * dE + d] = basisDer[q * Nb * Nc * dE + bcidx * dE + d];
255527f02ce8SMatthew G. Knepley }
255627f02ce8SMatthew G. Knepley }
25579566063dSJacob Faibussowitsch PetscCall(PetscFEPushforward(fe, fegeom, Nb, tmpBasis));
25582b6f951bSStefano Zampini // TODO This is currently broken since we do not pull the geometry down to the lower dimension
25592b6f951bSStefano Zampini // PetscCall(PetscFEPushforwardGradient(fe, fegeom, Nb, tmpBasisDer));
25600abb75b6SMatthew G. Knepley if (side == 2) {
25610abb75b6SMatthew G. Knepley // Integrating over whole cohesive cell, so insert for both sides
25620abb75b6SMatthew G. Knepley for (PetscInt s = 0; s < 2; ++s) {
25630abb75b6SMatthew G. Knepley for (PetscInt b = 0; b < Nb; ++b) {
25640abb75b6SMatthew G. Knepley for (PetscInt c = 0; c < Nc; ++c) {
25650abb75b6SMatthew G. Knepley const PetscInt bcidx = b * Nc + c;
25660abb75b6SMatthew G. Knepley const PetscInt qcidx = (q * 2 + s) * Nc + c;
25670abb75b6SMatthew G. Knepley
25680abb75b6SMatthew G. Knepley elemVec[Nb * s + b] += tmpBasis[bcidx] * f0[qcidx];
25690abb75b6SMatthew G. Knepley for (PetscInt d = 0; d < dE; ++d) elemVec[Nb * s + b] += tmpBasisDer[bcidx * dE + d] * f1[qcidx * dE + d];
25700abb75b6SMatthew G. Knepley }
25710abb75b6SMatthew G. Knepley }
25720abb75b6SMatthew G. Knepley }
25730abb75b6SMatthew G. Knepley } else {
25740abb75b6SMatthew G. Knepley // Integrating over endcaps of cohesive cell, so insert for correct side
25750abb75b6SMatthew G. Knepley for (PetscInt b = 0; b < Nb; ++b) {
25760abb75b6SMatthew G. Knepley for (PetscInt c = 0; c < Nc; ++c) {
257727f02ce8SMatthew G. Knepley const PetscInt bcidx = b * Nc + c;
2578c2b7495fSMatthew G. Knepley const PetscInt qcidx = q * Nc + c;
257927f02ce8SMatthew G. Knepley
25800abb75b6SMatthew G. Knepley elemVec[Nb * side + b] += tmpBasis[bcidx] * f0[qcidx];
25810abb75b6SMatthew G. Knepley for (PetscInt d = 0; d < dE; ++d) elemVec[Nb * side + b] += tmpBasisDer[bcidx * dE + d] * f1[qcidx * dE + d];
25820abb75b6SMatthew G. Knepley }
258327f02ce8SMatthew G. Knepley }
2584a8f1f9e5SMatthew G. Knepley }
2585a8f1f9e5SMatthew G. Knepley }
25863ba16761SJacob Faibussowitsch return PETSC_SUCCESS;
2587a8f1f9e5SMatthew G. Knepley }
2588a8f1f9e5SMatthew G. Knepley
25891a768569SStefano Zampini #define petsc_elemmat_kernel_g1(_NbI, _NcI, _NbJ, _NcJ, _dE) \
2590f102cd15SPierre Jolivet do { \
25911a768569SStefano Zampini for (PetscInt fc = 0; fc < (_NcI); ++fc) { \
25921a768569SStefano Zampini for (PetscInt gc = 0; gc < (_NcJ); ++gc) { \
25931a768569SStefano Zampini const PetscScalar *G = g1 + (fc * (_NcJ) + gc) * _dE; \
25941a768569SStefano Zampini for (PetscInt f = 0; f < (_NbI); ++f) { \
25951a768569SStefano Zampini const PetscScalar tBIv = tmpBasisI[f * (_NcI) + fc]; \
25961a768569SStefano Zampini for (PetscInt g = 0; g < (_NbJ); ++g) { \
25971a768569SStefano Zampini const PetscScalar *tBDJ = tmpBasisDerJ + (g * (_NcJ) + gc) * (_dE); \
25981a768569SStefano Zampini PetscScalar s = 0.0; \
25990b36fe0aSPierre Jolivet for (PetscInt df = 0; df < _dE; ++df) s += G[df] * tBDJ[df]; \
26001a768569SStefano Zampini elemMat[(offsetI + f) * totDim + (offsetJ + g)] += s * tBIv; \
26011a768569SStefano Zampini } \
26021a768569SStefano Zampini } \
26031a768569SStefano Zampini } \
2604f102cd15SPierre Jolivet } \
2605f102cd15SPierre Jolivet } while (0)
26061a768569SStefano Zampini
26071a768569SStefano Zampini #define petsc_elemmat_kernel_g2(_NbI, _NcI, _NbJ, _NcJ, _dE) \
2608f102cd15SPierre Jolivet do { \
26091a768569SStefano Zampini for (PetscInt gc = 0; gc < (_NcJ); ++gc) { \
26101a768569SStefano Zampini for (PetscInt fc = 0; fc < (_NcI); ++fc) { \
26111a768569SStefano Zampini const PetscScalar *G = g2 + (fc * (_NcJ) + gc) * _dE; \
26121a768569SStefano Zampini for (PetscInt g = 0; g < (_NbJ); ++g) { \
26131a768569SStefano Zampini const PetscScalar tBJv = tmpBasisJ[g * (_NcJ) + gc]; \
26141a768569SStefano Zampini for (PetscInt f = 0; f < (_NbI); ++f) { \
26151a768569SStefano Zampini const PetscScalar *tBDI = tmpBasisDerI + (f * (_NcI) + fc) * (_dE); \
26161a768569SStefano Zampini PetscScalar s = 0.0; \
26170b36fe0aSPierre Jolivet for (PetscInt df = 0; df < _dE; ++df) s += tBDI[df] * G[df]; \
26181a768569SStefano Zampini elemMat[(offsetI + f) * totDim + (offsetJ + g)] += s * tBJv; \
26191a768569SStefano Zampini } \
26201a768569SStefano Zampini } \
26211a768569SStefano Zampini } \
2622f102cd15SPierre Jolivet } \
2623f102cd15SPierre Jolivet } while (0)
26241a768569SStefano Zampini
26251a768569SStefano Zampini #define petsc_elemmat_kernel_g3(_NbI, _NcI, _NbJ, _NcJ, _dE) \
2626f102cd15SPierre Jolivet do { \
26271a768569SStefano Zampini for (PetscInt fc = 0; fc < (_NcI); ++fc) { \
26281a768569SStefano Zampini for (PetscInt gc = 0; gc < (_NcJ); ++gc) { \
26291a768569SStefano Zampini const PetscScalar *G = g3 + (fc * (_NcJ) + gc) * (_dE) * (_dE); \
26301a768569SStefano Zampini for (PetscInt f = 0; f < (_NbI); ++f) { \
26311a768569SStefano Zampini const PetscScalar *tBDI = tmpBasisDerI + (f * (_NcI) + fc) * (_dE); \
26321a768569SStefano Zampini for (PetscInt g = 0; g < (_NbJ); ++g) { \
26331a768569SStefano Zampini PetscScalar s = 0.0; \
26341a768569SStefano Zampini const PetscScalar *tBDJ = tmpBasisDerJ + (g * (_NcJ) + gc) * (_dE); \
26351a768569SStefano Zampini for (PetscInt df = 0; df < (_dE); ++df) { \
26360b36fe0aSPierre Jolivet for (PetscInt dg = 0; dg < (_dE); ++dg) s += tBDI[df] * G[df * (_dE) + dg] * tBDJ[dg]; \
26371a768569SStefano Zampini } \
26381a768569SStefano Zampini elemMat[(offsetI + f) * totDim + (offsetJ + g)] += s; \
26391a768569SStefano Zampini } \
26401a768569SStefano Zampini } \
26411a768569SStefano Zampini } \
2642f102cd15SPierre Jolivet } \
2643f102cd15SPierre Jolivet } while (0)
26441a768569SStefano Zampini
PetscFEUpdateElementMat_Internal(PetscFE feI,PetscFE feJ,PetscInt r,PetscInt q,PetscTabulation TI,PetscScalar tmpBasisI[],PetscScalar tmpBasisDerI[],PetscTabulation TJ,PetscScalar tmpBasisJ[],PetscScalar tmpBasisDerJ[],PetscFEGeom * fegeom,const PetscScalar g0[],const PetscScalar g1[],const PetscScalar g2[],const PetscScalar g3[],PetscInt totDim,PetscInt offsetI,PetscInt offsetJ,PetscScalar elemMat[])26451a768569SStefano Zampini PetscErrorCode PetscFEUpdateElementMat_Internal(PetscFE feI, PetscFE feJ, PetscInt r, PetscInt q, PetscTabulation TI, PetscScalar tmpBasisI[], PetscScalar tmpBasisDerI[], PetscTabulation TJ, PetscScalar tmpBasisJ[], PetscScalar tmpBasisDerJ[], PetscFEGeom *fegeom, const PetscScalar g0[], const PetscScalar g1[], const PetscScalar g2[], const PetscScalar g3[], PetscInt totDim, PetscInt offsetI, PetscInt offsetJ, PetscScalar elemMat[])
2646d71ae5a4SJacob Faibussowitsch {
26472b6f951bSStefano Zampini const PetscInt cdim = TI->cdim;
26482b6f951bSStefano Zampini const PetscInt dE = fegeom->dimEmbed;
2649ef0bb6c7SMatthew G. Knepley const PetscInt NqI = TI->Np;
2650ef0bb6c7SMatthew G. Knepley const PetscInt NbI = TI->Nb;
2651ef0bb6c7SMatthew G. Knepley const PetscInt NcI = TI->Nc;
2652ef0bb6c7SMatthew G. Knepley const PetscReal *basisI = &TI->T[0][(r * NqI + q) * NbI * NcI];
26532b6f951bSStefano Zampini const PetscReal *basisDerI = &TI->T[1][(r * NqI + q) * NbI * NcI * cdim];
2654ef0bb6c7SMatthew G. Knepley const PetscInt NqJ = TJ->Np;
2655ef0bb6c7SMatthew G. Knepley const PetscInt NbJ = TJ->Nb;
2656ef0bb6c7SMatthew G. Knepley const PetscInt NcJ = TJ->Nc;
2657ef0bb6c7SMatthew G. Knepley const PetscReal *basisJ = &TJ->T[0][(r * NqJ + q) * NbJ * NcJ];
26582b6f951bSStefano Zampini const PetscReal *basisDerJ = &TJ->T[1][(r * NqJ + q) * NbJ * NcJ * cdim];
2659a8f1f9e5SMatthew G. Knepley
26601a768569SStefano Zampini for (PetscInt f = 0; f < NbI; ++f) {
26611a768569SStefano Zampini for (PetscInt fc = 0; fc < NcI; ++fc) {
2662a8f1f9e5SMatthew G. Knepley const PetscInt fidx = f * NcI + fc; /* Test function basis index */
2663a8f1f9e5SMatthew G. Knepley
2664a8f1f9e5SMatthew G. Knepley tmpBasisI[fidx] = basisI[fidx];
26651a768569SStefano Zampini for (PetscInt df = 0; df < cdim; ++df) tmpBasisDerI[fidx * dE + df] = basisDerI[fidx * cdim + df];
2666a8f1f9e5SMatthew G. Knepley }
2667a8f1f9e5SMatthew G. Knepley }
26689566063dSJacob Faibussowitsch PetscCall(PetscFEPushforward(feI, fegeom, NbI, tmpBasisI));
26699566063dSJacob Faibussowitsch PetscCall(PetscFEPushforwardGradient(feI, fegeom, NbI, tmpBasisDerI));
26701a768569SStefano Zampini if (feI != feJ) {
26711a768569SStefano Zampini for (PetscInt g = 0; g < NbJ; ++g) {
26721a768569SStefano Zampini for (PetscInt gc = 0; gc < NcJ; ++gc) {
2673a8f1f9e5SMatthew G. Knepley const PetscInt gidx = g * NcJ + gc; /* Trial function basis index */
2674a8f1f9e5SMatthew G. Knepley
2675a8f1f9e5SMatthew G. Knepley tmpBasisJ[gidx] = basisJ[gidx];
26761a768569SStefano Zampini for (PetscInt dg = 0; dg < cdim; ++dg) tmpBasisDerJ[gidx * dE + dg] = basisDerJ[gidx * cdim + dg];
2677a8f1f9e5SMatthew G. Knepley }
2678a8f1f9e5SMatthew G. Knepley }
26799566063dSJacob Faibussowitsch PetscCall(PetscFEPushforward(feJ, fegeom, NbJ, tmpBasisJ));
26809566063dSJacob Faibussowitsch PetscCall(PetscFEPushforwardGradient(feJ, fegeom, NbJ, tmpBasisDerJ));
26811a768569SStefano Zampini } else {
26821a768569SStefano Zampini tmpBasisJ = tmpBasisI;
26831a768569SStefano Zampini tmpBasisDerJ = tmpBasisDerI;
26841a768569SStefano Zampini }
26851a768569SStefano Zampini if (PetscUnlikely(g0)) {
26861a768569SStefano Zampini for (PetscInt f = 0; f < NbI; ++f) {
2687a8f1f9e5SMatthew G. Knepley const PetscInt i = offsetI + f; /* Element matrix row */
2688a8f1f9e5SMatthew G. Knepley
26891a768569SStefano Zampini for (PetscInt fc = 0; fc < NcI; ++fc) {
26901a768569SStefano Zampini const PetscScalar bI = tmpBasisI[f * NcI + fc]; /* Test function basis value */
26911a768569SStefano Zampini
26921a768569SStefano Zampini for (PetscInt g = 0; g < NbJ; ++g) {
26931a768569SStefano Zampini const PetscInt j = offsetJ + g; /* Element matrix column */
26941a768569SStefano Zampini const PetscInt fOff = i * totDim + j;
26951a768569SStefano Zampini
2696ac530a7eSPierre Jolivet for (PetscInt gc = 0; gc < NcJ; ++gc) elemMat[fOff] += bI * g0[fc * NcJ + gc] * tmpBasisJ[g * NcJ + gc];
269727f02ce8SMatthew G. Knepley }
269827f02ce8SMatthew G. Knepley }
269927f02ce8SMatthew G. Knepley }
270027f02ce8SMatthew G. Knepley }
27011a768569SStefano Zampini if (PetscUnlikely(g1)) {
27021a768569SStefano Zampini #if 1
27031a768569SStefano Zampini if (dE == 2) {
27041a768569SStefano Zampini petsc_elemmat_kernel_g1(NbI, NcI, NbJ, NcJ, 2);
27051a768569SStefano Zampini } else if (dE == 3) {
27061a768569SStefano Zampini petsc_elemmat_kernel_g1(NbI, NcI, NbJ, NcJ, 3);
27071a768569SStefano Zampini } else {
27081a768569SStefano Zampini petsc_elemmat_kernel_g1(NbI, NcI, NbJ, NcJ, dE);
27091a768569SStefano Zampini }
27101a768569SStefano Zampini #else
27111a768569SStefano Zampini for (PetscInt f = 0; f < NbI; ++f) {
27121a768569SStefano Zampini const PetscInt i = offsetI + f; /* Element matrix row */
27131a768569SStefano Zampini
27141a768569SStefano Zampini for (PetscInt fc = 0; fc < NcI; ++fc) {
27151a768569SStefano Zampini const PetscScalar bI = tmpBasisI[f * NcI + fc]; /* Test function basis value */
27161a768569SStefano Zampini
27171a768569SStefano Zampini for (PetscInt g = 0; g < NbJ; ++g) {
27181a768569SStefano Zampini const PetscInt j = offsetJ + g; /* Element matrix column */
27191a768569SStefano Zampini const PetscInt fOff = i * totDim + j;
27201a768569SStefano Zampini
27211a768569SStefano Zampini for (PetscInt gc = 0; gc < NcJ; ++gc) {
27221a768569SStefano Zampini const PetscInt gidx = g * NcJ + gc; /* Trial function basis index */
27231a768569SStefano Zampini
2724ac530a7eSPierre Jolivet for (PetscInt df = 0; df < dE; ++df) elemMat[fOff] += bI * g1[(fc * NcJ + gc) * dE + df] * tmpBasisDerJ[gidx * dE + df];
27251a768569SStefano Zampini }
27261a768569SStefano Zampini }
27271a768569SStefano Zampini }
27281a768569SStefano Zampini }
27291a768569SStefano Zampini #endif
27301a768569SStefano Zampini }
27311a768569SStefano Zampini if (PetscUnlikely(g2)) {
27321a768569SStefano Zampini #if 1
27331a768569SStefano Zampini if (dE == 2) {
27341a768569SStefano Zampini petsc_elemmat_kernel_g2(NbI, NcI, NbJ, NcJ, 2);
27351a768569SStefano Zampini } else if (dE == 3) {
27361a768569SStefano Zampini petsc_elemmat_kernel_g2(NbI, NcI, NbJ, NcJ, 3);
27371a768569SStefano Zampini } else {
27381a768569SStefano Zampini petsc_elemmat_kernel_g2(NbI, NcI, NbJ, NcJ, dE);
27391a768569SStefano Zampini }
27401a768569SStefano Zampini #else
27411a768569SStefano Zampini for (PetscInt g = 0; g < NbJ; ++g) {
27421a768569SStefano Zampini const PetscInt j = offsetJ + g; /* Element matrix column */
27431a768569SStefano Zampini
27441a768569SStefano Zampini for (PetscInt gc = 0; gc < NcJ; ++gc) {
27451a768569SStefano Zampini const PetscScalar bJ = tmpBasisJ[g * NcJ + gc]; /* Trial function basis value */
27461a768569SStefano Zampini
27471a768569SStefano Zampini for (PetscInt f = 0; f < NbI; ++f) {
27481a768569SStefano Zampini const PetscInt i = offsetI + f; /* Element matrix row */
27491a768569SStefano Zampini const PetscInt fOff = i * totDim + j;
27501a768569SStefano Zampini
27511a768569SStefano Zampini for (PetscInt fc = 0; fc < NcI; ++fc) {
27521a768569SStefano Zampini const PetscInt fidx = f * NcI + fc; /* Test function basis index */
27531a768569SStefano Zampini
2754ac530a7eSPierre Jolivet for (PetscInt df = 0; df < dE; ++df) elemMat[fOff] += tmpBasisDerI[fidx * dE + df] * g2[(fc * NcJ + gc) * dE + df] * bJ;
27551a768569SStefano Zampini }
27561a768569SStefano Zampini }
27571a768569SStefano Zampini }
27581a768569SStefano Zampini }
27591a768569SStefano Zampini #endif
27601a768569SStefano Zampini }
27611a768569SStefano Zampini if (PetscUnlikely(g3)) {
27621a768569SStefano Zampini #if 1
27631a768569SStefano Zampini if (dE == 2) {
27641a768569SStefano Zampini petsc_elemmat_kernel_g3(NbI, NcI, NbJ, NcJ, 2);
27651a768569SStefano Zampini } else if (dE == 3) {
27661a768569SStefano Zampini petsc_elemmat_kernel_g3(NbI, NcI, NbJ, NcJ, 3);
27671a768569SStefano Zampini } else {
27681a768569SStefano Zampini petsc_elemmat_kernel_g3(NbI, NcI, NbJ, NcJ, dE);
27691a768569SStefano Zampini }
27701a768569SStefano Zampini #else
27711a768569SStefano Zampini for (PetscInt f = 0; f < NbI; ++f) {
27721a768569SStefano Zampini const PetscInt i = offsetI + f; /* Element matrix row */
27731a768569SStefano Zampini
27741a768569SStefano Zampini for (PetscInt fc = 0; fc < NcI; ++fc) {
27751a768569SStefano Zampini const PetscInt fidx = f * NcI + fc; /* Test function basis index */
27761a768569SStefano Zampini
27771a768569SStefano Zampini for (PetscInt g = 0; g < NbJ; ++g) {
27781a768569SStefano Zampini const PetscInt j = offsetJ + g; /* Element matrix column */
27791a768569SStefano Zampini const PetscInt fOff = i * totDim + j;
27801a768569SStefano Zampini
27811a768569SStefano Zampini for (PetscInt gc = 0; gc < NcJ; ++gc) {
27821a768569SStefano Zampini const PetscInt gidx = g * NcJ + gc; /* Trial function basis index */
27831a768569SStefano Zampini
27841a768569SStefano Zampini for (PetscInt df = 0; df < dE; ++df) {
2785ac530a7eSPierre Jolivet for (PetscInt dg = 0; dg < dE; ++dg) elemMat[fOff] += tmpBasisDerI[fidx * dE + df] * g3[((fc * NcJ + gc) * dE + df) * dE + dg] * tmpBasisDerJ[gidx * dE + dg];
27861a768569SStefano Zampini }
27871a768569SStefano Zampini }
27881a768569SStefano Zampini }
27891a768569SStefano Zampini }
27901a768569SStefano Zampini }
27911a768569SStefano Zampini #endif
279227f02ce8SMatthew G. Knepley }
27933ba16761SJacob Faibussowitsch return PETSC_SUCCESS;
279427f02ce8SMatthew G. Knepley }
279527f02ce8SMatthew G. Knepley
27961a768569SStefano Zampini #undef petsc_elemmat_kernel_g1
27971a768569SStefano Zampini #undef petsc_elemmat_kernel_g2
27981a768569SStefano Zampini #undef petsc_elemmat_kernel_g3
27991a768569SStefano Zampini
PetscFEUpdateElementMat_Hybrid_Internal(PetscFE feI,PetscBool isHybridI,PetscFE feJ,PetscBool isHybridJ,PetscInt r,PetscInt s,PetscInt t,PetscInt q,PetscTabulation TI,PetscScalar tmpBasisI[],PetscScalar tmpBasisDerI[],PetscTabulation TJ,PetscScalar tmpBasisJ[],PetscScalar tmpBasisDerJ[],PetscFEGeom * fegeom,const PetscScalar g0[],const PetscScalar g1[],const PetscScalar g2[],const PetscScalar g3[],PetscInt eOffset,PetscInt totDim,PetscInt offsetI,PetscInt offsetJ,PetscScalar elemMat[])28000abb75b6SMatthew G. Knepley PetscErrorCode PetscFEUpdateElementMat_Hybrid_Internal(PetscFE feI, PetscBool isHybridI, PetscFE feJ, PetscBool isHybridJ, PetscInt r, PetscInt s, PetscInt t, PetscInt q, PetscTabulation TI, PetscScalar tmpBasisI[], PetscScalar tmpBasisDerI[], PetscTabulation TJ, PetscScalar tmpBasisJ[], PetscScalar tmpBasisDerJ[], PetscFEGeom *fegeom, const PetscScalar g0[], const PetscScalar g1[], const PetscScalar g2[], const PetscScalar g3[], PetscInt eOffset, PetscInt totDim, PetscInt offsetI, PetscInt offsetJ, PetscScalar elemMat[])
2801d71ae5a4SJacob Faibussowitsch {
2802665f567fSMatthew G. Knepley const PetscInt dE = TI->cdim;
2803665f567fSMatthew G. Knepley const PetscInt NqI = TI->Np;
2804665f567fSMatthew G. Knepley const PetscInt NbI = TI->Nb;
2805665f567fSMatthew G. Knepley const PetscInt NcI = TI->Nc;
2806665f567fSMatthew G. Knepley const PetscReal *basisI = &TI->T[0][(r * NqI + q) * NbI * NcI];
2807665f567fSMatthew G. Knepley const PetscReal *basisDerI = &TI->T[1][(r * NqI + q) * NbI * NcI * dE];
2808665f567fSMatthew G. Knepley const PetscInt NqJ = TJ->Np;
2809665f567fSMatthew G. Knepley const PetscInt NbJ = TJ->Nb;
2810665f567fSMatthew G. Knepley const PetscInt NcJ = TJ->Nc;
2811665f567fSMatthew G. Knepley const PetscReal *basisJ = &TJ->T[0][(r * NqJ + q) * NbJ * NcJ];
2812665f567fSMatthew G. Knepley const PetscReal *basisDerJ = &TJ->T[1][(r * NqJ + q) * NbJ * NcJ * dE];
28135fedec97SMatthew G. Knepley const PetscInt so = isHybridI ? 0 : s;
28140abb75b6SMatthew G. Knepley const PetscInt to = isHybridJ ? 0 : t;
28155fedec97SMatthew G. Knepley PetscInt f, fc, g, gc, df, dg;
281627f02ce8SMatthew G. Knepley
281727f02ce8SMatthew G. Knepley for (f = 0; f < NbI; ++f) {
281827f02ce8SMatthew G. Knepley for (fc = 0; fc < NcI; ++fc) {
281927f02ce8SMatthew G. Knepley const PetscInt fidx = f * NcI + fc; /* Test function basis index */
282027f02ce8SMatthew G. Knepley
282127f02ce8SMatthew G. Knepley tmpBasisI[fidx] = basisI[fidx];
2822665f567fSMatthew G. Knepley for (df = 0; df < dE; ++df) tmpBasisDerI[fidx * dE + df] = basisDerI[fidx * dE + df];
282327f02ce8SMatthew G. Knepley }
282427f02ce8SMatthew G. Knepley }
28259566063dSJacob Faibussowitsch PetscCall(PetscFEPushforward(feI, fegeom, NbI, tmpBasisI));
28269566063dSJacob Faibussowitsch PetscCall(PetscFEPushforwardGradient(feI, fegeom, NbI, tmpBasisDerI));
282727f02ce8SMatthew G. Knepley for (g = 0; g < NbJ; ++g) {
282827f02ce8SMatthew G. Knepley for (gc = 0; gc < NcJ; ++gc) {
282927f02ce8SMatthew G. Knepley const PetscInt gidx = g * NcJ + gc; /* Trial function basis index */
283027f02ce8SMatthew G. Knepley
283127f02ce8SMatthew G. Knepley tmpBasisJ[gidx] = basisJ[gidx];
2832665f567fSMatthew G. Knepley for (dg = 0; dg < dE; ++dg) tmpBasisDerJ[gidx * dE + dg] = basisDerJ[gidx * dE + dg];
283327f02ce8SMatthew G. Knepley }
283427f02ce8SMatthew G. Knepley }
28359566063dSJacob Faibussowitsch PetscCall(PetscFEPushforward(feJ, fegeom, NbJ, tmpBasisJ));
28362b6f951bSStefano Zampini // TODO This is currently broken since we do not pull the geometry down to the lower dimension
28372b6f951bSStefano Zampini // PetscCall(PetscFEPushforwardGradient(feJ, fegeom, NbJ, tmpBasisDerJ));
283827f02ce8SMatthew G. Knepley for (f = 0; f < NbI; ++f) {
283927f02ce8SMatthew G. Knepley for (fc = 0; fc < NcI; ++fc) {
284027f02ce8SMatthew G. Knepley const PetscInt fidx = f * NcI + fc; /* Test function basis index */
28415fedec97SMatthew G. Knepley const PetscInt i = offsetI + NbI * so + f; /* Element matrix row */
284227f02ce8SMatthew G. Knepley for (g = 0; g < NbJ; ++g) {
284327f02ce8SMatthew G. Knepley for (gc = 0; gc < NcJ; ++gc) {
284427f02ce8SMatthew G. Knepley const PetscInt gidx = g * NcJ + gc; /* Trial function basis index */
28455fedec97SMatthew G. Knepley const PetscInt j = offsetJ + NbJ * to + g; /* Element matrix column */
284627f02ce8SMatthew G. Knepley const PetscInt fOff = eOffset + i * totDim + j;
284727f02ce8SMatthew G. Knepley
28485fedec97SMatthew G. Knepley elemMat[fOff] += tmpBasisI[fidx] * g0[fc * NcJ + gc] * tmpBasisJ[gidx];
284927f02ce8SMatthew G. Knepley for (df = 0; df < dE; ++df) {
28505fedec97SMatthew G. Knepley elemMat[fOff] += tmpBasisI[fidx] * g1[(fc * NcJ + gc) * dE + df] * tmpBasisDerJ[gidx * dE + df];
28515fedec97SMatthew G. Knepley elemMat[fOff] += tmpBasisDerI[fidx * dE + df] * g2[(fc * NcJ + gc) * dE + df] * tmpBasisJ[gidx];
2852ad540459SPierre Jolivet for (dg = 0; dg < dE; ++dg) elemMat[fOff] += tmpBasisDerI[fidx * dE + df] * g3[((fc * NcJ + gc) * dE + df) * dE + dg] * tmpBasisDerJ[gidx * dE + dg];
2853a8f1f9e5SMatthew G. Knepley }
2854a8f1f9e5SMatthew G. Knepley }
2855a8f1f9e5SMatthew G. Knepley }
2856a8f1f9e5SMatthew G. Knepley }
2857a8f1f9e5SMatthew G. Knepley }
28583ba16761SJacob Faibussowitsch return PETSC_SUCCESS;
2859a8f1f9e5SMatthew G. Knepley }
2860c9ba7969SMatthew G. Knepley
PetscFECreateCellGeometry(PetscFE fe,PetscQuadrature quad,PetscFEGeom * cgeom)2861d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFECreateCellGeometry(PetscFE fe, PetscQuadrature quad, PetscFEGeom *cgeom)
2862d71ae5a4SJacob Faibussowitsch {
2863c9ba7969SMatthew G. Knepley PetscDualSpace dsp;
2864c9ba7969SMatthew G. Knepley DM dm;
2865c9ba7969SMatthew G. Knepley PetscQuadrature quadDef;
2866c9ba7969SMatthew G. Knepley PetscInt dim, cdim, Nq;
2867c9ba7969SMatthew G. Knepley
2868c9ba7969SMatthew G. Knepley PetscFunctionBegin;
28699566063dSJacob Faibussowitsch PetscCall(PetscFEGetDualSpace(fe, &dsp));
28709566063dSJacob Faibussowitsch PetscCall(PetscDualSpaceGetDM(dsp, &dm));
28719566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &dim));
28729566063dSJacob Faibussowitsch PetscCall(DMGetCoordinateDim(dm, &cdim));
28739566063dSJacob Faibussowitsch PetscCall(PetscFEGetQuadrature(fe, &quadDef));
2874c9ba7969SMatthew G. Knepley quad = quad ? quad : quadDef;
28759566063dSJacob Faibussowitsch PetscCall(PetscQuadratureGetData(quad, NULL, NULL, &Nq, NULL, NULL));
28769566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(Nq * cdim, &cgeom->v));
28779566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(Nq * cdim * cdim, &cgeom->J));
28789566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(Nq * cdim * cdim, &cgeom->invJ));
28799566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(Nq, &cgeom->detJ));
2880c9ba7969SMatthew G. Knepley cgeom->dim = dim;
2881c9ba7969SMatthew G. Knepley cgeom->dimEmbed = cdim;
2882c9ba7969SMatthew G. Knepley cgeom->numCells = 1;
2883c9ba7969SMatthew G. Knepley cgeom->numPoints = Nq;
28849566063dSJacob Faibussowitsch PetscCall(DMPlexComputeCellGeometryFEM(dm, 0, quad, cgeom->v, cgeom->J, cgeom->invJ, cgeom->detJ));
28853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
2886c9ba7969SMatthew G. Knepley }
2887c9ba7969SMatthew G. Knepley
PetscFEDestroyCellGeometry(PetscFE fe,PetscFEGeom * cgeom)2888d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFEDestroyCellGeometry(PetscFE fe, PetscFEGeom *cgeom)
2889d71ae5a4SJacob Faibussowitsch {
2890c9ba7969SMatthew G. Knepley PetscFunctionBegin;
28919566063dSJacob Faibussowitsch PetscCall(PetscFree(cgeom->v));
28929566063dSJacob Faibussowitsch PetscCall(PetscFree(cgeom->J));
28939566063dSJacob Faibussowitsch PetscCall(PetscFree(cgeom->invJ));
28949566063dSJacob Faibussowitsch PetscCall(PetscFree(cgeom->detJ));
28953ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
2896c9ba7969SMatthew G. Knepley }
28971a768569SStefano Zampini
28981a768569SStefano Zampini #if 0
28991a768569SStefano Zampini PetscErrorCode PetscFEUpdateElementMat_Internal_SparseIndices(PetscTabulation TI, PetscTabulation TJ, PetscInt dimEmbed, const PetscInt g0[], const PetscInt g1[], const PetscInt g2[], const PetscInt g3[], PetscInt totDim, PetscInt offsetI, PetscInt offsetJ, PetscInt *n_g0, PetscInt **g0_idxs_out, PetscInt *n_g1, PetscInt **g1_idxs_out, PetscInt *n_g2, PetscInt **g2_idxs_out, PetscInt *n_g3, PetscInt **g3_idxs_out)
29001a768569SStefano Zampini {
29011a768569SStefano Zampini const PetscInt dE = dimEmbed;
29021a768569SStefano Zampini const PetscInt NbI = TI->Nb;
29031a768569SStefano Zampini const PetscInt NcI = TI->Nc;
29041a768569SStefano Zampini const PetscInt NbJ = TJ->Nb;
29051a768569SStefano Zampini const PetscInt NcJ = TJ->Nc;
29061a768569SStefano Zampini PetscBool has_g0 = g0 ? PETSC_TRUE : PETSC_FALSE;
29071a768569SStefano Zampini PetscBool has_g1 = g1 ? PETSC_TRUE : PETSC_FALSE;
29081a768569SStefano Zampini PetscBool has_g2 = g2 ? PETSC_TRUE : PETSC_FALSE;
29091a768569SStefano Zampini PetscBool has_g3 = g3 ? PETSC_TRUE : PETSC_FALSE;
29101a768569SStefano Zampini PetscInt *g0_idxs = NULL, *g1_idxs = NULL, *g2_idxs = NULL, *g3_idxs = NULL;
29111a768569SStefano Zampini PetscInt g0_i, g1_i, g2_i, g3_i;
29121a768569SStefano Zampini
29131a768569SStefano Zampini PetscFunctionBegin;
29141a768569SStefano Zampini g0_i = g1_i = g2_i = g3_i = 0;
29151a768569SStefano Zampini if (has_g0)
29161a768569SStefano Zampini for (PetscInt i = 0; i < NcI * NcJ; i++)
29171a768569SStefano Zampini if (g0[i]) g0_i += NbI * NbJ;
29181a768569SStefano Zampini if (has_g1)
29191a768569SStefano Zampini for (PetscInt i = 0; i < NcI * NcJ * dE; i++)
29201a768569SStefano Zampini if (g1[i]) g1_i += NbI * NbJ;
29211a768569SStefano Zampini if (has_g2)
29221a768569SStefano Zampini for (PetscInt i = 0; i < NcI * NcJ * dE; i++)
29231a768569SStefano Zampini if (g2[i]) g2_i += NbI * NbJ;
29241a768569SStefano Zampini if (has_g3)
29251a768569SStefano Zampini for (PetscInt i = 0; i < NcI * NcJ * dE * dE; i++)
29261a768569SStefano Zampini if (g3[i]) g3_i += NbI * NbJ;
29271a768569SStefano Zampini if (g0_i == NbI * NbJ * NcI * NcJ) g0_i = 0;
29281a768569SStefano Zampini if (g1_i == NbI * NbJ * NcI * NcJ * dE) g1_i = 0;
29291a768569SStefano Zampini if (g2_i == NbI * NbJ * NcI * NcJ * dE) g2_i = 0;
29301a768569SStefano Zampini if (g3_i == NbI * NbJ * NcI * NcJ * dE * dE) g3_i = 0;
29311a768569SStefano Zampini has_g0 = g0_i ? PETSC_TRUE : PETSC_FALSE;
29321a768569SStefano Zampini has_g1 = g1_i ? PETSC_TRUE : PETSC_FALSE;
29331a768569SStefano Zampini has_g2 = g2_i ? PETSC_TRUE : PETSC_FALSE;
29341a768569SStefano Zampini has_g3 = g3_i ? PETSC_TRUE : PETSC_FALSE;
29351a768569SStefano Zampini if (has_g0) PetscCall(PetscMalloc1(4 * g0_i, &g0_idxs));
29361a768569SStefano Zampini if (has_g1) PetscCall(PetscMalloc1(4 * g1_i, &g1_idxs));
29371a768569SStefano Zampini if (has_g2) PetscCall(PetscMalloc1(4 * g2_i, &g2_idxs));
29381a768569SStefano Zampini if (has_g3) PetscCall(PetscMalloc1(4 * g3_i, &g3_idxs));
29391a768569SStefano Zampini g0_i = g1_i = g2_i = g3_i = 0;
29401a768569SStefano Zampini
29411a768569SStefano Zampini for (PetscInt f = 0; f < NbI; ++f) {
29421a768569SStefano Zampini const PetscInt i = offsetI + f; /* Element matrix row */
29431a768569SStefano Zampini for (PetscInt fc = 0; fc < NcI; ++fc) {
29441a768569SStefano Zampini const PetscInt fidx = f * NcI + fc; /* Test function basis index */
29451a768569SStefano Zampini
29461a768569SStefano Zampini for (PetscInt g = 0; g < NbJ; ++g) {
29471a768569SStefano Zampini const PetscInt j = offsetJ + g; /* Element matrix column */
29481a768569SStefano Zampini const PetscInt fOff = i * totDim + j;
29491a768569SStefano Zampini for (PetscInt gc = 0; gc < NcJ; ++gc) {
29501a768569SStefano Zampini const PetscInt gidx = g * NcJ + gc; /* Trial function basis index */
29511a768569SStefano Zampini
29521a768569SStefano Zampini if (has_g0) {
29531a768569SStefano Zampini if (g0[fc * NcJ + gc]) {
29541a768569SStefano Zampini g0_idxs[4 * g0_i + 0] = fidx;
29551a768569SStefano Zampini g0_idxs[4 * g0_i + 1] = fc * NcJ + gc;
29561a768569SStefano Zampini g0_idxs[4 * g0_i + 2] = gidx;
29571a768569SStefano Zampini g0_idxs[4 * g0_i + 3] = fOff;
29581a768569SStefano Zampini g0_i++;
29591a768569SStefano Zampini }
29601a768569SStefano Zampini }
29611a768569SStefano Zampini
29621a768569SStefano Zampini for (PetscInt df = 0; df < dE; ++df) {
29631a768569SStefano Zampini if (has_g1) {
29641a768569SStefano Zampini if (g1[(fc * NcJ + gc) * dE + df]) {
29651a768569SStefano Zampini g1_idxs[4 * g1_i + 0] = fidx;
29661a768569SStefano Zampini g1_idxs[4 * g1_i + 1] = (fc * NcJ + gc) * dE + df;
29671a768569SStefano Zampini g1_idxs[4 * g1_i + 2] = gidx * dE + df;
29681a768569SStefano Zampini g1_idxs[4 * g1_i + 3] = fOff;
29691a768569SStefano Zampini g1_i++;
29701a768569SStefano Zampini }
29711a768569SStefano Zampini }
29721a768569SStefano Zampini if (has_g2) {
29731a768569SStefano Zampini if (g2[(fc * NcJ + gc) * dE + df]) {
29741a768569SStefano Zampini g2_idxs[4 * g2_i + 0] = fidx * dE + df;
29751a768569SStefano Zampini g2_idxs[4 * g2_i + 1] = (fc * NcJ + gc) * dE + df;
29761a768569SStefano Zampini g2_idxs[4 * g2_i + 2] = gidx;
29771a768569SStefano Zampini g2_idxs[4 * g2_i + 3] = fOff;
29781a768569SStefano Zampini g2_i++;
29791a768569SStefano Zampini }
29801a768569SStefano Zampini }
29811a768569SStefano Zampini if (has_g3) {
29821a768569SStefano Zampini for (PetscInt dg = 0; dg < dE; ++dg) {
29831a768569SStefano Zampini if (g3[((fc * NcJ + gc) * dE + df) * dE + dg]) {
29841a768569SStefano Zampini g3_idxs[4 * g3_i + 0] = fidx * dE + df;
29851a768569SStefano Zampini g3_idxs[4 * g3_i + 1] = ((fc * NcJ + gc) * dE + df) * dE + dg;
29861a768569SStefano Zampini g3_idxs[4 * g3_i + 2] = gidx * dE + dg;
29871a768569SStefano Zampini g3_idxs[4 * g3_i + 3] = fOff;
29881a768569SStefano Zampini g3_i++;
29891a768569SStefano Zampini }
29901a768569SStefano Zampini }
29911a768569SStefano Zampini }
29921a768569SStefano Zampini }
29931a768569SStefano Zampini }
29941a768569SStefano Zampini }
29951a768569SStefano Zampini }
29961a768569SStefano Zampini }
29971a768569SStefano Zampini *n_g0 = g0_i;
29981a768569SStefano Zampini *n_g1 = g1_i;
29991a768569SStefano Zampini *n_g2 = g2_i;
30001a768569SStefano Zampini *n_g3 = g3_i;
30011a768569SStefano Zampini
30021a768569SStefano Zampini *g0_idxs_out = g0_idxs;
30031a768569SStefano Zampini *g1_idxs_out = g1_idxs;
30041a768569SStefano Zampini *g2_idxs_out = g2_idxs;
30051a768569SStefano Zampini *g3_idxs_out = g3_idxs;
30061a768569SStefano Zampini PetscFunctionReturn(PETSC_SUCCESS);
30071a768569SStefano Zampini }
30081a768569SStefano Zampini
30091a768569SStefano Zampini //example HOW TO USE
30101a768569SStefano Zampini for (PetscInt i = 0; i < g0_sparse_n; i++) {
30111a768569SStefano Zampini PetscInt bM = g0_sparse_idxs[4 * i + 0];
30121a768569SStefano Zampini PetscInt bN = g0_sparse_idxs[4 * i + 1];
30131a768569SStefano Zampini PetscInt bK = g0_sparse_idxs[4 * i + 2];
30141a768569SStefano Zampini PetscInt bO = g0_sparse_idxs[4 * i + 3];
30151a768569SStefano Zampini elemMat[bO] += tmpBasisI[bM] * g0[bN] * tmpBasisJ[bK];
30161a768569SStefano Zampini }
30171a768569SStefano Zampini #endif
3018