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