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