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 PetscFunctionBegin; 44 PetscCall(PetscFunctionListAdd(&PetscSpaceList, sname, function)); 45 PetscFunctionReturn(0); 46 } 47 48 /*@C 49 PetscSpaceSetType - Builds a particular PetscSpace 50 51 Collective on sp 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: `PetscSpaceGetType()`, `PetscSpaceCreate()` 63 @*/ 64 PetscErrorCode PetscSpaceSetType(PetscSpace sp, PetscSpaceType name) { 65 PetscErrorCode (*r)(PetscSpace); 66 PetscBool match; 67 68 PetscFunctionBegin; 69 PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 70 PetscCall(PetscObjectTypeCompare((PetscObject)sp, name, &match)); 71 if (match) PetscFunctionReturn(0); 72 73 PetscCall(PetscSpaceRegisterAll()); 74 PetscCall(PetscFunctionListFind(PetscSpaceList, name, &r)); 75 PetscCheck(r, PetscObjectComm((PetscObject)sp), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown PetscSpace type: %s", name); 76 77 PetscTryTypeMethod(sp, destroy); 78 sp->ops->destroy = NULL; 79 80 sp->dim = PETSC_DETERMINE; 81 PetscCall((*r)(sp)); 82 PetscCall(PetscObjectChangeTypeName((PetscObject)sp, name)); 83 PetscFunctionReturn(0); 84 } 85 86 /*@C 87 PetscSpaceGetType - Gets the PetscSpace type name (as a string) from the object. 88 89 Not Collective 90 91 Input Parameter: 92 . sp - The PetscSpace 93 94 Output Parameter: 95 . name - The PetscSpace type name 96 97 Level: intermediate 98 99 .seealso: `PetscSpaceSetType()`, `PetscSpaceCreate()` 100 @*/ 101 PetscErrorCode PetscSpaceGetType(PetscSpace sp, PetscSpaceType *name) { 102 PetscFunctionBegin; 103 PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 104 PetscValidPointer(name, 2); 105 if (!PetscSpaceRegisterAllCalled) PetscCall(PetscSpaceRegisterAll()); 106 *name = ((PetscObject)sp)->type_name; 107 PetscFunctionReturn(0); 108 } 109 110 /*@C 111 PetscSpaceViewFromOptions - View from Options 112 113 Collective on PetscSpace 114 115 Input Parameters: 116 + A - the PetscSpace object 117 . obj - Optional object 118 - name - command line option 119 120 Level: intermediate 121 .seealso: `PetscSpace`, `PetscSpaceView`, `PetscObjectViewFromOptions()`, `PetscSpaceCreate()` 122 @*/ 123 PetscErrorCode PetscSpaceViewFromOptions(PetscSpace A, PetscObject obj, const char name[]) { 124 PetscFunctionBegin; 125 PetscValidHeaderSpecific(A, PETSCSPACE_CLASSID, 1); 126 PetscCall(PetscObjectViewFromOptions((PetscObject)A, obj, name)); 127 PetscFunctionReturn(0); 128 } 129 130 /*@C 131 PetscSpaceView - Views a PetscSpace 132 133 Collective on sp 134 135 Input Parameters: 136 + sp - the PetscSpace object to view 137 - v - the viewer 138 139 Level: beginner 140 141 .seealso `PetscSpaceDestroy()` 142 @*/ 143 PetscErrorCode PetscSpaceView(PetscSpace sp, PetscViewer v) { 144 PetscInt pdim; 145 PetscBool iascii; 146 147 PetscFunctionBegin; 148 PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 149 if (v) PetscValidHeaderSpecific(v, PETSC_VIEWER_CLASSID, 2); 150 if (!v) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)sp), &v)); 151 PetscCall(PetscSpaceGetDimension(sp, &pdim)); 152 PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)sp, v)); 153 PetscCall(PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERASCII, &iascii)); 154 PetscCall(PetscViewerASCIIPushTab(v)); 155 if (iascii) PetscCall(PetscViewerASCIIPrintf(v, "Space in %" PetscInt_FMT " variables with %" PetscInt_FMT " components, size %" PetscInt_FMT "\n", sp->Nv, sp->Nc, pdim)); 156 PetscTryTypeMethod(sp, view, v); 157 PetscCall(PetscViewerASCIIPopTab(v)); 158 PetscFunctionReturn(0); 159 } 160 161 /*@ 162 PetscSpaceSetFromOptions - sets parameters in a PetscSpace from the options database 163 164 Collective on sp 165 166 Input Parameter: 167 . sp - the PetscSpace object to set options for 168 169 Options Database: 170 + -petscspace_degree <deg> - the approximation order of the space 171 . -petscspace_variables <n> - the number of different variables, e.g. x and y 172 - -petscspace_components <c> - the number of components, say d for a vector field 173 174 Level: intermediate 175 176 .seealso `PetscSpaceView()` 177 @*/ 178 PetscErrorCode PetscSpaceSetFromOptions(PetscSpace sp) { 179 const char *defaultType; 180 char name[256]; 181 PetscBool flg; 182 183 PetscFunctionBegin; 184 PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 185 if (!((PetscObject)sp)->type_name) { 186 defaultType = PETSCSPACEPOLYNOMIAL; 187 } else { 188 defaultType = ((PetscObject)sp)->type_name; 189 } 190 if (!PetscSpaceRegisterAllCalled) PetscCall(PetscSpaceRegisterAll()); 191 192 PetscObjectOptionsBegin((PetscObject)sp); 193 PetscCall(PetscOptionsFList("-petscspace_type", "Linear space", "PetscSpaceSetType", PetscSpaceList, defaultType, name, 256, &flg)); 194 if (flg) { 195 PetscCall(PetscSpaceSetType(sp, name)); 196 } else if (!((PetscObject)sp)->type_name) { 197 PetscCall(PetscSpaceSetType(sp, defaultType)); 198 } 199 { 200 PetscCall(PetscOptionsDeprecated("-petscspace_order", "-petscspace_degree", "3.11", NULL)); 201 PetscCall(PetscOptionsBoundedInt("-petscspace_order", "DEPRECATED: The approximation order", "PetscSpaceSetDegree", sp->degree, &sp->degree, NULL, 0)); 202 } 203 PetscCall(PetscOptionsBoundedInt("-petscspace_degree", "The (maximally included) polynomial degree", "PetscSpaceSetDegree", sp->degree, &sp->degree, NULL, 0)); 204 PetscCall(PetscOptionsBoundedInt("-petscspace_variables", "The number of different variables, e.g. x and y", "PetscSpaceSetNumVariables", sp->Nv, &sp->Nv, NULL, 0)); 205 PetscCall(PetscOptionsBoundedInt("-petscspace_components", "The number of components", "PetscSpaceSetNumComponents", sp->Nc, &sp->Nc, NULL, 0)); 206 PetscTryTypeMethod(sp, setfromoptions, PetscOptionsObject); 207 /* process any options handlers added with PetscObjectAddOptionsHandler() */ 208 PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)sp, PetscOptionsObject)); 209 PetscOptionsEnd(); 210 PetscCall(PetscSpaceViewFromOptions(sp, NULL, "-petscspace_view")); 211 PetscFunctionReturn(0); 212 } 213 214 /*@C 215 PetscSpaceSetUp - Construct data structures for the PetscSpace 216 217 Collective on sp 218 219 Input Parameter: 220 . sp - the PetscSpace object to setup 221 222 Level: intermediate 223 224 .seealso `PetscSpaceView()`, `PetscSpaceDestroy()` 225 @*/ 226 PetscErrorCode PetscSpaceSetUp(PetscSpace sp) { 227 PetscFunctionBegin; 228 PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 229 PetscTryTypeMethod(sp, setup); 230 PetscFunctionReturn(0); 231 } 232 233 /*@ 234 PetscSpaceDestroy - Destroys a PetscSpace object 235 236 Collective on sp 237 238 Input Parameter: 239 . sp - the PetscSpace object to destroy 240 241 Level: beginner 242 243 .seealso `PetscSpaceView()` 244 @*/ 245 PetscErrorCode PetscSpaceDestroy(PetscSpace *sp) { 246 PetscFunctionBegin; 247 if (!*sp) PetscFunctionReturn(0); 248 PetscValidHeaderSpecific((*sp), PETSCSPACE_CLASSID, 1); 249 250 if (--((PetscObject)(*sp))->refct > 0) { 251 *sp = NULL; 252 PetscFunctionReturn(0); 253 } 254 ((PetscObject)(*sp))->refct = 0; 255 PetscCall(DMDestroy(&(*sp)->dm)); 256 257 PetscCall((*(*sp)->ops->destroy)(*sp)); 258 PetscCall(PetscHeaderDestroy(sp)); 259 PetscFunctionReturn(0); 260 } 261 262 /*@ 263 PetscSpaceCreate - Creates an empty PetscSpace object. The type can then be set with PetscSpaceSetType(). 264 265 Collective 266 267 Input Parameter: 268 . comm - The communicator for the PetscSpace object 269 270 Output Parameter: 271 . sp - The PetscSpace object 272 273 Level: beginner 274 275 .seealso: `PetscSpaceSetType()`, `PETSCSPACEPOLYNOMIAL` 276 @*/ 277 PetscErrorCode PetscSpaceCreate(MPI_Comm comm, PetscSpace *sp) { 278 PetscSpace s; 279 280 PetscFunctionBegin; 281 PetscValidPointer(sp, 2); 282 PetscCall(PetscCitationsRegister(FECitation, &FEcite)); 283 *sp = NULL; 284 PetscCall(PetscFEInitializePackage()); 285 286 PetscCall(PetscHeaderCreate(s, PETSCSPACE_CLASSID, "PetscSpace", "Linear Space", "PetscSpace", comm, PetscSpaceDestroy, PetscSpaceView)); 287 288 s->degree = 0; 289 s->maxDegree = PETSC_DETERMINE; 290 s->Nc = 1; 291 s->Nv = 0; 292 s->dim = PETSC_DETERMINE; 293 PetscCall(DMShellCreate(comm, &s->dm)); 294 PetscCall(PetscSpaceSetType(s, PETSCSPACEPOLYNOMIAL)); 295 296 *sp = s; 297 PetscFunctionReturn(0); 298 } 299 300 /*@ 301 PetscSpaceGetDimension - Return the dimension of this space, i.e. the number of basis vectors 302 303 Input Parameter: 304 . sp - The PetscSpace 305 306 Output Parameter: 307 . dim - The dimension 308 309 Level: intermediate 310 311 .seealso: `PetscSpaceGetDegree()`, `PetscSpaceCreate()`, `PetscSpace` 312 @*/ 313 PetscErrorCode PetscSpaceGetDimension(PetscSpace sp, PetscInt *dim) { 314 PetscFunctionBegin; 315 PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 316 PetscValidIntPointer(dim, 2); 317 if (sp->dim == PETSC_DETERMINE) PetscTryTypeMethod(sp, getdimension, &sp->dim); 318 *dim = sp->dim; 319 PetscFunctionReturn(0); 320 } 321 322 /*@ 323 PetscSpaceGetDegree - Return the polynomial degrees that characterize this space 324 325 Input Parameter: 326 . sp - The PetscSpace 327 328 Output Parameters: 329 + minDegree - The degree of the largest polynomial space contained in the space 330 - maxDegree - The degree of the smallest polynomial space containing the space 331 332 Level: intermediate 333 334 .seealso: `PetscSpaceSetDegree()`, `PetscSpaceGetDimension()`, `PetscSpaceCreate()`, `PetscSpace` 335 @*/ 336 PetscErrorCode PetscSpaceGetDegree(PetscSpace sp, PetscInt *minDegree, PetscInt *maxDegree) { 337 PetscFunctionBegin; 338 PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 339 if (minDegree) PetscValidIntPointer(minDegree, 2); 340 if (maxDegree) PetscValidIntPointer(maxDegree, 3); 341 if (minDegree) *minDegree = sp->degree; 342 if (maxDegree) *maxDegree = sp->maxDegree; 343 PetscFunctionReturn(0); 344 } 345 346 /*@ 347 PetscSpaceSetDegree - Set the degree of approximation for this space. 348 349 Input Parameters: 350 + sp - The PetscSpace 351 . degree - The degree of the largest polynomial space contained in the space 352 - maxDegree - The degree of the largest polynomial space containing the space. One of degree and maxDegree can be PETSC_DETERMINE. 353 354 Level: intermediate 355 356 .seealso: `PetscSpaceGetDegree()`, `PetscSpaceCreate()`, `PetscSpace` 357 @*/ 358 PetscErrorCode PetscSpaceSetDegree(PetscSpace sp, PetscInt degree, PetscInt maxDegree) { 359 PetscFunctionBegin; 360 PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 361 sp->degree = degree; 362 sp->maxDegree = maxDegree; 363 PetscFunctionReturn(0); 364 } 365 366 /*@ 367 PetscSpaceGetNumComponents - Return the number of components for this space 368 369 Input Parameter: 370 . sp - The PetscSpace 371 372 Output Parameter: 373 . Nc - The number of components 374 375 Note: A vector space, for example, will have d components, where d is the spatial dimension 376 377 Level: intermediate 378 379 .seealso: `PetscSpaceSetNumComponents()`, `PetscSpaceGetNumVariables()`, `PetscSpaceGetDimension()`, `PetscSpaceCreate()`, `PetscSpace` 380 @*/ 381 PetscErrorCode PetscSpaceGetNumComponents(PetscSpace sp, PetscInt *Nc) { 382 PetscFunctionBegin; 383 PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 384 PetscValidIntPointer(Nc, 2); 385 *Nc = sp->Nc; 386 PetscFunctionReturn(0); 387 } 388 389 /*@ 390 PetscSpaceSetNumComponents - Set the number of components for this space 391 392 Input Parameters: 393 + sp - The PetscSpace 394 - order - The number of components 395 396 Level: intermediate 397 398 .seealso: `PetscSpaceGetNumComponents()`, `PetscSpaceSetNumVariables()`, `PetscSpaceCreate()`, `PetscSpace` 399 @*/ 400 PetscErrorCode PetscSpaceSetNumComponents(PetscSpace sp, PetscInt Nc) { 401 PetscFunctionBegin; 402 PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 403 sp->Nc = Nc; 404 PetscFunctionReturn(0); 405 } 406 407 /*@ 408 PetscSpaceSetNumVariables - Set the number of variables for this space 409 410 Input Parameters: 411 + sp - The PetscSpace 412 - n - The number of variables, e.g. x, y, z... 413 414 Level: intermediate 415 416 .seealso: `PetscSpaceGetNumVariables()`, `PetscSpaceSetNumComponents()`, `PetscSpaceCreate()`, `PetscSpace` 417 @*/ 418 PetscErrorCode PetscSpaceSetNumVariables(PetscSpace sp, PetscInt n) { 419 PetscFunctionBegin; 420 PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 421 sp->Nv = n; 422 PetscFunctionReturn(0); 423 } 424 425 /*@ 426 PetscSpaceGetNumVariables - Return the number of variables for this space 427 428 Input Parameter: 429 . sp - The PetscSpace 430 431 Output Parameter: 432 . Nc - The number of variables, e.g. x, y, z... 433 434 Level: intermediate 435 436 .seealso: `PetscSpaceSetNumVariables()`, `PetscSpaceGetNumComponents()`, `PetscSpaceGetDimension()`, `PetscSpaceCreate()`, `PetscSpace` 437 @*/ 438 PetscErrorCode PetscSpaceGetNumVariables(PetscSpace sp, PetscInt *n) { 439 PetscFunctionBegin; 440 PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 441 PetscValidIntPointer(n, 2); 442 *n = sp->Nv; 443 PetscFunctionReturn(0); 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: beginner 463 464 .seealso: `PetscFECreateTabulation()`, `PetscFEGetCellTabulation()`, `PetscSpaceCreate()` 465 @*/ 466 PetscErrorCode PetscSpaceEvaluate(PetscSpace sp, PetscInt npoints, const PetscReal points[], PetscReal B[], PetscReal D[], PetscReal H[]) { 467 PetscFunctionBegin; 468 if (!npoints) PetscFunctionReturn(0); 469 PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 470 if (sp->Nv) PetscValidRealPointer(points, 3); 471 if (B) PetscValidRealPointer(B, 4); 472 if (D) PetscValidRealPointer(D, 5); 473 if (H) PetscValidRealPointer(H, 6); 474 PetscTryTypeMethod(sp, evaluate, npoints, points, B, D, H); 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 PetscFunctionBegin; 502 PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 503 PetscValidPointer(subsp, 3); 504 *subsp = NULL; 505 PetscTryTypeMethod(sp, getheightsubspace, height, subsp); 506 PetscFunctionReturn(0); 507 } 508