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