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 if (sp->ops->destroy) { 80 PetscCall((*sp->ops->destroy)(sp)); 81 sp->ops->destroy = NULL; 82 } 83 sp->dim = PETSC_DETERMINE; 84 PetscCall((*r)(sp)); 85 PetscCall(PetscObjectChangeTypeName((PetscObject) sp, name)); 86 PetscFunctionReturn(0); 87 } 88 89 /*@C 90 PetscSpaceGetType - Gets the PetscSpace type name (as a string) from the object. 91 92 Not Collective 93 94 Input Parameter: 95 . sp - The PetscSpace 96 97 Output Parameter: 98 . name - The PetscSpace type name 99 100 Level: intermediate 101 102 .seealso: PetscSpaceSetType(), PetscSpaceCreate() 103 @*/ 104 PetscErrorCode PetscSpaceGetType(PetscSpace sp, PetscSpaceType *name) 105 { 106 PetscFunctionBegin; 107 PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 108 PetscValidPointer(name, 2); 109 if (!PetscSpaceRegisterAllCalled) { 110 PetscCall(PetscSpaceRegisterAll()); 111 } 112 *name = ((PetscObject) sp)->type_name; 113 PetscFunctionReturn(0); 114 } 115 116 /*@C 117 PetscSpaceViewFromOptions - View from Options 118 119 Collective on PetscSpace 120 121 Input Parameters: 122 + A - the PetscSpace object 123 . obj - Optional object 124 - name - command line option 125 126 Level: intermediate 127 .seealso: PetscSpace, PetscSpaceView, PetscObjectViewFromOptions(), PetscSpaceCreate() 128 @*/ 129 PetscErrorCode PetscSpaceViewFromOptions(PetscSpace A,PetscObject obj,const char name[]) 130 { 131 PetscFunctionBegin; 132 PetscValidHeaderSpecific(A,PETSCSPACE_CLASSID,1); 133 PetscCall(PetscObjectViewFromOptions((PetscObject)A,obj,name)); 134 PetscFunctionReturn(0); 135 } 136 137 /*@C 138 PetscSpaceView - Views a PetscSpace 139 140 Collective on sp 141 142 Input Parameters: 143 + sp - the PetscSpace object to view 144 - v - the viewer 145 146 Level: beginner 147 148 .seealso PetscSpaceDestroy() 149 @*/ 150 PetscErrorCode PetscSpaceView(PetscSpace sp, PetscViewer v) 151 { 152 PetscInt pdim; 153 PetscBool iascii; 154 155 PetscFunctionBegin; 156 PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 157 if (v) PetscValidHeaderSpecific(v, PETSC_VIEWER_CLASSID, 2); 158 if (!v) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject) sp), &v)); 159 PetscCall(PetscSpaceGetDimension(sp, &pdim)); 160 PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)sp,v)); 161 PetscCall(PetscObjectTypeCompare((PetscObject) v, PETSCVIEWERASCII, &iascii)); 162 PetscCall(PetscViewerASCIIPushTab(v)); 163 if (iascii) PetscCall(PetscViewerASCIIPrintf(v, "Space in %" PetscInt_FMT " variables with %" PetscInt_FMT " components, size %" PetscInt_FMT "\n", sp->Nv, sp->Nc, pdim)); 164 if (sp->ops->view) PetscCall((*sp->ops->view)(sp, v)); 165 PetscCall(PetscViewerASCIIPopTab(v)); 166 PetscFunctionReturn(0); 167 } 168 169 /*@ 170 PetscSpaceSetFromOptions - sets parameters in a PetscSpace from the options database 171 172 Collective on sp 173 174 Input Parameter: 175 . sp - the PetscSpace object to set options for 176 177 Options Database: 178 + -petscspace_degree <deg> - the approximation order of the space 179 . -petscspace_variables <n> - the number of different variables, e.g. x and y 180 - -petscspace_components <c> - the number of components, say d for a vector field 181 182 Level: intermediate 183 184 .seealso PetscSpaceView() 185 @*/ 186 PetscErrorCode PetscSpaceSetFromOptions(PetscSpace sp) 187 { 188 const char *defaultType; 189 char name[256]; 190 PetscBool flg; 191 192 PetscFunctionBegin; 193 PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 194 if (!((PetscObject) sp)->type_name) { 195 defaultType = PETSCSPACEPOLYNOMIAL; 196 } else { 197 defaultType = ((PetscObject) sp)->type_name; 198 } 199 if (!PetscSpaceRegisterAllCalled) PetscCall(PetscSpaceRegisterAll()); 200 201 PetscObjectOptionsBegin((PetscObject) sp); 202 PetscCall(PetscOptionsFList("-petscspace_type", "Linear space", "PetscSpaceSetType", PetscSpaceList, defaultType, name, 256, &flg)); 203 if (flg) { 204 PetscCall(PetscSpaceSetType(sp, name)); 205 } else if (!((PetscObject) sp)->type_name) { 206 PetscCall(PetscSpaceSetType(sp, defaultType)); 207 } 208 { 209 PetscCall(PetscOptionsDeprecated("-petscspace_order","-petscspace_degree","3.11",NULL)); 210 PetscCall(PetscOptionsBoundedInt("-petscspace_order", "DEPRECATED: The approximation order", "PetscSpaceSetDegree", sp->degree, &sp->degree, NULL,0)); 211 } 212 PetscCall(PetscOptionsBoundedInt("-petscspace_degree", "The (maximally included) polynomial degree", "PetscSpaceSetDegree", sp->degree, &sp->degree, NULL,0)); 213 PetscCall(PetscOptionsBoundedInt("-petscspace_variables", "The number of different variables, e.g. x and y", "PetscSpaceSetNumVariables", sp->Nv, &sp->Nv, NULL,0)); 214 PetscCall(PetscOptionsBoundedInt("-petscspace_components", "The number of components", "PetscSpaceSetNumComponents", sp->Nc, &sp->Nc, NULL,0)); 215 if (sp->ops->setfromoptions) { 216 PetscCall((*sp->ops->setfromoptions)(PetscOptionsObject,sp)); 217 } 218 /* process any options handlers added with PetscObjectAddOptionsHandler() */ 219 PetscCall(PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject) sp)); 220 PetscOptionsEnd(); 221 PetscCall(PetscSpaceViewFromOptions(sp, NULL, "-petscspace_view")); 222 PetscFunctionReturn(0); 223 } 224 225 /*@C 226 PetscSpaceSetUp - Construct data structures for the PetscSpace 227 228 Collective on sp 229 230 Input Parameter: 231 . sp - the PetscSpace object to setup 232 233 Level: intermediate 234 235 .seealso PetscSpaceView(), PetscSpaceDestroy() 236 @*/ 237 PetscErrorCode PetscSpaceSetUp(PetscSpace sp) 238 { 239 PetscFunctionBegin; 240 PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 241 if (sp->ops->setup) PetscCall((*sp->ops->setup)(sp)); 242 PetscFunctionReturn(0); 243 } 244 245 /*@ 246 PetscSpaceDestroy - Destroys a PetscSpace object 247 248 Collective on sp 249 250 Input Parameter: 251 . sp - the PetscSpace object to destroy 252 253 Level: beginner 254 255 .seealso PetscSpaceView() 256 @*/ 257 PetscErrorCode PetscSpaceDestroy(PetscSpace *sp) 258 { 259 PetscFunctionBegin; 260 if (!*sp) PetscFunctionReturn(0); 261 PetscValidHeaderSpecific((*sp), PETSCSPACE_CLASSID, 1); 262 263 if (--((PetscObject)(*sp))->refct > 0) {*sp = NULL; PetscFunctionReturn(0);} 264 ((PetscObject) (*sp))->refct = 0; 265 PetscCall(DMDestroy(&(*sp)->dm)); 266 267 PetscCall((*(*sp)->ops->destroy)(*sp)); 268 PetscCall(PetscHeaderDestroy(sp)); 269 PetscFunctionReturn(0); 270 } 271 272 /*@ 273 PetscSpaceCreate - Creates an empty PetscSpace object. The type can then be set with PetscSpaceSetType(). 274 275 Collective 276 277 Input Parameter: 278 . comm - The communicator for the PetscSpace object 279 280 Output Parameter: 281 . sp - The PetscSpace object 282 283 Level: beginner 284 285 .seealso: PetscSpaceSetType(), PETSCSPACEPOLYNOMIAL 286 @*/ 287 PetscErrorCode PetscSpaceCreate(MPI_Comm comm, PetscSpace *sp) 288 { 289 PetscSpace s; 290 291 PetscFunctionBegin; 292 PetscValidPointer(sp, 2); 293 PetscCall(PetscCitationsRegister(FECitation,&FEcite)); 294 *sp = NULL; 295 PetscCall(PetscFEInitializePackage()); 296 297 PetscCall(PetscHeaderCreate(s, PETSCSPACE_CLASSID, "PetscSpace", "Linear Space", "PetscSpace", comm, PetscSpaceDestroy, PetscSpaceView)); 298 299 s->degree = 0; 300 s->maxDegree = PETSC_DETERMINE; 301 s->Nc = 1; 302 s->Nv = 0; 303 s->dim = PETSC_DETERMINE; 304 PetscCall(DMShellCreate(comm, &s->dm)); 305 PetscCall(PetscSpaceSetType(s, PETSCSPACEPOLYNOMIAL)); 306 307 *sp = s; 308 PetscFunctionReturn(0); 309 } 310 311 /*@ 312 PetscSpaceGetDimension - Return the dimension of this space, i.e. the number of basis vectors 313 314 Input Parameter: 315 . sp - The PetscSpace 316 317 Output Parameter: 318 . dim - The dimension 319 320 Level: intermediate 321 322 .seealso: PetscSpaceGetDegree(), PetscSpaceCreate(), PetscSpace 323 @*/ 324 PetscErrorCode PetscSpaceGetDimension(PetscSpace sp, PetscInt *dim) 325 { 326 PetscFunctionBegin; 327 PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 328 PetscValidIntPointer(dim, 2); 329 if (sp->dim == PETSC_DETERMINE) { 330 if (sp->ops->getdimension) PetscCall((*sp->ops->getdimension)(sp, &sp->dim)); 331 } 332 *dim = sp->dim; 333 PetscFunctionReturn(0); 334 } 335 336 /*@ 337 PetscSpaceGetDegree - Return the polynomial degrees that characterize this space 338 339 Input Parameter: 340 . sp - The PetscSpace 341 342 Output Parameters: 343 + minDegree - The degree of the largest polynomial space contained in the space 344 - maxDegree - The degree of the smallest polynomial space containing the space 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) PetscValidIntPointer(minDegree, 2); 355 if (maxDegree) PetscValidIntPointer(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(), PetscSpaceGetNumVariables(), PetscSpaceGetDimension(), PetscSpaceCreate(), PetscSpace 396 @*/ 397 PetscErrorCode PetscSpaceGetNumComponents(PetscSpace sp, PetscInt *Nc) 398 { 399 PetscFunctionBegin; 400 PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 401 PetscValidIntPointer(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(), PetscSpaceSetNumVariables(), 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 /*@ 426 PetscSpaceSetNumVariables - Set the number of variables for this space 427 428 Input Parameters: 429 + sp - The PetscSpace 430 - n - The number of variables, e.g. x, y, z... 431 432 Level: intermediate 433 434 .seealso: PetscSpaceGetNumVariables(), PetscSpaceSetNumComponents(), PetscSpaceCreate(), PetscSpace 435 @*/ 436 PetscErrorCode PetscSpaceSetNumVariables(PetscSpace sp, PetscInt n) 437 { 438 PetscFunctionBegin; 439 PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 440 sp->Nv = n; 441 PetscFunctionReturn(0); 442 } 443 444 /*@ 445 PetscSpaceGetNumVariables - Return the number of variables for this space 446 447 Input Parameter: 448 . sp - The PetscSpace 449 450 Output Parameter: 451 . Nc - The number of variables, e.g. x, y, z... 452 453 Level: intermediate 454 455 .seealso: PetscSpaceSetNumVariables(), PetscSpaceGetNumComponents(), PetscSpaceGetDimension(), PetscSpaceCreate(), PetscSpace 456 @*/ 457 PetscErrorCode PetscSpaceGetNumVariables(PetscSpace sp, PetscInt *n) 458 { 459 PetscFunctionBegin; 460 PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 461 PetscValidIntPointer(n, 2); 462 *n = sp->Nv; 463 PetscFunctionReturn(0); 464 } 465 466 /*@C 467 PetscSpaceEvaluate - Evaluate the basis functions and their derivatives (jet) at each point 468 469 Input Parameters: 470 + sp - The PetscSpace 471 . npoints - The number of evaluation points, in reference coordinates 472 - points - The point coordinates 473 474 Output Parameters: 475 + B - The function evaluations in a npoints x nfuncs array 476 . D - The derivative evaluations in a npoints x nfuncs x dim array 477 - H - The second derivative evaluations in a npoints x nfuncs x dim x dim array 478 479 Note: Above nfuncs is the dimension of the space, and dim is the spatial dimension. The coordinates are given 480 on the reference cell, not in real space. 481 482 Level: beginner 483 484 .seealso: PetscFECreateTabulation(), PetscFEGetCellTabulation(), PetscSpaceCreate() 485 @*/ 486 PetscErrorCode PetscSpaceEvaluate(PetscSpace sp, PetscInt npoints, const PetscReal points[], PetscReal B[], PetscReal D[], PetscReal H[]) 487 { 488 PetscFunctionBegin; 489 if (!npoints) PetscFunctionReturn(0); 490 PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 491 if (sp->Nv) PetscValidRealPointer(points, 3); 492 if (B) PetscValidRealPointer(B, 4); 493 if (D) PetscValidRealPointer(D, 5); 494 if (H) PetscValidRealPointer(H, 6); 495 if (sp->ops->evaluate) PetscCall((*sp->ops->evaluate)(sp, npoints, points, B, D, H)); 496 PetscFunctionReturn(0); 497 } 498 499 /*@ 500 PetscSpaceGetHeightSubspace - Get the subset of the primal space basis that is supported on a mesh point of a given height. 501 502 If the space is not defined on mesh points of the given height (e.g. if the space is discontinuous and 503 pointwise values are not defined on the element boundaries), or if the implementation of PetscSpace does not 504 support extracting subspaces, then NULL is returned. 505 506 This does not increment the reference count on the returned space, and the user should not destroy it. 507 508 Not collective 509 510 Input Parameters: 511 + sp - the PetscSpace object 512 - height - the height of the mesh point for which the subspace is desired 513 514 Output Parameter: 515 . subsp - the subspace 516 517 Level: advanced 518 519 .seealso: PetscDualSpaceGetHeightSubspace(), PetscSpace 520 @*/ 521 PetscErrorCode PetscSpaceGetHeightSubspace(PetscSpace sp, PetscInt height, PetscSpace *subsp) 522 { 523 PetscFunctionBegin; 524 PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 525 PetscValidPointer(subsp, 3); 526 *subsp = NULL; 527 if (sp->ops->getheightsubspace) { 528 PetscCall((*sp->ops->getheightsubspace)(sp, height, subsp)); 529 } 530 PetscFunctionReturn(0); 531 } 532