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