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 PETSC_EXTERN PetscErrorCode DMSetFromOptions_Moab(PetscOptionItems *PetscOptionsObject,DM dm) 996 { 997 PetscErrorCode ierr; 998 DM_Moab *dmmoab = (DM_Moab*)dm->data; 999 1000 PetscFunctionBegin; 1001 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1002 ierr = PetscOptionsHead(PetscOptionsObject,"DMMoab Options");CHKERRQ(ierr); 1003 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); 1004 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); 1005 /* TODO: typically, the read options are needed before a DM is completely created and available in which case, the options wont be available ?? */ 1006 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); 1007 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); 1008 ierr = PetscOptionsEnum("-dm_moab_read_mode", "MOAB parallel read mode", "DMView", MoabReadModes, (PetscEnum)dmmoab->read_mode, (PetscEnum*)&dmmoab->read_mode, NULL);CHKERRQ(ierr); 1009 ierr = PetscOptionsEnum("-dm_moab_write_mode", "MOAB parallel write mode", "DMView", MoabWriteModes, (PetscEnum)dmmoab->write_mode, (PetscEnum*)&dmmoab->write_mode, NULL);CHKERRQ(ierr); 1010 PetscFunctionReturn(0); 1011 } 1012 1013 1014 PETSC_EXTERN PetscErrorCode DMSetUp_Moab(DM dm) 1015 { 1016 PetscErrorCode ierr; 1017 moab::ErrorCode merr; 1018 Vec local, global; 1019 IS from,to; 1020 moab::Range::iterator iter; 1021 PetscInt i,j,f,bs,vent,totsize,*lgmap; 1022 DM_Moab *dmmoab = (DM_Moab*)dm->data; 1023 moab::Range adjs; 1024 1025 PetscFunctionBegin; 1026 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1027 /* Get the local and shared vertices and cache it */ 1028 if (dmmoab->mbiface == NULL) SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ORDER, "Set the MOAB Interface before calling SetUp."); 1029 #ifdef MOAB_HAVE_MPI 1030 if (dmmoab->pcomm == NULL) SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ORDER, "Set the MOAB ParallelComm object before calling SetUp."); 1031 #endif 1032 1033 /* Get the entities recursively in the current part of the mesh, if user did not set the local vertices explicitly */ 1034 if (dmmoab->vlocal->empty()) 1035 { 1036 //merr = dmmoab->mbiface->get_entities_by_type(dmmoab->fileset,moab::MBVERTEX,*dmmoab->vlocal,true);MBERRNM(merr); 1037 merr = dmmoab->mbiface->get_entities_by_dimension(dmmoab->fileset, 0, *dmmoab->vlocal, false);MBERRNM(merr); 1038 1039 #ifdef MOAB_HAVE_MPI 1040 /* filter based on parallel status */ 1041 merr = dmmoab->pcomm->filter_pstatus(*dmmoab->vlocal,PSTATUS_NOT_OWNED,PSTATUS_NOT,-1,dmmoab->vowned);MBERRNM(merr); 1042 1043 /* filter all the non-owned and shared entities out of the list */ 1044 adjs = moab::subtract(*dmmoab->vlocal, *dmmoab->vowned); 1045 merr = dmmoab->pcomm->filter_pstatus(adjs,PSTATUS_GHOST|PSTATUS_INTERFACE,PSTATUS_OR,-1,dmmoab->vghost);MBERRNM(merr); 1046 adjs = moab::subtract(adjs, *dmmoab->vghost); 1047 *dmmoab->vlocal = moab::subtract(*dmmoab->vlocal, adjs); 1048 #else 1049 *dmmoab->vowned=*dmmoab->vlocal; 1050 #endif 1051 1052 /* compute and cache the sizes of local and ghosted entities */ 1053 dmmoab->nloc = dmmoab->vowned->size(); 1054 dmmoab->nghost = dmmoab->vghost->size(); 1055 1056 #ifdef MOAB_HAVE_MPI 1057 ierr = MPIU_Allreduce(&dmmoab->nloc, &dmmoab->n, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm);CHKERRQ(ierr); 1058 PetscInfo4(NULL, "Filset ID: %u, Vertices: local - %D, owned - %D, ghosted - %D.\n", dmmoab->fileset, dmmoab->vlocal->size(), dmmoab->nloc, dmmoab->nghost); 1059 #else 1060 dmmoab->n=dmmoab->nloc; 1061 #endif 1062 } 1063 1064 { 1065 /* get the information about the local elements in the mesh */ 1066 dmmoab->eghost->clear(); 1067 1068 /* first decipher the leading dimension */ 1069 for (i=3;i>0;i--) { 1070 dmmoab->elocal->clear(); 1071 merr = dmmoab->mbiface->get_entities_by_dimension(dmmoab->fileset, i, *dmmoab->elocal, false);MBERRNM(merr); 1072 1073 /* store the current mesh dimension */ 1074 if (dmmoab->elocal->size()) { 1075 dmmoab->dim=i; 1076 break; 1077 } 1078 } 1079 1080 ierr = DMSetDimension(dm, dmmoab->dim);CHKERRQ(ierr); 1081 1082 #ifdef MOAB_HAVE_MPI 1083 /* filter the ghosted and owned element list */ 1084 *dmmoab->eghost = *dmmoab->elocal; 1085 merr = dmmoab->pcomm->filter_pstatus(*dmmoab->elocal,PSTATUS_NOT_OWNED,PSTATUS_NOT);MBERRNM(merr); 1086 *dmmoab->eghost = moab::subtract(*dmmoab->eghost, *dmmoab->elocal); 1087 #endif 1088 1089 dmmoab->neleloc = dmmoab->elocal->size(); 1090 dmmoab->neleghost = dmmoab->eghost->size(); 1091 1092 #ifdef MOAB_HAVE_MPI 1093 ierr = MPIU_Allreduce(&dmmoab->neleloc, &dmmoab->nele, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm);CHKERRQ(ierr); 1094 PetscInfo3(NULL, "%d-dim elements: owned - %D, ghosted - %D.\n", dmmoab->dim, dmmoab->neleloc, dmmoab->neleghost); 1095 #else 1096 dmmoab->nele=dmmoab->neleloc; 1097 #endif 1098 } 1099 1100 bs = dmmoab->bs; 1101 if (!dmmoab->ltog_tag) { 1102 /* Get the global ID tag. The global ID tag is applied to each 1103 vertex. It acts as an global identifier which MOAB uses to 1104 assemble the individual pieces of the mesh */ 1105 merr = dmmoab->mbiface->tag_get_handle(GLOBAL_ID_TAG_NAME, dmmoab->ltog_tag);MBERRNM(merr); 1106 } 1107 1108 totsize=dmmoab->vlocal->size(); 1109 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); 1110 ierr = PetscCalloc1(totsize,&dmmoab->gsindices);CHKERRQ(ierr); 1111 { 1112 /* first get the local indices */ 1113 merr = dmmoab->mbiface->tag_get_data(dmmoab->ltog_tag,*dmmoab->vowned,&dmmoab->gsindices[0]);MBERRNM(merr); 1114 if (dmmoab->nghost) { /* next get the ghosted indices */ 1115 merr = dmmoab->mbiface->tag_get_data(dmmoab->ltog_tag,*dmmoab->vghost,&dmmoab->gsindices[dmmoab->nloc]);MBERRNM(merr); 1116 } 1117 1118 /* find out the local and global minima of GLOBAL_ID */ 1119 dmmoab->lminmax[0]=dmmoab->lminmax[1]=dmmoab->gsindices[0]; 1120 for (i=0; i<totsize; ++i) { 1121 if(dmmoab->lminmax[0]>dmmoab->gsindices[i]) dmmoab->lminmax[0]=dmmoab->gsindices[i]; 1122 if(dmmoab->lminmax[1]<dmmoab->gsindices[i]) dmmoab->lminmax[1]=dmmoab->gsindices[i]; 1123 } 1124 1125 ierr = MPIU_Allreduce(&dmmoab->lminmax[0], &dmmoab->gminmax[0], 1, MPI_INT, MPI_MIN, ((PetscObject)dm)->comm);CHKERRQ(ierr); 1126 ierr = MPIU_Allreduce(&dmmoab->lminmax[1], &dmmoab->gminmax[1], 1, MPI_INT, MPI_MAX, ((PetscObject)dm)->comm);CHKERRQ(ierr); 1127 1128 /* set the GID map */ 1129 for (i=0; i<totsize; ++i) { 1130 dmmoab->gsindices[i]-=dmmoab->gminmax[0]; /* zero based index needed for IS */ 1131 } 1132 dmmoab->lminmax[0]-=dmmoab->gminmax[0]; 1133 dmmoab->lminmax[1]-=dmmoab->gminmax[0]; 1134 1135 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]); 1136 } 1137 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); 1138 1139 { 1140 dmmoab->seqstart=((PetscInt)dmmoab->vlocal->front()); 1141 dmmoab->seqend=((PetscInt)dmmoab->vlocal->back()); 1142 PetscInfo2(NULL, "SEQUENCE: Local [min, max] - [%D, %D]\n", dmmoab->seqstart, dmmoab->seqend); 1143 1144 ierr = PetscMalloc2(dmmoab->seqend-dmmoab->seqstart+1,&dmmoab->gidmap,dmmoab->seqend-dmmoab->seqstart+1,&dmmoab->lidmap);CHKERRQ(ierr); 1145 ierr = PetscMalloc1(totsize*dmmoab->numFields,&lgmap);CHKERRQ(ierr); 1146 1147 i=j=0; 1148 /* set the owned vertex data first */ 1149 for(moab::Range::iterator iter = dmmoab->vowned->begin(); iter != dmmoab->vowned->end(); iter++,i++) { 1150 vent=(PetscInt)(*iter)-dmmoab->seqstart; 1151 dmmoab->gidmap[vent]=dmmoab->gsindices[i]; 1152 dmmoab->lidmap[vent]=i; 1153 for (f=0;f<dmmoab->numFields;f++,j++) { 1154 lgmap[j]=(bs > 1 ? dmmoab->gsindices[i]*dmmoab->numFields+f : totsize*f+dmmoab->gsindices[i]); 1155 } 1156 } 1157 /* next arrange all the ghosted data information */ 1158 for(moab::Range::iterator iter = dmmoab->vghost->begin(); iter != dmmoab->vghost->end(); iter++,i++) { 1159 vent=(PetscInt)(*iter)-dmmoab->seqstart; 1160 dmmoab->gidmap[vent]=dmmoab->gsindices[i]; 1161 dmmoab->lidmap[vent]=i; 1162 for (f=0;f<dmmoab->numFields;f++,j++) { 1163 lgmap[j]=(bs > 1 ? dmmoab->gsindices[i]*dmmoab->numFields+f : totsize*f+dmmoab->gsindices[i]); 1164 } 1165 } 1166 1167 /* We need to create the Global to Local Vector Scatter Contexts 1168 1) First create a local and global vector 1169 2) Create a local and global IS 1170 3) Create VecScatter and LtoGMapping objects 1171 4) Cleanup the IS and Vec objects 1172 */ 1173 ierr = DMCreateGlobalVector(dm, &global);CHKERRQ(ierr); 1174 ierr = DMCreateLocalVector(dm, &local);CHKERRQ(ierr); 1175 1176 ierr = VecGetOwnershipRange(global, &dmmoab->vstart, &dmmoab->vend);CHKERRQ(ierr); 1177 1178 /* global to local must retrieve ghost points */ 1179 ierr = ISCreateStride(((PetscObject)dm)->comm,dmmoab->nloc*dmmoab->numFields,dmmoab->vstart,1,&from);CHKERRQ(ierr); 1180 ierr = ISSetBlockSize(from,bs);CHKERRQ(ierr); 1181 1182 ierr = ISCreateGeneral(((PetscObject)dm)->comm,dmmoab->nloc*dmmoab->numFields,&lgmap[0],PETSC_COPY_VALUES,&to);CHKERRQ(ierr); 1183 ierr = ISSetBlockSize(to,bs);CHKERRQ(ierr); 1184 1185 if (!dmmoab->ltog_map) { 1186 /* create to the local to global mapping for vectors in order to use VecSetValuesLocal */ 1187 ierr = ISLocalToGlobalMappingCreate(((PetscObject)dm)->comm,dmmoab->bs,totsize*dmmoab->numFields,lgmap, 1188 PETSC_COPY_VALUES,&dmmoab->ltog_map);CHKERRQ(ierr); 1189 } 1190 1191 /* now create the scatter object from local to global vector */ 1192 ierr = VecScatterCreate(local,from,global,to,&dmmoab->ltog_sendrecv);CHKERRQ(ierr); 1193 1194 /* clean up IS, Vec */ 1195 ierr = PetscFree(lgmap);CHKERRQ(ierr); 1196 ierr = ISDestroy(&from);CHKERRQ(ierr); 1197 ierr = ISDestroy(&to);CHKERRQ(ierr); 1198 ierr = VecDestroy(&local);CHKERRQ(ierr); 1199 ierr = VecDestroy(&global);CHKERRQ(ierr); 1200 } 1201 1202 dmmoab->bndyvtx = new moab::Range(); 1203 dmmoab->bndyfaces = new moab::Range(); 1204 dmmoab->bndyelems = new moab::Range(); 1205 /* skin the boundary and store nodes */ 1206 { 1207 /* get the skin vertices of boundary faces for the current partition and then filter 1208 the local, boundary faces, vertices and elements alone via PSTATUS flags; 1209 this should not give us any ghosted boundary, but if user needs such a functionality 1210 it would be easy to add it based on the find_skin query below */ 1211 moab::Skinner skinner(dmmoab->mbiface); 1212 1213 /* get the entities on the skin - only the faces */ 1214 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 1215 1216 #ifdef MOAB_HAVE_MPI 1217 /* filter all the non-owned and shared entities out of the list */ 1218 merr = dmmoab->pcomm->filter_pstatus(*dmmoab->bndyfaces,PSTATUS_NOT_OWNED,PSTATUS_NOT);MBERRNM(merr); 1219 merr = dmmoab->pcomm->filter_pstatus(*dmmoab->bndyfaces,PSTATUS_SHARED,PSTATUS_NOT);MBERRNM(merr); 1220 #endif 1221 1222 /* get all the nodes via connectivity and the parent elements via adjacency information */ 1223 merr = dmmoab->mbiface->get_connectivity(*dmmoab->bndyfaces, *dmmoab->bndyvtx, false);MBERRNM(ierr); 1224 merr = dmmoab->mbiface->get_adjacencies(*dmmoab->bndyvtx, dmmoab->dim, false, *dmmoab->bndyelems, moab::Interface::UNION);MBERRNM(ierr); 1225 } 1226 PetscInfo3(NULL, "Found %D boundary vertices, %D boundary faces and %D boundary elements.\n", dmmoab->bndyvtx->size(), dmmoab->bndyfaces->size(), dmmoab->bndyelems->size()); 1227 PetscFunctionReturn(0); 1228 } 1229 1230 1231 #undef __FUNCT__ 1232 #define __FUNCT__ "DMMoabCreateVertices" 1233 /*@ 1234 DMMoabCreateVertices - Creates and adds several vertices to the primary set represented by the DM. 1235 1236 Collective on MPI_Comm 1237 1238 Input Parameters: 1239 + dm - The DM object 1240 . type - The type of element to create and add (Edge/Tri/Quad/Tet/Hex/Prism/Pyramid/Polygon/Polyhedra) 1241 . conn - The connectivity of the element 1242 . nverts - The number of vertices that form the element 1243 1244 Output Parameter: 1245 . overts - The list of vertices that were created (can be NULL) 1246 1247 Level: beginner 1248 1249 .keywords: DM, create vertices 1250 1251 .seealso: DMMoabCreateSubmesh(), DMMoabCreateElement() 1252 @*/ 1253 PetscErrorCode DMMoabCreateVertices(DM dm, const PetscReal* coords, PetscInt nverts, moab::Range* overts) 1254 { 1255 moab::ErrorCode merr; 1256 DM_Moab *dmmoab; 1257 moab::Range verts; 1258 1259 PetscFunctionBegin; 1260 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1261 PetscValidPointer(coords,2); 1262 1263 dmmoab = (DM_Moab*) dm->data; 1264 1265 /* Insert new points */ 1266 merr = dmmoab->mbiface->create_vertices(&coords[0],nverts,verts);MBERRNM(merr); 1267 merr = dmmoab->mbiface->add_entities(dmmoab->fileset,verts);MBERRNM(merr); 1268 1269 if (overts) *overts=verts; 1270 PetscFunctionReturn(0); 1271 } 1272 1273 1274 #undef __FUNCT__ 1275 #define __FUNCT__ "DMMoabCreateElement" 1276 /*@ 1277 DMMoabCreateElement - Adds an element of specified type to the primary set represented by the DM. 1278 1279 Collective on MPI_Comm 1280 1281 Input Parameters: 1282 + dm - The DM object 1283 . type - The type of element to create and add (Edge/Tri/Quad/Tet/Hex/Prism/Pyramid/Polygon/Polyhedra) 1284 . conn - The connectivity of the element 1285 . nverts - The number of vertices that form the element 1286 1287 Output Parameter: 1288 . oelem - The handle to the element created and added to the DM object 1289 1290 Level: beginner 1291 1292 .keywords: DM, create element 1293 1294 .seealso: DMMoabCreateSubmesh(), DMMoabCreateVertices() 1295 @*/ 1296 PetscErrorCode DMMoabCreateElement(DM dm, const moab::EntityType type, const moab::EntityHandle* conn, PetscInt nverts, moab::EntityHandle* oelem) 1297 { 1298 moab::ErrorCode merr; 1299 DM_Moab *dmmoab; 1300 moab::EntityHandle elem; 1301 1302 PetscFunctionBegin; 1303 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1304 PetscValidPointer(conn,3); 1305 1306 dmmoab = (DM_Moab*) dm->data; 1307 1308 /* Insert new element */ 1309 merr = dmmoab->mbiface->create_element(type,conn,nverts,elem);MBERRNM(merr); 1310 merr = dmmoab->mbiface->add_entities(dmmoab->fileset,&elem,1);MBERRNM(merr); 1311 1312 if (oelem) *oelem = elem; 1313 PetscFunctionReturn(0); 1314 } 1315 1316 1317 #undef __FUNCT__ 1318 #define __FUNCT__ "DMMoabCreateSubmesh" 1319 /*@ 1320 DMMoabCreateSubmesh - Creates a sub-DM object with a set that contains all vertices/elements of the parent 1321 in addition to providing support for dynamic mesh modifications. This is useful for AMR calculations to 1322 create a DM object on a refined level. 1323 1324 Collective on MPI_Comm 1325 1326 Input Parameters: 1327 + dm - The DM object 1328 1329 Output Parameter: 1330 . newdm - The sub DM object with updated set information 1331 1332 Level: advanced 1333 1334 .keywords: DM, sub-DM 1335 1336 .seealso: DMCreate(), DMMoabCreateVertices(), DMMoabCreateElement() 1337 @*/ 1338 PetscErrorCode DMMoabCreateSubmesh(DM dm, DM *newdm) 1339 { 1340 DM_Moab *dmmoab; 1341 DM_Moab *ndmmoab; 1342 moab::ErrorCode merr; 1343 PetscErrorCode ierr; 1344 1345 PetscFunctionBegin; 1346 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1347 1348 dmmoab = (DM_Moab*) dm->data; 1349 1350 /* Create the basic DMMoab object and keep the default parameters created by DM impls */ 1351 ierr = DMMoabCreateMoab(((PetscObject)dm)->comm, dmmoab->mbiface, &dmmoab->ltog_tag, PETSC_NULL, newdm);CHKERRQ(ierr); 1352 1353 /* get all the necessary handles from the private DM object */ 1354 ndmmoab = (DM_Moab*) (*newdm)->data; 1355 1356 /* set the sub-mesh's parent DM reference */ 1357 ndmmoab->parent = &dm; 1358 1359 /* create a file set to associate all entities in current mesh */ 1360 merr = ndmmoab->mbiface->create_meshset(moab::MESHSET_SET, ndmmoab->fileset);MBERR("Creating file set failed", merr); 1361 1362 /* create a meshset and then add old fileset as child */ 1363 merr = ndmmoab->mbiface->add_entities(ndmmoab->fileset, *dmmoab->vlocal);MBERR("Adding child vertices to parent failed", merr); 1364 merr = ndmmoab->mbiface->add_entities(ndmmoab->fileset, *dmmoab->elocal);MBERR("Adding child elements to parent failed", merr); 1365 1366 /* preserve the field association between the parent and sub-mesh objects */ 1367 ierr = DMMoabSetFieldNames(*newdm, dmmoab->numFields, dmmoab->fieldNames);CHKERRQ(ierr); 1368 PetscFunctionReturn(0); 1369 } 1370 1371 1372 #undef __FUNCT__ 1373 #define __FUNCT__ "DMMoabView_Ascii" 1374 PETSC_EXTERN PetscErrorCode DMMoabView_Ascii(DM dm, PetscViewer viewer) 1375 { 1376 DM_Moab *dmmoab = (DM_Moab*)(dm)->data; 1377 const char *name; 1378 MPI_Comm comm; 1379 PetscMPIInt size; 1380 PetscErrorCode ierr; 1381 1382 PetscFunctionBegin; 1383 ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 1384 ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr); 1385 ierr = PetscObjectGetName((PetscObject) dm, &name);CHKERRQ(ierr); 1386 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1387 if (name) {ierr = PetscViewerASCIIPrintf(viewer, "%s in %D dimensions:\n", name, dmmoab->dim);CHKERRQ(ierr);} 1388 else {ierr = PetscViewerASCIIPrintf(viewer, "Mesh in %D dimensions:\n", dmmoab->dim);CHKERRQ(ierr);} 1389 /* print details about the global mesh */ 1390 { 1391 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1392 ierr = PetscViewerASCIIPrintf(viewer, "Sizes: cells=%D, vertices=%D, blocks=%D\n", dmmoab->n, dmmoab->nele, dmmoab->bs);CHKERRQ(ierr); 1393 /* print boundary data */ 1394 ierr = PetscViewerASCIIPrintf(viewer, "Boundary trace:\n", dmmoab->bndyelems->size(), dmmoab->bndyfaces->size(), dmmoab->bndyvtx->size());CHKERRQ(ierr); 1395 { 1396 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1397 ierr = PetscViewerASCIIPrintf(viewer, "cells=%D, faces=%D, vertices=%D\n", dmmoab->bndyelems->size(), dmmoab->bndyfaces->size(), dmmoab->bndyvtx->size());CHKERRQ(ierr); 1398 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1399 } 1400 /* print field data */ 1401 ierr = PetscViewerASCIIPrintf(viewer, "Fields: %D components\n", dmmoab->numFields);CHKERRQ(ierr); 1402 { 1403 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1404 for (int i=0; i<dmmoab->numFields; ++i) { 1405 ierr = PetscViewerASCIIPrintf(viewer, "[%D] - %s\n", i, dmmoab->fieldNames[i]);CHKERRQ(ierr); 1406 } 1407 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1408 } 1409 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1410 } 1411 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1412 ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 1413 PetscFunctionReturn(0); 1414 } 1415 1416 #undef __FUNCT__ 1417 #define __FUNCT__ "DMMoabView_VTK" 1418 PETSC_EXTERN PetscErrorCode DMMoabView_VTK(DM dm,PetscViewer v) 1419 { 1420 PetscFunctionReturn(0); 1421 } 1422 1423 #undef __FUNCT__ 1424 #define __FUNCT__ "DMMoabView_HDF5" 1425 PETSC_EXTERN PetscErrorCode DMMoabView_HDF5(DM dm,PetscViewer v) 1426 { 1427 PetscFunctionReturn(0); 1428 } 1429 1430 #undef __FUNCT__ 1431 #define __FUNCT__ "DMView_Moab" 1432 PETSC_EXTERN PetscErrorCode DMView_Moab(DM dm,PetscViewer viewer) 1433 { 1434 PetscBool iascii, ishdf5, isvtk; 1435 PetscErrorCode ierr; 1436 1437 PetscFunctionBegin; 1438 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1439 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 1440 ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr); 1441 ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERVTK, &isvtk);CHKERRQ(ierr); 1442 ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 1443 if (iascii) { 1444 ierr = DMMoabView_Ascii(dm, viewer);CHKERRQ(ierr); 1445 } else if (ishdf5) { 1446 #if defined(PETSC_HAVE_HDF5) && defined(MOAB_HAVE_HDF5) 1447 ierr = PetscViewerPushFormat(viewer, PETSC_VIEWER_HDF5_VIZ);CHKERRQ(ierr); 1448 ierr = DMMoabView_HDF5(dm, viewer);CHKERRQ(ierr); 1449 ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 1450 #else 1451 SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 1452 #endif 1453 } 1454 else if (isvtk) { 1455 ierr = DMMoabView_VTK(dm, viewer);CHKERRQ(ierr); 1456 } 1457 PetscFunctionReturn(0); 1458 } 1459 1460 1461 #undef __FUNCT__ 1462 #define __FUNCT__ "DMInitialize_Moab" 1463 PETSC_EXTERN PetscErrorCode DMInitialize_Moab(DM dm) 1464 { 1465 PetscFunctionBegin; 1466 dm->ops->view = DMView_Moab; 1467 dm->ops->load = NULL /*DMLoad_Moab*/; 1468 dm->ops->setfromoptions = DMSetFromOptions_Moab; 1469 dm->ops->clone = DMClone_Moab; 1470 dm->ops->setup = DMSetUp_Moab; 1471 dm->ops->createdefaultsection = NULL; 1472 dm->ops->createdefaultconstraints = NULL; 1473 dm->ops->createglobalvector = DMCreateGlobalVector_Moab; 1474 dm->ops->createlocalvector = DMCreateLocalVector_Moab; 1475 dm->ops->getlocaltoglobalmapping = NULL; 1476 dm->ops->createfieldis = NULL; 1477 dm->ops->createcoordinatedm = NULL /*DMCreateCoordinateDM_Moab*/; 1478 dm->ops->getcoloring = NULL; 1479 dm->ops->creatematrix = DMCreateMatrix_Moab; 1480 dm->ops->createinterpolation = DMCreateInterpolation_Moab; 1481 dm->ops->getaggregates = NULL; 1482 dm->ops->getinjection = NULL /*DMCreateInjection_Moab*/; 1483 dm->ops->refine = DMRefine_Moab; 1484 dm->ops->coarsen = DMCoarsen_Moab; 1485 dm->ops->refinehierarchy = DMRefineHierarchy_Moab; 1486 dm->ops->coarsenhierarchy = DMCoarsenHierarchy_Moab; 1487 dm->ops->globaltolocalbegin = DMGlobalToLocalBegin_Moab; 1488 dm->ops->globaltolocalend = DMGlobalToLocalEnd_Moab; 1489 dm->ops->localtoglobalbegin = DMLocalToGlobalBegin_Moab; 1490 dm->ops->localtoglobalend = DMLocalToGlobalEnd_Moab; 1491 dm->ops->destroy = DMDestroy_Moab; 1492 dm->ops->createsubdm = NULL /*DMCreateSubDM_Moab*/; 1493 dm->ops->getdimpoints = NULL /*DMGetDimPoints_Moab*/; 1494 dm->ops->locatepoints = NULL /*DMLocatePoints_Moab*/; 1495 PetscFunctionReturn(0); 1496 } 1497 1498 1499 #undef __FUNCT__ 1500 #define __FUNCT__ "DMClone_Moab" 1501 PETSC_EXTERN PetscErrorCode DMClone_Moab(DM dm, DM *newdm) 1502 { 1503 PetscErrorCode ierr; 1504 1505 PetscFunctionBegin; 1506 ierr = PetscObjectChangeTypeName((PetscObject) *newdm, DMMOAB);CHKERRQ(ierr); 1507 1508 /* get all the necessary handles from the private DM object */ 1509 (*newdm)->data = (DM_Moab*) dm->data; 1510 ((DM_Moab*)dm->data)->refct++; 1511 1512 ierr = DMInitialize_Moab(*newdm);CHKERRQ(ierr); 1513 PetscFunctionReturn(0); 1514 } 1515 1516 1517 #undef __FUNCT__ 1518 #define __FUNCT__ "DMCreate_Moab" 1519 PETSC_EXTERN PetscErrorCode DMCreate_Moab(DM dm) 1520 { 1521 PetscErrorCode ierr; 1522 1523 PetscFunctionBegin; 1524 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1525 ierr = PetscNewLog(dm,(DM_Moab**)&dm->data);CHKERRQ(ierr); 1526 1527 ((DM_Moab*)dm->data)->bs = 1; 1528 ((DM_Moab*)dm->data)->numFields = 1; 1529 ((DM_Moab*)dm->data)->n = 0; 1530 ((DM_Moab*)dm->data)->nloc = 0; 1531 ((DM_Moab*)dm->data)->nghost = 0; 1532 ((DM_Moab*)dm->data)->nele = 0; 1533 ((DM_Moab*)dm->data)->neleloc = 0; 1534 ((DM_Moab*)dm->data)->neleghost = 0; 1535 ((DM_Moab*)dm->data)->ltog_map = NULL; 1536 ((DM_Moab*)dm->data)->ltog_sendrecv = NULL; 1537 1538 ((DM_Moab*)dm->data)->refct = 1; 1539 ((DM_Moab*)dm->data)->parent = NULL; 1540 ((DM_Moab*)dm->data)->vlocal = new moab::Range(); 1541 ((DM_Moab*)dm->data)->vowned = new moab::Range(); 1542 ((DM_Moab*)dm->data)->vghost = new moab::Range(); 1543 ((DM_Moab*)dm->data)->elocal = new moab::Range(); 1544 ((DM_Moab*)dm->data)->eghost = new moab::Range(); 1545 1546 ierr = DMInitialize_Moab(dm);CHKERRQ(ierr); 1547 PetscFunctionReturn(0); 1548 } 1549 1550