xref: /petsc/src/dm/dt/space/interface/space.c (revision f5a02b640e1833d5b1da97b24d9eb32792dc0d7d)
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(maxDegree, 3);
344   if (minDegree) *minDegree = sp->degree;
345   if (maxDegree) *maxDegree = sp->maxDegree;
346   PetscFunctionReturn(0);
347 }
348 
349 /*@
350   PetscSpaceSetDegree - Set the degree of approximation for this space.
351 
352   Input Parameters:
353 + sp - The PetscSpace
354 - degree - The degree of the largest polynomial space contained in the space
355 
356   Level: intermediate
357 
358 .seealso: PetscSpaceGetDegree(), PetscSpaceCreate(), PetscSpace
359 @*/
360 PetscErrorCode PetscSpaceSetDegree(PetscSpace sp, PetscInt order)
361 {
362   PetscFunctionBegin;
363   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
364   sp->degree = order;
365   PetscFunctionReturn(0);
366 }
367 
368 /*@
369   PetscSpaceGetNumComponents - Return the number of components for this space
370 
371   Input Parameter:
372 . sp - The PetscSpace
373 
374   Output Parameter:
375 . Nc - The number of components
376 
377   Note: A vector space, for example, will have d components, where d is the spatial dimension
378 
379   Level: intermediate
380 
381 .seealso: PetscSpaceSetNumComponents(), PetscSpaceGetDimension(), PetscSpaceCreate(), PetscSpace
382 @*/
383 PetscErrorCode PetscSpaceGetNumComponents(PetscSpace sp, PetscInt *Nc)
384 {
385   PetscFunctionBegin;
386   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
387   PetscValidPointer(Nc, 2);
388   *Nc = sp->Nc;
389   PetscFunctionReturn(0);
390 }
391 
392 /*@
393   PetscSpaceSetNumComponents - Set the number of components for this space
394 
395   Input Parameters:
396 + sp - The PetscSpace
397 - order - The number of components
398 
399   Level: intermediate
400 
401 .seealso: PetscSpaceGetNumComponents(), PetscSpaceCreate(), PetscSpace
402 @*/
403 PetscErrorCode PetscSpaceSetNumComponents(PetscSpace sp, PetscInt Nc)
404 {
405   PetscFunctionBegin;
406   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
407   sp->Nc = Nc;
408   PetscFunctionReturn(0);
409 }
410 
411 PetscErrorCode PetscSpaceSetNumVariables(PetscSpace sp, PetscInt n)
412 {
413   PetscFunctionBegin;
414   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
415   sp->Nv = n;
416   PetscFunctionReturn(0);
417 }
418 
419 PetscErrorCode PetscSpaceGetNumVariables(PetscSpace sp, PetscInt *n)
420 {
421   PetscFunctionBegin;
422   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
423   PetscValidPointer(n, 2);
424   *n = sp->Nv;
425   PetscFunctionReturn(0);
426 }
427 
428 
429 /*@C
430   PetscSpaceEvaluate - Evaluate the basis functions and their derivatives (jet) at each point
431 
432   Input Parameters:
433 + sp      - The PetscSpace
434 . npoints - The number of evaluation points, in reference coordinates
435 - points  - The point coordinates
436 
437   Output Parameters:
438 + B - The function evaluations in a npoints x nfuncs array
439 . D - The derivative evaluations in a npoints x nfuncs x dim array
440 - H - The second derivative evaluations in a npoints x nfuncs x dim x dim array
441 
442   Note: Above nfuncs is the dimension of the space, and dim is the spatial dimension. The coordinates are given
443   on the reference cell, not in real space.
444 
445   Level: advanced
446 
447 .seealso: PetscFEGetTabulation(), PetscFEGetDefaultTabulation(), PetscSpaceCreate()
448 @*/
449 PetscErrorCode PetscSpaceEvaluate(PetscSpace sp, PetscInt npoints, const PetscReal points[], PetscReal B[], PetscReal D[], PetscReal H[])
450 {
451   PetscErrorCode ierr;
452 
453   PetscFunctionBegin;
454   if (!npoints) PetscFunctionReturn(0);
455   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
456   if (sp->Nv) PetscValidPointer(points, 3);
457   if (B) PetscValidPointer(B, 4);
458   if (D) PetscValidPointer(D, 5);
459   if (H) PetscValidPointer(H, 6);
460   if (sp->ops->evaluate) {ierr = (*sp->ops->evaluate)(sp, npoints, points, B, D, H);CHKERRQ(ierr);}
461   PetscFunctionReturn(0);
462 }
463 
464 /*@
465   PetscSpaceGetHeightSubspace - Get the subset of the primal space basis that is supported on a mesh point of a given height.
466 
467   If the space is not defined on mesh points of the given height (e.g. if the space is discontinuous and
468   pointwise values are not defined on the element boundaries), or if the implementation of PetscSpace does not
469   support extracting subspaces, then NULL is returned.
470 
471   This does not increment the reference count on the returned space, and the user should not destroy it.
472 
473   Not collective
474 
475   Input Parameters:
476 + sp - the PetscSpace object
477 - height - the height of the mesh point for which the subspace is desired
478 
479   Output Parameter:
480 . subsp - the subspace
481 
482   Level: advanced
483 
484 .seealso: PetscDualSpaceGetHeightSubspace(), PetscSpace
485 @*/
486 PetscErrorCode PetscSpaceGetHeightSubspace(PetscSpace sp, PetscInt height, PetscSpace *subsp)
487 {
488   PetscErrorCode ierr;
489 
490   PetscFunctionBegin;
491   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
492   PetscValidPointer(subsp, 3);
493   *subsp = NULL;
494   if (sp->ops->getheightsubspace) {
495     ierr = (*sp->ops->getheightsubspace)(sp, height, subsp);CHKERRQ(ierr);
496   }
497   PetscFunctionReturn(0);
498 }
499 
500