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, No Fortran Support
13
14 Input Parameters:
15 + sname - The name of a new user-defined creation routine
16 - function - The creation routine for the implementation type
17
18 Example Usage:
19 .vb
20 PetscSpaceRegister("my_space", MyPetscSpaceCreate);
21 .ve
22
23 Then, your PetscSpace type can be chosen with the procedural interface via
24 .vb
25 PetscSpaceCreate(MPI_Comm, PetscSpace *);
26 PetscSpaceSetType(PetscSpace, "my_space");
27 .ve
28 or at runtime via the option
29 .vb
30 -petscspace_type my_space
31 .ve
32
33 Level: advanced
34
35 Note:
36 `PetscSpaceRegister()` may be called multiple times to add several user-defined types of `PetscSpace`. The creation function is called
37 when the type is set to 'name'.
38
39 .seealso: `PetscSpace`, `PetscSpaceRegisterAll()`, `PetscSpaceRegisterDestroy()`
40 @*/
PetscSpaceRegister(const char sname[],PetscErrorCode (* function)(PetscSpace))41 PetscErrorCode PetscSpaceRegister(const char sname[], PetscErrorCode (*function)(PetscSpace))
42 {
43 PetscFunctionBegin;
44 PetscCall(PetscFunctionListAdd(&PetscSpaceList, sname, function));
45 PetscFunctionReturn(PETSC_SUCCESS);
46 }
47
48 /*@
49 PetscSpaceSetType - Builds a particular `PetscSpace`
50
51 Collective
52
53 Input Parameters:
54 + sp - The `PetscSpace` object
55 - name - The kind of space
56
57 Options Database Key:
58 . -petscspace_type <type> - Sets the `PetscSpace` type; use -help for a list of available types
59
60 Level: intermediate
61
62 .seealso: `PetscSpace`, `PetscSpaceType`, `PetscSpaceGetType()`, `PetscSpaceCreate()`
63 @*/
PetscSpaceSetType(PetscSpace sp,PetscSpaceType name)64 PetscErrorCode PetscSpaceSetType(PetscSpace sp, PetscSpaceType name)
65 {
66 PetscErrorCode (*r)(PetscSpace);
67 PetscBool match;
68
69 PetscFunctionBegin;
70 PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
71 PetscCall(PetscObjectTypeCompare((PetscObject)sp, name, &match));
72 if (match) PetscFunctionReturn(PETSC_SUCCESS);
73
74 PetscCall(PetscSpaceRegisterAll());
75 PetscCall(PetscFunctionListFind(PetscSpaceList, name, &r));
76 PetscCheck(r, PetscObjectComm((PetscObject)sp), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown PetscSpace type: %s", name);
77
78 PetscTryTypeMethod(sp, destroy);
79 sp->ops->destroy = NULL;
80
81 sp->dim = PETSC_DETERMINE;
82 PetscCall((*r)(sp));
83 PetscCall(PetscObjectChangeTypeName((PetscObject)sp, name));
84 PetscFunctionReturn(PETSC_SUCCESS);
85 }
86
87 /*@
88 PetscSpaceGetType - Gets the `PetscSpaceType` (as a string) from the object.
89
90 Not Collective
91
92 Input Parameter:
93 . sp - The `PetscSpace`
94
95 Output Parameter:
96 . name - The `PetscSpace` type name
97
98 Level: intermediate
99
100 .seealso: `PetscSpaceType`, `PetscSpace`, `PetscSpaceSetType()`, `PetscSpaceCreate()`
101 @*/
PetscSpaceGetType(PetscSpace sp,PetscSpaceType * name)102 PetscErrorCode PetscSpaceGetType(PetscSpace sp, PetscSpaceType *name)
103 {
104 PetscFunctionBegin;
105 PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
106 PetscAssertPointer(name, 2);
107 if (!PetscSpaceRegisterAllCalled) PetscCall(PetscSpaceRegisterAll());
108 *name = ((PetscObject)sp)->type_name;
109 PetscFunctionReturn(PETSC_SUCCESS);
110 }
111
112 /*@
113 PetscSpaceViewFromOptions - View a `PetscSpace` based on values in the options database
114
115 Collective
116
117 Input Parameters:
118 + A - the `PetscSpace` object
119 . obj - Optional object that provides the options name prefix
120 - name - command line option name
121
122 Level: intermediate
123
124 .seealso: `PetscSpace`, `PetscSpaceView()`, `PetscObjectViewFromOptions()`, `PetscSpaceCreate()`
125 @*/
PetscSpaceViewFromOptions(PetscSpace A,PetscObject obj,const char name[])126 PetscErrorCode PetscSpaceViewFromOptions(PetscSpace A, PetscObject obj, const char name[])
127 {
128 PetscFunctionBegin;
129 PetscValidHeaderSpecific(A, PETSCSPACE_CLASSID, 1);
130 PetscCall(PetscObjectViewFromOptions((PetscObject)A, obj, name));
131 PetscFunctionReturn(PETSC_SUCCESS);
132 }
133
134 /*@
135 PetscSpaceView - Views a `PetscSpace`
136
137 Collective
138
139 Input Parameters:
140 + sp - the `PetscSpace` object to view
141 - v - the viewer
142
143 Level: beginner
144
145 .seealso: `PetscSpace`, `PetscViewer`, `PetscSpaceViewFromOptions()`, `PetscSpaceDestroy()`
146 @*/
PetscSpaceView(PetscSpace sp,PetscViewer v)147 PetscErrorCode PetscSpaceView(PetscSpace sp, PetscViewer v)
148 {
149 PetscInt pdim;
150 PetscBool isascii;
151
152 PetscFunctionBegin;
153 PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
154 if (v) PetscValidHeaderSpecific(v, PETSC_VIEWER_CLASSID, 2);
155 if (!v) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)sp), &v));
156 PetscCall(PetscSpaceGetDimension(sp, &pdim));
157 PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)sp, v));
158 PetscCall(PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERASCII, &isascii));
159 PetscCall(PetscViewerASCIIPushTab(v));
160 if (isascii) PetscCall(PetscViewerASCIIPrintf(v, "Space in %" PetscInt_FMT " variables with %" PetscInt_FMT " components, size %" PetscInt_FMT "\n", sp->Nv, sp->Nc, pdim));
161 PetscTryTypeMethod(sp, view, v);
162 PetscCall(PetscViewerASCIIPopTab(v));
163 PetscFunctionReturn(PETSC_SUCCESS);
164 }
165
166 /*@
167 PetscSpaceSetFromOptions - sets parameters in a `PetscSpace` from the options database
168
169 Collective
170
171 Input Parameter:
172 . sp - the `PetscSpace` object to set options for
173
174 Options Database Keys:
175 + -petscspace_degree <deg> - the approximation order of the space
176 . -petscspace_variables <n> - the number of different variables, e.g. x and y
177 - -petscspace_components <c> - the number of components, say d for a vector field
178
179 Level: intermediate
180
181 .seealso: `PetscSpace`, `PetscSpaceView()`
182 @*/
PetscSpaceSetFromOptions(PetscSpace sp)183 PetscErrorCode PetscSpaceSetFromOptions(PetscSpace sp)
184 {
185 const char *defaultType;
186 char name[256];
187 PetscBool flg;
188
189 PetscFunctionBegin;
190 PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
191 if (!((PetscObject)sp)->type_name) {
192 defaultType = PETSCSPACEPOLYNOMIAL;
193 } else {
194 defaultType = ((PetscObject)sp)->type_name;
195 }
196 if (!PetscSpaceRegisterAllCalled) PetscCall(PetscSpaceRegisterAll());
197
198 PetscObjectOptionsBegin((PetscObject)sp);
199 PetscCall(PetscOptionsFList("-petscspace_type", "Linear space", "PetscSpaceSetType", PetscSpaceList, defaultType, name, 256, &flg));
200 if (flg) {
201 PetscCall(PetscSpaceSetType(sp, name));
202 } else if (!((PetscObject)sp)->type_name) {
203 PetscCall(PetscSpaceSetType(sp, defaultType));
204 }
205 {
206 PetscCall(PetscOptionsDeprecated("-petscspace_order", "-petscspace_degree", "3.11", NULL));
207 }
208 PetscCall(PetscOptionsBoundedInt("-petscspace_degree", "The (maximally included) polynomial degree", "PetscSpaceSetDegree", sp->degree, &sp->degree, NULL, 0));
209 PetscCall(PetscOptionsBoundedInt("-petscspace_variables", "The number of different variables, e.g. x and y", "PetscSpaceSetNumVariables", sp->Nv, &sp->Nv, NULL, 0));
210 PetscCall(PetscOptionsBoundedInt("-petscspace_components", "The number of components", "PetscSpaceSetNumComponents", sp->Nc, &sp->Nc, NULL, -1));
211 PetscTryTypeMethod(sp, setfromoptions, PetscOptionsObject);
212 /* process any options handlers added with PetscObjectAddOptionsHandler() */
213 PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)sp, PetscOptionsObject));
214 PetscOptionsEnd();
215 PetscCall(PetscSpaceViewFromOptions(sp, NULL, "-petscspace_view"));
216 PetscFunctionReturn(PETSC_SUCCESS);
217 }
218
219 /*@
220 PetscSpaceSetUp - Construct data structures for the `PetscSpace`
221
222 Collective
223
224 Input Parameter:
225 . sp - the `PetscSpace` object to setup
226
227 Level: intermediate
228
229 .seealso: `PetscSpace`, `PetscSpaceView()`, `PetscSpaceDestroy()`
230 @*/
PetscSpaceSetUp(PetscSpace sp)231 PetscErrorCode PetscSpaceSetUp(PetscSpace sp)
232 {
233 PetscFunctionBegin;
234 PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
235 PetscTryTypeMethod(sp, setup);
236 PetscFunctionReturn(PETSC_SUCCESS);
237 }
238
239 /*@
240 PetscSpaceDestroy - Destroys a `PetscSpace` object
241
242 Collective
243
244 Input Parameter:
245 . sp - the `PetscSpace` object to destroy
246
247 Level: beginner
248
249 .seealso: `PetscSpace`, `PetscSpaceCreate()`
250 @*/
PetscSpaceDestroy(PetscSpace * sp)251 PetscErrorCode PetscSpaceDestroy(PetscSpace *sp)
252 {
253 PetscFunctionBegin;
254 if (!*sp) PetscFunctionReturn(PETSC_SUCCESS);
255 PetscValidHeaderSpecific(*sp, PETSCSPACE_CLASSID, 1);
256
257 if (--((PetscObject)*sp)->refct > 0) {
258 *sp = NULL;
259 PetscFunctionReturn(PETSC_SUCCESS);
260 }
261 ((PetscObject)*sp)->refct = 0;
262 PetscCall(DMDestroy(&(*sp)->dm));
263
264 PetscUseTypeMethod(*sp, destroy);
265 PetscCall(PetscHeaderDestroy(sp));
266 PetscFunctionReturn(PETSC_SUCCESS);
267 }
268
269 /*@
270 PetscSpaceCreate - Creates an empty `PetscSpace` object. The type can then be set with `PetscSpaceSetType()`.
271
272 Collective
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: `PetscSpace`, `PetscSpaceSetType()`, `PETSCSPACEPOLYNOMIAL`
283 @*/
PetscSpaceCreate(MPI_Comm comm,PetscSpace * sp)284 PetscErrorCode PetscSpaceCreate(MPI_Comm comm, PetscSpace *sp)
285 {
286 PetscSpace s;
287
288 PetscFunctionBegin;
289 PetscAssertPointer(sp, 2);
290 PetscCall(PetscCitationsRegister(FECitation, &FEcite));
291 PetscCall(PetscFEInitializePackage());
292
293 PetscCall(PetscHeaderCreate(s, PETSCSPACE_CLASSID, "PetscSpace", "Linear Space", "PetscSpace", comm, PetscSpaceDestroy, PetscSpaceView));
294 s->degree = 0;
295 s->maxDegree = PETSC_DETERMINE;
296 s->Nc = 1;
297 s->Nv = 0;
298 s->dim = PETSC_DETERMINE;
299 PetscCall(DMShellCreate(comm, &s->dm));
300 PetscCall(PetscSpaceSetType(s, PETSCSPACEPOLYNOMIAL));
301
302 *sp = s;
303 PetscFunctionReturn(PETSC_SUCCESS);
304 }
305
306 /*@
307 PetscSpaceGetDimension - Return the dimension of this space, i.e. the number of basis vectors
308
309 Input Parameter:
310 . sp - The `PetscSpace`
311
312 Output Parameter:
313 . dim - The dimension
314
315 Level: intermediate
316
317 .seealso: `PetscSpace`, `PetscSpaceGetDegree()`, `PetscSpaceCreate()`
318 @*/
PetscSpaceGetDimension(PetscSpace sp,PetscInt * dim)319 PetscErrorCode PetscSpaceGetDimension(PetscSpace sp, PetscInt *dim)
320 {
321 PetscFunctionBegin;
322 PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
323 PetscAssertPointer(dim, 2);
324 if (sp->dim == PETSC_DETERMINE) PetscTryTypeMethod(sp, getdimension, &sp->dim);
325 *dim = sp->dim;
326 PetscFunctionReturn(PETSC_SUCCESS);
327 }
328
329 /*@
330 PetscSpaceGetDegree - Return the polynomial degrees that characterize this space
331
332 Input Parameter:
333 . sp - The `PetscSpace`
334
335 Output Parameters:
336 + minDegree - The degree of the largest polynomial space contained in the space, pass `NULL` if not needed
337 - maxDegree - The degree of the smallest polynomial space containing the space, pass `NULL` if not needed
338
339 Level: intermediate
340
341 .seealso: `PetscSpace`, `PetscSpaceSetDegree()`, `PetscSpaceGetDimension()`, `PetscSpaceCreate()`
342 @*/
PetscSpaceGetDegree(PetscSpace sp,PeOp PetscInt * minDegree,PeOp PetscInt * maxDegree)343 PetscErrorCode PetscSpaceGetDegree(PetscSpace sp, PeOp PetscInt *minDegree, PeOp PetscInt *maxDegree)
344 {
345 PetscFunctionBegin;
346 PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
347 if (minDegree) PetscAssertPointer(minDegree, 2);
348 if (maxDegree) PetscAssertPointer(maxDegree, 3);
349 if (minDegree) *minDegree = sp->degree;
350 if (maxDegree) *maxDegree = sp->maxDegree;
351 PetscFunctionReturn(PETSC_SUCCESS);
352 }
353
354 /*@
355 PetscSpaceSetDegree - Set the degree of approximation for this space.
356
357 Input Parameters:
358 + sp - The `PetscSpace`
359 . degree - The degree of the largest polynomial space contained in the space
360 - maxDegree - The degree of the largest polynomial space containing the space. One of degree and maxDegree can be `PETSC_DETERMINE`.
361
362 Level: intermediate
363
364 .seealso: `PetscSpace`, `PetscSpaceGetDegree()`, `PetscSpaceCreate()`
365 @*/
PetscSpaceSetDegree(PetscSpace sp,PetscInt degree,PetscInt maxDegree)366 PetscErrorCode PetscSpaceSetDegree(PetscSpace sp, PetscInt degree, PetscInt maxDegree)
367 {
368 PetscFunctionBegin;
369 PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
370 sp->degree = degree;
371 sp->maxDegree = maxDegree;
372 PetscFunctionReturn(PETSC_SUCCESS);
373 }
374
375 /*@
376 PetscSpaceGetNumComponents - Return the number of components for this space
377
378 Input Parameter:
379 . sp - The `PetscSpace`
380
381 Output Parameter:
382 . Nc - The number of components
383
384 Level: intermediate
385
386 Note:
387 A vector space, for example, will have d components, where d is the spatial dimension
388
389 .seealso: `PetscSpace`, `PetscSpaceSetNumComponents()`, `PetscSpaceGetNumVariables()`, `PetscSpaceGetDimension()`, `PetscSpaceCreate()`
390 @*/
PetscSpaceGetNumComponents(PetscSpace sp,PetscInt * Nc)391 PetscErrorCode PetscSpaceGetNumComponents(PetscSpace sp, PetscInt *Nc)
392 {
393 PetscFunctionBegin;
394 PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
395 PetscAssertPointer(Nc, 2);
396 *Nc = sp->Nc;
397 PetscFunctionReturn(PETSC_SUCCESS);
398 }
399
400 /*@
401 PetscSpaceSetNumComponents - Set the number of components for this space
402
403 Input Parameters:
404 + sp - The `PetscSpace`
405 - Nc - The number of components
406
407 Level: intermediate
408
409 .seealso: `PetscSpace`, `PetscSpaceGetNumComponents()`, `PetscSpaceSetNumVariables()`, `PetscSpaceCreate()`
410 @*/
PetscSpaceSetNumComponents(PetscSpace sp,PetscInt Nc)411 PetscErrorCode PetscSpaceSetNumComponents(PetscSpace sp, PetscInt Nc)
412 {
413 PetscFunctionBegin;
414 PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
415 sp->Nc = Nc;
416 PetscFunctionReturn(PETSC_SUCCESS);
417 }
418
419 /*@
420 PetscSpaceSetNumVariables - Set the number of variables for this space
421
422 Input Parameters:
423 + sp - The `PetscSpace`
424 - n - The number of variables, e.g. x, y, z...
425
426 Level: intermediate
427
428 .seealso: `PetscSpace`, `PetscSpaceGetNumVariables()`, `PetscSpaceSetNumComponents()`, `PetscSpaceCreate()`
429 @*/
PetscSpaceSetNumVariables(PetscSpace sp,PetscInt n)430 PetscErrorCode PetscSpaceSetNumVariables(PetscSpace sp, PetscInt n)
431 {
432 PetscFunctionBegin;
433 PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
434 sp->Nv = n;
435 PetscFunctionReturn(PETSC_SUCCESS);
436 }
437
438 /*@
439 PetscSpaceGetNumVariables - Return the number of variables for this space
440
441 Input Parameter:
442 . sp - The `PetscSpace`
443
444 Output Parameter:
445 . n - The number of variables, e.g. x, y, z...
446
447 Level: intermediate
448
449 .seealso: `PetscSpace`, `PetscSpaceSetNumVariables()`, `PetscSpaceGetNumComponents()`, `PetscSpaceGetDimension()`, `PetscSpaceCreate()`
450 @*/
PetscSpaceGetNumVariables(PetscSpace sp,PetscInt * n)451 PetscErrorCode PetscSpaceGetNumVariables(PetscSpace sp, PetscInt *n)
452 {
453 PetscFunctionBegin;
454 PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
455 PetscAssertPointer(n, 2);
456 *n = sp->Nv;
457 PetscFunctionReturn(PETSC_SUCCESS);
458 }
459
460 /*@
461 PetscSpaceEvaluate - Evaluate the basis functions and their derivatives (jet) at each point
462
463 Input Parameters:
464 + sp - The `PetscSpace`
465 . npoints - The number of evaluation points, in reference coordinates
466 - points - The point coordinates
467
468 Output Parameters:
469 + B - The function evaluations in a `npoints` x `nfuncs` array
470 . D - The derivative evaluations in a `npoints` x `nfuncs` x `dim` array
471 - H - The second derivative evaluations in a `npoints` x `nfuncs` x `dim` x `dim` array
472
473 Level: beginner
474
475 Note:
476 Above `nfuncs` is the dimension of the space, and `dim` is the spatial dimension. The coordinates are given
477 on the reference cell, not in real space.
478
479 .seealso: `PetscSpace`, `PetscFECreateTabulation()`, `PetscFEGetCellTabulation()`, `PetscSpaceCreate()`
480 @*/
PetscSpaceEvaluate(PetscSpace sp,PetscInt npoints,const PetscReal points[],PeOp PetscReal B[],PeOp PetscReal D[],PeOp PetscReal H[])481 PetscErrorCode PetscSpaceEvaluate(PetscSpace sp, PetscInt npoints, const PetscReal points[], PeOp PetscReal B[], PeOp PetscReal D[], PeOp PetscReal H[])
482 {
483 PetscFunctionBegin;
484 if (!npoints) PetscFunctionReturn(PETSC_SUCCESS);
485 PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
486 if (sp->Nv) PetscAssertPointer(points, 3);
487 if (B) PetscAssertPointer(B, 4);
488 if (D) PetscAssertPointer(D, 5);
489 if (H) PetscAssertPointer(H, 6);
490 PetscTryTypeMethod(sp, evaluate, npoints, points, B, D, H);
491 PetscFunctionReturn(PETSC_SUCCESS);
492 }
493
494 /*@
495 PetscSpaceGetHeightSubspace - Get the subset of the primal space basis that is supported on a mesh point of a given height.
496
497 Not Collective
498
499 Input Parameters:
500 + sp - the `PetscSpace` object
501 - height - the height of the mesh point for which the subspace is desired
502
503 Output Parameter:
504 . subsp - the subspace
505
506 Level: advanced
507
508 Notes:
509 If the space is not defined on mesh points of the given height (e.g. if the space is discontinuous and
510 pointwise values are not defined on the element boundaries), or if the implementation of `PetscSpace` does not
511 support extracting subspaces, then NULL is returned.
512
513 This does not increment the reference count on the returned space, and the user should not destroy it.
514
515 .seealso: `PetscDualSpaceGetHeightSubspace()`, `PetscSpace`
516 @*/
PetscSpaceGetHeightSubspace(PetscSpace sp,PetscInt height,PetscSpace * subsp)517 PetscErrorCode PetscSpaceGetHeightSubspace(PetscSpace sp, PetscInt height, PetscSpace *subsp)
518 {
519 PetscFunctionBegin;
520 PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1);
521 PetscAssertPointer(subsp, 3);
522 *subsp = NULL;
523 PetscTryTypeMethod(sp, getheightsubspace, height, subsp);
524 PetscFunctionReturn(PETSC_SUCCESS);
525 }
526