xref: /petsc/src/dm/dt/space/interface/space.c (revision bfcb38ea38335faa6e7f8d97f6bc6ce9aa2a1dd1)
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 .seealso: PetscSpaceRegisterAll(), PetscSpaceRegisterDestroy()
40 
41 @*/
42 PetscErrorCode PetscSpaceRegister(const char sname[], PetscErrorCode (*function)(PetscSpace))
43 {
44   PetscErrorCode ierr;
45 
46   PetscFunctionBegin;
47   ierr = PetscFunctionListAdd(&PetscSpaceList, sname, function);CHKERRQ(ierr);
48   PetscFunctionReturn(0);
49 }
50 
51 /*@C
52   PetscSpaceSetType - Builds a particular PetscSpace
53 
54   Collective on PetscSpace
55 
56   Input Parameters:
57 + sp   - The PetscSpace object
58 - name - The kind of space
59 
60   Options Database Key:
61 . -petscspace_type <type> - Sets the PetscSpace type; use -help for a list of available types
62 
63   Level: intermediate
64 
65 .seealso: PetscSpaceGetType(), PetscSpaceCreate()
66 @*/
67 PetscErrorCode PetscSpaceSetType(PetscSpace sp, PetscSpaceType name)
68 {
69   PetscErrorCode (*r)(PetscSpace);
70   PetscBool      match;
71   PetscErrorCode ierr;
72 
73   PetscFunctionBegin;
74   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
75   ierr = PetscObjectTypeCompare((PetscObject) sp, name, &match);CHKERRQ(ierr);
76   if (match) PetscFunctionReturn(0);
77 
78   ierr = PetscSpaceRegisterAll();CHKERRQ(ierr);
79   ierr = PetscFunctionListFind(PetscSpaceList, name, &r);CHKERRQ(ierr);
80   if (!r) SETERRQ1(PetscObjectComm((PetscObject) sp), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown PetscSpace type: %s", name);
81 
82   if (sp->ops->destroy) {
83     ierr             = (*sp->ops->destroy)(sp);CHKERRQ(ierr);
84     sp->ops->destroy = NULL;
85   }
86   sp->dim = PETSC_DETERMINE;
87   ierr = (*r)(sp);CHKERRQ(ierr);
88   ierr = PetscObjectChangeTypeName((PetscObject) sp, name);CHKERRQ(ierr);
89   PetscFunctionReturn(0);
90 }
91 
92 /*@C
93   PetscSpaceGetType - Gets the PetscSpace type name (as a string) from the object.
94 
95   Not Collective
96 
97   Input Parameter:
98 . sp  - The PetscSpace
99 
100   Output Parameter:
101 . name - The PetscSpace type name
102 
103   Level: intermediate
104 
105 .seealso: PetscSpaceSetType(), PetscSpaceCreate()
106 @*/
107 PetscErrorCode PetscSpaceGetType(PetscSpace sp, PetscSpaceType *name)
108 {
109   PetscErrorCode ierr;
110 
111   PetscFunctionBegin;
112   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
113   PetscValidPointer(name, 2);
114   if (!PetscSpaceRegisterAllCalled) {
115     ierr = PetscSpaceRegisterAll();CHKERRQ(ierr);
116   }
117   *name = ((PetscObject) sp)->type_name;
118   PetscFunctionReturn(0);
119 }
120 
121 /*@C
122   PetscSpaceView - Views a PetscSpace
123 
124   Collective on PetscSpace
125 
126   Input Parameter:
127 + sp - the PetscSpace object to view
128 - v  - the viewer
129 
130   Level: developer
131 
132 .seealso PetscSpaceDestroy()
133 @*/
134 PetscErrorCode PetscSpaceView(PetscSpace sp, PetscViewer v)
135 {
136   PetscInt       pdim;
137   PetscBool      iascii;
138   PetscErrorCode ierr;
139 
140   PetscFunctionBegin;
141   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
142   if (v) PetscValidHeaderSpecific(v, PETSC_VIEWER_CLASSID, 2);
143   if (!v) {ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject) sp), &v);CHKERRQ(ierr);}
144   ierr = PetscSpaceGetDimension(sp, &pdim);CHKERRQ(ierr);
145   ierr = PetscObjectPrintClassNamePrefixType((PetscObject)sp,v);CHKERRQ(ierr);
146   ierr = PetscObjectTypeCompare((PetscObject) v, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr);
147   ierr = PetscViewerASCIIPushTab(v);CHKERRQ(ierr);
148   if (iascii) {ierr = PetscViewerASCIIPrintf(v, "Space in %D variables with %D components, size %D\n", sp->Nv, sp->Nc, pdim);CHKERRQ(ierr);}
149   if (sp->ops->view) {ierr = (*sp->ops->view)(sp, v);CHKERRQ(ierr);}
150   ierr = PetscViewerASCIIPopTab(v);CHKERRQ(ierr);
151   PetscFunctionReturn(0);
152 }
153 
154 /*@
155   PetscSpaceSetFromOptions - sets parameters in a PetscSpace from the options database
156 
157   Collective on PetscSpace
158 
159   Input Parameter:
160 . sp - the PetscSpace object to set options for
161 
162   Options Database:
163 . -petscspace_degree the approximation order of the space
164 
165   Level: developer
166 
167 .seealso PetscSpaceView()
168 @*/
169 PetscErrorCode PetscSpaceSetFromOptions(PetscSpace sp)
170 {
171   const char    *defaultType;
172   char           name[256];
173   PetscBool      flg, orderflg;
174   PetscErrorCode ierr;
175 
176   PetscFunctionBegin;
177   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
178   if (!((PetscObject) sp)->type_name) {
179     defaultType = PETSCSPACEPOLYNOMIAL;
180   } else {
181     defaultType = ((PetscObject) sp)->type_name;
182   }
183   if (!PetscSpaceRegisterAllCalled) {ierr = PetscSpaceRegisterAll();CHKERRQ(ierr);}
184 
185   ierr = PetscObjectOptionsBegin((PetscObject) sp);CHKERRQ(ierr);
186   ierr = PetscOptionsFList("-petscspace_type", "Linear space", "PetscSpaceSetType", PetscSpaceList, defaultType, name, 256, &flg);CHKERRQ(ierr);
187   if (flg) {
188     ierr = PetscSpaceSetType(sp, name);CHKERRQ(ierr);
189   } else if (!((PetscObject) sp)->type_name) {
190     ierr = PetscSpaceSetType(sp, defaultType);CHKERRQ(ierr);
191   }
192   {
193     ierr = PetscOptionsInt("-petscspace_order", "DEPRECATED: The approximation order", "PetscSpaceSetDegree", sp->degree, &sp->degree, &orderflg);CHKERRQ(ierr);
194     if (orderflg) {
195       int compare;
196 
197       ierr = MPI_Comm_compare(PetscObjectComm((PetscObject)sp), PETSC_COMM_WORLD, &compare);CHKERRQ(ierr);
198 
199       if (compare == MPI_IDENT || compare == MPI_CONGRUENT) {
200         ierr = PetscPrintf(PetscObjectComm((PetscObject)sp), "Warning: -petscspace_order is deprecated.  Use -petscspace_degree\n");CHKERRQ(ierr);
201       }
202     }
203   }
204   ierr = PetscOptionsInt("-petscspace_degree", "The (maximally included) polynomial degree", "PetscSpaceSetDegree", sp->degree, &sp->degree, NULL);CHKERRQ(ierr);
205   ierr = PetscOptionsInt("-petscspace_variables", "The number of different variables, e.g. x and y", "PetscSpaceSetNumVariables", sp->Nv, &sp->Nv, NULL);CHKERRQ(ierr);
206   ierr = PetscOptionsInt("-petscspace_components", "The number of components", "PetscSpaceSetNumComponents", sp->Nc, &sp->Nc, NULL);CHKERRQ(ierr);
207   if (sp->ops->setfromoptions) {
208     ierr = (*sp->ops->setfromoptions)(PetscOptionsObject,sp);CHKERRQ(ierr);
209   }
210   /* process any options handlers added with PetscObjectAddOptionsHandler() */
211   ierr = PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject) sp);CHKERRQ(ierr);
212   ierr = PetscOptionsEnd();CHKERRQ(ierr);
213   ierr = PetscSpaceViewFromOptions(sp, NULL, "-petscspace_view");CHKERRQ(ierr);
214   PetscFunctionReturn(0);
215 }
216 
217 /*@C
218   PetscSpaceSetUp - Construct data structures for the PetscSpace
219 
220   Collective on PetscSpace
221 
222   Input Parameter:
223 . sp - the PetscSpace object to setup
224 
225   Level: developer
226 
227 .seealso PetscSpaceView(), PetscSpaceDestroy()
228 @*/
229 PetscErrorCode PetscSpaceSetUp(PetscSpace sp)
230 {
231   PetscErrorCode ierr;
232 
233   PetscFunctionBegin;
234   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
235   if (sp->ops->setup) {ierr = (*sp->ops->setup)(sp);CHKERRQ(ierr);}
236   PetscFunctionReturn(0);
237 }
238 
239 /*@
240   PetscSpaceDestroy - Destroys a PetscSpace object
241 
242   Collective on PetscSpace
243 
244   Input Parameter:
245 . sp - the PetscSpace object to destroy
246 
247   Level: developer
248 
249 .seealso PetscSpaceView()
250 @*/
251 PetscErrorCode PetscSpaceDestroy(PetscSpace *sp)
252 {
253   PetscErrorCode ierr;
254 
255   PetscFunctionBegin;
256   if (!*sp) PetscFunctionReturn(0);
257   PetscValidHeaderSpecific((*sp), PETSCSPACE_CLASSID, 1);
258 
259   if (--((PetscObject)(*sp))->refct > 0) {*sp = 0; PetscFunctionReturn(0);}
260   ((PetscObject) (*sp))->refct = 0;
261   ierr = DMDestroy(&(*sp)->dm);CHKERRQ(ierr);
262 
263   ierr = (*(*sp)->ops->destroy)(*sp);CHKERRQ(ierr);
264   ierr = PetscHeaderDestroy(sp);CHKERRQ(ierr);
265   PetscFunctionReturn(0);
266 }
267 
268 /*@
269   PetscSpaceCreate - Creates an empty PetscSpace object. The type can then be set with PetscSpaceSetType().
270 
271   Collective on MPI_Comm
272 
273   Input Parameter:
274 . comm - The communicator for the PetscSpace object
275 
276   Output Parameter:
277 . sp - The PetscSpace object
278 
279   Level: beginner
280 
281 .seealso: PetscSpaceSetType(), PETSCSPACEPOLYNOMIAL
282 @*/
283 PetscErrorCode PetscSpaceCreate(MPI_Comm comm, PetscSpace *sp)
284 {
285   PetscSpace     s;
286   PetscErrorCode ierr;
287 
288   PetscFunctionBegin;
289   PetscValidPointer(sp, 2);
290   ierr = PetscCitationsRegister(FECitation,&FEcite);CHKERRQ(ierr);
291   *sp  = NULL;
292   ierr = PetscFEInitializePackage();CHKERRQ(ierr);
293 
294   ierr = PetscHeaderCreate(s, PETSCSPACE_CLASSID, "PetscSpace", "Linear Space", "PetscSpace", comm, PetscSpaceDestroy, PetscSpaceView);CHKERRQ(ierr);
295 
296   s->degree    = 0;
297   s->maxDegree = PETSC_DETERMINE;
298   s->Nc        = 1;
299   s->Nv        = 0;
300   s->dim       = PETSC_DETERMINE;
301   ierr = DMShellCreate(comm, &s->dm);CHKERRQ(ierr);
302   ierr = PetscSpaceSetType(s, PETSCSPACEPOLYNOMIAL);CHKERRQ(ierr);
303 
304   *sp = s;
305   PetscFunctionReturn(0);
306 }
307 
308 /*@
309   PetscSpaceGetDimension - Return the dimension of this space, i.e. the number of basis vectors
310 
311   Input Parameter:
312 . sp - The PetscSpace
313 
314   Output Parameter:
315 . dim - The dimension
316 
317   Level: intermediate
318 
319 .seealso: PetscSpaceGetDegree(), PetscSpaceCreate(), PetscSpace
320 @*/
321 PetscErrorCode PetscSpaceGetDimension(PetscSpace sp, PetscInt *dim)
322 {
323   PetscErrorCode ierr;
324 
325   PetscFunctionBegin;
326   PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
327   PetscValidPointer(dim, 2);
328   if (sp->dim == PETSC_DETERMINE) {
329     if (sp->ops->getdimension) {ierr = (*sp->ops->getdimension)(sp, &sp->dim);CHKERRQ(ierr);}
330   }
331   *dim = sp->dim;
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