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