xref: /petsc/src/dm/dt/space/interface/space.c (revision 5a856986583887c326abe5dfd149e8184a29cd80)
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: developer
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: developer
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: developer
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: developer
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(), 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(), 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 PetscErrorCode PetscSpaceSetNumVariables(PetscSpace sp, PetscInt n)
418 {
419   PetscFunctionBegin;
420   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
421   sp->Nv = n;
422   PetscFunctionReturn(0);
423 }
424 
425 PetscErrorCode PetscSpaceGetNumVariables(PetscSpace sp, PetscInt *n)
426 {
427   PetscFunctionBegin;
428   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
429   PetscValidPointer(n, 2);
430   *n = sp->Nv;
431   PetscFunctionReturn(0);
432 }
433 
434 
435 /*@C
436   PetscSpaceEvaluate - Evaluate the basis functions and their derivatives (jet) at each point
437 
438   Input Parameters:
439 + sp      - The PetscSpace
440 . npoints - The number of evaluation points, in reference coordinates
441 - points  - The point coordinates
442 
443   Output Parameters:
444 + B - The function evaluations in a npoints x nfuncs array
445 . D - The derivative evaluations in a npoints x nfuncs x dim array
446 - H - The second derivative evaluations in a npoints x nfuncs x dim x dim array
447 
448   Note: Above nfuncs is the dimension of the space, and dim is the spatial dimension. The coordinates are given
449   on the reference cell, not in real space.
450 
451   Level: advanced
452 
453 .seealso: PetscFEGetTabulation(), PetscFEGetDefaultTabulation(), PetscSpaceCreate()
454 @*/
455 PetscErrorCode PetscSpaceEvaluate(PetscSpace sp, PetscInt npoints, const PetscReal points[], PetscReal B[], PetscReal D[], PetscReal H[])
456 {
457   PetscErrorCode ierr;
458 
459   PetscFunctionBegin;
460   if (!npoints) PetscFunctionReturn(0);
461   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
462   if (sp->Nv) PetscValidPointer(points, 3);
463   if (B) PetscValidPointer(B, 4);
464   if (D) PetscValidPointer(D, 5);
465   if (H) PetscValidPointer(H, 6);
466   if (sp->ops->evaluate) {ierr = (*sp->ops->evaluate)(sp, npoints, points, B, D, H);CHKERRQ(ierr);}
467   PetscFunctionReturn(0);
468 }
469 
470 /*@
471   PetscSpaceGetHeightSubspace - Get the subset of the primal space basis that is supported on a mesh point of a given height.
472 
473   If the space is not defined on mesh points of the given height (e.g. if the space is discontinuous and
474   pointwise values are not defined on the element boundaries), or if the implementation of PetscSpace does not
475   support extracting subspaces, then NULL is returned.
476 
477   This does not increment the reference count on the returned space, and the user should not destroy it.
478 
479   Not collective
480 
481   Input Parameters:
482 + sp - the PetscSpace object
483 - height - the height of the mesh point for which the subspace is desired
484 
485   Output Parameter:
486 . subsp - the subspace
487 
488   Level: advanced
489 
490 .seealso: PetscDualSpaceGetHeightSubspace(), PetscSpace
491 @*/
492 PetscErrorCode PetscSpaceGetHeightSubspace(PetscSpace sp, PetscInt height, PetscSpace *subsp)
493 {
494   PetscErrorCode ierr;
495 
496   PetscFunctionBegin;
497   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
498   PetscValidPointer(subsp, 3);
499   *subsp = NULL;
500   if (sp->ops->getheightsubspace) {
501     ierr = (*sp->ops->getheightsubspace)(sp, height, subsp);CHKERRQ(ierr);
502   }
503   PetscFunctionReturn(0);
504 }
505 
506