Actual source code: space.c

petsc-3.10.5 2019-03-28
Report Typos and Errors
  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: .keywords: PetscSpace, register
 40: .seealso: PetscSpaceRegisterAll(), PetscSpaceRegisterDestroy()

 42: @*/
 43: PetscErrorCode PetscSpaceRegister(const char sname[], PetscErrorCode (*function)(PetscSpace))
 44: {

 48:   PetscFunctionListAdd(&PetscSpaceList, sname, function);
 49:   return(0);
 50: }

 52: /*@C
 53:   PetscSpaceSetType - Builds a particular PetscSpace

 55:   Collective on PetscSpace

 57:   Input Parameters:
 58: + sp   - The PetscSpace object
 59: - name - The kind of space

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

 64:   Level: intermediate

 66: .keywords: PetscSpace, set, type
 67: .seealso: PetscSpaceGetType(), PetscSpaceCreate()
 68: @*/
 69: PetscErrorCode PetscSpaceSetType(PetscSpace sp, PetscSpaceType name)
 70: {
 71:   PetscErrorCode (*r)(PetscSpace);
 72:   PetscBool      match;

 77:   PetscObjectTypeCompare((PetscObject) sp, name, &match);
 78:   if (match) return(0);

 80:   PetscSpaceRegisterAll();
 81:   PetscFunctionListFind(PetscSpaceList, name, &r);
 82:   if (!r) SETERRQ1(PetscObjectComm((PetscObject) sp), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown PetscSpace type: %s", name);

 84:   if (sp->ops->destroy) {
 85:     (*sp->ops->destroy)(sp);
 86:     sp->ops->destroy = NULL;
 87:   }
 88:   sp->dim = PETSC_DETERMINE;
 89:   (*r)(sp);
 90:   PetscObjectChangeTypeName((PetscObject) sp, name);
 91:   return(0);
 92: }

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

 97:   Not Collective

 99:   Input Parameter:
100: . sp  - The PetscSpace

102:   Output Parameter:
103: . name - The PetscSpace type name

105:   Level: intermediate

107: .keywords: PetscSpace, get, type, name
108: .seealso: PetscSpaceSetType(), PetscSpaceCreate()
109: @*/
110: PetscErrorCode PetscSpaceGetType(PetscSpace sp, PetscSpaceType *name)
111: {

117:   if (!PetscSpaceRegisterAllCalled) {
118:     PetscSpaceRegisterAll();
119:   }
120:   *name = ((PetscObject) sp)->type_name;
121:   return(0);
122: }

124: /*@C
125:   PetscSpaceView - Views a PetscSpace

127:   Collective on PetscSpace

129:   Input Parameter:
130: + sp - the PetscSpace object to view
131: - v  - the viewer

133:   Level: developer

135: .seealso PetscSpaceDestroy()
136: @*/
137: PetscErrorCode PetscSpaceView(PetscSpace sp, PetscViewer v)
138: {
139:   PetscBool      iascii;

145:   if (!v) {PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject) sp), &v);}
146:   PetscObjectTypeCompare((PetscObject) v, PETSCVIEWERASCII, &iascii);
147:   if (iascii) {
148:     PetscObjectPrintClassNamePrefixType((PetscObject)sp,v);
149:     PetscViewerASCIIPushTab(v);
150:     PetscViewerASCIIPrintf(v, "Space in %D variables of order %D with %D components\n", sp->Nv, sp->degree, sp->Nc);
151:     PetscViewerASCIIPopTab(v);
152:   }
153:   PetscViewerASCIIPushTab(v);
154:   if (sp->ops->view) {(*sp->ops->view)(sp, v);}
155:   PetscViewerASCIIPopTab(v);
156:   return(0);
157: }

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

162:   Collective on PetscSpace

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

167:   Options Database:
168: . -petscspace_degree the approximation order of the space

170:   Level: developer

172: .seealso PetscSpaceView()
173: @*/
174: PetscErrorCode PetscSpaceSetFromOptions(PetscSpace sp)
175: {
176:   const char    *defaultType;
177:   char           name[256];
178:   PetscBool      flg, orderflg;

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

190:   PetscObjectOptionsBegin((PetscObject) sp);
191:   PetscOptionsFList("-petscspace_type", "Linear space", "PetscSpaceSetType", PetscSpaceList, defaultType, name, 256, &flg);
192:   if (flg) {
193:     PetscSpaceSetType(sp, name);
194:   } else if (!((PetscObject) sp)->type_name) {
195:     PetscSpaceSetType(sp, defaultType);
196:   }
197:   {
198:     PetscOptionsInt("-petscspace_order", "DEPRECATED: The approximation order", "PetscSpaceSetDegree", sp->degree, &sp->degree, &orderflg);
199:     if (orderflg) {
200:       int compare;

202:       MPI_Comm_compare(PetscObjectComm((PetscObject)sp), PETSC_COMM_WORLD, &compare);

204:       if (compare == MPI_IDENT || compare == MPI_CONGRUENT) {
205:         PetscPrintf(PetscObjectComm((PetscObject)sp), "Warning: -petscspace_order is deprecated.  Use -petscspace_degree\n");
206:       }
207:     }
208:   }
209:   PetscOptionsInt("-petscspace_degree", "The (maximally included) polynomial degree", "PetscSpaceSetDegree", sp->degree, &sp->degree, NULL);
210:   PetscOptionsInt("-petscspace_variables", "The number of different variables, e.g. x and y", "PetscSpaceSetNumVariables", sp->Nv, &sp->Nv, NULL);
211:   PetscOptionsInt("-petscspace_components", "The number of components", "PetscSpaceSetNumComponents", sp->Nc, &sp->Nc, NULL);
212:   if (sp->ops->setfromoptions) {
213:     (*sp->ops->setfromoptions)(PetscOptionsObject,sp);
214:   }
215:   /* process any options handlers added with PetscObjectAddOptionsHandler() */
216:   PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject) sp);
217:   PetscOptionsEnd();
218:   PetscSpaceViewFromOptions(sp, NULL, "-petscspace_view");
219:   return(0);
220: }

222: /*@C
223:   PetscSpaceSetUp - Construct data structures for the PetscSpace

225:   Collective on PetscSpace

227:   Input Parameter:
228: . sp - the PetscSpace object to setup

230:   Level: developer

232: .seealso PetscSpaceView(), PetscSpaceDestroy()
233: @*/
234: PetscErrorCode PetscSpaceSetUp(PetscSpace sp)
235: {

240:   if (sp->ops->setup) {(*sp->ops->setup)(sp);}
241:   return(0);
242: }

244: /*@
245:   PetscSpaceDestroy - Destroys a PetscSpace object

247:   Collective on PetscSpace

249:   Input Parameter:
250: . sp - the PetscSpace object to destroy

252:   Level: developer

254: .seealso PetscSpaceView()
255: @*/
256: PetscErrorCode PetscSpaceDestroy(PetscSpace *sp)
257: {

261:   if (!*sp) return(0);

264:   if (--((PetscObject)(*sp))->refct > 0) {*sp = 0; return(0);}
265:   ((PetscObject) (*sp))->refct = 0;
266:   DMDestroy(&(*sp)->dm);

268:   (*(*sp)->ops->destroy)(*sp);
269:   PetscHeaderDestroy(sp);
270:   return(0);
271: }

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

276:   Collective on MPI_Comm

278:   Input Parameter:
279: . comm - The communicator for the PetscSpace object

281:   Output Parameter:
282: . sp - The PetscSpace object

284:   Level: beginner

286: .seealso: PetscSpaceSetType(), PETSCSPACEPOLYNOMIAL
287: @*/
288: PetscErrorCode PetscSpaceCreate(MPI_Comm comm, PetscSpace *sp)
289: {
290:   PetscSpace     s;

295:   PetscCitationsRegister(FECitation,&FEcite);
296:   *sp  = NULL;
297:   PetscFEInitializePackage();

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

301:   s->degree    = 0;
302:   s->maxDegree = PETSC_DETERMINE;
303:   s->Nc        = 1;
304:   s->Nv        = 0;
305:   s->dim       = PETSC_DETERMINE;
306:   DMShellCreate(comm, &s->dm);
307:   PetscSpaceSetType(s, PETSCSPACEPOLYNOMIAL);

309:   *sp = s;
310:   return(0);
311: }

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

316:   Input Parameter:
317: . sp - The PetscSpace

319:   Output Parameter:
320: . dim - The dimension

322:   Level: intermediate

324: .seealso: PetscSpaceGetDegree(), PetscSpaceCreate(), PetscSpace
325: @*/
326: PetscErrorCode PetscSpaceGetDimension(PetscSpace sp, PetscInt *dim)
327: {

333:   if (sp->dim == PETSC_DETERMINE) {
334:     if (sp->ops->getdimension) {(*sp->ops->getdimension)(sp, &sp->dim);}
335:   }
336:   *dim = sp->dim;
337:   return(0);
338: }

340: /*@
341:   PetscSpaceGetDegree - Return the polynomial degrees that characterize this space

343:   Input Parameter:
344: . sp - The PetscSpace

346:   Output Parameter:
347: + minDegree - The degree of the largest polynomial space contained in the space
348: - maxDegree - The degree of the smallest polynomial space containing the space


351:   Level: intermediate

353: .seealso: PetscSpaceSetDegree(), PetscSpaceGetDimension(), PetscSpaceCreate(), PetscSpace
354: @*/
355: PetscErrorCode PetscSpaceGetDegree(PetscSpace sp, PetscInt *minDegree, PetscInt *maxDegree)
356: {
361:   if (minDegree) *minDegree = sp->degree;
362:   if (maxDegree) *maxDegree = sp->maxDegree;
363:   return(0);
364: }

366: /*@
367:   PetscSpaceSetDegree - Set the degree of approximation for this space.

369:   Input Parameters:
370: + sp - The PetscSpace
371: . degree - The degree of the largest polynomial space contained in the space
372: - maxDegree - The degree of the largest polynomial space containing the space.  One of degree and maxDegree can be PETSC_DETERMINE.

374:   Level: intermediate

376: .seealso: PetscSpaceGetDegree(), PetscSpaceCreate(), PetscSpace
377: @*/
378: PetscErrorCode PetscSpaceSetDegree(PetscSpace sp, PetscInt degree, PetscInt maxDegree)
379: {
382:   sp->degree = degree;
383:   sp->maxDegree = maxDegree;
384:   return(0);
385: }

387: /*@
388:   PetscSpaceGetNumComponents - Return the number of components for this space

390:   Input Parameter:
391: . sp - The PetscSpace

393:   Output Parameter:
394: . Nc - The number of components

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

398:   Level: intermediate

400: .seealso: PetscSpaceSetNumComponents(), PetscSpaceGetDimension(), PetscSpaceCreate(), PetscSpace
401: @*/
402: PetscErrorCode PetscSpaceGetNumComponents(PetscSpace sp, PetscInt *Nc)
403: {
407:   *Nc = sp->Nc;
408:   return(0);
409: }

411: /*@
412:   PetscSpaceSetNumComponents - Set the number of components for this space

414:   Input Parameters:
415: + sp - The PetscSpace
416: - order - The number of components

418:   Level: intermediate

420: .seealso: PetscSpaceGetNumComponents(), PetscSpaceCreate(), PetscSpace
421: @*/
422: PetscErrorCode PetscSpaceSetNumComponents(PetscSpace sp, PetscInt Nc)
423: {
426:   sp->Nc = Nc;
427:   return(0);
428: }

430: PetscErrorCode PetscSpaceSetNumVariables(PetscSpace sp, PetscInt n)
431: {
434:   sp->Nv = n;
435:   return(0);
436: }

438: PetscErrorCode PetscSpaceGetNumVariables(PetscSpace sp, PetscInt *n)
439: {
443:   *n = sp->Nv;
444:   return(0);
445: }


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

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

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

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

464:   Level: advanced

466: .seealso: PetscFEGetTabulation(), PetscFEGetDefaultTabulation(), PetscSpaceCreate()
467: @*/
468: PetscErrorCode PetscSpaceEvaluate(PetscSpace sp, PetscInt npoints, const PetscReal points[], PetscReal B[], PetscReal D[], PetscReal H[])
469: {

473:   if (!npoints) return(0);
479:   if (sp->ops->evaluate) {(*sp->ops->evaluate)(sp, npoints, points, B, D, H);}
480:   return(0);
481: }

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

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

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

492:   Not collective

494:   Input Parameters:
495: + sp - the PetscSpace object
496: - height - the height of the mesh point for which the subspace is desired

498:   Output Parameter:
499: . subsp - the subspace

501:   Level: advanced

503: .seealso: PetscDualSpaceGetHeightSubspace(), PetscSpace
504: @*/
505: PetscErrorCode PetscSpaceGetHeightSubspace(PetscSpace sp, PetscInt height, PetscSpace *subsp)
506: {

512:   *subsp = NULL;
513:   if (sp->ops->getheightsubspace) {
514:     (*sp->ops->getheightsubspace)(sp, height, subsp);
515:   }
516:   return(0);
517: }