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