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