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 (maximally included) polynomial degree", "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 - maxDegree - The degree of the largest polynomial space containing the space. One of degree and maxDegree can be PETSC_DETERMINE. 368 369 Level: intermediate 370 371 .seealso: PetscSpaceGetDegree(), PetscSpaceCreate(), PetscSpace 372 @*/ 373 PetscErrorCode PetscSpaceSetDegree(PetscSpace sp, PetscInt degree, PetscInt maxDegree) 374 { 375 PetscFunctionBegin; 376 PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 377 sp->degree = degree; 378 sp->maxDegree = maxDegree; 379 PetscFunctionReturn(0); 380 } 381 382 /*@ 383 PetscSpaceGetNumComponents - Return the number of components for this space 384 385 Input Parameter: 386 . sp - The PetscSpace 387 388 Output Parameter: 389 . Nc - The number of components 390 391 Note: A vector space, for example, will have d components, where d is the spatial dimension 392 393 Level: intermediate 394 395 .seealso: PetscSpaceSetNumComponents(), PetscSpaceGetDimension(), PetscSpaceCreate(), PetscSpace 396 @*/ 397 PetscErrorCode PetscSpaceGetNumComponents(PetscSpace sp, PetscInt *Nc) 398 { 399 PetscFunctionBegin; 400 PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 401 PetscValidPointer(Nc, 2); 402 *Nc = sp->Nc; 403 PetscFunctionReturn(0); 404 } 405 406 /*@ 407 PetscSpaceSetNumComponents - Set the number of components for this space 408 409 Input Parameters: 410 + sp - The PetscSpace 411 - order - The number of components 412 413 Level: intermediate 414 415 .seealso: PetscSpaceGetNumComponents(), PetscSpaceCreate(), PetscSpace 416 @*/ 417 PetscErrorCode PetscSpaceSetNumComponents(PetscSpace sp, PetscInt Nc) 418 { 419 PetscFunctionBegin; 420 PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 421 sp->Nc = Nc; 422 PetscFunctionReturn(0); 423 } 424 425 PetscErrorCode PetscSpaceSetNumVariables(PetscSpace sp, PetscInt n) 426 { 427 PetscFunctionBegin; 428 PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 429 sp->Nv = n; 430 PetscFunctionReturn(0); 431 } 432 433 PetscErrorCode PetscSpaceGetNumVariables(PetscSpace sp, PetscInt *n) 434 { 435 PetscFunctionBegin; 436 PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 437 PetscValidPointer(n, 2); 438 *n = sp->Nv; 439 PetscFunctionReturn(0); 440 } 441 442 443 /*@C 444 PetscSpaceEvaluate - Evaluate the basis functions and their derivatives (jet) at each point 445 446 Input Parameters: 447 + sp - The PetscSpace 448 . npoints - The number of evaluation points, in reference coordinates 449 - points - The point coordinates 450 451 Output Parameters: 452 + B - The function evaluations in a npoints x nfuncs array 453 . D - The derivative evaluations in a npoints x nfuncs x dim array 454 - H - The second derivative evaluations in a npoints x nfuncs x dim x dim array 455 456 Note: Above nfuncs is the dimension of the space, and dim is the spatial dimension. The coordinates are given 457 on the reference cell, not in real space. 458 459 Level: advanced 460 461 .seealso: PetscFEGetTabulation(), PetscFEGetDefaultTabulation(), PetscSpaceCreate() 462 @*/ 463 PetscErrorCode PetscSpaceEvaluate(PetscSpace sp, PetscInt npoints, const PetscReal points[], PetscReal B[], PetscReal D[], PetscReal H[]) 464 { 465 PetscErrorCode ierr; 466 467 PetscFunctionBegin; 468 if (!npoints) PetscFunctionReturn(0); 469 PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 470 if (sp->Nv) PetscValidPointer(points, 3); 471 if (B) PetscValidPointer(B, 4); 472 if (D) PetscValidPointer(D, 5); 473 if (H) PetscValidPointer(H, 6); 474 if (sp->ops->evaluate) {ierr = (*sp->ops->evaluate)(sp, npoints, points, B, D, H);CHKERRQ(ierr);} 475 PetscFunctionReturn(0); 476 } 477 478 /*@ 479 PetscSpaceGetHeightSubspace - Get the subset of the primal space basis that is supported on a mesh point of a given height. 480 481 If the space is not defined on mesh points of the given height (e.g. if the space is discontinuous and 482 pointwise values are not defined on the element boundaries), or if the implementation of PetscSpace does not 483 support extracting subspaces, then NULL is returned. 484 485 This does not increment the reference count on the returned space, and the user should not destroy it. 486 487 Not collective 488 489 Input Parameters: 490 + sp - the PetscSpace object 491 - height - the height of the mesh point for which the subspace is desired 492 493 Output Parameter: 494 . subsp - the subspace 495 496 Level: advanced 497 498 .seealso: PetscDualSpaceGetHeightSubspace(), PetscSpace 499 @*/ 500 PetscErrorCode PetscSpaceGetHeightSubspace(PetscSpace sp, PetscInt height, PetscSpace *subsp) 501 { 502 PetscErrorCode ierr; 503 504 PetscFunctionBegin; 505 PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 506 PetscValidPointer(subsp, 3); 507 *subsp = NULL; 508 if (sp->ops->getheightsubspace) { 509 ierr = (*sp->ops->getheightsubspace)(sp, height, subsp);CHKERRQ(ierr); 510 } 511 PetscFunctionReturn(0); 512 } 513 514