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