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