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