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