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