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