xref: /petsc/src/dm/dt/space/interface/space.c (revision 55e7fe800d976e85ed2b5cd8bfdef564daa37bd9)
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   sp->dim = PETSC_DETERMINE;
89   ierr = (*r)(sp);CHKERRQ(ierr);
90   ierr = PetscObjectChangeTypeName((PetscObject) sp, name);CHKERRQ(ierr);
91   PetscFunctionReturn(0);
92 }
93 
94 /*@C
95   PetscSpaceGetType - Gets the PetscSpace type name (as a string) from the object.
96 
97   Not Collective
98 
99   Input Parameter:
100 . sp  - The PetscSpace
101 
102   Output Parameter:
103 . name - The PetscSpace type name
104 
105   Level: intermediate
106 
107 .keywords: PetscSpace, get, type, name
108 .seealso: PetscSpaceSetType(), PetscSpaceCreate()
109 @*/
110 PetscErrorCode PetscSpaceGetType(PetscSpace sp, PetscSpaceType *name)
111 {
112   PetscErrorCode ierr;
113 
114   PetscFunctionBegin;
115   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
116   PetscValidPointer(name, 2);
117   if (!PetscSpaceRegisterAllCalled) {
118     ierr = PetscSpaceRegisterAll();CHKERRQ(ierr);
119   }
120   *name = ((PetscObject) sp)->type_name;
121   PetscFunctionReturn(0);
122 }
123 
124 /*@C
125   PetscSpaceView - Views a PetscSpace
126 
127   Collective on PetscSpace
128 
129   Input Parameter:
130 + sp - the PetscSpace object to view
131 - v  - the viewer
132 
133   Level: developer
134 
135 .seealso PetscSpaceDestroy()
136 @*/
137 PetscErrorCode PetscSpaceView(PetscSpace sp, PetscViewer v)
138 {
139   PetscBool      iascii;
140   PetscErrorCode ierr;
141 
142   PetscFunctionBegin;
143   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
144   if (v) PetscValidHeaderSpecific(v, PETSC_VIEWER_CLASSID, 2);
145   if (!v) {ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject) sp), &v);CHKERRQ(ierr);}
146   ierr = PetscObjectPrintClassNamePrefixType((PetscObject)sp,v);CHKERRQ(ierr);
147   ierr = PetscObjectTypeCompare((PetscObject) v, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr);
148   ierr = PetscViewerASCIIPushTab(v);CHKERRQ(ierr);
149   if (iascii) {ierr = PetscViewerASCIIPrintf(v, "Space in %D variables with %D components\n", sp->Nv, sp->Nc);CHKERRQ(ierr);}
150   if (sp->ops->view) {ierr = (*sp->ops->view)(sp, v);CHKERRQ(ierr);}
151   ierr = PetscViewerASCIIPopTab(v);CHKERRQ(ierr);
152   PetscFunctionReturn(0);
153 }
154 
155 /*@
156   PetscSpaceSetFromOptions - sets parameters in a PetscSpace from the options database
157 
158   Collective on PetscSpace
159 
160   Input Parameter:
161 . sp - the PetscSpace object to set options for
162 
163   Options Database:
164 . -petscspace_degree the approximation order of the space
165 
166   Level: developer
167 
168 .seealso PetscSpaceView()
169 @*/
170 PetscErrorCode PetscSpaceSetFromOptions(PetscSpace sp)
171 {
172   const char    *defaultType;
173   char           name[256];
174   PetscBool      flg, orderflg;
175   PetscErrorCode ierr;
176 
177   PetscFunctionBegin;
178   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
179   if (!((PetscObject) sp)->type_name) {
180     defaultType = PETSCSPACEPOLYNOMIAL;
181   } else {
182     defaultType = ((PetscObject) sp)->type_name;
183   }
184   if (!PetscSpaceRegisterAllCalled) {ierr = PetscSpaceRegisterAll();CHKERRQ(ierr);}
185 
186   ierr = PetscObjectOptionsBegin((PetscObject) sp);CHKERRQ(ierr);
187   ierr = PetscOptionsFList("-petscspace_type", "Linear space", "PetscSpaceSetType", PetscSpaceList, defaultType, name, 256, &flg);CHKERRQ(ierr);
188   if (flg) {
189     ierr = PetscSpaceSetType(sp, name);CHKERRQ(ierr);
190   } else if (!((PetscObject) sp)->type_name) {
191     ierr = PetscSpaceSetType(sp, defaultType);CHKERRQ(ierr);
192   }
193   {
194     ierr = PetscOptionsInt("-petscspace_order", "DEPRECATED: The approximation order", "PetscSpaceSetDegree", sp->degree, &sp->degree, &orderflg);CHKERRQ(ierr);
195     if (orderflg) {
196       int compare;
197 
198       ierr = MPI_Comm_compare(PetscObjectComm((PetscObject)sp), PETSC_COMM_WORLD, &compare);CHKERRQ(ierr);
199 
200       if (compare == MPI_IDENT || compare == MPI_CONGRUENT) {
201         ierr = PetscPrintf(PetscObjectComm((PetscObject)sp), "Warning: -petscspace_order is deprecated.  Use -petscspace_degree\n");CHKERRQ(ierr);
202       }
203     }
204   }
205   ierr = PetscOptionsInt("-petscspace_degree", "The (maximally included) polynomial degree", "PetscSpaceSetDegree", sp->degree, &sp->degree, NULL);CHKERRQ(ierr);
206   ierr = PetscOptionsInt("-petscspace_variables", "The number of different variables, e.g. x and y", "PetscSpaceSetNumVariables", sp->Nv, &sp->Nv, NULL);CHKERRQ(ierr);
207   ierr = PetscOptionsInt("-petscspace_components", "The number of components", "PetscSpaceSetNumComponents", sp->Nc, &sp->Nc, NULL);CHKERRQ(ierr);
208   if (sp->ops->setfromoptions) {
209     ierr = (*sp->ops->setfromoptions)(PetscOptionsObject,sp);CHKERRQ(ierr);
210   }
211   /* process any options handlers added with PetscObjectAddOptionsHandler() */
212   ierr = PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject) sp);CHKERRQ(ierr);
213   ierr = PetscOptionsEnd();CHKERRQ(ierr);
214   ierr = PetscSpaceViewFromOptions(sp, NULL, "-petscspace_view");CHKERRQ(ierr);
215   PetscFunctionReturn(0);
216 }
217 
218 /*@C
219   PetscSpaceSetUp - Construct data structures for the PetscSpace
220 
221   Collective on PetscSpace
222 
223   Input Parameter:
224 . sp - the PetscSpace object to setup
225 
226   Level: developer
227 
228 .seealso PetscSpaceView(), PetscSpaceDestroy()
229 @*/
230 PetscErrorCode PetscSpaceSetUp(PetscSpace sp)
231 {
232   PetscErrorCode ierr;
233 
234   PetscFunctionBegin;
235   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
236   if (sp->ops->setup) {ierr = (*sp->ops->setup)(sp);CHKERRQ(ierr);}
237   PetscFunctionReturn(0);
238 }
239 
240 /*@
241   PetscSpaceDestroy - Destroys a PetscSpace object
242 
243   Collective on PetscSpace
244 
245   Input Parameter:
246 . sp - the PetscSpace object to destroy
247 
248   Level: developer
249 
250 .seealso PetscSpaceView()
251 @*/
252 PetscErrorCode PetscSpaceDestroy(PetscSpace *sp)
253 {
254   PetscErrorCode ierr;
255 
256   PetscFunctionBegin;
257   if (!*sp) PetscFunctionReturn(0);
258   PetscValidHeaderSpecific((*sp), PETSCSPACE_CLASSID, 1);
259 
260   if (--((PetscObject)(*sp))->refct > 0) {*sp = 0; PetscFunctionReturn(0);}
261   ((PetscObject) (*sp))->refct = 0;
262   ierr = DMDestroy(&(*sp)->dm);CHKERRQ(ierr);
263 
264   ierr = (*(*sp)->ops->destroy)(*sp);CHKERRQ(ierr);
265   ierr = PetscHeaderDestroy(sp);CHKERRQ(ierr);
266   PetscFunctionReturn(0);
267 }
268 
269 /*@
270   PetscSpaceCreate - Creates an empty PetscSpace object. The type can then be set with PetscSpaceSetType().
271 
272   Collective on MPI_Comm
273 
274   Input Parameter:
275 . comm - The communicator for the PetscSpace object
276 
277   Output Parameter:
278 . sp - The PetscSpace object
279 
280   Level: beginner
281 
282 .seealso: PetscSpaceSetType(), PETSCSPACEPOLYNOMIAL
283 @*/
284 PetscErrorCode PetscSpaceCreate(MPI_Comm comm, PetscSpace *sp)
285 {
286   PetscSpace     s;
287   PetscErrorCode ierr;
288 
289   PetscFunctionBegin;
290   PetscValidPointer(sp, 2);
291   ierr = PetscCitationsRegister(FECitation,&FEcite);CHKERRQ(ierr);
292   *sp  = NULL;
293   ierr = PetscFEInitializePackage();CHKERRQ(ierr);
294 
295   ierr = PetscHeaderCreate(s, PETSCSPACE_CLASSID, "PetscSpace", "Linear Space", "PetscSpace", comm, PetscSpaceDestroy, PetscSpaceView);CHKERRQ(ierr);
296 
297   s->degree    = 0;
298   s->maxDegree = PETSC_DETERMINE;
299   s->Nc        = 1;
300   s->Nv        = 0;
301   s->dim       = PETSC_DETERMINE;
302   ierr = DMShellCreate(comm, &s->dm);CHKERRQ(ierr);
303   ierr = PetscSpaceSetType(s, PETSCSPACEPOLYNOMIAL);CHKERRQ(ierr);
304 
305   *sp = s;
306   PetscFunctionReturn(0);
307 }
308 
309 /*@
310   PetscSpaceGetDimension - Return the dimension of this space, i.e. the number of basis vectors
311 
312   Input Parameter:
313 . sp - The PetscSpace
314 
315   Output Parameter:
316 . dim - The dimension
317 
318   Level: intermediate
319 
320 .seealso: PetscSpaceGetDegree(), PetscSpaceCreate(), PetscSpace
321 @*/
322 PetscErrorCode PetscSpaceGetDimension(PetscSpace sp, PetscInt *dim)
323 {
324   PetscErrorCode ierr;
325 
326   PetscFunctionBegin;
327   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
328   PetscValidPointer(dim, 2);
329   if (sp->dim == PETSC_DETERMINE) {
330     if (sp->ops->getdimension) {ierr = (*sp->ops->getdimension)(sp, &sp->dim);CHKERRQ(ierr);}
331   }
332   *dim = sp->dim;
333   PetscFunctionReturn(0);
334 }
335 
336 /*@
337   PetscSpaceGetDegree - Return the polynomial degrees that characterize this space
338 
339   Input Parameter:
340 . sp - The PetscSpace
341 
342   Output Parameter:
343 + minDegree - The degree of the largest polynomial space contained in the space
344 - maxDegree - The degree of the smallest polynomial space containing the space
345 
346 
347   Level: intermediate
348 
349 .seealso: PetscSpaceSetDegree(), PetscSpaceGetDimension(), PetscSpaceCreate(), PetscSpace
350 @*/
351 PetscErrorCode PetscSpaceGetDegree(PetscSpace sp, PetscInt *minDegree, PetscInt *maxDegree)
352 {
353   PetscFunctionBegin;
354   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
355   if (minDegree) PetscValidPointer(minDegree, 2);
356   if (maxDegree) PetscValidPointer(maxDegree, 3);
357   if (minDegree) *minDegree = sp->degree;
358   if (maxDegree) *maxDegree = sp->maxDegree;
359   PetscFunctionReturn(0);
360 }
361 
362 /*@
363   PetscSpaceSetDegree - Set the degree of approximation for this space.
364 
365   Input Parameters:
366 + sp - The PetscSpace
367 . degree - The degree of the largest polynomial space contained in the space
368 - maxDegree - The degree of the largest polynomial space containing the space.  One of degree and maxDegree can be PETSC_DETERMINE.
369 
370   Level: intermediate
371 
372 .seealso: PetscSpaceGetDegree(), PetscSpaceCreate(), PetscSpace
373 @*/
374 PetscErrorCode PetscSpaceSetDegree(PetscSpace sp, PetscInt degree, PetscInt maxDegree)
375 {
376   PetscFunctionBegin;
377   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
378   sp->degree = degree;
379   sp->maxDegree = maxDegree;
380   PetscFunctionReturn(0);
381 }
382 
383 /*@
384   PetscSpaceGetNumComponents - Return the number of components for this space
385 
386   Input Parameter:
387 . sp - The PetscSpace
388 
389   Output Parameter:
390 . Nc - The number of components
391 
392   Note: A vector space, for example, will have d components, where d is the spatial dimension
393 
394   Level: intermediate
395 
396 .seealso: PetscSpaceSetNumComponents(), PetscSpaceGetDimension(), PetscSpaceCreate(), PetscSpace
397 @*/
398 PetscErrorCode PetscSpaceGetNumComponents(PetscSpace sp, PetscInt *Nc)
399 {
400   PetscFunctionBegin;
401   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
402   PetscValidPointer(Nc, 2);
403   *Nc = sp->Nc;
404   PetscFunctionReturn(0);
405 }
406 
407 /*@
408   PetscSpaceSetNumComponents - Set the number of components for this space
409 
410   Input Parameters:
411 + sp - The PetscSpace
412 - order - The number of components
413 
414   Level: intermediate
415 
416 .seealso: PetscSpaceGetNumComponents(), PetscSpaceCreate(), PetscSpace
417 @*/
418 PetscErrorCode PetscSpaceSetNumComponents(PetscSpace sp, PetscInt Nc)
419 {
420   PetscFunctionBegin;
421   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
422   sp->Nc = Nc;
423   PetscFunctionReturn(0);
424 }
425 
426 PetscErrorCode PetscSpaceSetNumVariables(PetscSpace sp, PetscInt n)
427 {
428   PetscFunctionBegin;
429   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
430   sp->Nv = n;
431   PetscFunctionReturn(0);
432 }
433 
434 PetscErrorCode PetscSpaceGetNumVariables(PetscSpace sp, PetscInt *n)
435 {
436   PetscFunctionBegin;
437   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
438   PetscValidPointer(n, 2);
439   *n = sp->Nv;
440   PetscFunctionReturn(0);
441 }
442 
443 
444 /*@C
445   PetscSpaceEvaluate - Evaluate the basis functions and their derivatives (jet) at each point
446 
447   Input Parameters:
448 + sp      - The PetscSpace
449 . npoints - The number of evaluation points, in reference coordinates
450 - points  - The point coordinates
451 
452   Output Parameters:
453 + B - The function evaluations in a npoints x nfuncs array
454 . D - The derivative evaluations in a npoints x nfuncs x dim array
455 - H - The second derivative evaluations in a npoints x nfuncs x dim x dim array
456 
457   Note: Above nfuncs is the dimension of the space, and dim is the spatial dimension. The coordinates are given
458   on the reference cell, not in real space.
459 
460   Level: advanced
461 
462 .seealso: PetscFEGetTabulation(), PetscFEGetDefaultTabulation(), PetscSpaceCreate()
463 @*/
464 PetscErrorCode PetscSpaceEvaluate(PetscSpace sp, PetscInt npoints, const PetscReal points[], PetscReal B[], PetscReal D[], PetscReal H[])
465 {
466   PetscErrorCode ierr;
467 
468   PetscFunctionBegin;
469   if (!npoints) PetscFunctionReturn(0);
470   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
471   if (sp->Nv) PetscValidPointer(points, 3);
472   if (B) PetscValidPointer(B, 4);
473   if (D) PetscValidPointer(D, 5);
474   if (H) PetscValidPointer(H, 6);
475   if (sp->ops->evaluate) {ierr = (*sp->ops->evaluate)(sp, npoints, points, B, D, H);CHKERRQ(ierr);}
476   PetscFunctionReturn(0);
477 }
478 
479 /*@
480   PetscSpaceGetHeightSubspace - Get the subset of the primal space basis that is supported on a mesh point of a given height.
481 
482   If the space is not defined on mesh points of the given height (e.g. if the space is discontinuous and
483   pointwise values are not defined on the element boundaries), or if the implementation of PetscSpace does not
484   support extracting subspaces, then NULL is returned.
485 
486   This does not increment the reference count on the returned space, and the user should not destroy it.
487 
488   Not collective
489 
490   Input Parameters:
491 + sp - the PetscSpace object
492 - height - the height of the mesh point for which the subspace is desired
493 
494   Output Parameter:
495 . subsp - the subspace
496 
497   Level: advanced
498 
499 .seealso: PetscDualSpaceGetHeightSubspace(), PetscSpace
500 @*/
501 PetscErrorCode PetscSpaceGetHeightSubspace(PetscSpace sp, PetscInt height, PetscSpace *subsp)
502 {
503   PetscErrorCode ierr;
504 
505   PetscFunctionBegin;
506   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
507   PetscValidPointer(subsp, 3);
508   *subsp = NULL;
509   if (sp->ops->getheightsubspace) {
510     ierr = (*sp->ops->getheightsubspace)(sp, height, subsp);CHKERRQ(ierr);
511   }
512   PetscFunctionReturn(0);
513 }
514 
515