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