Actual source code: space.c

  1: #include <petsc/private/petscfeimpl.h>
  2: #include <petscdmshell.h>

  4: PetscClassId PETSCSPACE_CLASSID = 0;

  6: PetscFunctionList PetscSpaceList              = NULL;
  7: PetscBool         PetscSpaceRegisterAllCalled = PETSC_FALSE;

  9: /*@C
 10:   PetscSpaceRegister - Adds a new `PetscSpace` implementation

 12:   Not Collective, No Fortran Support

 14:   Input Parameters:
 15: + sname    - The name of a new user-defined creation routine
 16: - function - The creation routine for the implementation type

 18:   Example Usage:
 19: .vb
 20:     PetscSpaceRegister("my_space", MyPetscSpaceCreate);
 21: .ve

 23:   Then, your PetscSpace type can be chosen with the procedural interface via
 24: .vb
 25:     PetscSpaceCreate(MPI_Comm, PetscSpace *);
 26:     PetscSpaceSetType(PetscSpace, "my_space");
 27: .ve
 28:   or at runtime via the option
 29: .vb
 30:     -petscspace_type my_space
 31: .ve

 33:   Level: advanced

 35:   Note:
 36:   `PetscSpaceRegister()` may be called multiple times to add several user-defined types of `PetscSpace`.  The creation function is called
 37:   when the type is set to 'name'.

 39: .seealso: `PetscSpace`, `PetscSpaceRegisterAll()`, `PetscSpaceRegisterDestroy()`
 40: @*/
 41: PetscErrorCode PetscSpaceRegister(const char sname[], PetscErrorCode (*function)(PetscSpace))
 42: {
 43:   PetscFunctionBegin;
 44:   PetscCall(PetscFunctionListAdd(&PetscSpaceList, sname, function));
 45:   PetscFunctionReturn(PETSC_SUCCESS);
 46: }

 48: /*@
 49:   PetscSpaceSetType - Builds a particular `PetscSpace`

 51:   Collective

 53:   Input Parameters:
 54: + sp   - The `PetscSpace` object
 55: - name - The kind of space

 57:   Options Database Key:
 58: . -petscspace_type type - Sets the `PetscSpace` type; use -help for a list of available types

 60:   Level: intermediate

 62: .seealso: `PetscSpace`, `PetscSpaceType`, `PetscSpaceGetType()`, `PetscSpaceCreate()`
 63: @*/
 64: PetscErrorCode PetscSpaceSetType(PetscSpace sp, PetscSpaceType name)
 65: {
 66:   PetscErrorCode (*r)(PetscSpace);
 67:   PetscBool match;

 69:   PetscFunctionBegin;
 71:   PetscCall(PetscObjectTypeCompare((PetscObject)sp, name, &match));
 72:   if (match) PetscFunctionReturn(PETSC_SUCCESS);

 74:   PetscCall(PetscSpaceRegisterAll());
 75:   PetscCall(PetscFunctionListFind(PetscSpaceList, name, &r));
 76:   PetscCheck(r, PetscObjectComm((PetscObject)sp), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown PetscSpace type: %s", name);

 78:   PetscTryTypeMethod(sp, destroy);
 79:   sp->ops->destroy = NULL;

 81:   sp->dim = PETSC_DETERMINE;
 82:   PetscCall((*r)(sp));
 83:   PetscCall(PetscObjectChangeTypeName((PetscObject)sp, name));
 84:   PetscFunctionReturn(PETSC_SUCCESS);
 85: }

 87: /*@
 88:   PetscSpaceGetType - Gets the `PetscSpaceType` (as a string) from the object.

 90:   Not Collective

 92:   Input Parameter:
 93: . sp - The `PetscSpace`

 95:   Output Parameter:
 96: . name - The `PetscSpace` type name

 98:   Level: intermediate

100: .seealso: `PetscSpaceType`, `PetscSpace`, `PetscSpaceSetType()`, `PetscSpaceCreate()`
101: @*/
102: PetscErrorCode PetscSpaceGetType(PetscSpace sp, PetscSpaceType *name)
103: {
104:   PetscFunctionBegin;
106:   PetscAssertPointer(name, 2);
107:   if (!PetscSpaceRegisterAllCalled) PetscCall(PetscSpaceRegisterAll());
108:   *name = ((PetscObject)sp)->type_name;
109:   PetscFunctionReturn(PETSC_SUCCESS);
110: }

112: /*@
113:   PetscSpaceViewFromOptions - View a `PetscSpace` based on values in the options database

115:   Collective

117:   Input Parameters:
118: + A    - the `PetscSpace` object
119: . obj  - Optional object that provides the options name prefix
120: - name - command line option name

122:   Options Database Key:
123: . -name [viewertype][:...] - option name and values. See `PetscObjectViewFromOptions()` for the possible arguments

125:   Level: intermediate

127: .seealso: `PetscSpace`, `PetscSpaceView()`, `PetscObjectViewFromOptions()`, `PetscSpaceCreate()`
128: @*/
129: PetscErrorCode PetscSpaceViewFromOptions(PetscSpace A, PetscObject obj, const char name[])
130: {
131:   PetscFunctionBegin;
133:   PetscCall(PetscObjectViewFromOptions((PetscObject)A, obj, name));
134:   PetscFunctionReturn(PETSC_SUCCESS);
135: }

137: /*@
138:   PetscSpaceView - Views a `PetscSpace`

140:   Collective

142:   Input Parameters:
143: + sp - the `PetscSpace` object to view
144: - v  - the viewer

146:   Level: beginner

148: .seealso: `PetscSpace`, `PetscViewer`, `PetscSpaceViewFromOptions()`, `PetscSpaceDestroy()`
149: @*/
150: PetscErrorCode PetscSpaceView(PetscSpace sp, PetscViewer v)
151: {
152:   PetscInt  pdim;
153:   PetscBool isascii;

155:   PetscFunctionBegin;
158:   if (!v) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)sp), &v));
159:   PetscCall(PetscSpaceGetDimension(sp, &pdim));
160:   PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)sp, v));
161:   PetscCall(PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERASCII, &isascii));
162:   PetscCall(PetscViewerASCIIPushTab(v));
163:   if (isascii) PetscCall(PetscViewerASCIIPrintf(v, "Space in %" PetscInt_FMT " variables with %" PetscInt_FMT " components, size %" PetscInt_FMT "\n", sp->Nv, sp->Nc, pdim));
164:   PetscTryTypeMethod(sp, view, v);
165:   PetscCall(PetscViewerASCIIPopTab(v));
166:   PetscFunctionReturn(PETSC_SUCCESS);
167: }

169: /*@
170:   PetscSpaceSetFromOptions - sets parameters in a `PetscSpace` from the options database

172:   Collective

174:   Input Parameter:
175: . sp - the `PetscSpace` object to set options for

177:   Options Database Keys:
178: + -petscspace_degree deg   - the degree of the space
179: . -petscspace_variables n  - the number of different variables, e.g. x and y
180: - -petscspace_components c - the number of components, say d for a vector field

182:   Level: intermediate

184: .seealso: `PetscSpace`, `PetscSpaceView()`
185: @*/
186: PetscErrorCode PetscSpaceSetFromOptions(PetscSpace sp)
187: {
188:   const char *defaultType;
189:   char        name[256];
190:   PetscBool   flg;

192:   PetscFunctionBegin;
194:   if (!((PetscObject)sp)->type_name) defaultType = PETSCSPACEPOLYNOMIAL;
195:   else defaultType = ((PetscObject)sp)->type_name;
196:   if (!PetscSpaceRegisterAllCalled) PetscCall(PetscSpaceRegisterAll());

198:   PetscObjectOptionsBegin((PetscObject)sp);
199:   PetscCall(PetscOptionsFList("-petscspace_type", "Linear space", "PetscSpaceSetType", PetscSpaceList, defaultType, name, 256, &flg));
200:   if (flg) PetscCall(PetscSpaceSetType(sp, name));
201:   else if (!((PetscObject)sp)->type_name) PetscCall(PetscSpaceSetType(sp, defaultType));
202:   {
203:     PetscCall(PetscOptionsDeprecated("-petscspace_order", "-petscspace_degree", "3.11", NULL));
204:   }
205:   PetscCall(PetscOptionsBoundedInt("-petscspace_degree", "The (maximally included) polynomial degree", "PetscSpaceSetDegree", sp->degree, &sp->degree, NULL, 0));
206:   PetscCall(PetscOptionsBoundedInt("-petscspace_variables", "The number of different variables, e.g. x and y", "PetscSpaceSetNumVariables", sp->Nv, &sp->Nv, NULL, 0));
207:   PetscCall(PetscOptionsBoundedInt("-petscspace_components", "The number of components", "PetscSpaceSetNumComponents", sp->Nc, &sp->Nc, NULL, -1));
208:   PetscTryTypeMethod(sp, setfromoptions, PetscOptionsObject);
209:   /* process any options handlers added with PetscObjectAddOptionsHandler() */
210:   PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)sp, PetscOptionsObject));
211:   PetscOptionsEnd();
212:   PetscCall(PetscSpaceViewFromOptions(sp, NULL, "-petscspace_view"));
213:   PetscFunctionReturn(PETSC_SUCCESS);
214: }

216: /*@
217:   PetscSpaceSetUp - Construct data structures for the `PetscSpace`

219:   Collective

221:   Input Parameter:
222: . sp - the `PetscSpace` object to setup

224:   Level: intermediate

226: .seealso: `PetscSpace`, `PetscSpaceView()`, `PetscSpaceDestroy()`
227: @*/
228: PetscErrorCode PetscSpaceSetUp(PetscSpace sp)
229: {
230:   PetscFunctionBegin;
232:   PetscTryTypeMethod(sp, setup);
233:   PetscFunctionReturn(PETSC_SUCCESS);
234: }

236: /*@
237:   PetscSpaceDestroy - Destroys a `PetscSpace` object

239:   Collective

241:   Input Parameter:
242: . sp - the `PetscSpace` object to destroy

244:   Level: beginner

246: .seealso: `PetscSpace`, `PetscSpaceCreate()`
247: @*/
248: PetscErrorCode PetscSpaceDestroy(PetscSpace *sp)
249: {
250:   PetscFunctionBegin;
251:   if (!*sp) PetscFunctionReturn(PETSC_SUCCESS);

254:   if (--((PetscObject)*sp)->refct > 0) {
255:     *sp = NULL;
256:     PetscFunctionReturn(PETSC_SUCCESS);
257:   }
258:   ((PetscObject)*sp)->refct = 0;
259:   PetscCall(DMDestroy(&(*sp)->dm));

261:   PetscUseTypeMethod(*sp, destroy);
262:   PetscCall(PetscHeaderDestroy(sp));
263:   PetscFunctionReturn(PETSC_SUCCESS);
264: }

266: /*@
267:   PetscSpaceCreate - Creates an empty `PetscSpace` object. The type can then be set with `PetscSpaceSetType()`.

269:   Collective

271:   Input Parameter:
272: . comm - The communicator for the `PetscSpace` object

274:   Output Parameter:
275: . sp - The `PetscSpace` object

277:   Level: beginner

279: .seealso: `PetscSpace`, `PetscSpaceSetType()`, `PETSCSPACEPOLYNOMIAL`
280: @*/
281: PetscErrorCode PetscSpaceCreate(MPI_Comm comm, PetscSpace *sp)
282: {
283:   PetscSpace s;

285:   PetscFunctionBegin;
286:   PetscAssertPointer(sp, 2);
287:   PetscCall(PetscCitationsRegister(FECitation, &FEcite));
288:   PetscCall(PetscFEInitializePackage());

290:   PetscCall(PetscHeaderCreate(s, PETSCSPACE_CLASSID, "PetscSpace", "Linear Space", "PetscSpace", comm, PetscSpaceDestroy, PetscSpaceView));
291:   s->degree    = 0;
292:   s->maxDegree = PETSC_DETERMINE;
293:   s->Nc        = 1;
294:   s->Nv        = 0;
295:   s->dim       = PETSC_DETERMINE;
296:   PetscCall(DMShellCreate(comm, &s->dm));
297:   PetscCall(PetscSpaceSetType(s, PETSCSPACEPOLYNOMIAL));

299:   *sp = s;
300:   PetscFunctionReturn(PETSC_SUCCESS);
301: }

303: /*@
304:   PetscSpaceGetDimension - Return the dimension of this space, i.e. the number of basis vectors

306:   Input Parameter:
307: . sp - The `PetscSpace`

309:   Output Parameter:
310: . dim - The dimension

312:   Level: intermediate

314: .seealso: `PetscSpace`, `PetscSpaceGetDegree()`, `PetscSpaceCreate()`
315: @*/
316: PetscErrorCode PetscSpaceGetDimension(PetscSpace sp, PetscInt *dim)
317: {
318:   PetscFunctionBegin;
320:   PetscAssertPointer(dim, 2);
321:   if (sp->dim == PETSC_DETERMINE) PetscTryTypeMethod(sp, getdimension, &sp->dim);
322:   *dim = sp->dim;
323:   PetscFunctionReturn(PETSC_SUCCESS);
324: }

326: /*@
327:   PetscSpaceGetDegree - Return the polynomial degrees that characterize this space

329:   Input Parameter:
330: . sp - The `PetscSpace`

332:   Output Parameters:
333: + minDegree - The degree of the largest polynomial space contained in the space, pass `NULL` if not needed
334: - maxDegree - The degree of the smallest polynomial space containing the space, pass `NULL` if not needed

336:   Level: intermediate

338: .seealso: `PetscSpace`, `PetscSpaceSetDegree()`, `PetscSpaceGetDimension()`, `PetscSpaceCreate()`
339: @*/
340: PetscErrorCode PetscSpaceGetDegree(PetscSpace sp, PeOp PetscInt *minDegree, PeOp PetscInt *maxDegree)
341: {
342:   PetscFunctionBegin;
344:   if (minDegree) PetscAssertPointer(minDegree, 2);
345:   if (maxDegree) PetscAssertPointer(maxDegree, 3);
346:   if (minDegree) *minDegree = sp->degree;
347:   if (maxDegree) *maxDegree = sp->maxDegree;
348:   PetscFunctionReturn(PETSC_SUCCESS);
349: }

351: /*@
352:   PetscSpaceSetDegree - Set the degree of approximation for this space.

354:   Input Parameters:
355: + sp        - The `PetscSpace`
356: . degree    - The degree of the largest polynomial space contained in the space
357: - maxDegree - The degree of the largest polynomial space containing the space.  One of degree and maxDegree can be `PETSC_DETERMINE`.

359:   Level: intermediate

361: .seealso: `PetscSpace`, `PetscSpaceGetDegree()`, `PetscSpaceCreate()`
362: @*/
363: PetscErrorCode PetscSpaceSetDegree(PetscSpace sp, PetscInt degree, PetscInt maxDegree)
364: {
365:   PetscFunctionBegin;
367:   sp->degree    = degree;
368:   sp->maxDegree = maxDegree;
369:   PetscFunctionReturn(PETSC_SUCCESS);
370: }

372: /*@
373:   PetscSpaceGetNumComponents - Return the number of components for this space

375:   Input Parameter:
376: . sp - The `PetscSpace`

378:   Output Parameter:
379: . Nc - The number of components

381:   Level: intermediate

383:   Note:
384:   A vector space, for example, will have d components, where d is the spatial dimension

386: .seealso: `PetscSpace`, `PetscSpaceSetNumComponents()`, `PetscSpaceGetNumVariables()`, `PetscSpaceGetDimension()`, `PetscSpaceCreate()`
387: @*/
388: PetscErrorCode PetscSpaceGetNumComponents(PetscSpace sp, PetscInt *Nc)
389: {
390:   PetscFunctionBegin;
392:   PetscAssertPointer(Nc, 2);
393:   *Nc = sp->Nc;
394:   PetscFunctionReturn(PETSC_SUCCESS);
395: }

397: /*@
398:   PetscSpaceSetNumComponents - Set the number of components for this space

400:   Input Parameters:
401: + sp - The `PetscSpace`
402: - Nc - The number of components

404:   Level: intermediate

406: .seealso: `PetscSpace`, `PetscSpaceGetNumComponents()`, `PetscSpaceSetNumVariables()`, `PetscSpaceCreate()`
407: @*/
408: PetscErrorCode PetscSpaceSetNumComponents(PetscSpace sp, PetscInt Nc)
409: {
410:   PetscFunctionBegin;
412:   sp->Nc = Nc;
413:   PetscFunctionReturn(PETSC_SUCCESS);
414: }

416: /*@
417:   PetscSpaceSetNumVariables - Set the number of variables for this space

419:   Input Parameters:
420: + sp - The `PetscSpace`
421: - n  - The number of variables, e.g. x, y, z...

423:   Level: intermediate

425: .seealso: `PetscSpace`, `PetscSpaceGetNumVariables()`, `PetscSpaceSetNumComponents()`, `PetscSpaceCreate()`
426: @*/
427: PetscErrorCode PetscSpaceSetNumVariables(PetscSpace sp, PetscInt n)
428: {
429:   PetscFunctionBegin;
431:   sp->Nv = n;
432:   PetscFunctionReturn(PETSC_SUCCESS);
433: }

435: /*@
436:   PetscSpaceGetNumVariables - Return the number of variables for this space

438:   Input Parameter:
439: . sp - The `PetscSpace`

441:   Output Parameter:
442: . n - The number of variables, e.g. x, y, z...

444:   Level: intermediate

446: .seealso: `PetscSpace`, `PetscSpaceSetNumVariables()`, `PetscSpaceGetNumComponents()`, `PetscSpaceGetDimension()`, `PetscSpaceCreate()`
447: @*/
448: PetscErrorCode PetscSpaceGetNumVariables(PetscSpace sp, PetscInt *n)
449: {
450:   PetscFunctionBegin;
452:   PetscAssertPointer(n, 2);
453:   *n = sp->Nv;
454:   PetscFunctionReturn(PETSC_SUCCESS);
455: }

457: /*@
458:   PetscSpaceEvaluate - Evaluate the basis functions and their derivatives (jet) at each point

460:   Input Parameters:
461: + sp      - The `PetscSpace`
462: . npoints - The number of evaluation points, in reference coordinates
463: - points  - The point coordinates

465:   Output Parameters:
466: + B - The function evaluations in a `npoints` x `nfuncs` array
467: . D - The derivative evaluations in a `npoints` x `nfuncs` x `dim` array
468: - H - The second derivative evaluations in a `npoints` x `nfuncs` x `dim` x `dim` array

470:   Level: beginner

472:   Note:
473:   Above `nfuncs` is the dimension of the space, and `dim` is the spatial dimension. The coordinates are given
474:   on the reference cell, not in real space.

476: .seealso: `PetscSpace`, `PetscFECreateTabulation()`, `PetscFEGetCellTabulation()`, `PetscSpaceCreate()`
477: @*/
478: PetscErrorCode PetscSpaceEvaluate(PetscSpace sp, PetscInt npoints, const PetscReal points[], PeOp PetscReal B[], PeOp PetscReal D[], PeOp PetscReal H[])
479: {
480:   PetscFunctionBegin;
481:   if (!npoints) PetscFunctionReturn(PETSC_SUCCESS);
483:   if (sp->Nv) PetscAssertPointer(points, 3);
484:   if (B) PetscAssertPointer(B, 4);
485:   if (D) PetscAssertPointer(D, 5);
486:   if (H) PetscAssertPointer(H, 6);
487:   PetscTryTypeMethod(sp, evaluate, npoints, points, B, D, H);
488:   PetscFunctionReturn(PETSC_SUCCESS);
489: }

491: /*@
492:   PetscSpaceGetHeightSubspace - Get the subset of the primal space basis that is supported on a mesh point of a given height.

494:   Not Collective

496:   Input Parameters:
497: + sp     - the `PetscSpace` object
498: - height - the height of the mesh point for which the subspace is desired

500:   Output Parameter:
501: . subsp - the subspace

503:   Level: advanced

505:   Notes:
506:   If the space is not defined on mesh points of the given height (e.g. if the space is discontinuous and
507:   pointwise values are not defined on the element boundaries), or if the implementation of `PetscSpace` does not
508:   support extracting subspaces, then NULL is returned.

510:   This does not increment the reference count on the returned space, and the user should not destroy it.

512: .seealso: `PetscDualSpaceGetHeightSubspace()`, `PetscSpace`
513: @*/
514: PetscErrorCode PetscSpaceGetHeightSubspace(PetscSpace sp, PetscInt height, PetscSpace *subsp)
515: {
516:   PetscFunctionBegin;
518:   PetscAssertPointer(subsp, 3);
519:   *subsp = NULL;
520:   PetscTryTypeMethod(sp, getheightsubspace, height, subsp);
521:   PetscFunctionReturn(PETSC_SUCCESS);
522: }