xref: /petsc/src/dm/dt/space/interface/space.c (revision 20cf1dd8cd656e27510885a71ea4be028bf48813)
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 .keywords: PetscSpace, register
40 .seealso: PetscSpaceRegisterAll(), PetscSpaceRegisterDestroy()
41 
42 @*/
43 PetscErrorCode PetscSpaceRegister(const char sname[], PetscErrorCode (*function)(PetscSpace))
44 {
45   PetscErrorCode ierr;
46 
47   PetscFunctionBegin;
48   ierr = PetscFunctionListAdd(&PetscSpaceList, sname, function);CHKERRQ(ierr);
49   PetscFunctionReturn(0);
50 }
51 
52 /*@C
53   PetscSpaceSetType - Builds a particular PetscSpace
54 
55   Collective on PetscSpace
56 
57   Input Parameters:
58 + sp   - The PetscSpace object
59 - name - The kind of space
60 
61   Options Database Key:
62 . -petscspace_type <type> - Sets the PetscSpace type; use -help for a list of available types
63 
64   Level: intermediate
65 
66 .keywords: PetscSpace, set, type
67 .seealso: PetscSpaceGetType(), PetscSpaceCreate()
68 @*/
69 PetscErrorCode PetscSpaceSetType(PetscSpace sp, PetscSpaceType name)
70 {
71   PetscErrorCode (*r)(PetscSpace);
72   PetscBool      match;
73   PetscErrorCode ierr;
74 
75   PetscFunctionBegin;
76   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
77   ierr = PetscObjectTypeCompare((PetscObject) sp, name, &match);CHKERRQ(ierr);
78   if (match) PetscFunctionReturn(0);
79 
80   ierr = PetscSpaceRegisterAll();CHKERRQ(ierr);
81   ierr = PetscFunctionListFind(PetscSpaceList, name, &r);CHKERRQ(ierr);
82   if (!r) SETERRQ1(PetscObjectComm((PetscObject) sp), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown PetscSpace type: %s", name);
83 
84   if (sp->ops->destroy) {
85     ierr             = (*sp->ops->destroy)(sp);CHKERRQ(ierr);
86     sp->ops->destroy = NULL;
87   }
88   ierr = (*r)(sp);CHKERRQ(ierr);
89   ierr = PetscObjectChangeTypeName((PetscObject) sp, name);CHKERRQ(ierr);
90   PetscFunctionReturn(0);
91 }
92 
93 /*@C
94   PetscSpaceGetType - Gets the PetscSpace type name (as a string) from the object.
95 
96   Not Collective
97 
98   Input Parameter:
99 . sp  - The PetscSpace
100 
101   Output Parameter:
102 . name - The PetscSpace type name
103 
104   Level: intermediate
105 
106 .keywords: PetscSpace, get, type, name
107 .seealso: PetscSpaceSetType(), PetscSpaceCreate()
108 @*/
109 PetscErrorCode PetscSpaceGetType(PetscSpace sp, PetscSpaceType *name)
110 {
111   PetscErrorCode ierr;
112 
113   PetscFunctionBegin;
114   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
115   PetscValidPointer(name, 2);
116   if (!PetscSpaceRegisterAllCalled) {
117     ierr = PetscSpaceRegisterAll();CHKERRQ(ierr);
118   }
119   *name = ((PetscObject) sp)->type_name;
120   PetscFunctionReturn(0);
121 }
122 
123 /*@C
124   PetscSpaceView - Views a PetscSpace
125 
126   Collective on PetscSpace
127 
128   Input Parameter:
129 + sp - the PetscSpace object to view
130 - v  - the viewer
131 
132   Level: developer
133 
134 .seealso PetscSpaceDestroy()
135 @*/
136 PetscErrorCode PetscSpaceView(PetscSpace sp, PetscViewer v)
137 {
138   PetscBool      iascii;
139   PetscErrorCode ierr;
140 
141   PetscFunctionBegin;
142   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
143   if (v) PetscValidHeaderSpecific(v, PETSC_VIEWER_CLASSID, 2);
144   if (!v) {ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject) sp), &v);CHKERRQ(ierr);}
145   ierr = PetscObjectTypeCompare((PetscObject) v, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr);
146   if (iascii) {
147     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)sp,v);CHKERRQ(ierr);
148     ierr = PetscViewerASCIIPushTab(v);CHKERRQ(ierr);
149     ierr = PetscViewerASCIIPrintf(v, "Space in %D variables of order %D with %D components\n", sp->Nv, sp->degree, sp->Nc);CHKERRQ(ierr);
150     ierr = PetscViewerASCIIPopTab(v);CHKERRQ(ierr);
151   }
152   ierr = PetscViewerASCIIPushTab(v);CHKERRQ(ierr);
153   if (sp->ops->view) {ierr = (*sp->ops->view)(sp, v);CHKERRQ(ierr);}
154   ierr = PetscViewerASCIIPopTab(v);CHKERRQ(ierr);
155   PetscFunctionReturn(0);
156 }
157 
158 /*@
159   PetscSpaceSetFromOptions - sets parameters in a PetscSpace from the options database
160 
161   Collective on PetscSpace
162 
163   Input Parameter:
164 . sp - the PetscSpace object to set options for
165 
166   Options Database:
167 . -petscspace_order the approximation order of the space
168 
169   Level: developer
170 
171 .seealso PetscSpaceView()
172 @*/
173 PetscErrorCode PetscSpaceSetFromOptions(PetscSpace sp)
174 {
175   const char    *defaultType;
176   char           name[256];
177   PetscBool      flg;
178   PetscErrorCode ierr;
179 
180   PetscFunctionBegin;
181   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
182   if (!((PetscObject) sp)->type_name) {
183     defaultType = PETSCSPACEPOLYNOMIAL;
184   } else {
185     defaultType = ((PetscObject) sp)->type_name;
186   }
187   if (!PetscSpaceRegisterAllCalled) {ierr = PetscSpaceRegisterAll();CHKERRQ(ierr);}
188 
189   ierr = PetscObjectOptionsBegin((PetscObject) sp);CHKERRQ(ierr);
190   ierr = PetscOptionsFList("-petscspace_type", "Linear space", "PetscSpaceSetType", PetscSpaceList, defaultType, name, 256, &flg);CHKERRQ(ierr);
191   if (flg) {
192     ierr = PetscSpaceSetType(sp, name);CHKERRQ(ierr);
193   } else if (!((PetscObject) sp)->type_name) {
194     ierr = PetscSpaceSetType(sp, defaultType);CHKERRQ(ierr);
195   }
196   ierr = PetscOptionsInt("-petscspace_order", "The approximation order", "PetscSpaceSetDegree", sp->degree, &sp->degree, NULL);CHKERRQ(ierr);
197   ierr = PetscOptionsInt("-petscspace_variables", "The number of different variables, e.g. x and y", "PetscSpaceSetNumVariables", sp->Nv, &sp->Nv, NULL);CHKERRQ(ierr);
198   ierr = PetscOptionsInt("-petscspace_components", "The number of components", "PetscSpaceSetNumComponents", sp->Nc, &sp->Nc, NULL);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 PetscSpace
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 PetscSpace
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 on MPI_Comm
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->Nc     = 1;
290   s->Nv     = 0;
291   ierr = DMShellCreate(comm, &s->dm);CHKERRQ(ierr);
292   ierr = PetscSpaceSetType(s, PETSCSPACEPOLYNOMIAL);CHKERRQ(ierr);
293 
294   *sp = s;
295   PetscFunctionReturn(0);
296 }
297 
298 /*@
299   PetscSpaceGetDimension - Return the dimension of this space, i.e. the number of basis vectors
300 
301   Input Parameter:
302 . sp - The PetscSpace
303 
304   Output Parameter:
305 . dim - The dimension
306 
307   Level: intermediate
308 
309 .seealso: PetscSpaceGetDegree(), PetscSpaceCreate(), PetscSpace
310 @*/
311 PetscErrorCode PetscSpaceGetDimension(PetscSpace sp, PetscInt *dim)
312 {
313   PetscErrorCode ierr;
314 
315   PetscFunctionBegin;
316   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
317   PetscValidPointer(dim, 2);
318   *dim = 0;
319   if (sp->ops->getdimension) {ierr = (*sp->ops->getdimension)(sp, dim);CHKERRQ(ierr);}
320   PetscFunctionReturn(0);
321 }
322 
323 /*@
324   PetscSpaceGetDegree - Return the polynomial degrees that characterize this space
325 
326   Input Parameter:
327 . sp - The PetscSpace
328 
329   Output Parameter:
330 + minDegree - The degree of the largest polynomial space contained in the space
331 - maxDegree - The degree of the smallest polynomial space containing the space
332 
333 
334   Level: intermediate
335 
336 .seealso: PetscSpaceSetDegree(), PetscSpaceGetDimension(), PetscSpaceCreate(), PetscSpace
337 @*/
338 PetscErrorCode PetscSpaceGetDegree(PetscSpace sp, PetscInt *minDegree, PetscInt *maxDegree)
339 {
340   PetscFunctionBegin;
341   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
342   if (minDegree) PetscValidPointer(minDegree, 2);
343   if (maxDegree) PetscValidPointer(minDegree, 3);
344   if (minDegree) *minDegree = sp->degree;
345   PetscFunctionReturn(0);
346 }
347 
348 /*@
349   PetscSpaceSetDegree - Set the degree of approximation for this space.
350 
351   Input Parameters:
352 + sp - The PetscSpace
353 - degree - The degree of the largest polynomial space contained in the space
354 
355   Level: intermediate
356 
357 .seealso: PetscSpaceGetDegree(), PetscSpaceCreate(), PetscSpace
358 @*/
359 PetscErrorCode PetscSpaceSetDegree(PetscSpace sp, PetscInt order)
360 {
361   PetscFunctionBegin;
362   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
363   sp->degree = order;
364   PetscFunctionReturn(0);
365 }
366 
367 /*@
368   PetscSpaceGetNumComponents - Return the number of components for this space
369 
370   Input Parameter:
371 . sp - The PetscSpace
372 
373   Output Parameter:
374 . Nc - The number of components
375 
376   Note: A vector space, for example, will have d components, where d is the spatial dimension
377 
378   Level: intermediate
379 
380 .seealso: PetscSpaceSetNumComponents(), PetscSpaceGetDimension(), PetscSpaceCreate(), PetscSpace
381 @*/
382 PetscErrorCode PetscSpaceGetNumComponents(PetscSpace sp, PetscInt *Nc)
383 {
384   PetscFunctionBegin;
385   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
386   PetscValidPointer(Nc, 2);
387   *Nc = sp->Nc;
388   PetscFunctionReturn(0);
389 }
390 
391 /*@
392   PetscSpaceSetNumComponents - Set the number of components for this space
393 
394   Input Parameters:
395 + sp - The PetscSpace
396 - order - The number of components
397 
398   Level: intermediate
399 
400 .seealso: PetscSpaceGetNumComponents(), PetscSpaceCreate(), PetscSpace
401 @*/
402 PetscErrorCode PetscSpaceSetNumComponents(PetscSpace sp, PetscInt Nc)
403 {
404   PetscFunctionBegin;
405   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
406   sp->Nc = Nc;
407   PetscFunctionReturn(0);
408 }
409 
410 PetscErrorCode PetscSpaceSetNumVariables(PetscSpace sp, PetscInt n)
411 {
412   PetscFunctionBegin;
413   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
414   sp->Nv = n;
415   PetscFunctionReturn(0);
416 }
417 
418 PetscErrorCode PetscSpaceGetNumVariables(PetscSpace sp, PetscInt *n)
419 {
420   PetscFunctionBegin;
421   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
422   PetscValidPointer(n, 2);
423   *n = sp->Nv;
424   PetscFunctionReturn(0);
425 }
426 
427 
428 /*@C
429   PetscSpaceEvaluate - Evaluate the basis functions and their derivatives (jet) at each point
430 
431   Input Parameters:
432 + sp      - The PetscSpace
433 . npoints - The number of evaluation points, in reference coordinates
434 - points  - The point coordinates
435 
436   Output Parameters:
437 + B - The function evaluations in a npoints x nfuncs array
438 . D - The derivative evaluations in a npoints x nfuncs x dim array
439 - H - The second derivative evaluations in a npoints x nfuncs x dim x dim array
440 
441   Note: Above nfuncs is the dimension of the space, and dim is the spatial dimension. The coordinates are given
442   on the reference cell, not in real space.
443 
444   Level: advanced
445 
446 .seealso: PetscFEGetTabulation(), PetscFEGetDefaultTabulation(), PetscSpaceCreate()
447 @*/
448 PetscErrorCode PetscSpaceEvaluate(PetscSpace sp, PetscInt npoints, const PetscReal points[], PetscReal B[], PetscReal D[], PetscReal H[])
449 {
450   PetscErrorCode ierr;
451 
452   PetscFunctionBegin;
453   if (!npoints) PetscFunctionReturn(0);
454   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
455   if (sp->Nv) PetscValidPointer(points, 3);
456   if (B) PetscValidPointer(B, 4);
457   if (D) PetscValidPointer(D, 5);
458   if (H) PetscValidPointer(H, 6);
459   if (sp->ops->evaluate) {ierr = (*sp->ops->evaluate)(sp, npoints, points, B, D, H);CHKERRQ(ierr);}
460   PetscFunctionReturn(0);
461 }
462 
463 /*@
464   PetscSpaceGetHeightSubspace - Get the subset of the primal space basis that is supported on a mesh point of a given height.
465 
466   If the space is not defined on mesh points of the given height (e.g. if the space is discontinuous and
467   pointwise values are not defined on the element boundaries), or if the implementation of PetscSpace does not
468   support extracting subspaces, then NULL is returned.
469 
470   This does not increment the reference count on the returned space, and the user should not destroy it.
471 
472   Not collective
473 
474   Input Parameters:
475 + sp - the PetscSpace object
476 - height - the height of the mesh point for which the subspace is desired
477 
478   Output Parameter:
479 . subsp - the subspace
480 
481   Level: advanced
482 
483 .seealso: PetscDualSpaceGetHeightSubspace(), PetscSpace
484 @*/
485 PetscErrorCode PetscSpaceGetHeightSubspace(PetscSpace sp, PetscInt height, PetscSpace *subsp)
486 {
487   PetscErrorCode ierr;
488 
489   PetscFunctionBegin;
490   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
491   PetscValidPointer(subsp, 3);
492   *subsp = NULL;
493   if (sp->ops->getheightsubspace) {
494     ierr = (*sp->ops->getheightsubspace)(sp, height, subsp);CHKERRQ(ierr);
495   }
496   PetscFunctionReturn(0);
497 }
498 
499