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

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

 18:   Sample 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:   PetscFunctionListAdd(&PetscSpaceList, sname, function);
 44:   return 0;
 45: }

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

 50:   Collective on sp

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

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

 59:   Level: intermediate

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

 69:   PetscObjectTypeCompare((PetscObject)sp, name, &match);
 70:   if (match) return 0;

 72:   PetscSpaceRegisterAll();
 73:   PetscFunctionListFind(PetscSpaceList, name, &r);

 76:   PetscTryTypeMethod(sp, destroy);
 77:   sp->ops->destroy = NULL;

 79:   sp->dim = PETSC_DETERMINE;
 80:   (*r)(sp);
 81:   PetscObjectChangeTypeName((PetscObject)sp, name);
 82:   return 0;
 83: }

 85: /*@C
 86:   PetscSpaceGetType - Gets the `PetscSpaceType` (as a string) from the object.

 88:   Not Collective

 90:   Input Parameter:
 91: . sp  - The `PetscSpace`

 93:   Output Parameter:
 94: . name - The `PetscSpace` type name

 96:   Level: intermediate

 98: .seealso: `PetscSpaceType`, `PetscSpace`, `PetscSpaceSetType()`, `PetscSpaceCreate()`
 99: @*/
100: PetscErrorCode PetscSpaceGetType(PetscSpace sp, PetscSpaceType *name)
101: {
104:   if (!PetscSpaceRegisterAllCalled) PetscSpaceRegisterAll();
105:   *name = ((PetscObject)sp)->type_name;
106:   return 0;
107: }

109: /*@C
110:    PetscSpaceViewFromOptions - View a `PetscSpace` based on values in the options database

112:    Collective on PetscSpace

114:    Input Parameters:
115: +  A - the PetscSpace object
116: .  obj - Optional object that provides the options name prefix
117: -  name - command line option name

119:    Level: intermediate
120: .seealso: `PetscSpace`, `PetscSpaceView()`, `PetscObjectViewFromOptions()`, `PetscSpaceCreate()`
121: @*/
122: PetscErrorCode PetscSpaceViewFromOptions(PetscSpace A, PetscObject obj, const char name[])
123: {
125:   PetscObjectViewFromOptions((PetscObject)A, obj, name);
126:   return 0;
127: }

129: /*@C
130:   PetscSpaceView - Views a `PetscSpace`

132:   Collective on sp

134:   Input Parameters:
135: + sp - the `PetscSpace` object to view
136: - v  - the viewer

138:   Level: beginner

140: .seealso: `PetscSpace`, `PetscViewer`, `PetscSpaceViewFromOptions()`, `PetscSpaceDestroy()`
141: @*/
142: PetscErrorCode PetscSpaceView(PetscSpace sp, PetscViewer v)
143: {
144:   PetscInt  pdim;
145:   PetscBool iascii;

149:   if (!v) PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)sp), &v);
150:   PetscSpaceGetDimension(sp, &pdim);
151:   PetscObjectPrintClassNamePrefixType((PetscObject)sp, v);
152:   PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERASCII, &iascii);
153:   PetscViewerASCIIPushTab(v);
154:   if (iascii) PetscViewerASCIIPrintf(v, "Space in %" PetscInt_FMT " variables with %" PetscInt_FMT " components, size %" PetscInt_FMT "\n", sp->Nv, sp->Nc, pdim);
155:   PetscTryTypeMethod(sp, view, v);
156:   PetscViewerASCIIPopTab(v);
157:   return 0;
158: }

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

163:   Collective on sp

165:   Input Parameter:
166: . sp - the `PetscSpace` object to set options for

168:   Options Database Keys:
169: + -petscspace_degree <deg> - the approximation order of the space
170: . -petscspace_variables <n> - the number of different variables, e.g. x and y
171: - -petscspace_components <c> - the number of components, say d for a vector field

173:   Level: intermediate

175: .seealso: `PetscSpace`, `PetscSpaceView()`
176: @*/
177: PetscErrorCode PetscSpaceSetFromOptions(PetscSpace sp)
178: {
179:   const char *defaultType;
180:   char        name[256];
181:   PetscBool   flg;

184:   if (!((PetscObject)sp)->type_name) {
185:     defaultType = PETSCSPACEPOLYNOMIAL;
186:   } else {
187:     defaultType = ((PetscObject)sp)->type_name;
188:   }
189:   if (!PetscSpaceRegisterAllCalled) PetscSpaceRegisterAll();

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

213: /*@C
214:   PetscSpaceSetUp - Construct data structures for the `PetscSpace`

216:   Collective on sp

218:   Input Parameter:
219: . sp - the `PetscSpace` object to setup

221:   Level: intermediate

223: .seealso: `PetscSpace`, `PetscSpaceView()`, `PetscSpaceDestroy()`
224: @*/
225: PetscErrorCode PetscSpaceSetUp(PetscSpace sp)
226: {
228:   PetscTryTypeMethod(sp, setup);
229:   return 0;
230: }

232: /*@
233:   PetscSpaceDestroy - Destroys a `PetscSpace` object

235:   Collective on sp

237:   Input Parameter:
238: . sp - the PetscSpace object to destroy

240:   Level: beginner

242: .seealso: `PetscSpace`, `PetscSpaceCreate()`
243: @*/
244: PetscErrorCode PetscSpaceDestroy(PetscSpace *sp)
245: {
246:   if (!*sp) return 0;

249:   if (--((PetscObject)(*sp))->refct > 0) {
250:     *sp = NULL;
251:     return 0;
252:   }
253:   ((PetscObject)(*sp))->refct = 0;
254:   DMDestroy(&(*sp)->dm);

256:   (*(*sp)->ops->destroy)(*sp);
257:   PetscHeaderDestroy(sp);
258:   return 0;
259: }

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

264:   Collective

266:   Input Parameter:
267: . comm - The communicator for the `PetscSpace` object

269:   Output Parameter:
270: . sp - The `PetscSpace` object

272:   Level: beginner

274: .seealso: `PetscSpace`, `PetscSpaceSetType()`, `PETSCSPACEPOLYNOMIAL`
275: @*/
276: PetscErrorCode PetscSpaceCreate(MPI_Comm comm, PetscSpace *sp)
277: {
278:   PetscSpace s;

281:   PetscCitationsRegister(FECitation, &FEcite);
282:   *sp = NULL;
283:   PetscFEInitializePackage();

285:   PetscHeaderCreate(s, PETSCSPACE_CLASSID, "PetscSpace", "Linear Space", "PetscSpace", comm, PetscSpaceDestroy, PetscSpaceView);

287:   s->degree    = 0;
288:   s->maxDegree = PETSC_DETERMINE;
289:   s->Nc        = 1;
290:   s->Nv        = 0;
291:   s->dim       = PETSC_DETERMINE;
292:   DMShellCreate(comm, &s->dm);
293:   PetscSpaceSetType(s, PETSCSPACEPOLYNOMIAL);

295:   *sp = s;
296:   return 0;
297: }

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

302:   Input Parameter:
303: . sp - The `PetscSpace`

305:   Output Parameter:
306: . dim - The dimension

308:   Level: intermediate

310: .seealso: `PetscSpace`, `PetscSpaceGetDegree()`, `PetscSpaceCreate()`, `PetscSpace`
311: @*/
312: PetscErrorCode PetscSpaceGetDimension(PetscSpace sp, PetscInt *dim)
313: {
316:   if (sp->dim == PETSC_DETERMINE) PetscTryTypeMethod(sp, getdimension, &sp->dim);
317:   *dim = sp->dim;
318:   return 0;
319: }

321: /*@
322:   PetscSpaceGetDegree - Return the polynomial degrees that characterize this space

324:   Input Parameter:
325: . sp - The `PetscSpace`

327:   Output Parameters:
328: + minDegree - The degree of the largest polynomial space contained in the space
329: - maxDegree - The degree of the smallest polynomial space containing the space

331:   Level: intermediate

333: .seealso: `PetscSpace`, `PetscSpaceSetDegree()`, `PetscSpaceGetDimension()`, `PetscSpaceCreate()`, `PetscSpace`
334: @*/
335: PetscErrorCode PetscSpaceGetDegree(PetscSpace sp, PetscInt *minDegree, PetscInt *maxDegree)
336: {
340:   if (minDegree) *minDegree = sp->degree;
341:   if (maxDegree) *maxDegree = sp->maxDegree;
342:   return 0;
343: }

345: /*@
346:   PetscSpaceSetDegree - Set the degree of approximation for this space.

348:   Input Parameters:
349: + sp - The `PetscSpace`
350: . degree - The degree of the largest polynomial space contained in the space
351: - maxDegree - The degree of the largest polynomial space containing the space.  One of degree and maxDegree can be `PETSC_DETERMINE`.

353:   Level: intermediate

355: .seealso: `PetscSpace`, `PetscSpaceGetDegree()`, `PetscSpaceCreate()`, `PetscSpace`
356: @*/
357: PetscErrorCode PetscSpaceSetDegree(PetscSpace sp, PetscInt degree, PetscInt maxDegree)
358: {
360:   sp->degree    = degree;
361:   sp->maxDegree = maxDegree;
362:   return 0;
363: }

365: /*@
366:   PetscSpaceGetNumComponents - Return the number of components for this space

368:   Input Parameter:
369: . sp - The `PetscSpace`

371:   Output Parameter:
372: . Nc - The number of components

374:   Level: intermediate

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

379: .seealso: `PetscSpace`, `PetscSpaceSetNumComponents()`, `PetscSpaceGetNumVariables()`, `PetscSpaceGetDimension()`, `PetscSpaceCreate()`, `PetscSpace`
380: @*/
381: PetscErrorCode PetscSpaceGetNumComponents(PetscSpace sp, PetscInt *Nc)
382: {
385:   *Nc = sp->Nc;
386:   return 0;
387: }

389: /*@
390:   PetscSpaceSetNumComponents - Set the number of components for this space

392:   Input Parameters:
393: + sp - The `PetscSpace`
394: - order - The number of components

396:   Level: intermediate

398: .seealso: `PetscSpace`, `PetscSpaceGetNumComponents()`, `PetscSpaceSetNumVariables()`, `PetscSpaceCreate()`, `PetscSpace`
399: @*/
400: PetscErrorCode PetscSpaceSetNumComponents(PetscSpace sp, PetscInt Nc)
401: {
403:   sp->Nc = Nc;
404:   return 0;
405: }

407: /*@
408:   PetscSpaceSetNumVariables - Set the number of variables for this space

410:   Input Parameters:
411: + sp - The `PetscSpace`
412: - n - The number of variables, e.g. x, y, z...

414:   Level: intermediate

416: .seealso: `PetscSpace`, `PetscSpaceGetNumVariables()`, `PetscSpaceSetNumComponents()`, `PetscSpaceCreate()`, `PetscSpace`
417: @*/
418: PetscErrorCode PetscSpaceSetNumVariables(PetscSpace sp, PetscInt n)
419: {
421:   sp->Nv = n;
422:   return 0;
423: }

425: /*@
426:   PetscSpaceGetNumVariables - Return the number of variables for this space

428:   Input Parameter:
429: . sp - The `PetscSpace`

431:   Output Parameter:
432: . Nc - The number of variables, e.g. x, y, z...

434:   Level: intermediate

436: .seealso: `PetscSpace`, `PetscSpaceSetNumVariables()`, `PetscSpaceGetNumComponents()`, `PetscSpaceGetDimension()`, `PetscSpaceCreate()`, `PetscSpace`
437: @*/
438: PetscErrorCode PetscSpaceGetNumVariables(PetscSpace sp, PetscInt *n)
439: {
442:   *n = sp->Nv;
443:   return 0;
444: }

446: /*@C
447:   PetscSpaceEvaluate - Evaluate the basis functions and their derivatives (jet) at each point

449:   Input Parameters:
450: + sp      - The `PetscSpace`
451: . npoints - The number of evaluation points, in reference coordinates
452: - points  - The point coordinates

454:   Output Parameters:
455: + B - The function evaluations in a npoints x nfuncs array
456: . D - The derivative evaluations in a npoints x nfuncs x dim array
457: - H - The second derivative evaluations in a npoints x nfuncs x dim x dim array

459:   Level: beginner

461:   Note:
462:   Above nfuncs is the dimension of the space, and dim is the spatial dimension. The coordinates are given
463:   on the reference cell, not in real space.

465: .seealso: `PetscSpace`, `PetscFECreateTabulation()`, `PetscFEGetCellTabulation()`, `PetscSpaceCreate()`
466: @*/
467: PetscErrorCode PetscSpaceEvaluate(PetscSpace sp, PetscInt npoints, const PetscReal points[], PetscReal B[], PetscReal D[], PetscReal H[])
468: {
469:   if (!npoints) return 0;
475:   PetscTryTypeMethod(sp, evaluate, npoints, points, B, D, H);
476:   return 0;
477: }

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

482:   Not collective

484:   Input Parameters:
485: + sp - the PetscSpace object
486: - height - the height of the mesh point for which the subspace is desired

488:   Output Parameter:
489: . subsp - the subspace

491:   Level: advanced

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

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

500: .seealso: `PetscDualSpaceGetHeightSubspace()`, `PetscSpace`
501: @*/
502: PetscErrorCode PetscSpaceGetHeightSubspace(PetscSpace sp, PetscInt height, PetscSpace *subsp)
503: {
506:   *subsp = NULL;
507:   PetscTryTypeMethod(sp, getheightsubspace, height, subsp);
508:   return 0;
509: }