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