xref: /petsc/src/dm/dt/space/interface/space.c (revision 030f984af8d8bb4c203755d35bded3c05b3d83ce)
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   Level: intermediate
363 
364 .seealso: PetscSpaceSetDegree(), PetscSpaceGetDimension(), PetscSpaceCreate(), PetscSpace
365 @*/
366 PetscErrorCode PetscSpaceGetDegree(PetscSpace sp, PetscInt *minDegree, PetscInt *maxDegree)
367 {
368   PetscFunctionBegin;
369   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
370   if (minDegree) PetscValidPointer(minDegree, 2);
371   if (maxDegree) PetscValidPointer(maxDegree, 3);
372   if (minDegree) *minDegree = sp->degree;
373   if (maxDegree) *maxDegree = sp->maxDegree;
374   PetscFunctionReturn(0);
375 }
376 
377 /*@
378   PetscSpaceSetDegree - Set the degree of approximation for this space.
379 
380   Input Parameters:
381 + sp - The PetscSpace
382 . degree - The degree of the largest polynomial space contained in the space
383 - maxDegree - The degree of the largest polynomial space containing the space.  One of degree and maxDegree can be PETSC_DETERMINE.
384 
385   Level: intermediate
386 
387 .seealso: PetscSpaceGetDegree(), PetscSpaceCreate(), PetscSpace
388 @*/
389 PetscErrorCode PetscSpaceSetDegree(PetscSpace sp, PetscInt degree, PetscInt maxDegree)
390 {
391   PetscFunctionBegin;
392   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
393   sp->degree = degree;
394   sp->maxDegree = maxDegree;
395   PetscFunctionReturn(0);
396 }
397 
398 /*@
399   PetscSpaceGetNumComponents - Return the number of components for this space
400 
401   Input Parameter:
402 . sp - The PetscSpace
403 
404   Output Parameter:
405 . Nc - The number of components
406 
407   Note: A vector space, for example, will have d components, where d is the spatial dimension
408 
409   Level: intermediate
410 
411 .seealso: PetscSpaceSetNumComponents(), PetscSpaceGetNumVariables(), PetscSpaceGetDimension(), PetscSpaceCreate(), PetscSpace
412 @*/
413 PetscErrorCode PetscSpaceGetNumComponents(PetscSpace sp, PetscInt *Nc)
414 {
415   PetscFunctionBegin;
416   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
417   PetscValidPointer(Nc, 2);
418   *Nc = sp->Nc;
419   PetscFunctionReturn(0);
420 }
421 
422 /*@
423   PetscSpaceSetNumComponents - Set the number of components for this space
424 
425   Input Parameters:
426 + sp - The PetscSpace
427 - order - The number of components
428 
429   Level: intermediate
430 
431 .seealso: PetscSpaceGetNumComponents(), PetscSpaceSetNumVariables(), PetscSpaceCreate(), PetscSpace
432 @*/
433 PetscErrorCode PetscSpaceSetNumComponents(PetscSpace sp, PetscInt Nc)
434 {
435   PetscFunctionBegin;
436   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
437   sp->Nc = Nc;
438   PetscFunctionReturn(0);
439 }
440 
441 /*@
442   PetscSpaceSetNumVariables - Set the number of variables for this space
443 
444   Input Parameters:
445 + sp - The PetscSpace
446 - n - The number of variables, e.g. x, y, z...
447 
448   Level: intermediate
449 
450 .seealso: PetscSpaceGetNumVariables(), PetscSpaceSetNumComponents(), PetscSpaceCreate(), PetscSpace
451 @*/
452 PetscErrorCode PetscSpaceSetNumVariables(PetscSpace sp, PetscInt n)
453 {
454   PetscFunctionBegin;
455   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
456   sp->Nv = n;
457   PetscFunctionReturn(0);
458 }
459 
460 /*@
461   PetscSpaceGetNumVariables - Return the number of variables for this space
462 
463   Input Parameter:
464 . sp - The PetscSpace
465 
466   Output Parameter:
467 . Nc - The number of variables, e.g. x, y, z...
468 
469   Level: intermediate
470 
471 .seealso: PetscSpaceSetNumVariables(), PetscSpaceGetNumComponents(), PetscSpaceGetDimension(), PetscSpaceCreate(), PetscSpace
472 @*/
473 PetscErrorCode PetscSpaceGetNumVariables(PetscSpace sp, PetscInt *n)
474 {
475   PetscFunctionBegin;
476   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
477   PetscValidPointer(n, 2);
478   *n = sp->Nv;
479   PetscFunctionReturn(0);
480 }
481 
482 /*@C
483   PetscSpaceEvaluate - Evaluate the basis functions and their derivatives (jet) at each point
484 
485   Input Parameters:
486 + sp      - The PetscSpace
487 . npoints - The number of evaluation points, in reference coordinates
488 - points  - The point coordinates
489 
490   Output Parameters:
491 + B - The function evaluations in a npoints x nfuncs array
492 . D - The derivative evaluations in a npoints x nfuncs x dim array
493 - H - The second derivative evaluations in a npoints x nfuncs x dim x dim array
494 
495   Note: Above nfuncs is the dimension of the space, and dim is the spatial dimension. The coordinates are given
496   on the reference cell, not in real space.
497 
498   Level: beginner
499 
500 .seealso: PetscFECreateTabulation(), PetscFEGetCellTabulation(), PetscSpaceCreate()
501 @*/
502 PetscErrorCode PetscSpaceEvaluate(PetscSpace sp, PetscInt npoints, const PetscReal points[], PetscReal B[], PetscReal D[], PetscReal H[])
503 {
504   PetscErrorCode ierr;
505 
506   PetscFunctionBegin;
507   if (!npoints) PetscFunctionReturn(0);
508   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
509   if (sp->Nv) PetscValidPointer(points, 3);
510   if (B) PetscValidPointer(B, 4);
511   if (D) PetscValidPointer(D, 5);
512   if (H) PetscValidPointer(H, 6);
513   if (sp->ops->evaluate) {ierr = (*sp->ops->evaluate)(sp, npoints, points, B, D, H);CHKERRQ(ierr);}
514   PetscFunctionReturn(0);
515 }
516 
517 /*@
518   PetscSpaceGetHeightSubspace - Get the subset of the primal space basis that is supported on a mesh point of a given height.
519 
520   If the space is not defined on mesh points of the given height (e.g. if the space is discontinuous and
521   pointwise values are not defined on the element boundaries), or if the implementation of PetscSpace does not
522   support extracting subspaces, then NULL is returned.
523 
524   This does not increment the reference count on the returned space, and the user should not destroy it.
525 
526   Not collective
527 
528   Input Parameters:
529 + sp - the PetscSpace object
530 - height - the height of the mesh point for which the subspace is desired
531 
532   Output Parameter:
533 . subsp - the subspace
534 
535   Level: advanced
536 
537 .seealso: PetscDualSpaceGetHeightSubspace(), PetscSpace
538 @*/
539 PetscErrorCode PetscSpaceGetHeightSubspace(PetscSpace sp, PetscInt height, PetscSpace *subsp)
540 {
541   PetscErrorCode ierr;
542 
543   PetscFunctionBegin;
544   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
545   PetscValidPointer(subsp, 3);
546   *subsp = NULL;
547   if (sp->ops->getheightsubspace) {
548     ierr = (*sp->ops->getheightsubspace)(sp, height, subsp);CHKERRQ(ierr);
549   }
550   PetscFunctionReturn(0);
551 }
552