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