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