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