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