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