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_order 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; 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 ierr = PetscOptionsInt("-petscspace_order", "The approximation order", "PetscSpaceSetDegree", sp->degree, &sp->degree, NULL);CHKERRQ(ierr); 197 ierr = PetscOptionsInt("-petscspace_variables", "The number of different variables, e.g. x and y", "PetscSpaceSetNumVariables", sp->Nv, &sp->Nv, NULL);CHKERRQ(ierr); 198 ierr = PetscOptionsInt("-petscspace_components", "The number of components", "PetscSpaceSetNumComponents", sp->Nc, &sp->Nc, NULL);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 PetscSpace 213 214 Input Parameter: 215 . sp - the PetscSpace object to setup 216 217 Level: developer 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 PetscSpace 235 236 Input Parameter: 237 . sp - the PetscSpace object to destroy 238 239 Level: developer 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 on MPI_Comm 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->Nc = 1; 290 s->Nv = 0; 291 ierr = DMShellCreate(comm, &s->dm);CHKERRQ(ierr); 292 ierr = PetscSpaceSetType(s, PETSCSPACEPOLYNOMIAL);CHKERRQ(ierr); 293 294 *sp = s; 295 PetscFunctionReturn(0); 296 } 297 298 /*@ 299 PetscSpaceGetDimension - Return the dimension of this space, i.e. the number of basis vectors 300 301 Input Parameter: 302 . sp - The PetscSpace 303 304 Output Parameter: 305 . dim - The dimension 306 307 Level: intermediate 308 309 .seealso: PetscSpaceGetDegree(), PetscSpaceCreate(), PetscSpace 310 @*/ 311 PetscErrorCode PetscSpaceGetDimension(PetscSpace sp, PetscInt *dim) 312 { 313 PetscErrorCode ierr; 314 315 PetscFunctionBegin; 316 PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 317 PetscValidPointer(dim, 2); 318 *dim = 0; 319 if (sp->ops->getdimension) {ierr = (*sp->ops->getdimension)(sp, dim);CHKERRQ(ierr);} 320 PetscFunctionReturn(0); 321 } 322 323 /*@ 324 PetscSpaceGetDegree - Return the polynomial degrees that characterize this space 325 326 Input Parameter: 327 . sp - The PetscSpace 328 329 Output Parameter: 330 + minDegree - The degree of the largest polynomial space contained in the space 331 - maxDegree - The degree of the smallest polynomial space containing the space 332 333 334 Level: intermediate 335 336 .seealso: PetscSpaceSetDegree(), PetscSpaceGetDimension(), PetscSpaceCreate(), PetscSpace 337 @*/ 338 PetscErrorCode PetscSpaceGetDegree(PetscSpace sp, PetscInt *minDegree, PetscInt *maxDegree) 339 { 340 PetscFunctionBegin; 341 PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 342 if (minDegree) PetscValidPointer(minDegree, 2); 343 if (maxDegree) PetscValidPointer(maxDegree, 3); 344 if (minDegree) *minDegree = sp->degree; 345 if (maxDegree) *maxDegree = sp->maxDegree; 346 PetscFunctionReturn(0); 347 } 348 349 /*@ 350 PetscSpaceSetDegree - Set the degree of approximation for this space. 351 352 Input Parameters: 353 + sp - The PetscSpace 354 - degree - The degree of the largest polynomial space contained in the space 355 356 Level: intermediate 357 358 .seealso: PetscSpaceGetDegree(), PetscSpaceCreate(), PetscSpace 359 @*/ 360 PetscErrorCode PetscSpaceSetDegree(PetscSpace sp, PetscInt order) 361 { 362 PetscFunctionBegin; 363 PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 364 sp->degree = order; 365 PetscFunctionReturn(0); 366 } 367 368 /*@ 369 PetscSpaceGetNumComponents - Return the number of components for this space 370 371 Input Parameter: 372 . sp - The PetscSpace 373 374 Output Parameter: 375 . Nc - The number of components 376 377 Note: A vector space, for example, will have d components, where d is the spatial dimension 378 379 Level: intermediate 380 381 .seealso: PetscSpaceSetNumComponents(), PetscSpaceGetDimension(), PetscSpaceCreate(), PetscSpace 382 @*/ 383 PetscErrorCode PetscSpaceGetNumComponents(PetscSpace sp, PetscInt *Nc) 384 { 385 PetscFunctionBegin; 386 PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 387 PetscValidPointer(Nc, 2); 388 *Nc = sp->Nc; 389 PetscFunctionReturn(0); 390 } 391 392 /*@ 393 PetscSpaceSetNumComponents - Set the number of components for this space 394 395 Input Parameters: 396 + sp - The PetscSpace 397 - order - The number of components 398 399 Level: intermediate 400 401 .seealso: PetscSpaceGetNumComponents(), PetscSpaceCreate(), PetscSpace 402 @*/ 403 PetscErrorCode PetscSpaceSetNumComponents(PetscSpace sp, PetscInt Nc) 404 { 405 PetscFunctionBegin; 406 PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 407 sp->Nc = Nc; 408 PetscFunctionReturn(0); 409 } 410 411 PetscErrorCode PetscSpaceSetNumVariables(PetscSpace sp, PetscInt n) 412 { 413 PetscFunctionBegin; 414 PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 415 sp->Nv = n; 416 PetscFunctionReturn(0); 417 } 418 419 PetscErrorCode PetscSpaceGetNumVariables(PetscSpace sp, PetscInt *n) 420 { 421 PetscFunctionBegin; 422 PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 423 PetscValidPointer(n, 2); 424 *n = sp->Nv; 425 PetscFunctionReturn(0); 426 } 427 428 429 /*@C 430 PetscSpaceEvaluate - Evaluate the basis functions and their derivatives (jet) at each point 431 432 Input Parameters: 433 + sp - The PetscSpace 434 . npoints - The number of evaluation points, in reference coordinates 435 - points - The point coordinates 436 437 Output Parameters: 438 + B - The function evaluations in a npoints x nfuncs array 439 . D - The derivative evaluations in a npoints x nfuncs x dim array 440 - H - The second derivative evaluations in a npoints x nfuncs x dim x dim array 441 442 Note: Above nfuncs is the dimension of the space, and dim is the spatial dimension. The coordinates are given 443 on the reference cell, not in real space. 444 445 Level: advanced 446 447 .seealso: PetscFEGetTabulation(), PetscFEGetDefaultTabulation(), PetscSpaceCreate() 448 @*/ 449 PetscErrorCode PetscSpaceEvaluate(PetscSpace sp, PetscInt npoints, const PetscReal points[], PetscReal B[], PetscReal D[], PetscReal H[]) 450 { 451 PetscErrorCode ierr; 452 453 PetscFunctionBegin; 454 if (!npoints) PetscFunctionReturn(0); 455 PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 456 if (sp->Nv) PetscValidPointer(points, 3); 457 if (B) PetscValidPointer(B, 4); 458 if (D) PetscValidPointer(D, 5); 459 if (H) PetscValidPointer(H, 6); 460 if (sp->ops->evaluate) {ierr = (*sp->ops->evaluate)(sp, npoints, points, B, D, H);CHKERRQ(ierr);} 461 PetscFunctionReturn(0); 462 } 463 464 /*@ 465 PetscSpaceGetHeightSubspace - Get the subset of the primal space basis that is supported on a mesh point of a given height. 466 467 If the space is not defined on mesh points of the given height (e.g. if the space is discontinuous and 468 pointwise values are not defined on the element boundaries), or if the implementation of PetscSpace does not 469 support extracting subspaces, then NULL is returned. 470 471 This does not increment the reference count on the returned space, and the user should not destroy it. 472 473 Not collective 474 475 Input Parameters: 476 + sp - the PetscSpace object 477 - height - the height of the mesh point for which the subspace is desired 478 479 Output Parameter: 480 . subsp - the subspace 481 482 Level: advanced 483 484 .seealso: PetscDualSpaceGetHeightSubspace(), PetscSpace 485 @*/ 486 PetscErrorCode PetscSpaceGetHeightSubspace(PetscSpace sp, PetscInt height, PetscSpace *subsp) 487 { 488 PetscErrorCode ierr; 489 490 PetscFunctionBegin; 491 PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 492 PetscValidPointer(subsp, 3); 493 *subsp = NULL; 494 if (sp->ops->getheightsubspace) { 495 ierr = (*sp->ops->getheightsubspace)(sp, height, subsp);CHKERRQ(ierr); 496 } 497 PetscFunctionReturn(0); 498 } 499 500