1 #include <petsc/private/dmmbimpl.h> /*I "petscdmmoab.h" I*/ 2 3 #include <petscdmmoab.h> 4 #include <MBTagConventions.hpp> 5 #include <moab/NestedRefine.hpp> 6 #include <moab/Skinner.hpp> 7 8 /*MC 9 DMMOAB = "moab" - A DM object that encapsulates an unstructured mesh described by the MOAB mesh database. 10 Direct access to the MOAB Interface and other mesh manipulation related objects are available 11 through public API. Ability to create global and local representation of Vecs containing all 12 unknowns in the interior and shared boundary via a transparent tag-data wrapper is provided 13 along with utility functions to traverse the mesh and assemble a discrete system via 14 field-based/blocked Vec(Get/Set) methods. Input from and output to different formats are 15 available. 16 17 Reference: https://www.mcs.anl.gov/~fathom/moab-docs/html/contents.html 18 19 Level: intermediate 20 21 .seealso: `DMType`, `DMMoabCreate()`, `DMCreate()`, `DMSetType()`, `DMMoabCreateMoab()` 22 M*/ 23 24 /* External function declarations here */ 25 PETSC_EXTERN PetscErrorCode DMCreateInterpolation_Moab(DM dmCoarse, DM dmFine, Mat *interpolation, Vec *scaling); 26 PETSC_EXTERN PetscErrorCode DMCreateDefaultConstraints_Moab(DM dm); 27 PETSC_EXTERN PetscErrorCode DMCreateMatrix_Moab(DM dm, Mat *J); 28 PETSC_EXTERN PetscErrorCode DMCreateCoordinateDM_Moab(DM dm, DM *cdm); 29 PETSC_EXTERN PetscErrorCode DMRefine_Moab(DM dm, MPI_Comm comm, DM *dmRefined); 30 PETSC_EXTERN PetscErrorCode DMCoarsen_Moab(DM dm, MPI_Comm comm, DM *dmCoarsened); 31 PETSC_EXTERN PetscErrorCode DMRefineHierarchy_Moab(DM dm, PetscInt nlevels, DM dmRefined[]); 32 PETSC_EXTERN PetscErrorCode DMCoarsenHierarchy_Moab(DM dm, PetscInt nlevels, DM dmCoarsened[]); 33 PETSC_EXTERN PetscErrorCode DMClone_Moab(DM dm, DM *newdm); 34 PETSC_EXTERN PetscErrorCode DMCreateGlobalVector_Moab(DM, Vec *); 35 PETSC_EXTERN PetscErrorCode DMCreateLocalVector_Moab(DM, Vec *); 36 PETSC_EXTERN PetscErrorCode DMCreateMatrix_Moab(DM dm, Mat *J); 37 PETSC_EXTERN PetscErrorCode DMGlobalToLocalBegin_Moab(DM, Vec, InsertMode, Vec); 38 PETSC_EXTERN PetscErrorCode DMGlobalToLocalEnd_Moab(DM, Vec, InsertMode, Vec); 39 PETSC_EXTERN PetscErrorCode DMLocalToGlobalBegin_Moab(DM, Vec, InsertMode, Vec); 40 PETSC_EXTERN PetscErrorCode DMLocalToGlobalEnd_Moab(DM, Vec, InsertMode, Vec); 41 42 /* Un-implemented routines */ 43 /* 44 PETSC_EXTERN PetscErrorCode DMCreatelocalsection_Moab(DM dm); 45 PETSC_EXTERN PetscErrorCode DMCreateInjection_Moab(DM dmCoarse, DM dmFine, Mat *mat); 46 PETSC_EXTERN PetscErrorCode DMLoad_Moab(DM dm, PetscViewer viewer); 47 PETSC_EXTERN PetscErrorCode DMGetDimPoints_Moab(DM dm, PetscInt dim, PetscInt *pStart, PetscInt *pEnd); 48 PETSC_EXTERN PetscErrorCode DMCreateSubDM_Moab(DM dm, PetscInt numFields, PetscInt fields[], IS *is, DM *subdm); 49 PETSC_EXTERN PetscErrorCode DMLocatePoints_Moab(DM dm, Vec v, IS *cellIS); 50 */ 51 52 /*@C 53 DMMoabCreate - Creates a DMMoab object, which encapsulates a moab instance 54 55 Collective 56 57 Input Parameter: 58 . comm - The communicator for the DMMoab object 59 60 Output Parameter: 61 . dmb - The DMMoab object 62 63 Level: beginner 64 65 @*/ 66 PetscErrorCode DMMoabCreate(MPI_Comm comm, DM *dmb) { 67 PetscFunctionBegin; 68 PetscValidPointer(dmb, 2); 69 PetscCall(DMCreate(comm, dmb)); 70 PetscCall(DMSetType(*dmb, DMMOAB)); 71 PetscFunctionReturn(0); 72 } 73 74 /*@C 75 DMMoabCreateMoab - Creates a DMMoab object, optionally from an instance and other data 76 77 Collective 78 79 Input Parameters: 80 + comm - The communicator for the DMMoab object 81 . mbiface - (ptr to) the MOAB Instance; if passed in NULL, MOAB instance is created inside PETSc, and destroyed 82 along with the DMMoab 83 . ltog_tag - A tag to use to retrieve global id for an entity; if 0, will use GLOBAL_ID_TAG_NAME/tag 84 - range - If non-NULL, contains range of entities to which DOFs will be assigned 85 86 Output Parameter: 87 . dmb - The DMMoab object 88 89 Level: intermediate 90 91 @*/ 92 PetscErrorCode DMMoabCreateMoab(MPI_Comm comm, moab::Interface *mbiface, moab::Tag *ltog_tag, moab::Range *range, DM *dmb) { 93 moab::ErrorCode merr; 94 DM dmmb; 95 DM_Moab *dmmoab; 96 97 PetscFunctionBegin; 98 PetscValidPointer(dmb, 6); 99 100 PetscCall(DMMoabCreate(comm, &dmmb)); 101 dmmoab = (DM_Moab *)(dmmb)->data; 102 103 if (!mbiface) { 104 dmmoab->mbiface = new moab::Core(); 105 dmmoab->icreatedinstance = PETSC_TRUE; 106 } else { 107 dmmoab->mbiface = mbiface; 108 dmmoab->icreatedinstance = PETSC_FALSE; 109 } 110 111 /* by default the fileset = root set. This set stores the hierarchy of entities belonging to current DM */ 112 dmmoab->fileset = 0; 113 dmmoab->hlevel = 0; 114 dmmoab->nghostrings = 0; 115 116 #ifdef MOAB_HAVE_MPI 117 moab::EntityHandle partnset; 118 119 /* Create root sets for each mesh. Then pass these 120 to the load_file functions to be populated. */ 121 merr = dmmoab->mbiface->create_meshset(moab::MESHSET_SET, partnset); 122 MBERR("Creating partition set failed", merr); 123 124 /* Create the parallel communicator object with the partition handle associated with MOAB */ 125 dmmoab->pcomm = moab::ParallelComm::get_pcomm(dmmoab->mbiface, partnset, &comm); 126 #endif 127 128 /* do the remaining initializations for DMMoab */ 129 dmmoab->bs = 1; 130 dmmoab->numFields = 1; 131 PetscCall(PetscMalloc(dmmoab->numFields * sizeof(char *), &dmmoab->fieldNames)); 132 PetscCall(PetscStrallocpy("DEFAULT", (char **)&dmmoab->fieldNames[0])); 133 dmmoab->rw_dbglevel = 0; 134 dmmoab->partition_by_rank = PETSC_FALSE; 135 dmmoab->extra_read_options[0] = '\0'; 136 dmmoab->extra_write_options[0] = '\0'; 137 dmmoab->read_mode = READ_PART; 138 dmmoab->write_mode = WRITE_PART; 139 140 /* set global ID tag handle */ 141 if (ltog_tag && *ltog_tag) { 142 PetscCall(DMMoabSetLocalToGlobalTag(dmmb, *ltog_tag)); 143 } else { 144 merr = dmmoab->mbiface->tag_get_handle(GLOBAL_ID_TAG_NAME, dmmoab->ltog_tag); 145 MBERRNM(merr); 146 if (ltog_tag) *ltog_tag = dmmoab->ltog_tag; 147 } 148 149 merr = dmmoab->mbiface->tag_get_handle(MATERIAL_SET_TAG_NAME, dmmoab->material_tag); 150 MBERRNM(merr); 151 152 /* set the local range of entities (vertices) of interest */ 153 if (range) { PetscCall(DMMoabSetLocalVertices(dmmb, range)); } 154 *dmb = dmmb; 155 PetscFunctionReturn(0); 156 } 157 158 #ifdef MOAB_HAVE_MPI 159 160 /*@C 161 DMMoabGetParallelComm - Get the ParallelComm used with this DMMoab 162 163 Collective 164 165 Input Parameter: 166 . dm - The DMMoab object being set 167 168 Output Parameter: 169 . pcomm - The ParallelComm for the DMMoab 170 171 Level: beginner 172 173 @*/ 174 PetscErrorCode DMMoabGetParallelComm(DM dm, moab::ParallelComm **pcomm) { 175 PetscFunctionBegin; 176 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 177 *pcomm = ((DM_Moab *)(dm)->data)->pcomm; 178 PetscFunctionReturn(0); 179 } 180 181 #endif /* MOAB_HAVE_MPI */ 182 183 /*@C 184 DMMoabSetInterface - Set the MOAB instance used with this DMMoab 185 186 Collective 187 188 Input Parameters: 189 + dm - The DMMoab object being set 190 - mbiface - The MOAB instance being set on this DMMoab 191 192 Level: beginner 193 194 @*/ 195 PetscErrorCode DMMoabSetInterface(DM dm, moab::Interface *mbiface) { 196 DM_Moab *dmmoab = (DM_Moab *)(dm)->data; 197 198 PetscFunctionBegin; 199 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 200 PetscValidPointer(mbiface, 2); 201 #ifdef MOAB_HAVE_MPI 202 dmmoab->pcomm = NULL; 203 #endif 204 dmmoab->mbiface = mbiface; 205 dmmoab->icreatedinstance = PETSC_FALSE; 206 PetscFunctionReturn(0); 207 } 208 209 /*@C 210 DMMoabGetInterface - Get the MOAB instance used with this DMMoab 211 212 Collective 213 214 Input Parameter: 215 . dm - The DMMoab object being set 216 217 Output Parameter: 218 . mbiface - The MOAB instance set on this DMMoab 219 220 Level: beginner 221 222 @*/ 223 PetscErrorCode DMMoabGetInterface(DM dm, moab::Interface **mbiface) { 224 static PetscBool cite = PETSC_FALSE; 225 226 PetscFunctionBegin; 227 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 228 PetscCall(PetscCitationsRegister("@techreport{tautges_moab:_2004,\n type = {{SAND2004-1592}},\n title = {{MOAB:} A Mesh-Oriented Database}, institution = {Sandia National Laboratories},\n author = {Tautges, T. J. and Meyers, R. and Merkley, " 229 "K. and Stimpson, C. and Ernst, C.},\n year = {2004}, note = {Report}\n}\n", 230 &cite)); 231 *mbiface = ((DM_Moab *)dm->data)->mbiface; 232 PetscFunctionReturn(0); 233 } 234 235 /*@C 236 DMMoabSetLocalVertices - Set the entities having DOFs on this DMMoab 237 238 Collective 239 240 Input Parameters: 241 + dm - The DMMoab object being set 242 - range - The entities treated by this DMMoab 243 244 Level: beginner 245 246 @*/ 247 PetscErrorCode DMMoabSetLocalVertices(DM dm, moab::Range *range) { 248 moab::Range tmpvtxs; 249 DM_Moab *dmmoab = (DM_Moab *)(dm)->data; 250 251 PetscFunctionBegin; 252 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 253 dmmoab->vlocal->clear(); 254 dmmoab->vowned->clear(); 255 256 dmmoab->vlocal->insert(range->begin(), range->end()); 257 258 #ifdef MOAB_HAVE_MPI 259 moab::ErrorCode merr; 260 /* filter based on parallel status */ 261 merr = dmmoab->pcomm->filter_pstatus(*dmmoab->vlocal, PSTATUS_NOT_OWNED, PSTATUS_NOT, -1, dmmoab->vowned); 262 MBERRNM(merr); 263 264 /* filter all the non-owned and shared entities out of the list */ 265 tmpvtxs = moab::subtract(*dmmoab->vlocal, *dmmoab->vowned); 266 merr = dmmoab->pcomm->filter_pstatus(tmpvtxs, PSTATUS_INTERFACE, PSTATUS_OR, -1, dmmoab->vghost); 267 MBERRNM(merr); 268 tmpvtxs = moab::subtract(tmpvtxs, *dmmoab->vghost); 269 *dmmoab->vlocal = moab::subtract(*dmmoab->vlocal, tmpvtxs); 270 #else 271 *dmmoab->vowned = *dmmoab->vlocal; 272 #endif 273 274 /* compute and cache the sizes of local and ghosted entities */ 275 dmmoab->nloc = dmmoab->vowned->size(); 276 dmmoab->nghost = dmmoab->vghost->size(); 277 #ifdef MOAB_HAVE_MPI 278 PetscCall(MPIU_Allreduce(&dmmoab->nloc, &dmmoab->n, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm)); 279 #else 280 dmmoab->n = dmmoab->nloc; 281 #endif 282 PetscFunctionReturn(0); 283 } 284 285 /*@C 286 DMMoabGetAllVertices - Get the entities having DOFs on this DMMoab 287 288 Collective 289 290 Input Parameter: 291 . dm - The DMMoab object being set 292 293 Output Parameter: 294 . owned - The local vertex entities in this DMMoab = (owned+ghosted) 295 296 Level: beginner 297 298 @*/ 299 PetscErrorCode DMMoabGetAllVertices(DM dm, moab::Range *local) { 300 PetscFunctionBegin; 301 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 302 if (local) *local = *((DM_Moab *)dm->data)->vlocal; 303 PetscFunctionReturn(0); 304 } 305 306 /*@C 307 DMMoabGetLocalVertices - Get the entities having DOFs on this DMMoab 308 309 Collective 310 311 Input Parameter: 312 . dm - The DMMoab object being set 313 314 Output Parameters: 315 + owned - The owned vertex entities in this DMMoab 316 - ghost - The ghosted entities (non-owned) stored locally in this partition 317 318 Level: beginner 319 320 @*/ 321 PetscErrorCode DMMoabGetLocalVertices(DM dm, const moab::Range **owned, const moab::Range **ghost) { 322 PetscFunctionBegin; 323 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 324 if (owned) *owned = ((DM_Moab *)dm->data)->vowned; 325 if (ghost) *ghost = ((DM_Moab *)dm->data)->vghost; 326 PetscFunctionReturn(0); 327 } 328 329 /*@C 330 DMMoabGetLocalElements - Get the higher-dimensional entities that are locally owned 331 332 Collective 333 334 Input Parameter: 335 . dm - The DMMoab object being set 336 337 Output Parameter: 338 . range - The entities owned locally 339 340 Level: beginner 341 342 @*/ 343 PetscErrorCode DMMoabGetLocalElements(DM dm, const moab::Range **range) { 344 PetscFunctionBegin; 345 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 346 if (range) *range = ((DM_Moab *)dm->data)->elocal; 347 PetscFunctionReturn(0); 348 } 349 350 /*@C 351 DMMoabSetLocalElements - Set the entities having DOFs on this DMMoab 352 353 Collective 354 355 Input Parameters: 356 + dm - The DMMoab object being set 357 - range - The entities treated by this DMMoab 358 359 Level: beginner 360 361 @*/ 362 PetscErrorCode DMMoabSetLocalElements(DM dm, moab::Range *range) { 363 DM_Moab *dmmoab = (DM_Moab *)(dm)->data; 364 365 PetscFunctionBegin; 366 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 367 dmmoab->elocal->clear(); 368 dmmoab->eghost->clear(); 369 dmmoab->elocal->insert(range->begin(), range->end()); 370 #ifdef MOAB_HAVE_MPI 371 moab::ErrorCode merr; 372 merr = dmmoab->pcomm->filter_pstatus(*dmmoab->elocal, PSTATUS_NOT_OWNED, PSTATUS_NOT); 373 MBERRNM(merr); 374 *dmmoab->eghost = moab::subtract(*range, *dmmoab->elocal); 375 #endif 376 dmmoab->neleloc = dmmoab->elocal->size(); 377 dmmoab->neleghost = dmmoab->eghost->size(); 378 #ifdef MOAB_HAVE_MPI 379 PetscCall(MPIU_Allreduce(&dmmoab->neleloc, &dmmoab->nele, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm)); 380 PetscInfo(dm, "Created %" PetscInt_FMT " local and %" PetscInt_FMT " global elements.\n", dmmoab->neleloc, dmmoab->nele); 381 #else 382 dmmoab->nele = dmmoab->neleloc; 383 #endif 384 PetscFunctionReturn(0); 385 } 386 387 /*@C 388 DMMoabSetLocalToGlobalTag - Set the tag used for local to global numbering 389 390 Collective 391 392 Input Parameters: 393 + dm - The DMMoab object being set 394 - ltogtag - The MOAB tag used for local to global ids 395 396 Level: beginner 397 398 @*/ 399 PetscErrorCode DMMoabSetLocalToGlobalTag(DM dm, moab::Tag ltogtag) { 400 PetscFunctionBegin; 401 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 402 ((DM_Moab *)dm->data)->ltog_tag = ltogtag; 403 PetscFunctionReturn(0); 404 } 405 406 /*@C 407 DMMoabGetLocalToGlobalTag - Get the tag used for local to global numbering 408 409 Collective 410 411 Input Parameter: 412 . dm - The DMMoab object being set 413 414 Output Parameter: 415 . ltogtag - The MOAB tag used for local to global ids 416 417 Level: beginner 418 419 @*/ 420 PetscErrorCode DMMoabGetLocalToGlobalTag(DM dm, moab::Tag *ltog_tag) { 421 PetscFunctionBegin; 422 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 423 *ltog_tag = ((DM_Moab *)dm->data)->ltog_tag; 424 PetscFunctionReturn(0); 425 } 426 427 /*@C 428 DMMoabSetBlockSize - Set the block size used with this DMMoab 429 430 Collective 431 432 Input Parameters: 433 + dm - The DMMoab object being set 434 - bs - The block size used with this DMMoab 435 436 Level: beginner 437 438 @*/ 439 PetscErrorCode DMMoabSetBlockSize(DM dm, PetscInt bs) { 440 PetscFunctionBegin; 441 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 442 ((DM_Moab *)dm->data)->bs = bs; 443 PetscFunctionReturn(0); 444 } 445 446 /*@C 447 DMMoabGetBlockSize - Get the block size used with this DMMoab 448 449 Collective 450 451 Input Parameter: 452 . dm - The DMMoab object being set 453 454 Output Parameter: 455 . bs - The block size used with this DMMoab 456 457 Level: beginner 458 459 @*/ 460 PetscErrorCode DMMoabGetBlockSize(DM dm, PetscInt *bs) { 461 PetscFunctionBegin; 462 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 463 *bs = ((DM_Moab *)dm->data)->bs; 464 PetscFunctionReturn(0); 465 } 466 467 /*@C 468 DMMoabGetSize - Get the global vertex size used with this DMMoab 469 470 Collective on dm 471 472 Input Parameter: 473 . dm - The DMMoab object being set 474 475 Output Parameters: 476 + neg - The number of global elements in the DMMoab instance 477 - nvg - The number of global vertices in the DMMoab instance 478 479 Level: beginner 480 481 @*/ 482 PetscErrorCode DMMoabGetSize(DM dm, PetscInt *neg, PetscInt *nvg) { 483 PetscFunctionBegin; 484 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 485 if (neg) *neg = ((DM_Moab *)dm->data)->nele; 486 if (nvg) *nvg = ((DM_Moab *)dm->data)->n; 487 PetscFunctionReturn(0); 488 } 489 490 /*@C 491 DMMoabGetLocalSize - Get the local and ghosted vertex size used with this DMMoab 492 493 Collective on dm 494 495 Input Parameter: 496 . dm - The DMMoab object being set 497 498 Output Parameters: 499 + nel - The number of owned elements in this processor 500 . neg - The number of ghosted elements in this processor 501 . nvl - The number of owned vertices in this processor 502 - nvg - The number of ghosted vertices in this processor 503 504 Level: beginner 505 506 @*/ 507 PetscErrorCode DMMoabGetLocalSize(DM dm, PetscInt *nel, PetscInt *neg, PetscInt *nvl, PetscInt *nvg) { 508 PetscFunctionBegin; 509 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 510 if (nel) *nel = ((DM_Moab *)dm->data)->neleloc; 511 if (neg) *neg = ((DM_Moab *)dm->data)->neleghost; 512 if (nvl) *nvl = ((DM_Moab *)dm->data)->nloc; 513 if (nvg) *nvg = ((DM_Moab *)dm->data)->nghost; 514 PetscFunctionReturn(0); 515 } 516 517 /*@C 518 DMMoabGetOffset - Get the local offset for the global vector 519 520 Collective 521 522 Input Parameter: 523 . dm - The DMMoab object being set 524 525 Output Parameter: 526 . offset - The local offset for the global vector 527 528 Level: beginner 529 530 @*/ 531 PetscErrorCode DMMoabGetOffset(DM dm, PetscInt *offset) { 532 PetscFunctionBegin; 533 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 534 *offset = ((DM_Moab *)dm->data)->vstart; 535 PetscFunctionReturn(0); 536 } 537 538 /*@C 539 DMMoabGetDimension - Get the dimension of the DM Mesh 540 541 Collective 542 543 Input Parameter: 544 . dm - The DMMoab object 545 546 Output Parameter: 547 . dim - The dimension of DM 548 549 Level: beginner 550 551 @*/ 552 PetscErrorCode DMMoabGetDimension(DM dm, PetscInt *dim) { 553 PetscFunctionBegin; 554 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 555 *dim = ((DM_Moab *)dm->data)->dim; 556 PetscFunctionReturn(0); 557 } 558 559 /*@C 560 DMMoabGetHierarchyLevel - Get the current level of the mesh hierarchy 561 generated through uniform refinement. 562 563 Collective on dm 564 565 Input Parameter: 566 . dm - The DMMoab object being set 567 568 Output Parameter: 569 . nvg - The current mesh hierarchy level 570 571 Level: beginner 572 573 @*/ 574 PetscErrorCode DMMoabGetHierarchyLevel(DM dm, PetscInt *nlevel) { 575 PetscFunctionBegin; 576 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 577 if (nlevel) *nlevel = ((DM_Moab *)dm->data)->hlevel; 578 PetscFunctionReturn(0); 579 } 580 581 /*@C 582 DMMoabGetMaterialBlock - Get the material ID corresponding to the current entity of the DM Mesh 583 584 Collective 585 586 Input Parameters: 587 + dm - The DMMoab object 588 - ehandle - The element entity handle 589 590 Output Parameter: 591 . mat - The material ID for the current entity 592 593 Level: beginner 594 595 @*/ 596 PetscErrorCode DMMoabGetMaterialBlock(DM dm, const moab::EntityHandle ehandle, PetscInt *mat) { 597 DM_Moab *dmmoab; 598 599 PetscFunctionBegin; 600 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 601 if (*mat) { 602 dmmoab = (DM_Moab *)(dm)->data; 603 *mat = dmmoab->materials[dmmoab->elocal->index(ehandle)]; 604 } 605 PetscFunctionReturn(0); 606 } 607 608 /*@C 609 DMMoabGetVertexCoordinates - Get the coordinates corresponding to the requested vertex entities 610 611 Collective 612 613 Input Parameters: 614 + dm - The DMMoab object 615 . nconn - Number of entities whose coordinates are needed 616 - conn - The vertex entity handles 617 618 Output Parameter: 619 . vpos - The coordinates of the requested vertex entities 620 621 Level: beginner 622 623 .seealso: `DMMoabGetVertexConnectivity()` 624 @*/ 625 PetscErrorCode DMMoabGetVertexCoordinates(DM dm, PetscInt nconn, const moab::EntityHandle *conn, PetscReal *vpos) { 626 DM_Moab *dmmoab; 627 moab::ErrorCode merr; 628 629 PetscFunctionBegin; 630 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 631 PetscValidPointer(conn, 3); 632 PetscValidPointer(vpos, 4); 633 dmmoab = (DM_Moab *)(dm)->data; 634 635 /* Get connectivity information in MOAB canonical ordering */ 636 if (dmmoab->hlevel) { 637 merr = dmmoab->hierarchy->get_coordinates(const_cast<moab::EntityHandle *>(conn), nconn, dmmoab->hlevel, vpos); 638 MBERRNM(merr); 639 } else { 640 merr = dmmoab->mbiface->get_coords(conn, nconn, vpos); 641 MBERRNM(merr); 642 } 643 PetscFunctionReturn(0); 644 } 645 646 /*@C 647 DMMoabGetVertexConnectivity - Get the vertex adjacency for the given entity 648 649 Collective 650 651 Input Parameters: 652 + dm - The DMMoab object 653 - vhandle - Vertex entity handle 654 655 Output Parameters: 656 + nconn - Number of entities whose coordinates are needed 657 - conn - The vertex entity handles 658 659 Level: beginner 660 661 .seealso: `DMMoabGetVertexCoordinates()`, `DMMoabRestoreVertexConnectivity()` 662 @*/ 663 PetscErrorCode DMMoabGetVertexConnectivity(DM dm, moab::EntityHandle vhandle, PetscInt *nconn, moab::EntityHandle **conn) { 664 DM_Moab *dmmoab; 665 std::vector<moab::EntityHandle> adj_entities, connect; 666 moab::ErrorCode merr; 667 668 PetscFunctionBegin; 669 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 670 PetscValidPointer(conn, 4); 671 dmmoab = (DM_Moab *)(dm)->data; 672 673 /* Get connectivity information in MOAB canonical ordering */ 674 merr = dmmoab->mbiface->get_adjacencies(&vhandle, 1, 1, true, adj_entities, moab::Interface::UNION); 675 MBERRNM(merr); 676 merr = dmmoab->mbiface->get_connectivity(&adj_entities[0], adj_entities.size(), connect); 677 MBERRNM(merr); 678 679 if (conn) { 680 PetscCall(PetscMalloc(sizeof(moab::EntityHandle) * connect.size(), conn)); 681 PetscCall(PetscArraycpy(*conn, &connect[0], connect.size())); 682 } 683 if (nconn) *nconn = connect.size(); 684 PetscFunctionReturn(0); 685 } 686 687 /*@C 688 DMMoabRestoreVertexConnectivity - Restore the vertex connectivity for the given entity 689 690 Collective 691 692 Input Parameters: 693 + dm - The DMMoab object 694 . vhandle - Vertex entity handle 695 . nconn - Number of entities whose coordinates are needed 696 - conn - The vertex entity handles 697 698 Level: beginner 699 700 .seealso: `DMMoabGetVertexCoordinates()`, `DMMoabGetVertexConnectivity()` 701 @*/ 702 PetscErrorCode DMMoabRestoreVertexConnectivity(DM dm, moab::EntityHandle ehandle, PetscInt *nconn, moab::EntityHandle **conn) { 703 PetscFunctionBegin; 704 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 705 PetscValidPointer(conn, 4); 706 707 if (conn) { PetscCall(PetscFree(*conn)); } 708 if (nconn) *nconn = 0; 709 PetscFunctionReturn(0); 710 } 711 712 /*@C 713 DMMoabGetElementConnectivity - Get the vertex adjacency for the given entity 714 715 Collective 716 717 Input Parameters: 718 + dm - The DMMoab object 719 - ehandle - Vertex entity handle 720 721 Output Parameters: 722 + nconn - Number of entities whose coordinates are needed 723 - conn - The vertex entity handles 724 725 Level: beginner 726 727 .seealso: `DMMoabGetVertexCoordinates()`, `DMMoabGetVertexConnectivity()`, `DMMoabRestoreVertexConnectivity()` 728 @*/ 729 PetscErrorCode DMMoabGetElementConnectivity(DM dm, moab::EntityHandle ehandle, PetscInt *nconn, const moab::EntityHandle **conn) { 730 DM_Moab *dmmoab; 731 const moab::EntityHandle *connect; 732 std::vector<moab::EntityHandle> vconn; 733 moab::ErrorCode merr; 734 PetscInt nnodes; 735 736 PetscFunctionBegin; 737 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 738 PetscValidPointer(conn, 4); 739 dmmoab = (DM_Moab *)(dm)->data; 740 741 /* Get connectivity information in MOAB canonical ordering */ 742 merr = dmmoab->mbiface->get_connectivity(ehandle, connect, nnodes); 743 MBERRNM(merr); 744 if (conn) *conn = connect; 745 if (nconn) *nconn = nnodes; 746 PetscFunctionReturn(0); 747 } 748 749 /*@C 750 DMMoabIsEntityOnBoundary - Check whether a given entity is on the boundary (vertex, edge, face, element) 751 752 Collective 753 754 Input Parameters: 755 + dm - The DMMoab object 756 - ent - Entity handle 757 758 Output Parameter: 759 . ent_on_boundary - PETSC_TRUE if entity on boundary; PETSC_FALSE otherwise 760 761 Level: beginner 762 763 .seealso: `DMMoabCheckBoundaryVertices()` 764 @*/ 765 PetscErrorCode DMMoabIsEntityOnBoundary(DM dm, const moab::EntityHandle ent, PetscBool *ent_on_boundary) { 766 moab::EntityType etype; 767 DM_Moab *dmmoab; 768 PetscInt edim; 769 770 PetscFunctionBegin; 771 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 772 PetscValidPointer(ent_on_boundary, 3); 773 dmmoab = (DM_Moab *)(dm)->data; 774 775 /* get the entity type and handle accordingly */ 776 etype = dmmoab->mbiface->type_from_handle(ent); 777 PetscCheck(etype < moab::MBPOLYHEDRON, PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE, "Entity type on the boundary skin is invalid. EntityType = %" PetscInt_FMT, etype); 778 779 /* get the entity dimension */ 780 edim = dmmoab->mbiface->dimension_from_handle(ent); 781 782 *ent_on_boundary = PETSC_FALSE; 783 if (etype == moab::MBVERTEX && edim == 0) { 784 *ent_on_boundary = ((dmmoab->bndyvtx->index(ent) >= 0) ? PETSC_TRUE : PETSC_FALSE); 785 } else { 786 if (edim == dmmoab->dim) { /* check the higher-dimensional elements first */ 787 if (dmmoab->bndyelems->index(ent) >= 0) *ent_on_boundary = PETSC_TRUE; 788 } else { /* next check the lower-dimensional faces */ 789 if (dmmoab->bndyfaces->index(ent) >= 0) *ent_on_boundary = PETSC_TRUE; 790 } 791 } 792 PetscFunctionReturn(0); 793 } 794 795 /*@C 796 DMMoabCheckBoundaryVertices - Check whether a given entity is on the boundary (vertex, edge, face, element) 797 798 Input Parameters: 799 + dm - The DMMoab object 800 . nconn - Number of handles 801 - cnt - Array of entity handles 802 803 Output Parameter: 804 . isbdvtx - Array of boundary markers - PETSC_TRUE if entity on boundary; PETSC_FALSE otherwise 805 806 Level: beginner 807 808 .seealso: `DMMoabIsEntityOnBoundary()` 809 @*/ 810 PetscErrorCode DMMoabCheckBoundaryVertices(DM dm, PetscInt nconn, const moab::EntityHandle *cnt, PetscBool *isbdvtx) { 811 DM_Moab *dmmoab; 812 PetscInt i; 813 814 PetscFunctionBegin; 815 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 816 PetscValidPointer(cnt, 3); 817 PetscValidPointer(isbdvtx, 4); 818 dmmoab = (DM_Moab *)(dm)->data; 819 820 for (i = 0; i < nconn; ++i) { isbdvtx[i] = (dmmoab->bndyvtx->index(cnt[i]) >= 0 ? PETSC_TRUE : PETSC_FALSE); } 821 PetscFunctionReturn(0); 822 } 823 824 /*@C 825 DMMoabGetBoundaryMarkers - Return references to the vertices, faces, elements on the boundary 826 827 Input Parameter: 828 . dm - The DMMoab object 829 830 Output Parameters: 831 + bdvtx - Boundary vertices 832 . bdelems - Boundary elements 833 - bdfaces - Boundary faces 834 835 Level: beginner 836 837 .seealso: `DMMoabCheckBoundaryVertices()`, `DMMoabIsEntityOnBoundary()` 838 @*/ 839 PetscErrorCode DMMoabGetBoundaryMarkers(DM dm, const moab::Range **bdvtx, const moab::Range **bdelems, const moab::Range **bdfaces) { 840 DM_Moab *dmmoab; 841 842 PetscFunctionBegin; 843 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 844 dmmoab = (DM_Moab *)(dm)->data; 845 846 if (bdvtx) *bdvtx = dmmoab->bndyvtx; 847 if (bdfaces) *bdfaces = dmmoab->bndyfaces; 848 if (bdelems) *bdfaces = dmmoab->bndyelems; 849 PetscFunctionReturn(0); 850 } 851 852 PETSC_EXTERN PetscErrorCode DMDestroy_Moab(DM dm) { 853 PetscInt i; 854 moab::ErrorCode merr; 855 DM_Moab *dmmoab = (DM_Moab *)dm->data; 856 857 PetscFunctionBegin; 858 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 859 860 dmmoab->refct--; 861 if (!dmmoab->refct) { 862 delete dmmoab->vlocal; 863 delete dmmoab->vowned; 864 delete dmmoab->vghost; 865 delete dmmoab->elocal; 866 delete dmmoab->eghost; 867 delete dmmoab->bndyvtx; 868 delete dmmoab->bndyfaces; 869 delete dmmoab->bndyelems; 870 871 PetscCall(PetscFree(dmmoab->gsindices)); 872 PetscCall(PetscFree2(dmmoab->gidmap, dmmoab->lidmap)); 873 PetscCall(PetscFree(dmmoab->dfill)); 874 PetscCall(PetscFree(dmmoab->ofill)); 875 PetscCall(PetscFree(dmmoab->materials)); 876 if (dmmoab->fieldNames) { 877 for (i = 0; i < dmmoab->numFields; i++) { PetscCall(PetscFree(dmmoab->fieldNames[i])); } 878 PetscCall(PetscFree(dmmoab->fieldNames)); 879 } 880 881 if (dmmoab->nhlevels) { 882 PetscCall(PetscFree(dmmoab->hsets)); 883 dmmoab->nhlevels = 0; 884 if (!dmmoab->hlevel && dmmoab->icreatedinstance) delete dmmoab->hierarchy; 885 dmmoab->hierarchy = NULL; 886 } 887 888 if (dmmoab->icreatedinstance) { 889 delete dmmoab->pcomm; 890 merr = dmmoab->mbiface->delete_mesh(); 891 MBERRNM(merr); 892 delete dmmoab->mbiface; 893 } 894 dmmoab->mbiface = NULL; 895 #ifdef MOAB_HAVE_MPI 896 dmmoab->pcomm = NULL; 897 #endif 898 PetscCall(VecScatterDestroy(&dmmoab->ltog_sendrecv)); 899 PetscCall(ISLocalToGlobalMappingDestroy(&dmmoab->ltog_map)); 900 PetscCall(PetscFree(dm->data)); 901 } 902 PetscFunctionReturn(0); 903 } 904 905 PETSC_EXTERN PetscErrorCode DMSetFromOptions_Moab(DM dm, PetscOptionItems *PetscOptionsObject) { 906 DM_Moab *dmmoab = (DM_Moab *)dm->data; 907 908 PetscFunctionBegin; 909 PetscOptionsHeadBegin(PetscOptionsObject, "DMMoab Options"); 910 PetscCall(PetscOptionsBoundedInt("-dm_moab_rw_dbg", "The verbosity level for reading and writing MOAB meshes", "DMView", dmmoab->rw_dbglevel, &dmmoab->rw_dbglevel, NULL, 0)); 911 PetscCall(PetscOptionsBool("-dm_moab_partiton_by_rank", "Use partition by rank when reading MOAB meshes from file", "DMView", dmmoab->partition_by_rank, &dmmoab->partition_by_rank, NULL)); 912 /* TODO: typically, the read options are needed before a DM is completely created and available in which case, the options wont be available ?? */ 913 PetscCall(PetscOptionsString("-dm_moab_read_opts", "Extra options to enable MOAB reader to load DM from file", "DMView", dmmoab->extra_read_options, dmmoab->extra_read_options, sizeof(dmmoab->extra_read_options), NULL)); 914 PetscCall(PetscOptionsString("-dm_moab_write_opts", "Extra options to enable MOAB writer to serialize DM to file", "DMView", dmmoab->extra_write_options, dmmoab->extra_write_options, sizeof(dmmoab->extra_write_options), NULL)); 915 PetscCall(PetscOptionsEnum("-dm_moab_read_mode", "MOAB parallel read mode", "DMView", MoabReadModes, (PetscEnum)dmmoab->read_mode, (PetscEnum *)&dmmoab->read_mode, NULL)); 916 PetscCall(PetscOptionsEnum("-dm_moab_write_mode", "MOAB parallel write mode", "DMView", MoabWriteModes, (PetscEnum)dmmoab->write_mode, (PetscEnum *)&dmmoab->write_mode, NULL)); 917 PetscOptionsHeadEnd(); 918 PetscFunctionReturn(0); 919 } 920 921 PETSC_EXTERN PetscErrorCode DMSetUp_Moab(DM dm) { 922 moab::ErrorCode merr; 923 Vec local, global; 924 IS from, to; 925 moab::Range::iterator iter; 926 PetscInt i, j, f, bs, vent, totsize, *lgmap; 927 DM_Moab *dmmoab = (DM_Moab *)dm->data; 928 moab::Range adjs; 929 930 PetscFunctionBegin; 931 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 932 /* Get the local and shared vertices and cache it */ 933 PetscCheck(dmmoab->mbiface != NULL, PETSC_COMM_WORLD, PETSC_ERR_ORDER, "Set the MOAB Interface before calling SetUp."); 934 #ifdef MOAB_HAVE_MPI 935 PetscCheck(dmmoab->pcomm != NULL, PETSC_COMM_WORLD, PETSC_ERR_ORDER, "Set the MOAB ParallelComm object before calling SetUp."); 936 #endif 937 938 /* Get the entities recursively in the current part of the mesh, if user did not set the local vertices explicitly */ 939 if (dmmoab->vlocal->empty()) { 940 //merr = dmmoab->mbiface->get_entities_by_type(dmmoab->fileset,moab::MBVERTEX,*dmmoab->vlocal,true);MBERRNM(merr); 941 merr = dmmoab->mbiface->get_entities_by_dimension(dmmoab->fileset, 0, *dmmoab->vlocal, false); 942 MBERRNM(merr); 943 944 #ifdef MOAB_HAVE_MPI 945 /* filter based on parallel status */ 946 merr = dmmoab->pcomm->filter_pstatus(*dmmoab->vlocal, PSTATUS_NOT_OWNED, PSTATUS_NOT, -1, dmmoab->vowned); 947 MBERRNM(merr); 948 949 /* filter all the non-owned and shared entities out of the list */ 950 // *dmmoab->vghost = moab::subtract(*dmmoab->vlocal, *dmmoab->vowned); 951 adjs = moab::subtract(*dmmoab->vlocal, *dmmoab->vowned); 952 merr = dmmoab->pcomm->filter_pstatus(adjs, PSTATUS_GHOST | PSTATUS_INTERFACE, PSTATUS_OR, -1, dmmoab->vghost); 953 MBERRNM(merr); 954 adjs = moab::subtract(adjs, *dmmoab->vghost); 955 *dmmoab->vlocal = moab::subtract(*dmmoab->vlocal, adjs); 956 #else 957 *dmmoab->vowned = *dmmoab->vlocal; 958 #endif 959 960 /* compute and cache the sizes of local and ghosted entities */ 961 dmmoab->nloc = dmmoab->vowned->size(); 962 dmmoab->nghost = dmmoab->vghost->size(); 963 964 #ifdef MOAB_HAVE_MPI 965 PetscCall(MPIU_Allreduce(&dmmoab->nloc, &dmmoab->n, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm)); 966 PetscInfo(NULL, "Filset ID: %lu, Vertices: local - %zu, owned - %" PetscInt_FMT ", ghosted - %" PetscInt_FMT ".\n", dmmoab->fileset, dmmoab->vlocal->size(), dmmoab->nloc, dmmoab->nghost); 967 #else 968 dmmoab->n = dmmoab->nloc; 969 #endif 970 } 971 972 { 973 /* get the information about the local elements in the mesh */ 974 dmmoab->eghost->clear(); 975 976 /* first decipher the leading dimension */ 977 for (i = 3; i > 0; i--) { 978 dmmoab->elocal->clear(); 979 merr = dmmoab->mbiface->get_entities_by_dimension(dmmoab->fileset, i, *dmmoab->elocal, false); 980 MBERRNM(merr); 981 982 /* store the current mesh dimension */ 983 if (dmmoab->elocal->size()) { 984 dmmoab->dim = i; 985 break; 986 } 987 } 988 989 PetscCall(DMSetDimension(dm, dmmoab->dim)); 990 991 #ifdef MOAB_HAVE_MPI 992 /* filter the ghosted and owned element list */ 993 *dmmoab->eghost = *dmmoab->elocal; 994 merr = dmmoab->pcomm->filter_pstatus(*dmmoab->elocal, PSTATUS_NOT_OWNED, PSTATUS_NOT); 995 MBERRNM(merr); 996 *dmmoab->eghost = moab::subtract(*dmmoab->eghost, *dmmoab->elocal); 997 #endif 998 999 dmmoab->neleloc = dmmoab->elocal->size(); 1000 dmmoab->neleghost = dmmoab->eghost->size(); 1001 1002 #ifdef MOAB_HAVE_MPI 1003 PetscCall(MPIU_Allreduce(&dmmoab->neleloc, &dmmoab->nele, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm)); 1004 PetscInfo(NULL, "%d-dim elements: owned - %" PetscInt_FMT ", ghosted - %" PetscInt_FMT ".\n", dmmoab->dim, dmmoab->neleloc, dmmoab->neleghost); 1005 #else 1006 dmmoab->nele = dmmoab->neleloc; 1007 #endif 1008 } 1009 1010 bs = dmmoab->bs; 1011 if (!dmmoab->ltog_tag) { 1012 /* Get the global ID tag. The global ID tag is applied to each 1013 vertex. It acts as an global identifier which MOAB uses to 1014 assemble the individual pieces of the mesh */ 1015 merr = dmmoab->mbiface->tag_get_handle(GLOBAL_ID_TAG_NAME, dmmoab->ltog_tag); 1016 MBERRNM(merr); 1017 } 1018 1019 totsize = dmmoab->vlocal->size(); 1020 PetscCheck(totsize == dmmoab->nloc + dmmoab->nghost, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Mismatch between local and owned+ghost vertices. %" PetscInt_FMT " != %" PetscInt_FMT ".", totsize, dmmoab->nloc + dmmoab->nghost); 1021 PetscCall(PetscCalloc1(totsize, &dmmoab->gsindices)); 1022 { 1023 /* first get the local indices */ 1024 merr = dmmoab->mbiface->tag_get_data(dmmoab->ltog_tag, *dmmoab->vowned, &dmmoab->gsindices[0]); 1025 MBERRNM(merr); 1026 if (dmmoab->nghost) { /* next get the ghosted indices */ 1027 merr = dmmoab->mbiface->tag_get_data(dmmoab->ltog_tag, *dmmoab->vghost, &dmmoab->gsindices[dmmoab->nloc]); 1028 MBERRNM(merr); 1029 } 1030 1031 /* find out the local and global minima of GLOBAL_ID */ 1032 dmmoab->lminmax[0] = dmmoab->lminmax[1] = dmmoab->gsindices[0]; 1033 for (i = 0; i < totsize; ++i) { 1034 if (dmmoab->lminmax[0] > dmmoab->gsindices[i]) dmmoab->lminmax[0] = dmmoab->gsindices[i]; 1035 if (dmmoab->lminmax[1] < dmmoab->gsindices[i]) dmmoab->lminmax[1] = dmmoab->gsindices[i]; 1036 } 1037 1038 PetscCall(MPIU_Allreduce(&dmmoab->lminmax[0], &dmmoab->gminmax[0], 1, MPI_INT, MPI_MIN, ((PetscObject)dm)->comm)); 1039 PetscCall(MPIU_Allreduce(&dmmoab->lminmax[1], &dmmoab->gminmax[1], 1, MPI_INT, MPI_MAX, ((PetscObject)dm)->comm)); 1040 1041 /* set the GID map */ 1042 for (i = 0; i < totsize; ++i) { dmmoab->gsindices[i] -= dmmoab->gminmax[0]; /* zero based index needed for IS */ } 1043 dmmoab->lminmax[0] -= dmmoab->gminmax[0]; 1044 dmmoab->lminmax[1] -= dmmoab->gminmax[0]; 1045 1046 PetscInfo(NULL, "GLOBAL_ID: Local [min, max] - [%" PetscInt_FMT ", %" PetscInt_FMT "], Global [min, max] - [%" PetscInt_FMT ", %" PetscInt_FMT "]\n", dmmoab->lminmax[0], dmmoab->lminmax[1], dmmoab->gminmax[0], dmmoab->gminmax[1]); 1047 } 1048 PetscCheck(dmmoab->bs == dmmoab->numFields || dmmoab->bs == 1, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Mismatch between block size and number of component fields. %" PetscInt_FMT " != 1 OR %" PetscInt_FMT " != %" PetscInt_FMT ".", dmmoab->bs, dmmoab->bs, 1049 dmmoab->numFields); 1050 1051 { 1052 dmmoab->seqstart = dmmoab->mbiface->id_from_handle(dmmoab->vlocal->front()); 1053 dmmoab->seqend = dmmoab->mbiface->id_from_handle(dmmoab->vlocal->back()); 1054 PetscInfo(NULL, "SEQUENCE: Local [min, max] - [%" PetscInt_FMT ", %" PetscInt_FMT "]\n", dmmoab->seqstart, dmmoab->seqend); 1055 1056 PetscCall(PetscMalloc2(dmmoab->seqend - dmmoab->seqstart + 1, &dmmoab->gidmap, dmmoab->seqend - dmmoab->seqstart + 1, &dmmoab->lidmap)); 1057 PetscCall(PetscMalloc1(totsize * dmmoab->numFields, &lgmap)); 1058 1059 i = j = 0; 1060 /* set the owned vertex data first */ 1061 for (moab::Range::iterator iter = dmmoab->vowned->begin(); iter != dmmoab->vowned->end(); iter++, i++) { 1062 vent = dmmoab->mbiface->id_from_handle(*iter) - dmmoab->seqstart; 1063 dmmoab->gidmap[vent] = dmmoab->gsindices[i]; 1064 dmmoab->lidmap[vent] = i; 1065 for (f = 0; f < dmmoab->numFields; f++, j++) { lgmap[j] = (bs > 1 ? dmmoab->gsindices[i] * dmmoab->numFields + f : totsize * f + dmmoab->gsindices[i]); } 1066 } 1067 /* next arrange all the ghosted data information */ 1068 for (moab::Range::iterator iter = dmmoab->vghost->begin(); iter != dmmoab->vghost->end(); iter++, i++) { 1069 vent = dmmoab->mbiface->id_from_handle(*iter) - dmmoab->seqstart; 1070 dmmoab->gidmap[vent] = dmmoab->gsindices[i]; 1071 dmmoab->lidmap[vent] = i; 1072 for (f = 0; f < dmmoab->numFields; f++, j++) { lgmap[j] = (bs > 1 ? dmmoab->gsindices[i] * dmmoab->numFields + f : totsize * f + dmmoab->gsindices[i]); } 1073 } 1074 1075 /* We need to create the Global to Local Vector Scatter Contexts 1076 1) First create a local and global vector 1077 2) Create a local and global IS 1078 3) Create VecScatter and LtoGMapping objects 1079 4) Cleanup the IS and Vec objects 1080 */ 1081 PetscCall(DMCreateGlobalVector(dm, &global)); 1082 PetscCall(DMCreateLocalVector(dm, &local)); 1083 1084 PetscCall(VecGetOwnershipRange(global, &dmmoab->vstart, &dmmoab->vend)); 1085 1086 /* global to local must retrieve ghost points */ 1087 PetscCall(ISCreateStride(((PetscObject)dm)->comm, dmmoab->nloc * dmmoab->numFields, dmmoab->vstart, 1, &from)); 1088 PetscCall(ISSetBlockSize(from, bs)); 1089 1090 PetscCall(ISCreateGeneral(((PetscObject)dm)->comm, dmmoab->nloc * dmmoab->numFields, &lgmap[0], PETSC_COPY_VALUES, &to)); 1091 PetscCall(ISSetBlockSize(to, bs)); 1092 1093 if (!dmmoab->ltog_map) { 1094 /* create to the local to global mapping for vectors in order to use VecSetValuesLocal */ 1095 PetscCall(ISLocalToGlobalMappingCreate(((PetscObject)dm)->comm, dmmoab->bs, totsize * dmmoab->numFields, lgmap, PETSC_COPY_VALUES, &dmmoab->ltog_map)); 1096 } 1097 1098 /* now create the scatter object from local to global vector */ 1099 PetscCall(VecScatterCreate(local, from, global, to, &dmmoab->ltog_sendrecv)); 1100 1101 /* clean up IS, Vec */ 1102 PetscCall(PetscFree(lgmap)); 1103 PetscCall(ISDestroy(&from)); 1104 PetscCall(ISDestroy(&to)); 1105 PetscCall(VecDestroy(&local)); 1106 PetscCall(VecDestroy(&global)); 1107 } 1108 1109 dmmoab->bndyvtx = new moab::Range(); 1110 dmmoab->bndyfaces = new moab::Range(); 1111 dmmoab->bndyelems = new moab::Range(); 1112 /* skin the boundary and store nodes */ 1113 if (!dmmoab->hlevel) { 1114 /* get the skin vertices of boundary faces for the current partition and then filter 1115 the local, boundary faces, vertices and elements alone via PSTATUS flags; 1116 this should not give us any ghosted boundary, but if user needs such a functionality 1117 it would be easy to add it based on the find_skin query below */ 1118 moab::Skinner skinner(dmmoab->mbiface); 1119 1120 /* get the entities on the skin - only the faces */ 1121 merr = skinner.find_skin(dmmoab->fileset, *dmmoab->elocal, false, *dmmoab->bndyfaces, NULL, true, true, false); 1122 MBERRNM(merr); // 'false' param indicates we want faces back, not vertices 1123 1124 #ifdef MOAB_HAVE_MPI 1125 /* filter all the non-owned and shared entities out of the list */ 1126 merr = dmmoab->pcomm->filter_pstatus(*dmmoab->bndyfaces, PSTATUS_NOT_OWNED, PSTATUS_NOT); 1127 MBERRNM(merr); 1128 merr = dmmoab->pcomm->filter_pstatus(*dmmoab->bndyfaces, PSTATUS_INTERFACE, PSTATUS_NOT); 1129 MBERRNM(merr); 1130 #endif 1131 1132 /* get all the nodes via connectivity and the parent elements via adjacency information */ 1133 merr = dmmoab->mbiface->get_connectivity(*dmmoab->bndyfaces, *dmmoab->bndyvtx, false); 1134 MBERRNM(merr); 1135 merr = dmmoab->mbiface->get_adjacencies(*dmmoab->bndyvtx, dmmoab->dim, false, *dmmoab->bndyelems, moab::Interface::UNION); 1136 MBERRNM(merr); 1137 } else { 1138 /* Let us query the hierarchy manager and get the results directly for this level */ 1139 for (moab::Range::iterator iter = dmmoab->elocal->begin(); iter != dmmoab->elocal->end(); iter++) { 1140 moab::EntityHandle elemHandle = *iter; 1141 if (dmmoab->hierarchy->is_entity_on_boundary(elemHandle)) { 1142 dmmoab->bndyelems->insert(elemHandle); 1143 /* For this boundary element, query the vertices and add them to the list */ 1144 std::vector<moab::EntityHandle> connect; 1145 merr = dmmoab->hierarchy->get_connectivity(elemHandle, dmmoab->hlevel, connect); 1146 MBERRNM(merr); 1147 for (unsigned iv = 0; iv < connect.size(); ++iv) 1148 if (dmmoab->hierarchy->is_entity_on_boundary(connect[iv])) dmmoab->bndyvtx->insert(connect[iv]); 1149 /* Next, let us query the boundary faces and add them also to the list */ 1150 std::vector<moab::EntityHandle> faces; 1151 merr = dmmoab->hierarchy->get_adjacencies(elemHandle, dmmoab->dim - 1, faces); 1152 MBERRNM(merr); 1153 for (unsigned ifa = 0; ifa < faces.size(); ++ifa) 1154 if (dmmoab->hierarchy->is_entity_on_boundary(faces[ifa])) dmmoab->bndyfaces->insert(faces[ifa]); 1155 } 1156 } 1157 #ifdef MOAB_HAVE_MPI 1158 /* filter all the non-owned and shared entities out of the list */ 1159 merr = dmmoab->pcomm->filter_pstatus(*dmmoab->bndyvtx, PSTATUS_NOT_OWNED, PSTATUS_NOT); 1160 MBERRNM(merr); 1161 merr = dmmoab->pcomm->filter_pstatus(*dmmoab->bndyfaces, PSTATUS_NOT_OWNED, PSTATUS_NOT); 1162 MBERRNM(merr); 1163 merr = dmmoab->pcomm->filter_pstatus(*dmmoab->bndyelems, PSTATUS_NOT_OWNED, PSTATUS_NOT); 1164 MBERRNM(merr); 1165 #endif 1166 } 1167 PetscInfo(NULL, "Found %zu boundary vertices, %zu boundary faces and %zu boundary elements.\n", dmmoab->bndyvtx->size(), dmmoab->bndyfaces->size(), dmmoab->bndyelems->size()); 1168 1169 /* Get the material sets and populate the data for all locally owned elements */ 1170 { 1171 PetscCall(PetscCalloc1(dmmoab->elocal->size(), &dmmoab->materials)); 1172 /* Get the count of entities of particular type from dmmoab->elocal 1173 -- Then, for each non-zero type, loop through and query the fileset to get the material tag data */ 1174 moab::Range msets; 1175 merr = dmmoab->mbiface->get_entities_by_type_and_tag(dmmoab->fileset, moab::MBENTITYSET, &dmmoab->material_tag, NULL, 1, msets, moab::Interface::UNION); 1176 MB_CHK_ERR(merr); 1177 if (msets.size() == 0) { PetscInfo(NULL, "No material sets found in the fileset."); } 1178 1179 for (unsigned i = 0; i < msets.size(); ++i) { 1180 moab::Range msetelems; 1181 merr = dmmoab->mbiface->get_entities_by_dimension(msets[i], dmmoab->dim, msetelems, true); 1182 MB_CHK_ERR(merr); 1183 #ifdef MOAB_HAVE_MPI 1184 /* filter all the non-owned and shared entities out of the list */ 1185 merr = dmmoab->pcomm->filter_pstatus(msetelems, PSTATUS_NOT_OWNED, PSTATUS_NOT); 1186 MBERRNM(merr); 1187 #endif 1188 1189 int partID; 1190 moab::EntityHandle mset = msets[i]; 1191 merr = dmmoab->mbiface->tag_get_data(dmmoab->material_tag, &mset, 1, &partID); 1192 MB_CHK_ERR(merr); 1193 1194 for (unsigned j = 0; j < msetelems.size(); ++j) dmmoab->materials[dmmoab->elocal->index(msetelems[j])] = partID; 1195 } 1196 } 1197 1198 PetscFunctionReturn(0); 1199 } 1200 1201 /*@C 1202 DMMoabCreateVertices - Creates and adds several vertices to the primary set represented by the DM. 1203 1204 Collective 1205 1206 Input Parameters: 1207 + dm - The DM object 1208 . type - The type of element to create and add (Edge/Tri/Quad/Tet/Hex/Prism/Pyramid/Polygon/Polyhedra) 1209 . conn - The connectivity of the element 1210 - nverts - The number of vertices that form the element 1211 1212 Output Parameter: 1213 . overts - The list of vertices that were created (can be NULL) 1214 1215 Level: beginner 1216 1217 .seealso: `DMMoabCreateSubmesh()`, `DMMoabCreateElement()` 1218 @*/ 1219 PetscErrorCode DMMoabCreateVertices(DM dm, const PetscReal *coords, PetscInt nverts, moab::Range *overts) { 1220 moab::ErrorCode merr; 1221 DM_Moab *dmmoab; 1222 moab::Range verts; 1223 1224 PetscFunctionBegin; 1225 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1226 PetscValidPointer(coords, 2); 1227 1228 dmmoab = (DM_Moab *)dm->data; 1229 1230 /* Insert new points */ 1231 merr = dmmoab->mbiface->create_vertices(&coords[0], nverts, verts); 1232 MBERRNM(merr); 1233 merr = dmmoab->mbiface->add_entities(dmmoab->fileset, verts); 1234 MBERRNM(merr); 1235 1236 if (overts) *overts = verts; 1237 PetscFunctionReturn(0); 1238 } 1239 1240 /*@C 1241 DMMoabCreateElement - Adds an element of specified type to the primary set represented by the DM. 1242 1243 Collective 1244 1245 Input Parameters: 1246 + dm - The DM object 1247 . type - The type of element to create and add (Edge/Tri/Quad/Tet/Hex/Prism/Pyramid/Polygon/Polyhedra) 1248 . conn - The connectivity of the element 1249 - nverts - The number of vertices that form the element 1250 1251 Output Parameter: 1252 . oelem - The handle to the element created and added to the DM object 1253 1254 Level: beginner 1255 1256 .seealso: `DMMoabCreateSubmesh()`, `DMMoabCreateVertices()` 1257 @*/ 1258 PetscErrorCode DMMoabCreateElement(DM dm, const moab::EntityType type, const moab::EntityHandle *conn, PetscInt nverts, moab::EntityHandle *oelem) { 1259 moab::ErrorCode merr; 1260 DM_Moab *dmmoab; 1261 moab::EntityHandle elem; 1262 1263 PetscFunctionBegin; 1264 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1265 PetscValidPointer(conn, 3); 1266 1267 dmmoab = (DM_Moab *)dm->data; 1268 1269 /* Insert new element */ 1270 merr = dmmoab->mbiface->create_element(type, conn, nverts, elem); 1271 MBERRNM(merr); 1272 merr = dmmoab->mbiface->add_entities(dmmoab->fileset, &elem, 1); 1273 MBERRNM(merr); 1274 1275 if (oelem) *oelem = elem; 1276 PetscFunctionReturn(0); 1277 } 1278 1279 /*@C 1280 DMMoabCreateSubmesh - Creates a sub-DM object with a set that contains all vertices/elements of the parent 1281 in addition to providing support for dynamic mesh modifications. This is useful for AMR calculations to 1282 create a DM object on a refined level. 1283 1284 Collective 1285 1286 Input Parameters: 1287 . dm - The DM object 1288 1289 Output Parameter: 1290 . newdm - The sub DM object with updated set information 1291 1292 Level: advanced 1293 1294 .seealso: `DMCreate()`, `DMMoabCreateVertices()`, `DMMoabCreateElement()` 1295 @*/ 1296 PetscErrorCode DMMoabCreateSubmesh(DM dm, DM *newdm) { 1297 DM_Moab *dmmoab; 1298 DM_Moab *ndmmoab; 1299 moab::ErrorCode merr; 1300 1301 PetscFunctionBegin; 1302 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1303 1304 dmmoab = (DM_Moab *)dm->data; 1305 1306 /* Create the basic DMMoab object and keep the default parameters created by DM impls */ 1307 PetscCall(DMMoabCreateMoab(((PetscObject)dm)->comm, dmmoab->mbiface, &dmmoab->ltog_tag, PETSC_NULL, newdm)); 1308 1309 /* get all the necessary handles from the private DM object */ 1310 ndmmoab = (DM_Moab *)(*newdm)->data; 1311 1312 /* set the sub-mesh's parent DM reference */ 1313 ndmmoab->parent = &dm; 1314 1315 /* create a file set to associate all entities in current mesh */ 1316 merr = ndmmoab->mbiface->create_meshset(moab::MESHSET_SET, ndmmoab->fileset); 1317 MBERR("Creating file set failed", merr); 1318 1319 /* create a meshset and then add old fileset as child */ 1320 merr = ndmmoab->mbiface->add_entities(ndmmoab->fileset, *dmmoab->vlocal); 1321 MBERR("Adding child vertices to parent failed", merr); 1322 merr = ndmmoab->mbiface->add_entities(ndmmoab->fileset, *dmmoab->elocal); 1323 MBERR("Adding child elements to parent failed", merr); 1324 1325 /* preserve the field association between the parent and sub-mesh objects */ 1326 PetscCall(DMMoabSetFieldNames(*newdm, dmmoab->numFields, dmmoab->fieldNames)); 1327 PetscFunctionReturn(0); 1328 } 1329 1330 PETSC_EXTERN PetscErrorCode DMMoabView_Ascii(DM dm, PetscViewer viewer) { 1331 DM_Moab *dmmoab = (DM_Moab *)(dm)->data; 1332 const char *name; 1333 MPI_Comm comm; 1334 PetscMPIInt size; 1335 1336 PetscFunctionBegin; 1337 PetscCall(PetscObjectGetComm((PetscObject)dm, &comm)); 1338 PetscCallMPI(MPI_Comm_size(comm, &size)); 1339 PetscCall(PetscObjectGetName((PetscObject)dm, &name)); 1340 PetscCall(PetscViewerASCIIPushTab(viewer)); 1341 if (name) PetscCall(PetscViewerASCIIPrintf(viewer, "%s in %" PetscInt_FMT " dimensions:\n", name, dmmoab->dim)); 1342 else PetscCall(PetscViewerASCIIPrintf(viewer, "Mesh in %" PetscInt_FMT " dimensions:\n", dmmoab->dim)); 1343 /* print details about the global mesh */ 1344 { 1345 PetscCall(PetscViewerASCIIPushTab(viewer)); 1346 PetscCall(PetscViewerASCIIPrintf(viewer, "Sizes: cells=%" PetscInt_FMT ", vertices=%" PetscInt_FMT ", blocks=%" PetscInt_FMT "\n", dmmoab->nele, dmmoab->n, dmmoab->bs)); 1347 /* print boundary data */ 1348 PetscCall(PetscViewerASCIIPrintf(viewer, "Boundary trace:\n")); 1349 { 1350 PetscCall(PetscViewerASCIIPushTab(viewer)); 1351 PetscCall(PetscViewerASCIIPrintf(viewer, "cells=%zu, faces=%zu, vertices=%zu\n", dmmoab->bndyelems->size(), dmmoab->bndyfaces->size(), dmmoab->bndyvtx->size())); 1352 PetscCall(PetscViewerASCIIPopTab(viewer)); 1353 } 1354 /* print field data */ 1355 PetscCall(PetscViewerASCIIPrintf(viewer, "Fields: %" PetscInt_FMT " components\n", dmmoab->numFields)); 1356 { 1357 PetscCall(PetscViewerASCIIPushTab(viewer)); 1358 for (int i = 0; i < dmmoab->numFields; ++i) { PetscCall(PetscViewerASCIIPrintf(viewer, "[%" PetscInt_FMT "] - %s\n", i, dmmoab->fieldNames[i])); } 1359 PetscCall(PetscViewerASCIIPopTab(viewer)); 1360 } 1361 PetscCall(PetscViewerASCIIPopTab(viewer)); 1362 } 1363 PetscCall(PetscViewerASCIIPopTab(viewer)); 1364 PetscCall(PetscViewerFlush(viewer)); 1365 PetscFunctionReturn(0); 1366 } 1367 1368 PETSC_EXTERN PetscErrorCode DMMoabView_VTK(DM dm, PetscViewer v) { 1369 PetscFunctionReturn(0); 1370 } 1371 1372 PETSC_EXTERN PetscErrorCode DMMoabView_HDF5(DM dm, PetscViewer v) { 1373 PetscFunctionReturn(0); 1374 } 1375 1376 PETSC_EXTERN PetscErrorCode DMView_Moab(DM dm, PetscViewer viewer) { 1377 PetscBool iascii, ishdf5, isvtk; 1378 1379 PetscFunctionBegin; 1380 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1381 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 1382 PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 1383 PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERVTK, &isvtk)); 1384 PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5, &ishdf5)); 1385 if (iascii) { 1386 PetscCall(DMMoabView_Ascii(dm, viewer)); 1387 } else if (ishdf5) { 1388 #if defined(PETSC_HAVE_HDF5) && defined(MOAB_HAVE_HDF5) 1389 PetscCall(PetscViewerPushFormat(viewer, PETSC_VIEWER_HDF5_VIZ)); 1390 PetscCall(DMMoabView_HDF5(dm, viewer)); 1391 PetscCall(PetscViewerPopFormat(viewer)); 1392 #else 1393 SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 1394 #endif 1395 } else if (isvtk) { 1396 PetscCall(DMMoabView_VTK(dm, viewer)); 1397 } 1398 PetscFunctionReturn(0); 1399 } 1400 1401 PETSC_EXTERN PetscErrorCode DMInitialize_Moab(DM dm) { 1402 PetscFunctionBegin; 1403 dm->ops->view = DMView_Moab; 1404 dm->ops->load = NULL /* DMLoad_Moab */; 1405 dm->ops->setfromoptions = DMSetFromOptions_Moab; 1406 dm->ops->clone = DMClone_Moab; 1407 dm->ops->setup = DMSetUp_Moab; 1408 dm->ops->createlocalsection = NULL; 1409 dm->ops->createdefaultconstraints = NULL; 1410 dm->ops->createglobalvector = DMCreateGlobalVector_Moab; 1411 dm->ops->createlocalvector = DMCreateLocalVector_Moab; 1412 dm->ops->getlocaltoglobalmapping = NULL; 1413 dm->ops->createfieldis = NULL; 1414 dm->ops->createcoordinatedm = NULL /* DMCreateCoordinateDM_Moab */; 1415 dm->ops->getcoloring = NULL; 1416 dm->ops->creatematrix = DMCreateMatrix_Moab; 1417 dm->ops->createinterpolation = DMCreateInterpolation_Moab; 1418 dm->ops->createinjection = NULL /* DMCreateInjection_Moab */; 1419 dm->ops->refine = DMRefine_Moab; 1420 dm->ops->coarsen = DMCoarsen_Moab; 1421 dm->ops->refinehierarchy = DMRefineHierarchy_Moab; 1422 dm->ops->coarsenhierarchy = DMCoarsenHierarchy_Moab; 1423 dm->ops->globaltolocalbegin = DMGlobalToLocalBegin_Moab; 1424 dm->ops->globaltolocalend = DMGlobalToLocalEnd_Moab; 1425 dm->ops->localtoglobalbegin = DMLocalToGlobalBegin_Moab; 1426 dm->ops->localtoglobalend = DMLocalToGlobalEnd_Moab; 1427 dm->ops->destroy = DMDestroy_Moab; 1428 dm->ops->createsubdm = NULL /* DMCreateSubDM_Moab */; 1429 dm->ops->getdimpoints = NULL /* DMGetDimPoints_Moab */; 1430 dm->ops->locatepoints = NULL /* DMLocatePoints_Moab */; 1431 PetscFunctionReturn(0); 1432 } 1433 1434 PETSC_EXTERN PetscErrorCode DMClone_Moab(DM dm, DM *newdm) { 1435 PetscFunctionBegin; 1436 /* get all the necessary handles from the private DM object */ 1437 (*newdm)->data = (DM_Moab *)dm->data; 1438 ((DM_Moab *)dm->data)->refct++; 1439 1440 PetscCall(PetscObjectChangeTypeName((PetscObject)*newdm, DMMOAB)); 1441 PetscCall(DMInitialize_Moab(*newdm)); 1442 PetscFunctionReturn(0); 1443 } 1444 1445 PETSC_EXTERN PetscErrorCode DMCreate_Moab(DM dm) { 1446 PetscFunctionBegin; 1447 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1448 PetscCall(PetscNewLog(dm, (DM_Moab **)&dm->data)); 1449 1450 ((DM_Moab *)dm->data)->bs = 1; 1451 ((DM_Moab *)dm->data)->numFields = 1; 1452 ((DM_Moab *)dm->data)->n = 0; 1453 ((DM_Moab *)dm->data)->nloc = 0; 1454 ((DM_Moab *)dm->data)->nghost = 0; 1455 ((DM_Moab *)dm->data)->nele = 0; 1456 ((DM_Moab *)dm->data)->neleloc = 0; 1457 ((DM_Moab *)dm->data)->neleghost = 0; 1458 ((DM_Moab *)dm->data)->ltog_map = NULL; 1459 ((DM_Moab *)dm->data)->ltog_sendrecv = NULL; 1460 1461 ((DM_Moab *)dm->data)->refct = 1; 1462 ((DM_Moab *)dm->data)->parent = NULL; 1463 ((DM_Moab *)dm->data)->vlocal = new moab::Range(); 1464 ((DM_Moab *)dm->data)->vowned = new moab::Range(); 1465 ((DM_Moab *)dm->data)->vghost = new moab::Range(); 1466 ((DM_Moab *)dm->data)->elocal = new moab::Range(); 1467 ((DM_Moab *)dm->data)->eghost = new moab::Range(); 1468 1469 PetscCall(DMInitialize_Moab(dm)); 1470 PetscFunctionReturn(0); 1471 } 1472