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