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