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 .seealso: PetscSpaceRegisterAll(), PetscSpaceRegisterDestroy() 40 41 @*/ 42 PetscErrorCode PetscSpaceRegister(const char sname[], PetscErrorCode (*function)(PetscSpace)) 43 { 44 PetscErrorCode ierr; 45 46 PetscFunctionBegin; 47 ierr = PetscFunctionListAdd(&PetscSpaceList, sname, function);CHKERRQ(ierr); 48 PetscFunctionReturn(0); 49 } 50 51 /*@C 52 PetscSpaceSetType - Builds a particular PetscSpace 53 54 Collective on PetscSpace 55 56 Input Parameters: 57 + sp - The PetscSpace object 58 - name - The kind of space 59 60 Options Database Key: 61 . -petscspace_type <type> - Sets the PetscSpace type; use -help for a list of available types 62 63 Level: intermediate 64 65 .seealso: PetscSpaceGetType(), PetscSpaceCreate() 66 @*/ 67 PetscErrorCode PetscSpaceSetType(PetscSpace sp, PetscSpaceType name) 68 { 69 PetscErrorCode (*r)(PetscSpace); 70 PetscBool match; 71 PetscErrorCode ierr; 72 73 PetscFunctionBegin; 74 PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 75 ierr = PetscObjectTypeCompare((PetscObject) sp, name, &match);CHKERRQ(ierr); 76 if (match) PetscFunctionReturn(0); 77 78 ierr = PetscSpaceRegisterAll();CHKERRQ(ierr); 79 ierr = PetscFunctionListFind(PetscSpaceList, name, &r);CHKERRQ(ierr); 80 if (!r) SETERRQ1(PetscObjectComm((PetscObject) sp), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown PetscSpace type: %s", name); 81 82 if (sp->ops->destroy) { 83 ierr = (*sp->ops->destroy)(sp);CHKERRQ(ierr); 84 sp->ops->destroy = NULL; 85 } 86 sp->dim = PETSC_DETERMINE; 87 ierr = (*r)(sp);CHKERRQ(ierr); 88 ierr = PetscObjectChangeTypeName((PetscObject) sp, name);CHKERRQ(ierr); 89 PetscFunctionReturn(0); 90 } 91 92 /*@C 93 PetscSpaceGetType - Gets the PetscSpace type name (as a string) from the object. 94 95 Not Collective 96 97 Input Parameter: 98 . sp - The PetscSpace 99 100 Output Parameter: 101 . name - The PetscSpace type name 102 103 Level: intermediate 104 105 .seealso: PetscSpaceSetType(), PetscSpaceCreate() 106 @*/ 107 PetscErrorCode PetscSpaceGetType(PetscSpace sp, PetscSpaceType *name) 108 { 109 PetscErrorCode ierr; 110 111 PetscFunctionBegin; 112 PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 113 PetscValidPointer(name, 2); 114 if (!PetscSpaceRegisterAllCalled) { 115 ierr = PetscSpaceRegisterAll();CHKERRQ(ierr); 116 } 117 *name = ((PetscObject) sp)->type_name; 118 PetscFunctionReturn(0); 119 } 120 121 /*@C 122 PetscSpaceView - Views a PetscSpace 123 124 Collective on PetscSpace 125 126 Input Parameter: 127 + sp - the PetscSpace object to view 128 - v - the viewer 129 130 Level: developer 131 132 .seealso PetscSpaceDestroy() 133 @*/ 134 PetscErrorCode PetscSpaceView(PetscSpace sp, PetscViewer v) 135 { 136 PetscInt pdim; 137 PetscBool iascii; 138 PetscErrorCode ierr; 139 140 PetscFunctionBegin; 141 PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 142 if (v) PetscValidHeaderSpecific(v, PETSC_VIEWER_CLASSID, 2); 143 if (!v) {ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject) sp), &v);CHKERRQ(ierr);} 144 ierr = PetscSpaceGetDimension(sp, &pdim);CHKERRQ(ierr); 145 ierr = PetscObjectPrintClassNamePrefixType((PetscObject)sp,v);CHKERRQ(ierr); 146 ierr = PetscObjectTypeCompare((PetscObject) v, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr); 147 ierr = PetscViewerASCIIPushTab(v);CHKERRQ(ierr); 148 if (iascii) {ierr = PetscViewerASCIIPrintf(v, "Space in %D variables with %D components, size %D\n", sp->Nv, sp->Nc, pdim);CHKERRQ(ierr);} 149 if (sp->ops->view) {ierr = (*sp->ops->view)(sp, v);CHKERRQ(ierr);} 150 ierr = PetscViewerASCIIPopTab(v);CHKERRQ(ierr); 151 PetscFunctionReturn(0); 152 } 153 154 /*@ 155 PetscSpaceSetFromOptions - sets parameters in a PetscSpace from the options database 156 157 Collective on PetscSpace 158 159 Input Parameter: 160 . sp - the PetscSpace object to set options for 161 162 Options Database: 163 . -petscspace_degree the approximation order of the space 164 165 Level: developer 166 167 .seealso PetscSpaceView() 168 @*/ 169 PetscErrorCode PetscSpaceSetFromOptions(PetscSpace sp) 170 { 171 const char *defaultType; 172 char name[256]; 173 PetscBool flg, orderflg; 174 PetscErrorCode ierr; 175 176 PetscFunctionBegin; 177 PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 178 if (!((PetscObject) sp)->type_name) { 179 defaultType = PETSCSPACEPOLYNOMIAL; 180 } else { 181 defaultType = ((PetscObject) sp)->type_name; 182 } 183 if (!PetscSpaceRegisterAllCalled) {ierr = PetscSpaceRegisterAll();CHKERRQ(ierr);} 184 185 ierr = PetscObjectOptionsBegin((PetscObject) sp);CHKERRQ(ierr); 186 ierr = PetscOptionsFList("-petscspace_type", "Linear space", "PetscSpaceSetType", PetscSpaceList, defaultType, name, 256, &flg);CHKERRQ(ierr); 187 if (flg) { 188 ierr = PetscSpaceSetType(sp, name);CHKERRQ(ierr); 189 } else if (!((PetscObject) sp)->type_name) { 190 ierr = PetscSpaceSetType(sp, defaultType);CHKERRQ(ierr); 191 } 192 { 193 ierr = PetscOptionsInt("-petscspace_order", "DEPRECATED: The approximation order", "PetscSpaceSetDegree", sp->degree, &sp->degree, &orderflg);CHKERRQ(ierr); 194 if (orderflg) { 195 int compare; 196 197 ierr = MPI_Comm_compare(PetscObjectComm((PetscObject)sp), PETSC_COMM_WORLD, &compare);CHKERRQ(ierr); 198 199 if (compare == MPI_IDENT || compare == MPI_CONGRUENT) { 200 ierr = PetscPrintf(PetscObjectComm((PetscObject)sp), "Warning: -petscspace_order is deprecated. Use -petscspace_degree\n");CHKERRQ(ierr); 201 } 202 } 203 } 204 ierr = PetscOptionsInt("-petscspace_degree", "The (maximally included) polynomial degree", "PetscSpaceSetDegree", sp->degree, &sp->degree, NULL);CHKERRQ(ierr); 205 ierr = PetscOptionsInt("-petscspace_variables", "The number of different variables, e.g. x and y", "PetscSpaceSetNumVariables", sp->Nv, &sp->Nv, NULL);CHKERRQ(ierr); 206 ierr = PetscOptionsInt("-petscspace_components", "The number of components", "PetscSpaceSetNumComponents", sp->Nc, &sp->Nc, NULL);CHKERRQ(ierr); 207 if (sp->ops->setfromoptions) { 208 ierr = (*sp->ops->setfromoptions)(PetscOptionsObject,sp);CHKERRQ(ierr); 209 } 210 /* process any options handlers added with PetscObjectAddOptionsHandler() */ 211 ierr = PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject) sp);CHKERRQ(ierr); 212 ierr = PetscOptionsEnd();CHKERRQ(ierr); 213 ierr = PetscSpaceViewFromOptions(sp, NULL, "-petscspace_view");CHKERRQ(ierr); 214 PetscFunctionReturn(0); 215 } 216 217 /*@C 218 PetscSpaceSetUp - Construct data structures for the PetscSpace 219 220 Collective on PetscSpace 221 222 Input Parameter: 223 . sp - the PetscSpace object to setup 224 225 Level: developer 226 227 .seealso PetscSpaceView(), PetscSpaceDestroy() 228 @*/ 229 PetscErrorCode PetscSpaceSetUp(PetscSpace sp) 230 { 231 PetscErrorCode ierr; 232 233 PetscFunctionBegin; 234 PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 235 if (sp->ops->setup) {ierr = (*sp->ops->setup)(sp);CHKERRQ(ierr);} 236 PetscFunctionReturn(0); 237 } 238 239 /*@ 240 PetscSpaceDestroy - Destroys a PetscSpace object 241 242 Collective on PetscSpace 243 244 Input Parameter: 245 . sp - the PetscSpace object to destroy 246 247 Level: developer 248 249 .seealso PetscSpaceView() 250 @*/ 251 PetscErrorCode PetscSpaceDestroy(PetscSpace *sp) 252 { 253 PetscErrorCode ierr; 254 255 PetscFunctionBegin; 256 if (!*sp) PetscFunctionReturn(0); 257 PetscValidHeaderSpecific((*sp), PETSCSPACE_CLASSID, 1); 258 259 if (--((PetscObject)(*sp))->refct > 0) {*sp = 0; PetscFunctionReturn(0);} 260 ((PetscObject) (*sp))->refct = 0; 261 ierr = DMDestroy(&(*sp)->dm);CHKERRQ(ierr); 262 263 ierr = (*(*sp)->ops->destroy)(*sp);CHKERRQ(ierr); 264 ierr = PetscHeaderDestroy(sp);CHKERRQ(ierr); 265 PetscFunctionReturn(0); 266 } 267 268 /*@ 269 PetscSpaceCreate - Creates an empty PetscSpace object. The type can then be set with PetscSpaceSetType(). 270 271 Collective on MPI_Comm 272 273 Input Parameter: 274 . comm - The communicator for the PetscSpace object 275 276 Output Parameter: 277 . sp - The PetscSpace object 278 279 Level: beginner 280 281 .seealso: PetscSpaceSetType(), PETSCSPACEPOLYNOMIAL 282 @*/ 283 PetscErrorCode PetscSpaceCreate(MPI_Comm comm, PetscSpace *sp) 284 { 285 PetscSpace s; 286 PetscErrorCode ierr; 287 288 PetscFunctionBegin; 289 PetscValidPointer(sp, 2); 290 ierr = PetscCitationsRegister(FECitation,&FEcite);CHKERRQ(ierr); 291 *sp = NULL; 292 ierr = PetscFEInitializePackage();CHKERRQ(ierr); 293 294 ierr = PetscHeaderCreate(s, PETSCSPACE_CLASSID, "PetscSpace", "Linear Space", "PetscSpace", comm, PetscSpaceDestroy, PetscSpaceView);CHKERRQ(ierr); 295 296 s->degree = 0; 297 s->maxDegree = PETSC_DETERMINE; 298 s->Nc = 1; 299 s->Nv = 0; 300 s->dim = PETSC_DETERMINE; 301 ierr = DMShellCreate(comm, &s->dm);CHKERRQ(ierr); 302 ierr = PetscSpaceSetType(s, PETSCSPACEPOLYNOMIAL);CHKERRQ(ierr); 303 304 *sp = s; 305 PetscFunctionReturn(0); 306 } 307 308 /*@ 309 PetscSpaceGetDimension - Return the dimension of this space, i.e. the number of basis vectors 310 311 Input Parameter: 312 . sp - The PetscSpace 313 314 Output Parameter: 315 . dim - The dimension 316 317 Level: intermediate 318 319 .seealso: PetscSpaceGetDegree(), PetscSpaceCreate(), PetscSpace 320 @*/ 321 PetscErrorCode PetscSpaceGetDimension(PetscSpace sp, PetscInt *dim) 322 { 323 PetscErrorCode ierr; 324 325 PetscFunctionBegin; 326 PetscValidHeaderSpecific(sp, PETSCSPACE_CLASSID, 1); 327 PetscValidPointer(dim, 2); 328 if (sp->dim == PETSC_DETERMINE) { 329 if (sp->ops->getdimension) {ierr = (*sp->ops->getdimension)(sp, &sp->dim);CHKERRQ(ierr);} 330 } 331 *dim = sp->dim; 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