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