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