xref: /petsc/src/dm/dt/space/interface/space.c (revision 7be5e7486ad090eef6dbc1e09e6fd40be450d1fc)
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_degree 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, orderflg;
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   {
197     ierr = PetscOptionsInt("-petscspace_order", "DEPRECATED: The approximation order", "PetscSpaceSetDegree", sp->degree, &sp->degree, &orderflg);CHKERRQ(ierr);
198     if (orderflg) {
199       int compare;
200 
201       ierr = MPI_Comm_compare(PetscObjectComm((PetscObject)sp), PETSC_COMM_WORLD, &compare);CHKERRQ(ierr);
202 
203       if (compare == MPI_IDENT || compare == MPI_CONGRUENT) {
204         ierr = PetscPrintf(PetscObjectComm((PetscObject)sp), "Warning: -petscspace_order is deprecated.  Use -petscspace_degree\n");CHKERRQ(ierr);
205       }
206     }
207   }
208   ierr = PetscOptionsInt("-petscspace_degree", "The polynomial degree contained by the space", "PetscSpaceSetDegree", sp->degree, &sp->degree, NULL);CHKERRQ(ierr);
209   ierr = PetscOptionsInt("-petscspace_variables", "The number of different variables, e.g. x and y", "PetscSpaceSetNumVariables", sp->Nv, &sp->Nv, NULL);CHKERRQ(ierr);
210   ierr = PetscOptionsInt("-petscspace_components", "The number of components", "PetscSpaceSetNumComponents", sp->Nc, &sp->Nc, NULL);CHKERRQ(ierr);
211   if (sp->ops->setfromoptions) {
212     ierr = (*sp->ops->setfromoptions)(PetscOptionsObject,sp);CHKERRQ(ierr);
213   }
214   /* process any options handlers added with PetscObjectAddOptionsHandler() */
215   ierr = PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject) sp);CHKERRQ(ierr);
216   ierr = PetscOptionsEnd();CHKERRQ(ierr);
217   ierr = PetscSpaceViewFromOptions(sp, NULL, "-petscspace_view");CHKERRQ(ierr);
218   PetscFunctionReturn(0);
219 }
220 
221 /*@C
222   PetscSpaceSetUp - Construct data structures for the PetscSpace
223 
224   Collective on PetscSpace
225 
226   Input Parameter:
227 . sp - the PetscSpace object to setup
228 
229   Level: developer
230 
231 .seealso PetscSpaceView(), PetscSpaceDestroy()
232 @*/
233 PetscErrorCode PetscSpaceSetUp(PetscSpace sp)
234 {
235   PetscErrorCode ierr;
236 
237   PetscFunctionBegin;
238   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
239   if (sp->ops->setup) {ierr = (*sp->ops->setup)(sp);CHKERRQ(ierr);}
240   PetscFunctionReturn(0);
241 }
242 
243 /*@
244   PetscSpaceDestroy - Destroys a PetscSpace object
245 
246   Collective on PetscSpace
247 
248   Input Parameter:
249 . sp - the PetscSpace object to destroy
250 
251   Level: developer
252 
253 .seealso PetscSpaceView()
254 @*/
255 PetscErrorCode PetscSpaceDestroy(PetscSpace *sp)
256 {
257   PetscErrorCode ierr;
258 
259   PetscFunctionBegin;
260   if (!*sp) PetscFunctionReturn(0);
261   PetscValidHeaderSpecific((*sp), PETSCSPACE_CLASSID, 1);
262 
263   if (--((PetscObject)(*sp))->refct > 0) {*sp = 0; PetscFunctionReturn(0);}
264   ((PetscObject) (*sp))->refct = 0;
265   ierr = DMDestroy(&(*sp)->dm);CHKERRQ(ierr);
266 
267   ierr = (*(*sp)->ops->destroy)(*sp);CHKERRQ(ierr);
268   ierr = PetscHeaderDestroy(sp);CHKERRQ(ierr);
269   PetscFunctionReturn(0);
270 }
271 
272 /*@
273   PetscSpaceCreate - Creates an empty PetscSpace object. The type can then be set with PetscSpaceSetType().
274 
275   Collective on MPI_Comm
276 
277   Input Parameter:
278 . comm - The communicator for the PetscSpace object
279 
280   Output Parameter:
281 . sp - The PetscSpace object
282 
283   Level: beginner
284 
285 .seealso: PetscSpaceSetType(), PETSCSPACEPOLYNOMIAL
286 @*/
287 PetscErrorCode PetscSpaceCreate(MPI_Comm comm, PetscSpace *sp)
288 {
289   PetscSpace     s;
290   PetscErrorCode ierr;
291 
292   PetscFunctionBegin;
293   PetscValidPointer(sp, 2);
294   ierr = PetscCitationsRegister(FECitation,&FEcite);CHKERRQ(ierr);
295   *sp  = NULL;
296   ierr = PetscFEInitializePackage();CHKERRQ(ierr);
297 
298   ierr = PetscHeaderCreate(s, PETSCSPACE_CLASSID, "PetscSpace", "Linear Space", "PetscSpace", comm, PetscSpaceDestroy, PetscSpaceView);CHKERRQ(ierr);
299 
300   s->degree = 0;
301   s->Nc     = 1;
302   s->Nv     = 0;
303   ierr = DMShellCreate(comm, &s->dm);CHKERRQ(ierr);
304   ierr = PetscSpaceSetType(s, PETSCSPACEPOLYNOMIAL);CHKERRQ(ierr);
305 
306   *sp = s;
307   PetscFunctionReturn(0);
308 }
309 
310 /*@
311   PetscSpaceGetDimension - Return the dimension of this space, i.e. the number of basis vectors
312 
313   Input Parameter:
314 . sp - The PetscSpace
315 
316   Output Parameter:
317 . dim - The dimension
318 
319   Level: intermediate
320 
321 .seealso: PetscSpaceGetDegree(), PetscSpaceCreate(), PetscSpace
322 @*/
323 PetscErrorCode PetscSpaceGetDimension(PetscSpace sp, PetscInt *dim)
324 {
325   PetscErrorCode ierr;
326 
327   PetscFunctionBegin;
328   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
329   PetscValidPointer(dim, 2);
330   *dim = 0;
331   if (sp->ops->getdimension) {ierr = (*sp->ops->getdimension)(sp, dim);CHKERRQ(ierr);}
332   PetscFunctionReturn(0);
333 }
334 
335 /*@
336   PetscSpaceGetDegree - Return the polynomial degrees that characterize this space
337 
338   Input Parameter:
339 . sp - The PetscSpace
340 
341   Output Parameter:
342 + minDegree - The degree of the largest polynomial space contained in the space
343 - maxDegree - The degree of the smallest polynomial space containing the space
344 
345 
346   Level: intermediate
347 
348 .seealso: PetscSpaceSetDegree(), PetscSpaceGetDimension(), PetscSpaceCreate(), PetscSpace
349 @*/
350 PetscErrorCode PetscSpaceGetDegree(PetscSpace sp, PetscInt *minDegree, PetscInt *maxDegree)
351 {
352   PetscFunctionBegin;
353   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
354   if (minDegree) PetscValidPointer(minDegree, 2);
355   if (maxDegree) PetscValidPointer(maxDegree, 3);
356   if (minDegree) *minDegree = sp->degree;
357   if (maxDegree) *maxDegree = sp->maxDegree;
358   PetscFunctionReturn(0);
359 }
360 
361 /*@
362   PetscSpaceSetDegree - Set the degree of approximation for this space.
363 
364   Input Parameters:
365 + sp - The PetscSpace
366 - degree - The degree of the largest polynomial space contained in the space
367 
368   Level: intermediate
369 
370 .seealso: PetscSpaceGetDegree(), PetscSpaceCreate(), PetscSpace
371 @*/
372 PetscErrorCode PetscSpaceSetDegree(PetscSpace sp, PetscInt order)
373 {
374   PetscFunctionBegin;
375   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
376   sp->degree = order;
377   PetscFunctionReturn(0);
378 }
379 
380 /*@
381   PetscSpaceGetNumComponents - Return the number of components for this space
382 
383   Input Parameter:
384 . sp - The PetscSpace
385 
386   Output Parameter:
387 . Nc - The number of components
388 
389   Note: A vector space, for example, will have d components, where d is the spatial dimension
390 
391   Level: intermediate
392 
393 .seealso: PetscSpaceSetNumComponents(), PetscSpaceGetDimension(), PetscSpaceCreate(), PetscSpace
394 @*/
395 PetscErrorCode PetscSpaceGetNumComponents(PetscSpace sp, PetscInt *Nc)
396 {
397   PetscFunctionBegin;
398   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
399   PetscValidPointer(Nc, 2);
400   *Nc = sp->Nc;
401   PetscFunctionReturn(0);
402 }
403 
404 /*@
405   PetscSpaceSetNumComponents - Set the number of components for this space
406 
407   Input Parameters:
408 + sp - The PetscSpace
409 - order - The number of components
410 
411   Level: intermediate
412 
413 .seealso: PetscSpaceGetNumComponents(), PetscSpaceCreate(), PetscSpace
414 @*/
415 PetscErrorCode PetscSpaceSetNumComponents(PetscSpace sp, PetscInt Nc)
416 {
417   PetscFunctionBegin;
418   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
419   sp->Nc = Nc;
420   PetscFunctionReturn(0);
421 }
422 
423 PetscErrorCode PetscSpaceSetNumVariables(PetscSpace sp, PetscInt n)
424 {
425   PetscFunctionBegin;
426   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
427   sp->Nv = n;
428   PetscFunctionReturn(0);
429 }
430 
431 PetscErrorCode PetscSpaceGetNumVariables(PetscSpace sp, PetscInt *n)
432 {
433   PetscFunctionBegin;
434   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
435   PetscValidPointer(n, 2);
436   *n = sp->Nv;
437   PetscFunctionReturn(0);
438 }
439 
440 
441 /*@C
442   PetscSpaceEvaluate - Evaluate the basis functions and their derivatives (jet) at each point
443 
444   Input Parameters:
445 + sp      - The PetscSpace
446 . npoints - The number of evaluation points, in reference coordinates
447 - points  - The point coordinates
448 
449   Output Parameters:
450 + B - The function evaluations in a npoints x nfuncs array
451 . D - The derivative evaluations in a npoints x nfuncs x dim array
452 - H - The second derivative evaluations in a npoints x nfuncs x dim x dim array
453 
454   Note: Above nfuncs is the dimension of the space, and dim is the spatial dimension. The coordinates are given
455   on the reference cell, not in real space.
456 
457   Level: advanced
458 
459 .seealso: PetscFEGetTabulation(), PetscFEGetDefaultTabulation(), PetscSpaceCreate()
460 @*/
461 PetscErrorCode PetscSpaceEvaluate(PetscSpace sp, PetscInt npoints, const PetscReal points[], PetscReal B[], PetscReal D[], PetscReal H[])
462 {
463   PetscErrorCode ierr;
464 
465   PetscFunctionBegin;
466   if (!npoints) PetscFunctionReturn(0);
467   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
468   if (sp->Nv) PetscValidPointer(points, 3);
469   if (B) PetscValidPointer(B, 4);
470   if (D) PetscValidPointer(D, 5);
471   if (H) PetscValidPointer(H, 6);
472   if (sp->ops->evaluate) {ierr = (*sp->ops->evaluate)(sp, npoints, points, B, D, H);CHKERRQ(ierr);}
473   PetscFunctionReturn(0);
474 }
475 
476 /*@
477   PetscSpaceGetHeightSubspace - Get the subset of the primal space basis that is supported on a mesh point of a given height.
478 
479   If the space is not defined on mesh points of the given height (e.g. if the space is discontinuous and
480   pointwise values are not defined on the element boundaries), or if the implementation of PetscSpace does not
481   support extracting subspaces, then NULL is returned.
482 
483   This does not increment the reference count on the returned space, and the user should not destroy it.
484 
485   Not collective
486 
487   Input Parameters:
488 + sp - the PetscSpace object
489 - height - the height of the mesh point for which the subspace is desired
490 
491   Output Parameter:
492 . subsp - the subspace
493 
494   Level: advanced
495 
496 .seealso: PetscDualSpaceGetHeightSubspace(), PetscSpace
497 @*/
498 PetscErrorCode PetscSpaceGetHeightSubspace(PetscSpace sp, PetscInt height, PetscSpace *subsp)
499 {
500   PetscErrorCode ierr;
501 
502   PetscFunctionBegin;
503   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
504   PetscValidPointer(subsp, 3);
505   *subsp = NULL;
506   if (sp->ops->getheightsubspace) {
507     ierr = (*sp->ops->getheightsubspace)(sp, height, subsp);CHKERRQ(ierr);
508   }
509   PetscFunctionReturn(0);
510 }
511 
512