xref: /petsc/src/dm/dt/space/interface/space.c (revision a69119a591a03a9d906b29c0a4e9802e4d7c9795)
1 #include <petsc/private/petscfeimpl.h> /*I  "petscfe.h"  I*/
2 #include <petscdmshell.h>
3 
4 PetscClassId PETSCSPACE_CLASSID = 0;
5 
6 PetscFunctionList PetscSpaceList              = NULL;
7 PetscBool         PetscSpaceRegisterAllCalled = PETSC_FALSE;
8 
9 /*@C
10   PetscSpaceRegister - Adds a new PetscSpace implementation
11 
12   Not Collective
13 
14   Input Parameters:
15 + name        - The name of a new user-defined creation routine
16 - create_func - The creation routine for the implementation type
17 
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'.
21 
22   Sample usage:
23 .vb
24     PetscSpaceRegister("my_space", MyPetscSpaceCreate);
25 .ve
26 
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
36 
37   Level: advanced
38 
39 .seealso: `PetscSpaceRegisterAll()`, `PetscSpaceRegisterDestroy()`
40 
41 @*/
42 PetscErrorCode PetscSpaceRegister(const char sname[], PetscErrorCode (*function)(PetscSpace)) {
43   PetscFunctionBegin;
44   PetscCall(PetscFunctionListAdd(&PetscSpaceList, sname, function));
45   PetscFunctionReturn(0);
46 }
47 
48 /*@C
49   PetscSpaceSetType - Builds a particular PetscSpace
50 
51   Collective on sp
52 
53   Input Parameters:
54 + sp   - The PetscSpace object
55 - name - The kind of space
56 
57   Options Database Key:
58 . -petscspace_type <type> - Sets the PetscSpace type; use -help for a list of available types
59 
60   Level: intermediate
61 
62 .seealso: `PetscSpaceGetType()`, `PetscSpaceCreate()`
63 @*/
64 PetscErrorCode PetscSpaceSetType(PetscSpace sp, PetscSpaceType name) {
65   PetscErrorCode (*r)(PetscSpace);
66   PetscBool match;
67 
68   PetscFunctionBegin;
69   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
70   PetscCall(PetscObjectTypeCompare((PetscObject)sp, name, &match));
71   if (match) PetscFunctionReturn(0);
72 
73   PetscCall(PetscSpaceRegisterAll());
74   PetscCall(PetscFunctionListFind(PetscSpaceList, name, &r));
75   PetscCheck(r, PetscObjectComm((PetscObject)sp), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown PetscSpace type: %s", name);
76 
77   PetscTryTypeMethod(sp, destroy);
78   sp->ops->destroy = NULL;
79 
80   sp->dim = PETSC_DETERMINE;
81   PetscCall((*r)(sp));
82   PetscCall(PetscObjectChangeTypeName((PetscObject)sp, name));
83   PetscFunctionReturn(0);
84 }
85 
86 /*@C
87   PetscSpaceGetType - Gets the PetscSpace type name (as a string) from the object.
88 
89   Not Collective
90 
91   Input Parameter:
92 . sp  - The PetscSpace
93 
94   Output Parameter:
95 . name - The PetscSpace type name
96 
97   Level: intermediate
98 
99 .seealso: `PetscSpaceSetType()`, `PetscSpaceCreate()`
100 @*/
101 PetscErrorCode PetscSpaceGetType(PetscSpace sp, PetscSpaceType *name) {
102   PetscFunctionBegin;
103   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
104   PetscValidPointer(name, 2);
105   if (!PetscSpaceRegisterAllCalled) PetscCall(PetscSpaceRegisterAll());
106   *name = ((PetscObject)sp)->type_name;
107   PetscFunctionReturn(0);
108 }
109 
110 /*@C
111    PetscSpaceViewFromOptions - View from Options
112 
113    Collective on PetscSpace
114 
115    Input Parameters:
116 +  A - the PetscSpace object
117 .  obj - Optional object
118 -  name - command line option
119 
120    Level: intermediate
121 .seealso: `PetscSpace`, `PetscSpaceView`, `PetscObjectViewFromOptions()`, `PetscSpaceCreate()`
122 @*/
123 PetscErrorCode PetscSpaceViewFromOptions(PetscSpace A, PetscObject obj, const char name[]) {
124   PetscFunctionBegin;
125   PetscValidHeaderSpecific(A, PETSCSPACE_CLASSID, 1);
126   PetscCall(PetscObjectViewFromOptions((PetscObject)A, obj, name));
127   PetscFunctionReturn(0);
128 }
129 
130 /*@C
131   PetscSpaceView - Views a PetscSpace
132 
133   Collective on sp
134 
135   Input Parameters:
136 + sp - the PetscSpace object to view
137 - v  - the viewer
138 
139   Level: beginner
140 
141 .seealso `PetscSpaceDestroy()`
142 @*/
143 PetscErrorCode PetscSpaceView(PetscSpace sp, PetscViewer v) {
144   PetscInt  pdim;
145   PetscBool iascii;
146 
147   PetscFunctionBegin;
148   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
149   if (v) PetscValidHeaderSpecific(v, PETSC_VIEWER_CLASSID, 2);
150   if (!v) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)sp), &v));
151   PetscCall(PetscSpaceGetDimension(sp, &pdim));
152   PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)sp, v));
153   PetscCall(PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERASCII, &iascii));
154   PetscCall(PetscViewerASCIIPushTab(v));
155   if (iascii) PetscCall(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   PetscCall(PetscViewerASCIIPopTab(v));
158   PetscFunctionReturn(0);
159 }
160 
161 /*@
162   PetscSpaceSetFromOptions - sets parameters in a PetscSpace from the options database
163 
164   Collective on sp
165 
166   Input Parameter:
167 . sp - the PetscSpace object to set options for
168 
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
173 
174   Level: intermediate
175 
176 .seealso `PetscSpaceView()`
177 @*/
178 PetscErrorCode PetscSpaceSetFromOptions(PetscSpace sp) {
179   const char *defaultType;
180   char        name[256];
181   PetscBool   flg;
182 
183   PetscFunctionBegin;
184   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
185   if (!((PetscObject)sp)->type_name) {
186     defaultType = PETSCSPACEPOLYNOMIAL;
187   } else {
188     defaultType = ((PetscObject)sp)->type_name;
189   }
190   if (!PetscSpaceRegisterAllCalled) PetscCall(PetscSpaceRegisterAll());
191 
192   PetscObjectOptionsBegin((PetscObject)sp);
193   PetscCall(PetscOptionsFList("-petscspace_type", "Linear space", "PetscSpaceSetType", PetscSpaceList, defaultType, name, 256, &flg));
194   if (flg) {
195     PetscCall(PetscSpaceSetType(sp, name));
196   } else if (!((PetscObject)sp)->type_name) {
197     PetscCall(PetscSpaceSetType(sp, defaultType));
198   }
199   {
200     PetscCall(PetscOptionsDeprecated("-petscspace_order", "-petscspace_degree", "3.11", NULL));
201     PetscCall(PetscOptionsBoundedInt("-petscspace_order", "DEPRECATED: The approximation order", "PetscSpaceSetDegree", sp->degree, &sp->degree, NULL, 0));
202   }
203   PetscCall(PetscOptionsBoundedInt("-petscspace_degree", "The (maximally included) polynomial degree", "PetscSpaceSetDegree", sp->degree, &sp->degree, NULL, 0));
204   PetscCall(PetscOptionsBoundedInt("-petscspace_variables", "The number of different variables, e.g. x and y", "PetscSpaceSetNumVariables", sp->Nv, &sp->Nv, NULL, 0));
205   PetscCall(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   PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)sp, PetscOptionsObject));
209   PetscOptionsEnd();
210   PetscCall(PetscSpaceViewFromOptions(sp, NULL, "-petscspace_view"));
211   PetscFunctionReturn(0);
212 }
213 
214 /*@C
215   PetscSpaceSetUp - Construct data structures for the PetscSpace
216 
217   Collective on sp
218 
219   Input Parameter:
220 . sp - the PetscSpace object to setup
221 
222   Level: intermediate
223 
224 .seealso `PetscSpaceView()`, `PetscSpaceDestroy()`
225 @*/
226 PetscErrorCode PetscSpaceSetUp(PetscSpace sp) {
227   PetscFunctionBegin;
228   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
229   PetscTryTypeMethod(sp, setup);
230   PetscFunctionReturn(0);
231 }
232 
233 /*@
234   PetscSpaceDestroy - Destroys a PetscSpace object
235 
236   Collective on sp
237 
238   Input Parameter:
239 . sp - the PetscSpace object to destroy
240 
241   Level: beginner
242 
243 .seealso `PetscSpaceView()`
244 @*/
245 PetscErrorCode PetscSpaceDestroy(PetscSpace *sp) {
246   PetscFunctionBegin;
247   if (!*sp) PetscFunctionReturn(0);
248   PetscValidHeaderSpecific((*sp), PETSCSPACE_CLASSID, 1);
249 
250   if (--((PetscObject)(*sp))->refct > 0) {
251     *sp = NULL;
252     PetscFunctionReturn(0);
253   }
254   ((PetscObject)(*sp))->refct = 0;
255   PetscCall(DMDestroy(&(*sp)->dm));
256 
257   PetscCall((*(*sp)->ops->destroy)(*sp));
258   PetscCall(PetscHeaderDestroy(sp));
259   PetscFunctionReturn(0);
260 }
261 
262 /*@
263   PetscSpaceCreate - Creates an empty PetscSpace object. The type can then be set with PetscSpaceSetType().
264 
265   Collective
266 
267   Input Parameter:
268 . comm - The communicator for the PetscSpace object
269 
270   Output Parameter:
271 . sp - The PetscSpace object
272 
273   Level: beginner
274 
275 .seealso: `PetscSpaceSetType()`, `PETSCSPACEPOLYNOMIAL`
276 @*/
277 PetscErrorCode PetscSpaceCreate(MPI_Comm comm, PetscSpace *sp) {
278   PetscSpace s;
279 
280   PetscFunctionBegin;
281   PetscValidPointer(sp, 2);
282   PetscCall(PetscCitationsRegister(FECitation, &FEcite));
283   *sp = NULL;
284   PetscCall(PetscFEInitializePackage());
285 
286   PetscCall(PetscHeaderCreate(s, PETSCSPACE_CLASSID, "PetscSpace", "Linear Space", "PetscSpace", comm, PetscSpaceDestroy, PetscSpaceView));
287 
288   s->degree    = 0;
289   s->maxDegree = PETSC_DETERMINE;
290   s->Nc        = 1;
291   s->Nv        = 0;
292   s->dim       = PETSC_DETERMINE;
293   PetscCall(DMShellCreate(comm, &s->dm));
294   PetscCall(PetscSpaceSetType(s, PETSCSPACEPOLYNOMIAL));
295 
296   *sp = s;
297   PetscFunctionReturn(0);
298 }
299 
300 /*@
301   PetscSpaceGetDimension - Return the dimension of this space, i.e. the number of basis vectors
302 
303   Input Parameter:
304 . sp - The PetscSpace
305 
306   Output Parameter:
307 . dim - The dimension
308 
309   Level: intermediate
310 
311 .seealso: `PetscSpaceGetDegree()`, `PetscSpaceCreate()`, `PetscSpace`
312 @*/
313 PetscErrorCode PetscSpaceGetDimension(PetscSpace sp, PetscInt *dim) {
314   PetscFunctionBegin;
315   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
316   PetscValidIntPointer(dim, 2);
317   if (sp->dim == PETSC_DETERMINE) PetscTryTypeMethod(sp, getdimension, &sp->dim);
318   *dim = sp->dim;
319   PetscFunctionReturn(0);
320 }
321 
322 /*@
323   PetscSpaceGetDegree - Return the polynomial degrees that characterize this space
324 
325   Input Parameter:
326 . sp - The PetscSpace
327 
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
331 
332   Level: intermediate
333 
334 .seealso: `PetscSpaceSetDegree()`, `PetscSpaceGetDimension()`, `PetscSpaceCreate()`, `PetscSpace`
335 @*/
336 PetscErrorCode PetscSpaceGetDegree(PetscSpace sp, PetscInt *minDegree, PetscInt *maxDegree) {
337   PetscFunctionBegin;
338   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
339   if (minDegree) PetscValidIntPointer(minDegree, 2);
340   if (maxDegree) PetscValidIntPointer(maxDegree, 3);
341   if (minDegree) *minDegree = sp->degree;
342   if (maxDegree) *maxDegree = sp->maxDegree;
343   PetscFunctionReturn(0);
344 }
345 
346 /*@
347   PetscSpaceSetDegree - Set the degree of approximation for this space.
348 
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.
353 
354   Level: intermediate
355 
356 .seealso: `PetscSpaceGetDegree()`, `PetscSpaceCreate()`, `PetscSpace`
357 @*/
358 PetscErrorCode PetscSpaceSetDegree(PetscSpace sp, PetscInt degree, PetscInt maxDegree) {
359   PetscFunctionBegin;
360   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
361   sp->degree    = degree;
362   sp->maxDegree = maxDegree;
363   PetscFunctionReturn(0);
364 }
365 
366 /*@
367   PetscSpaceGetNumComponents - Return the number of components for this space
368 
369   Input Parameter:
370 . sp - The PetscSpace
371 
372   Output Parameter:
373 . Nc - The number of components
374 
375   Note: A vector space, for example, will have d components, where d is the spatial dimension
376 
377   Level: intermediate
378 
379 .seealso: `PetscSpaceSetNumComponents()`, `PetscSpaceGetNumVariables()`, `PetscSpaceGetDimension()`, `PetscSpaceCreate()`, `PetscSpace`
380 @*/
381 PetscErrorCode PetscSpaceGetNumComponents(PetscSpace sp, PetscInt *Nc) {
382   PetscFunctionBegin;
383   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
384   PetscValidIntPointer(Nc, 2);
385   *Nc = sp->Nc;
386   PetscFunctionReturn(0);
387 }
388 
389 /*@
390   PetscSpaceSetNumComponents - Set the number of components for this space
391 
392   Input Parameters:
393 + sp - The PetscSpace
394 - order - The number of components
395 
396   Level: intermediate
397 
398 .seealso: `PetscSpaceGetNumComponents()`, `PetscSpaceSetNumVariables()`, `PetscSpaceCreate()`, `PetscSpace`
399 @*/
400 PetscErrorCode PetscSpaceSetNumComponents(PetscSpace sp, PetscInt Nc) {
401   PetscFunctionBegin;
402   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
403   sp->Nc = Nc;
404   PetscFunctionReturn(0);
405 }
406 
407 /*@
408   PetscSpaceSetNumVariables - Set the number of variables for this space
409 
410   Input Parameters:
411 + sp - The PetscSpace
412 - n - The number of variables, e.g. x, y, z...
413 
414   Level: intermediate
415 
416 .seealso: `PetscSpaceGetNumVariables()`, `PetscSpaceSetNumComponents()`, `PetscSpaceCreate()`, `PetscSpace`
417 @*/
418 PetscErrorCode PetscSpaceSetNumVariables(PetscSpace sp, PetscInt n) {
419   PetscFunctionBegin;
420   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
421   sp->Nv = n;
422   PetscFunctionReturn(0);
423 }
424 
425 /*@
426   PetscSpaceGetNumVariables - Return the number of variables for this space
427 
428   Input Parameter:
429 . sp - The PetscSpace
430 
431   Output Parameter:
432 . Nc - The number of variables, e.g. x, y, z...
433 
434   Level: intermediate
435 
436 .seealso: `PetscSpaceSetNumVariables()`, `PetscSpaceGetNumComponents()`, `PetscSpaceGetDimension()`, `PetscSpaceCreate()`, `PetscSpace`
437 @*/
438 PetscErrorCode PetscSpaceGetNumVariables(PetscSpace sp, PetscInt *n) {
439   PetscFunctionBegin;
440   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
441   PetscValidIntPointer(n, 2);
442   *n = sp->Nv;
443   PetscFunctionReturn(0);
444 }
445 
446 /*@C
447   PetscSpaceEvaluate - Evaluate the basis functions and their derivatives (jet) at each point
448 
449   Input Parameters:
450 + sp      - The PetscSpace
451 . npoints - The number of evaluation points, in reference coordinates
452 - points  - The point coordinates
453 
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
458 
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.
461 
462   Level: beginner
463 
464 .seealso: `PetscFECreateTabulation()`, `PetscFEGetCellTabulation()`, `PetscSpaceCreate()`
465 @*/
466 PetscErrorCode PetscSpaceEvaluate(PetscSpace sp, PetscInt npoints, const PetscReal points[], PetscReal B[], PetscReal D[], PetscReal H[]) {
467   PetscFunctionBegin;
468   if (!npoints) PetscFunctionReturn(0);
469   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
470   if (sp->Nv) PetscValidRealPointer(points, 3);
471   if (B) PetscValidRealPointer(B, 4);
472   if (D) PetscValidRealPointer(D, 5);
473   if (H) PetscValidRealPointer(H, 6);
474   PetscTryTypeMethod(sp, evaluate, npoints, points, B, D, H);
475   PetscFunctionReturn(0);
476 }
477 
478 /*@
479   PetscSpaceGetHeightSubspace - Get the subset of the primal space basis that is supported on a mesh point of a given height.
480 
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.
484 
485   This does not increment the reference count on the returned space, and the user should not destroy it.
486 
487   Not collective
488 
489   Input Parameters:
490 + sp - the PetscSpace object
491 - height - the height of the mesh point for which the subspace is desired
492 
493   Output Parameter:
494 . subsp - the subspace
495 
496   Level: advanced
497 
498 .seealso: `PetscDualSpaceGetHeightSubspace()`, `PetscSpace`
499 @*/
500 PetscErrorCode PetscSpaceGetHeightSubspace(PetscSpace sp, PetscInt height, PetscSpace *subsp) {
501   PetscFunctionBegin;
502   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
503   PetscValidPointer(subsp, 3);
504   *subsp = NULL;
505   PetscTryTypeMethod(sp, getheightsubspace, height, subsp);
506   PetscFunctionReturn(0);
507 }
508