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:   Notes:
 19:   PetscSpaceRegister() may be called multiple times to add several user-defined types of PetscSpaces.  The creation function is called
 20:   when the type is set to 'name'.

 22:   Sample usage:
 23: .vb
 24:     PetscSpaceRegister("my_space", MyPetscSpaceCreate);
 25: .ve

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

 37:   Level: advanced

 39: .seealso: `PetscSpaceRegisterAll()`, `PetscSpaceRegisterDestroy()`

 41: @*/
 42: PetscErrorCode PetscSpaceRegister(const char sname[], PetscErrorCode (*function)(PetscSpace))
 43: {
 44:   PetscFunctionListAdd(&PetscSpaceList, sname, function);
 45:   return 0;
 46: }

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

 51:   Collective on sp

 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: `PetscSpaceGetType()`, `PetscSpaceCreate()`
 63: @*/
 64: PetscErrorCode PetscSpaceSetType(PetscSpace sp, PetscSpaceType name)
 65: {
 66:   PetscErrorCode (*r)(PetscSpace);
 67:   PetscBool match;

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

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

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

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

 86: /*@C
 87:   PetscSpaceGetType - Gets the PetscSpace type name (as a string) from the object.

 89:   Not Collective

 91:   Input Parameter:
 92: . sp  - The PetscSpace

 94:   Output Parameter:
 95: . name - The PetscSpace type name

 97:   Level: intermediate

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

110: /*@C
111:    PetscSpaceViewFromOptions - View from Options

113:    Collective on PetscSpace

115:    Input Parameters:
116: +  A - the PetscSpace object
117: .  obj - Optional object
118: -  name - command line option

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

130: /*@C
131:   PetscSpaceView - Views a PetscSpace

133:   Collective on sp

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

139:   Level: beginner

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

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

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

164:   Collective on sp

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

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

174:   Level: intermediate

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

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

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

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

217:   Collective on sp

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

222:   Level: intermediate

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

233: /*@
234:   PetscSpaceDestroy - Destroys a PetscSpace object

236:   Collective on sp

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

241:   Level: beginner

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

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

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

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

265:   Collective

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

270:   Output Parameter:
271: . sp - The PetscSpace object

273:   Level: beginner

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

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

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

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

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

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

303:   Input Parameter:
304: . sp - The PetscSpace

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

309:   Level: intermediate

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

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

325:   Input Parameter:
326: . sp - The PetscSpace

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

332:   Level: intermediate

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

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

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

354:   Level: intermediate

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

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

369:   Input Parameter:
370: . sp - The PetscSpace

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

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

377:   Level: intermediate

379: .seealso: `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: `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: `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: `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:   Note: Above nfuncs is the dimension of the space, and dim is the spatial dimension. The coordinates are given
460:   on the reference cell, not in real space.

462:   Level: beginner

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

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

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

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

487:   Not collective

489:   Input Parameters:
490: + sp - the PetscSpace object
491: - height - the height of the mesh point for which the subspace is desired

493:   Output Parameter:
494: . subsp - the subspace

496:   Level: advanced

498: .seealso: `PetscDualSpaceGetHeightSubspace()`, `PetscSpace`
499: @*/
500: PetscErrorCode PetscSpaceGetHeightSubspace(PetscSpace sp, PetscInt height, PetscSpace *subsp)
501: {
504:   *subsp = NULL;
505:   PetscTryTypeMethod(sp, getheightsubspace, height, subsp);
506:   return 0;
507: }