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: /*@
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()`
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, pass `NULL` to use the options prefix of `A`
120: - name - command line option name
122: Options Database Key:
123: . -name viewer_specification - See `PetscOptionsCreateViewer()` for the values of `viewer_specification`
125: Level: intermediate
127: Note:
128: This checks the options database, creates the viewer on-the-fly, uses it and then destroys it. Hence it should not be called in heavily used routines,
129: rather `PetscOptionsCreateViewer()` should be used to construct the viewer once which can then be utilized in the heavily used routine.
131: .seealso: `PetscSpace`, `PetscSpaceView()`, `PetscObjectViewFromOptions()`, `PetscSpaceCreate()`, `PetscOptionsCreateViewer()`
132: @*/
133: PetscErrorCode PetscSpaceViewFromOptions(PetscSpace A, PetscObject obj, const char name[])
134: {
135: PetscFunctionBegin;
137: PetscCall(PetscObjectViewFromOptions((PetscObject)A, obj, name));
138: PetscFunctionReturn(PETSC_SUCCESS);
139: }
141: /*@
142: PetscSpaceView - Views a `PetscSpace`
144: Collective
146: Input Parameters:
147: + sp - the `PetscSpace` object to view
148: - v - the viewer
150: Level: beginner
152: .seealso: `PetscSpace`, `PetscViewer`, `PetscSpaceViewFromOptions()`, `PetscSpaceDestroy()`
153: @*/
154: PetscErrorCode PetscSpaceView(PetscSpace sp, PetscViewer v)
155: {
156: PetscInt pdim;
157: PetscBool isascii;
159: PetscFunctionBegin;
162: if (!v) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)sp), &v));
163: PetscCall(PetscSpaceGetDimension(sp, &pdim));
164: PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)sp, v));
165: PetscCall(PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERASCII, &isascii));
166: PetscCall(PetscViewerASCIIPushTab(v));
167: if (isascii) PetscCall(PetscViewerASCIIPrintf(v, "Space in %" PetscInt_FMT " variables with %" PetscInt_FMT " components, size %" PetscInt_FMT "\n", sp->Nv, sp->Nc, pdim));
168: PetscTryTypeMethod(sp, view, v);
169: PetscCall(PetscViewerASCIIPopTab(v));
170: PetscFunctionReturn(PETSC_SUCCESS);
171: }
173: /*@
174: PetscSpaceSetFromOptions - sets parameters in a `PetscSpace` from the options database
176: Collective
178: Input Parameter:
179: . sp - the `PetscSpace` object to set options for
181: Options Database Keys:
182: + -petscspace_degree deg - the degree of the space
183: . -petscspace_variables n - the number of different variables, e.g. x and y
184: - -petscspace_components c - the number of components, say d for a vector field
186: Level: intermediate
188: .seealso: `PetscSpace`, `PetscSpaceView()`
189: @*/
190: PetscErrorCode PetscSpaceSetFromOptions(PetscSpace sp)
191: {
192: const char *defaultType;
193: char name[256];
194: PetscBool flg;
196: PetscFunctionBegin;
198: if (!((PetscObject)sp)->type_name) defaultType = PETSCSPACEPOLYNOMIAL;
199: else defaultType = ((PetscObject)sp)->type_name;
200: if (!PetscSpaceRegisterAllCalled) PetscCall(PetscSpaceRegisterAll());
202: PetscObjectOptionsBegin((PetscObject)sp);
203: PetscCall(PetscOptionsFList("-petscspace_type", "Linear space", "PetscSpaceSetType", PetscSpaceList, defaultType, name, sizeof(name), &flg));
204: if (flg) PetscCall(PetscSpaceSetType(sp, name));
205: else if (!((PetscObject)sp)->type_name) PetscCall(PetscSpaceSetType(sp, defaultType));
206: {
207: PetscCall(PetscOptionsDeprecated("-petscspace_order", "-petscspace_degree", "3.11", NULL));
208: }
209: PetscCall(PetscOptionsBoundedInt("-petscspace_degree", "The (maximally included) polynomial degree", "PetscSpaceSetDegree", sp->degree, &sp->degree, NULL, 0));
210: PetscCall(PetscOptionsBoundedInt("-petscspace_variables", "The number of different variables, e.g. x and y", "PetscSpaceSetNumVariables", sp->Nv, &sp->Nv, NULL, 0));
211: PetscCall(PetscOptionsBoundedInt("-petscspace_components", "The number of components", "PetscSpaceSetNumComponents", sp->Nc, &sp->Nc, NULL, -1));
212: PetscTryTypeMethod(sp, setfromoptions, PetscOptionsObject);
213: /* process any options handlers added with PetscObjectAddOptionsHandler() */
214: PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)sp, PetscOptionsObject));
215: PetscOptionsEnd();
216: PetscCall(PetscSpaceViewFromOptions(sp, NULL, "-petscspace_view"));
217: PetscFunctionReturn(PETSC_SUCCESS);
218: }
220: /*@
221: PetscSpaceSetUp - Construct data structures for the `PetscSpace`
223: Collective
225: Input Parameter:
226: . sp - the `PetscSpace` object to setup
228: Level: intermediate
230: .seealso: `PetscSpace`, `PetscSpaceView()`, `PetscSpaceDestroy()`
231: @*/
232: PetscErrorCode PetscSpaceSetUp(PetscSpace sp)
233: {
234: PetscFunctionBegin;
236: PetscTryTypeMethod(sp, setup);
237: PetscFunctionReturn(PETSC_SUCCESS);
238: }
240: /*@
241: PetscSpaceDestroy - Destroys a `PetscSpace` object
243: Collective
245: Input Parameter:
246: . sp - the `PetscSpace` object to destroy
248: Level: beginner
250: .seealso: `PetscSpace`, `PetscSpaceCreate()`
251: @*/
252: PetscErrorCode PetscSpaceDestroy(PetscSpace *sp)
253: {
254: PetscFunctionBegin;
255: if (!*sp) PetscFunctionReturn(PETSC_SUCCESS);
258: if (--((PetscObject)*sp)->refct > 0) {
259: *sp = NULL;
260: PetscFunctionReturn(PETSC_SUCCESS);
261: }
262: ((PetscObject)*sp)->refct = 0;
263: PetscCall(DMDestroy(&(*sp)->dm));
265: PetscUseTypeMethod(*sp, destroy);
266: PetscCall(PetscHeaderDestroy(sp));
267: PetscFunctionReturn(PETSC_SUCCESS);
268: }
270: /*@
271: PetscSpaceCreate - Creates an empty `PetscSpace` object. The type can then be set with `PetscSpaceSetType()`.
273: Collective
275: Input Parameter:
276: . comm - The communicator for the `PetscSpace` object
278: Output Parameter:
279: . sp - The `PetscSpace` object
281: Level: beginner
283: .seealso: `PetscSpace`, `PetscSpaceSetType()`, `PETSCSPACEPOLYNOMIAL`
284: @*/
285: PetscErrorCode PetscSpaceCreate(MPI_Comm comm, PetscSpace *sp)
286: {
287: PetscSpace s;
289: PetscFunctionBegin;
290: PetscAssertPointer(sp, 2);
291: PetscCall(PetscCitationsRegister(FECitation, &FEcite));
292: PetscCall(PetscFEInitializePackage());
294: PetscCall(PetscHeaderCreate(s, PETSCSPACE_CLASSID, "PetscSpace", "Linear Space", "PetscSpace", comm, PetscSpaceDestroy, PetscSpaceView));
295: s->degree = 0;
296: s->maxDegree = PETSC_DETERMINE;
297: s->Nc = 1;
298: s->Nv = 0;
299: s->dim = PETSC_DETERMINE;
300: PetscCall(DMShellCreate(comm, &s->dm));
301: PetscCall(PetscSpaceSetType(s, PETSCSPACEPOLYNOMIAL));
303: *sp = s;
304: PetscFunctionReturn(PETSC_SUCCESS);
305: }
307: /*@
308: PetscSpaceGetDimension - Return the dimension of this space, i.e. the number of basis vectors
310: Input Parameter:
311: . sp - The `PetscSpace`
313: Output Parameter:
314: . dim - The dimension
316: Level: intermediate
318: .seealso: `PetscSpace`, `PetscSpaceGetDegree()`, `PetscSpaceCreate()`
319: @*/
320: PetscErrorCode PetscSpaceGetDimension(PetscSpace sp, PetscInt *dim)
321: {
322: PetscFunctionBegin;
324: PetscAssertPointer(dim, 2);
325: if (sp->dim == PETSC_DETERMINE) PetscTryTypeMethod(sp, getdimension, &sp->dim);
326: *dim = sp->dim;
327: PetscFunctionReturn(PETSC_SUCCESS);
328: }
330: /*@
331: PetscSpaceGetDegree - Return the polynomial degrees that characterize this space
333: Input Parameter:
334: . sp - The `PetscSpace`
336: Output Parameters:
337: + minDegree - The degree of the largest polynomial space contained in the space, pass `NULL` if not needed
338: - maxDegree - The degree of the smallest polynomial space containing the space, pass `NULL` if not needed
340: Level: intermediate
342: .seealso: `PetscSpace`, `PetscSpaceSetDegree()`, `PetscSpaceGetDimension()`, `PetscSpaceCreate()`
343: @*/
344: PetscErrorCode PetscSpaceGetDegree(PetscSpace sp, PeOp PetscInt *minDegree, PeOp PetscInt *maxDegree)
345: {
346: PetscFunctionBegin;
348: if (minDegree) PetscAssertPointer(minDegree, 2);
349: if (maxDegree) PetscAssertPointer(maxDegree, 3);
350: if (minDegree) *minDegree = sp->degree;
351: if (maxDegree) *maxDegree = sp->maxDegree;
352: PetscFunctionReturn(PETSC_SUCCESS);
353: }
355: /*@
356: PetscSpaceSetDegree - Set the degree of approximation for this space.
358: Input Parameters:
359: + sp - The `PetscSpace`
360: . degree - The degree of the largest polynomial space contained in the space
361: - maxDegree - The degree of the largest polynomial space containing the space. One of degree and maxDegree can be `PETSC_DETERMINE`.
363: Level: intermediate
365: .seealso: `PetscSpace`, `PetscSpaceGetDegree()`, `PetscSpaceCreate()`
366: @*/
367: PetscErrorCode PetscSpaceSetDegree(PetscSpace sp, PetscInt degree, PetscInt maxDegree)
368: {
369: PetscFunctionBegin;
371: sp->degree = degree;
372: sp->maxDegree = maxDegree;
373: PetscFunctionReturn(PETSC_SUCCESS);
374: }
376: /*@
377: PetscSpaceGetNumComponents - Return the number of components for this space
379: Input Parameter:
380: . sp - The `PetscSpace`
382: Output Parameter:
383: . Nc - The number of components
385: Level: intermediate
387: Note:
388: A vector space, for example, will have d components, where d is the spatial dimension
390: .seealso: `PetscSpace`, `PetscSpaceSetNumComponents()`, `PetscSpaceGetNumVariables()`, `PetscSpaceGetDimension()`, `PetscSpaceCreate()`
391: @*/
392: PetscErrorCode PetscSpaceGetNumComponents(PetscSpace sp, PetscInt *Nc)
393: {
394: PetscFunctionBegin;
396: PetscAssertPointer(Nc, 2);
397: *Nc = sp->Nc;
398: PetscFunctionReturn(PETSC_SUCCESS);
399: }
401: /*@
402: PetscSpaceSetNumComponents - Set the number of components for this space
404: Input Parameters:
405: + sp - The `PetscSpace`
406: - Nc - The number of components
408: Level: intermediate
410: .seealso: `PetscSpace`, `PetscSpaceGetNumComponents()`, `PetscSpaceSetNumVariables()`, `PetscSpaceCreate()`
411: @*/
412: PetscErrorCode PetscSpaceSetNumComponents(PetscSpace sp, PetscInt Nc)
413: {
414: PetscFunctionBegin;
416: sp->Nc = Nc;
417: PetscFunctionReturn(PETSC_SUCCESS);
418: }
420: /*@
421: PetscSpaceSetNumVariables - Set the number of variables for this space
423: Input Parameters:
424: + sp - The `PetscSpace`
425: - n - The number of variables, e.g. x, y, z...
427: Level: intermediate
429: .seealso: `PetscSpace`, `PetscSpaceGetNumVariables()`, `PetscSpaceSetNumComponents()`, `PetscSpaceCreate()`
430: @*/
431: PetscErrorCode PetscSpaceSetNumVariables(PetscSpace sp, PetscInt n)
432: {
433: PetscFunctionBegin;
435: sp->Nv = n;
436: PetscFunctionReturn(PETSC_SUCCESS);
437: }
439: /*@
440: PetscSpaceGetNumVariables - Return the number of variables for this space
442: Input Parameter:
443: . sp - The `PetscSpace`
445: Output Parameter:
446: . n - The number of variables, e.g. x, y, z...
448: Level: intermediate
450: .seealso: `PetscSpace`, `PetscSpaceSetNumVariables()`, `PetscSpaceGetNumComponents()`, `PetscSpaceGetDimension()`, `PetscSpaceCreate()`
451: @*/
452: PetscErrorCode PetscSpaceGetNumVariables(PetscSpace sp, PetscInt *n)
453: {
454: PetscFunctionBegin;
456: PetscAssertPointer(n, 2);
457: *n = sp->Nv;
458: PetscFunctionReturn(PETSC_SUCCESS);
459: }
461: /*@
462: PetscSpaceEvaluate - Evaluate the basis functions and their derivatives (jet) at each point
464: Input Parameters:
465: + sp - The `PetscSpace`
466: . npoints - The number of evaluation points, in reference coordinates
467: - points - The point coordinates
469: Output Parameters:
470: + B - The function evaluations in a `npoints` x `nfuncs` array
471: . D - The derivative evaluations in a `npoints` x `nfuncs` x `dim` array
472: - H - The second derivative evaluations in a `npoints` x `nfuncs` x `dim` x `dim` array
474: Level: beginner
476: Note:
477: Above `nfuncs` is the dimension of the space, and `dim` is the spatial dimension. The coordinates are given
478: on the reference cell, not in real space.
480: .seealso: `PetscSpace`, `PetscFECreateTabulation()`, `PetscFEGetCellTabulation()`, `PetscSpaceCreate()`
481: @*/
482: PetscErrorCode PetscSpaceEvaluate(PetscSpace sp, PetscInt npoints, const PetscReal points[], PeOp PetscReal B[], PeOp PetscReal D[], PeOp PetscReal H[])
483: {
484: PetscFunctionBegin;
485: if (!npoints) PetscFunctionReturn(PETSC_SUCCESS);
487: if (sp->Nv) PetscAssertPointer(points, 3);
488: if (B) PetscAssertPointer(B, 4);
489: if (D) PetscAssertPointer(D, 5);
490: if (H) PetscAssertPointer(H, 6);
491: PetscTryTypeMethod(sp, evaluate, npoints, points, B, D, H);
492: PetscFunctionReturn(PETSC_SUCCESS);
493: }
495: /*@
496: PetscSpaceGetHeightSubspace - Get the subset of the primal space basis that is supported on a mesh point of a given height.
498: Not Collective
500: Input Parameters:
501: + sp - the `PetscSpace` object
502: - height - the height of the mesh point for which the subspace is desired
504: Output Parameter:
505: . subsp - the subspace
507: Level: advanced
509: Notes:
510: If the space is not defined on mesh points of the given height (e.g. if the space is discontinuous and
511: pointwise values are not defined on the element boundaries), or if the implementation of `PetscSpace` does not
512: support extracting subspaces, then NULL is returned.
514: This does not increment the reference count on the returned space, and the user should not destroy it.
516: .seealso: `PetscDualSpaceGetHeightSubspace()`, `PetscSpace`
517: @*/
518: PetscErrorCode PetscSpaceGetHeightSubspace(PetscSpace sp, PetscInt height, PetscSpace *subsp)
519: {
520: PetscFunctionBegin;
522: PetscAssertPointer(subsp, 3);
523: *subsp = NULL;
524: PetscTryTypeMethod(sp, getheightsubspace, height, subsp);
525: PetscFunctionReturn(PETSC_SUCCESS);
526: }