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 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 25 /*@ 26 DMMoabCreate - Creates a DMMoab object, which encapsulates a moab instance 27 28 Collective on MPI_Comm 29 30 Input Parameter: 31 . comm - The communicator for the DMMoab object 32 33 Output Parameter: 34 . dmb - The DMMoab object 35 36 Level: beginner 37 38 .keywords: DMMoab, create 39 @*/ 40 PetscErrorCode DMMoabCreate(MPI_Comm comm, DM *dmb) 41 { 42 PetscErrorCode ierr; 43 44 PetscFunctionBegin; 45 PetscValidPointer(dmb,2); 46 ierr = DMCreate(comm, dmb);CHKERRQ(ierr); 47 ierr = DMSetType(*dmb, DMMOAB);CHKERRQ(ierr); 48 PetscFunctionReturn(0); 49 } 50 51 /*@ 52 DMMoabCreateMoab - Creates a DMMoab object, optionally from an instance and other data 53 54 Collective on MPI_Comm 55 56 Input Parameter: 57 . comm - The communicator for the DMMoab object 58 . mbiface - (ptr to) the MOAB Instance; if passed in NULL, MOAB instance is created inside PETSc, and destroyed 59 along with the DMMoab 60 . pcomm - (ptr to) a ParallelComm; if NULL, creates one internally for the whole communicator 61 . ltog_tag - A tag to use to retrieve global id for an entity; if 0, will use GLOBAL_ID_TAG_NAME/tag 62 . range - If non-NULL, contains range of entities to which DOFs will be assigned 63 64 Output Parameter: 65 . dmb - The DMMoab object 66 67 Level: intermediate 68 69 .keywords: DMMoab, create 70 @*/ 71 PetscErrorCode DMMoabCreateMoab(MPI_Comm comm, moab::Interface *mbiface, moab::ParallelComm *pcomm, moab::Tag *ltog_tag, moab::Range *range, DM *dmb) 72 { 73 PetscErrorCode ierr; 74 moab::ErrorCode merr; 75 moab::EntityHandle partnset; 76 PetscInt rank, nprocs; 77 DM dmmb; 78 DM_Moab *dmmoab; 79 80 PetscFunctionBegin; 81 PetscValidPointer(dmb,6); 82 83 ierr = DMMoabCreate(comm, &dmmb);CHKERRQ(ierr); 84 dmmoab = (DM_Moab*)(dmmb)->data; 85 86 if (!mbiface) { 87 dmmoab->mbiface = new moab::Core(); 88 dmmoab->icreatedinstance = PETSC_TRUE; 89 } 90 else { 91 dmmoab->mbiface = mbiface; 92 dmmoab->icreatedinstance = PETSC_FALSE; 93 } 94 95 /* by default the fileset = root set. This set stores the hierarchy of entities belonging to current DM */ 96 dmmoab->fileset=0; 97 dmmoab->hlevel=0; 98 dmmoab->nghostrings=0; 99 100 if (!pcomm) { 101 ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); 102 ierr = MPI_Comm_size(comm, &nprocs);CHKERRQ(ierr); 103 104 /* Create root sets for each mesh. Then pass these 105 to the load_file functions to be populated. */ 106 merr = dmmoab->mbiface->create_meshset(moab::MESHSET_SET, partnset);MBERR("Creating partition set failed", merr); 107 108 /* Create the parallel communicator object with the partition handle associated with MOAB */ 109 dmmoab->pcomm = moab::ParallelComm::get_pcomm(dmmoab->mbiface, partnset, &comm); 110 } 111 else { 112 ierr = DMMoabSetParallelComm(dmmb, pcomm);CHKERRQ(ierr); 113 } 114 115 /* do the remaining initializations for DMMoab */ 116 dmmoab->bs = 1; 117 dmmoab->numFields = 1; 118 ierr = PetscMalloc(dmmoab->numFields*sizeof(char*),&dmmoab->fieldNames);CHKERRQ(ierr); 119 ierr = PetscStrallocpy("DEFAULT", (char**) &dmmoab->fieldNames[0]);CHKERRQ(ierr); 120 dmmoab->rw_dbglevel = 0; 121 dmmoab->partition_by_rank = PETSC_FALSE; 122 dmmoab->extra_read_options[0] = '\0'; 123 dmmoab->extra_write_options[0] = '\0'; 124 dmmoab->read_mode = READ_PART; 125 dmmoab->write_mode = WRITE_PART; 126 127 /* set global ID tag handle */ 128 if (ltog_tag && *ltog_tag) { 129 ierr = DMMoabSetLocalToGlobalTag(dmmb, *ltog_tag);CHKERRQ(ierr); 130 } 131 else { 132 merr = dmmoab->mbiface->tag_get_handle(GLOBAL_ID_TAG_NAME, dmmoab->ltog_tag);MBERRNM(merr); 133 if (ltog_tag) *ltog_tag = dmmoab->ltog_tag; 134 } 135 136 merr = dmmoab->mbiface->tag_get_handle(MATERIAL_SET_TAG_NAME, dmmoab->material_tag);MBERRNM(merr); 137 138 /* set the local range of entities (vertices) of interest */ 139 if (range) { 140 ierr = DMMoabSetLocalVertices(dmmb, range);CHKERRQ(ierr); 141 } 142 *dmb=dmmb; 143 PetscFunctionReturn(0); 144 } 145 146 /*@ 147 DMMoabSetParallelComm - Set the ParallelComm used with this DMMoab 148 149 Collective on MPI_Comm 150 151 Input Parameter: 152 . dm - The DMMoab object being set 153 . pcomm - The ParallelComm being set on the DMMoab 154 155 Level: beginner 156 157 .keywords: DMMoab, create 158 @*/ 159 PetscErrorCode DMMoabSetParallelComm(DM dm,moab::ParallelComm *pcomm) 160 { 161 DM_Moab *dmmoab = (DM_Moab*)(dm)->data; 162 163 PetscFunctionBegin; 164 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 165 PetscValidPointer(pcomm,2); 166 dmmoab->pcomm = pcomm; 167 dmmoab->mbiface = pcomm->get_moab(); 168 dmmoab->icreatedinstance = PETSC_FALSE; 169 PetscFunctionReturn(0); 170 } 171 172 173 /*@ 174 DMMoabGetParallelComm - Get the ParallelComm used with this DMMoab 175 176 Collective on MPI_Comm 177 178 Input Parameter: 179 . dm - The DMMoab object being set 180 181 Output Parameter: 182 . pcomm - The ParallelComm for the DMMoab 183 184 Level: beginner 185 186 .keywords: DMMoab, create 187 @*/ 188 PetscErrorCode DMMoabGetParallelComm(DM dm,moab::ParallelComm **pcomm) 189 { 190 PetscFunctionBegin; 191 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 192 *pcomm = ((DM_Moab*)(dm)->data)->pcomm; 193 PetscFunctionReturn(0); 194 } 195 196 197 /*@ 198 DMMoabSetInterface - Set the MOAB instance used with this DMMoab 199 200 Collective on MPI_Comm 201 202 Input Parameter: 203 . dm - The DMMoab object being set 204 . mbiface - The MOAB instance being set on this DMMoab 205 206 Level: beginner 207 208 .keywords: DMMoab, create 209 @*/ 210 PetscErrorCode DMMoabSetInterface(DM dm,moab::Interface *mbiface) 211 { 212 DM_Moab *dmmoab = (DM_Moab*)(dm)->data; 213 214 PetscFunctionBegin; 215 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 216 PetscValidPointer(mbiface,2); 217 dmmoab->pcomm = NULL; 218 dmmoab->mbiface = mbiface; 219 dmmoab->icreatedinstance = PETSC_FALSE; 220 PetscFunctionReturn(0); 221 } 222 223 224 /*@ 225 DMMoabGetInterface - Get the MOAB instance used with this DMMoab 226 227 Collective on MPI_Comm 228 229 Input Parameter: 230 . dm - The DMMoab object being set 231 232 Output Parameter: 233 . mbiface - The MOAB instance set on this DMMoab 234 235 Level: beginner 236 237 .keywords: DMMoab, create 238 @*/ 239 PetscErrorCode DMMoabGetInterface(DM dm,moab::Interface **mbiface) 240 { 241 PetscErrorCode ierr; 242 static PetscBool cite = PETSC_FALSE; 243 244 PetscFunctionBegin; 245 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 246 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); 247 *mbiface = ((DM_Moab*)dm->data)->mbiface; 248 PetscFunctionReturn(0); 249 } 250 251 252 /*@ 253 DMMoabSetLocalVertices - Set the entities having DOFs on this DMMoab 254 255 Collective on MPI_Comm 256 257 Input Parameter: 258 . dm - The DMMoab object being set 259 . range - The entities treated by this DMMoab 260 261 Level: beginner 262 263 .keywords: DMMoab, create 264 @*/ 265 PetscErrorCode DMMoabSetLocalVertices(DM dm,moab::Range *range) 266 { 267 moab::ErrorCode merr; 268 PetscErrorCode ierr; 269 moab::Range tmpvtxs; 270 DM_Moab *dmmoab = (DM_Moab*)(dm)->data; 271 272 PetscFunctionBegin; 273 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 274 dmmoab->vlocal->clear(); 275 dmmoab->vowned->clear(); 276 277 dmmoab->vlocal->insert(range->begin(), range->end()); 278 279 /* filter based on parallel status */ 280 merr = dmmoab->pcomm->filter_pstatus(*dmmoab->vlocal,PSTATUS_NOT_OWNED,PSTATUS_NOT,-1,dmmoab->vowned);MBERRNM(merr); 281 282 /* filter all the non-owned and shared entities out of the list */ 283 tmpvtxs = moab::subtract(*dmmoab->vlocal, *dmmoab->vowned); 284 merr = dmmoab->pcomm->filter_pstatus(tmpvtxs,PSTATUS_INTERFACE,PSTATUS_OR,-1,dmmoab->vghost);MBERRNM(merr); 285 tmpvtxs = moab::subtract(tmpvtxs, *dmmoab->vghost); 286 *dmmoab->vlocal = moab::subtract(*dmmoab->vlocal, tmpvtxs); 287 288 /* compute and cache the sizes of local and ghosted entities */ 289 dmmoab->nloc = dmmoab->vowned->size(); 290 dmmoab->nghost = dmmoab->vghost->size(); 291 ierr = MPIU_Allreduce(&dmmoab->nloc, &dmmoab->n, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm);CHKERRQ(ierr); 292 PetscFunctionReturn(0); 293 } 294 295 296 /*@ 297 DMMoabGetAllVertices - Get the entities having DOFs on this DMMoab 298 299 Collective on MPI_Comm 300 301 Input Parameter: 302 . dm - The DMMoab object being set 303 304 Output Parameter: 305 . owned - The local vertex entities in this DMMoab = (owned+ghosted) 306 307 Level: beginner 308 309 .keywords: DMMoab, create 310 @*/ 311 PetscErrorCode DMMoabGetAllVertices(DM dm,moab::Range *local) 312 { 313 PetscFunctionBegin; 314 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 315 if (local) *local = *((DM_Moab*)dm->data)->vlocal; 316 PetscFunctionReturn(0); 317 } 318 319 320 321 /*@ 322 DMMoabGetLocalVertices - Get the entities having DOFs on this DMMoab 323 324 Collective on MPI_Comm 325 326 Input Parameter: 327 . dm - The DMMoab object being set 328 329 Output Parameter: 330 . owned - The owned vertex entities in this DMMoab 331 . ghost - The ghosted entities (non-owned) stored locally in this partition 332 333 Level: beginner 334 335 .keywords: DMMoab, create 336 @*/ 337 PetscErrorCode DMMoabGetLocalVertices(DM dm,const moab::Range **owned,const moab::Range **ghost) 338 { 339 PetscFunctionBegin; 340 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 341 if (owned) *owned = ((DM_Moab*)dm->data)->vowned; 342 if (ghost) *ghost = ((DM_Moab*)dm->data)->vghost; 343 PetscFunctionReturn(0); 344 } 345 346 /*@ 347 DMMoabGetLocalElements - Get the higher-dimensional entities that are locally owned 348 349 Collective on MPI_Comm 350 351 Input Parameter: 352 . dm - The DMMoab object being set 353 354 Output Parameter: 355 . range - The entities owned locally 356 357 Level: beginner 358 359 .keywords: DMMoab, create 360 @*/ 361 PetscErrorCode DMMoabGetLocalElements(DM dm,const moab::Range **range) 362 { 363 PetscFunctionBegin; 364 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 365 if (range) *range = ((DM_Moab*)dm->data)->elocal; 366 PetscFunctionReturn(0); 367 } 368 369 370 /*@ 371 DMMoabSetLocalElements - Set the entities having DOFs on this DMMoab 372 373 Collective on MPI_Comm 374 375 Input Parameter: 376 . dm - The DMMoab object being set 377 . range - The entities treated by this DMMoab 378 379 Level: beginner 380 381 .keywords: DMMoab, create 382 @*/ 383 PetscErrorCode DMMoabSetLocalElements(DM dm,moab::Range *range) 384 { 385 moab::ErrorCode merr; 386 PetscErrorCode ierr; 387 DM_Moab *dmmoab = (DM_Moab*)(dm)->data; 388 389 PetscFunctionBegin; 390 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 391 dmmoab->elocal->clear(); 392 dmmoab->eghost->clear(); 393 dmmoab->elocal->insert(range->begin(), range->end()); 394 merr = dmmoab->pcomm->filter_pstatus(*dmmoab->elocal,PSTATUS_NOT_OWNED,PSTATUS_NOT);MBERRNM(merr); 395 *dmmoab->eghost = moab::subtract(*range, *dmmoab->elocal); 396 dmmoab->neleloc=dmmoab->elocal->size(); 397 dmmoab->neleghost=dmmoab->eghost->size(); 398 ierr = MPIU_Allreduce(&dmmoab->nele, &dmmoab->neleloc, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm);CHKERRQ(ierr); 399 PetscInfo2(dm, "Created %D local and %D global elements.\n", dmmoab->neleloc, dmmoab->nele); 400 PetscFunctionReturn(0); 401 } 402 403 404 /*@ 405 DMMoabSetLocalToGlobalTag - Set the tag used for local to global numbering 406 407 Collective on MPI_Comm 408 409 Input Parameter: 410 . dm - The DMMoab object being set 411 . ltogtag - The MOAB tag used for local to global ids 412 413 Level: beginner 414 415 .keywords: DMMoab, create 416 @*/ 417 PetscErrorCode DMMoabSetLocalToGlobalTag(DM dm,moab::Tag ltogtag) 418 { 419 PetscFunctionBegin; 420 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 421 ((DM_Moab*)dm->data)->ltog_tag = ltogtag; 422 PetscFunctionReturn(0); 423 } 424 425 426 /*@ 427 DMMoabGetLocalToGlobalTag - Get the tag used for local to global numbering 428 429 Collective on MPI_Comm 430 431 Input Parameter: 432 . dm - The DMMoab object being set 433 434 Output Parameter: 435 . ltogtag - The MOAB tag used for local to global ids 436 437 Level: beginner 438 439 .keywords: DMMoab, create 440 @*/ 441 PetscErrorCode DMMoabGetLocalToGlobalTag(DM dm,moab::Tag *ltog_tag) 442 { 443 PetscFunctionBegin; 444 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 445 *ltog_tag = ((DM_Moab*)dm->data)->ltog_tag; 446 PetscFunctionReturn(0); 447 } 448 449 450 /*@ 451 DMMoabSetBlockSize - Set the block size used with this DMMoab 452 453 Collective on MPI_Comm 454 455 Input Parameter: 456 . dm - The DMMoab object being set 457 . bs - The block size used with this DMMoab 458 459 Level: beginner 460 461 .keywords: DMMoab, create 462 @*/ 463 PetscErrorCode DMMoabSetBlockSize(DM dm,PetscInt bs) 464 { 465 PetscFunctionBegin; 466 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 467 ((DM_Moab*)dm->data)->bs = bs; 468 PetscFunctionReturn(0); 469 } 470 471 472 /*@ 473 DMMoabGetBlockSize - Get the block size used with this DMMoab 474 475 Collective on MPI_Comm 476 477 Input Parameter: 478 . dm - The DMMoab object being set 479 480 Output Parameter: 481 . bs - The block size used with this DMMoab 482 483 Level: beginner 484 485 .keywords: DMMoab, create 486 @*/ 487 PetscErrorCode DMMoabGetBlockSize(DM dm,PetscInt *bs) 488 { 489 PetscFunctionBegin; 490 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 491 *bs = ((DM_Moab*)dm->data)->bs; 492 PetscFunctionReturn(0); 493 } 494 495 496 /*@ 497 DMMoabGetSize - Get the global vertex size used with this DMMoab 498 499 Collective on DM 500 501 Input Parameter: 502 . dm - The DMMoab object being set 503 504 Output Parameter: 505 . neg - The number of global elements in the DMMoab instance 506 . nvg - The number of global vertices in the DMMoab instance 507 508 Level: beginner 509 510 .keywords: DMMoab, create 511 @*/ 512 PetscErrorCode DMMoabGetSize(DM dm,PetscInt *neg,PetscInt *nvg) 513 { 514 PetscFunctionBegin; 515 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 516 if(neg) *neg = ((DM_Moab*)dm->data)->nele; 517 if(nvg) *nvg = ((DM_Moab*)dm->data)->n; 518 PetscFunctionReturn(0); 519 } 520 521 522 /*@ 523 DMMoabGetLocalSize - Get the local and ghosted vertex size used with this DMMoab 524 525 Collective on DM 526 527 Input Parameter: 528 . dm - The DMMoab object being set 529 530 Output Parameter: 531 + nel - The number of owned elements in this processor 532 . neg - The number of ghosted elements in this processor 533 . nvl - The number of owned vertices in this processor 534 . nvg - The number of ghosted vertices in this processor 535 536 Level: beginner 537 538 .keywords: DMMoab, create 539 @*/ 540 PetscErrorCode DMMoabGetLocalSize(DM dm,PetscInt *nel,PetscInt *neg,PetscInt *nvl,PetscInt *nvg) 541 { 542 PetscFunctionBegin; 543 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 544 if(nel) *nel = ((DM_Moab*)dm->data)->neleloc; 545 if(neg) *neg = ((DM_Moab*)dm->data)->neleghost; 546 if(nvl) *nvl = ((DM_Moab*)dm->data)->nloc; 547 if(nvg) *nvg = ((DM_Moab*)dm->data)->nghost; 548 PetscFunctionReturn(0); 549 } 550 551 552 /*@ 553 DMMoabGetOffset - Get the local offset for the global vector 554 555 Collective on MPI_Comm 556 557 Input Parameter: 558 . dm - The DMMoab object being set 559 560 Output Parameter: 561 . offset - The local offset for the global vector 562 563 Level: beginner 564 565 .keywords: DMMoab, create 566 @*/ 567 PetscErrorCode DMMoabGetOffset(DM dm,PetscInt *offset) 568 { 569 PetscFunctionBegin; 570 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 571 *offset = ((DM_Moab*)dm->data)->vstart; 572 PetscFunctionReturn(0); 573 } 574 575 576 /*@ 577 DMMoabGetDimension - Get the dimension of the DM Mesh 578 579 Collective on MPI_Comm 580 581 Input Parameter: 582 . dm - The DMMoab object 583 584 Output Parameter: 585 . dim - The dimension of DM 586 587 Level: beginner 588 589 .keywords: DMMoab, create 590 @*/ 591 PetscErrorCode DMMoabGetDimension(DM dm,PetscInt *dim) 592 { 593 PetscFunctionBegin; 594 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 595 *dim = ((DM_Moab*)dm->data)->dim; 596 PetscFunctionReturn(0); 597 } 598 599 600 #undef __FUNCT__ 601 #define __FUNCT__ "DMMoabGetHierarchyLevel" 602 /*@ 603 DMMoabGetHierarchyLevel - Get the current level of the mesh hierarchy 604 generated through uniform refinement. 605 606 Collective on DM 607 608 Input Parameter: 609 . dm - The DMMoab object being set 610 611 Output Parameter: 612 . nvg - The current mesh hierarchy level 613 614 Level: beginner 615 616 .keywords: DMMoab, multigrid 617 @*/ 618 PetscErrorCode DMMoabGetHierarchyLevel(DM dm,PetscInt *nlevel) 619 { 620 PetscFunctionBegin; 621 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 622 if(nlevel) *nlevel = ((DM_Moab*)dm->data)->hlevel; 623 PetscFunctionReturn(0); 624 } 625 626 627 #undef __FUNCT__ 628 #define __FUNCT__ "DMMoabGetMaterialBlock" 629 /*@ 630 DMMoabGetMaterialBlock - Get the material ID corresponding to the current entity of the DM Mesh 631 632 Collective on MPI_Comm 633 634 Input Parameter: 635 . dm - The DMMoab object 636 . ehandle - The element entity handle 637 638 Output Parameter: 639 . mat - The material ID for the current entity 640 641 Level: beginner 642 643 .keywords: DMMoab, create 644 @*/ 645 PetscErrorCode DMMoabGetMaterialBlock(DM dm,const moab::EntityHandle ehandle, PetscInt *mat) 646 { 647 DM_Moab *dmmoab; 648 moab::ErrorCode merr; 649 650 PetscFunctionBegin; 651 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 652 if (*mat) { 653 dmmoab = (DM_Moab*)(dm)->data; 654 merr=dmmoab->mbiface->tag_get_data(dmmoab->material_tag, &ehandle, 1, mat);MBERRNM(merr); 655 } 656 PetscFunctionReturn(0); 657 } 658 659 660 /*@ 661 DMMoabGetVertexCoordinates - Get the coordinates corresponding to the requested vertex entities 662 663 Collective on MPI_Comm 664 665 Input Parameter: 666 . dm - The DMMoab object 667 . nconn - Number of entities whose coordinates are needed 668 . conn - The vertex entity handles 669 670 Output Parameter: 671 . vpos - The coordinates of the requested vertex entities 672 673 Level: beginner 674 675 .seealso: DMMoabGetVertexConnectivity() 676 @*/ 677 PetscErrorCode DMMoabGetVertexCoordinates(DM dm,PetscInt nconn,const moab::EntityHandle *conn,PetscReal *vpos) 678 { 679 DM_Moab *dmmoab; 680 PetscErrorCode ierr; 681 moab::ErrorCode merr; 682 683 PetscFunctionBegin; 684 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 685 PetscValidPointer(conn,3); 686 dmmoab = (DM_Moab*)(dm)->data; 687 688 if (!vpos) { 689 ierr = PetscMalloc1(nconn*3, &vpos);CHKERRQ(ierr); 690 } 691 692 /* Get connectivity information in MOAB canonical ordering */ 693 merr = dmmoab->mbiface->get_coords(conn, nconn, vpos);MBERRNM(merr); 694 PetscFunctionReturn(0); 695 } 696 697 698 /*@ 699 DMMoabGetVertexConnectivity - Get the vertex adjacency for the given entity 700 701 Collective on MPI_Comm 702 703 Input Parameter: 704 . dm - The DMMoab object 705 . vhandle - Vertex entity handle 706 707 Output Parameter: 708 . nconn - Number of entities whose coordinates are needed 709 . conn - The vertex entity handles 710 711 Level: beginner 712 713 .seealso: DMMoabGetVertexCoordinates(), DMMoabRestoreVertexConnectivity() 714 @*/ 715 PetscErrorCode DMMoabGetVertexConnectivity(DM dm,moab::EntityHandle vhandle,PetscInt* nconn, moab::EntityHandle **conn) 716 { 717 DM_Moab *dmmoab; 718 std::vector<moab::EntityHandle> adj_entities,connect; 719 PetscErrorCode ierr; 720 moab::ErrorCode merr; 721 722 PetscFunctionBegin; 723 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 724 PetscValidPointer(conn,4); 725 dmmoab = (DM_Moab*)(dm)->data; 726 727 /* Get connectivity information in MOAB canonical ordering */ 728 merr = dmmoab->mbiface->get_adjacencies(&vhandle, 1, 1, true, adj_entities, moab::Interface::UNION);MBERRNM(merr); 729 merr = dmmoab->mbiface->get_connectivity(&adj_entities[0],adj_entities.size(),connect);MBERRNM(merr); 730 731 if (conn) { 732 ierr = PetscMalloc(sizeof(moab::EntityHandle)*connect.size(), conn);CHKERRQ(ierr); 733 ierr = PetscMemcpy(*conn, &connect[0], sizeof(moab::EntityHandle)*connect.size());CHKERRQ(ierr); 734 } 735 if (nconn) *nconn=connect.size(); 736 PetscFunctionReturn(0); 737 } 738 739 740 /*@ 741 DMMoabRestoreVertexConnectivity - Restore the vertex connectivity for the given entity 742 743 Collective on MPI_Comm 744 745 Input Parameter: 746 . dm - The DMMoab object 747 . vhandle - Vertex entity handle 748 . nconn - Number of entities whose coordinates are needed 749 . conn - The vertex entity handles 750 751 Level: beginner 752 753 .seealso: DMMoabGetVertexCoordinates(), DMMoabGetVertexConnectivity() 754 @*/ 755 PetscErrorCode DMMoabRestoreVertexConnectivity(DM dm,moab::EntityHandle ehandle,PetscInt* nconn, moab::EntityHandle **conn) 756 { 757 PetscErrorCode ierr; 758 759 PetscFunctionBegin; 760 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 761 PetscValidPointer(conn,4); 762 763 if (conn) { 764 ierr = PetscFree(*conn);CHKERRQ(ierr); 765 } 766 if (nconn) *nconn=0; 767 PetscFunctionReturn(0); 768 } 769 770 771 /*@ 772 DMMoabGetElementConnectivity - Get the vertex adjacency for the given entity 773 774 Collective on MPI_Comm 775 776 Input Parameter: 777 . dm - The DMMoab object 778 . ehandle - Vertex entity handle 779 780 Output Parameter: 781 . nconn - Number of entities whose coordinates are needed 782 . conn - The vertex entity handles 783 784 Level: beginner 785 786 .seealso: DMMoabGetVertexCoordinates(), DMMoabGetVertexConnectivity(), DMMoabRestoreVertexConnectivity() 787 @*/ 788 PetscErrorCode DMMoabGetElementConnectivity(DM dm,moab::EntityHandle ehandle,PetscInt* nconn,const moab::EntityHandle **conn) 789 { 790 DM_Moab *dmmoab; 791 const moab::EntityHandle *connect; 792 moab::ErrorCode merr; 793 PetscInt nnodes; 794 795 PetscFunctionBegin; 796 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 797 PetscValidPointer(conn,4); 798 dmmoab = (DM_Moab*)(dm)->data; 799 800 /* Get connectivity information in MOAB canonical ordering */ 801 merr = dmmoab->mbiface->get_connectivity(ehandle, connect, nnodes);MBERRNM(merr); 802 if (conn) *conn=connect; 803 if (nconn) *nconn=nnodes; 804 PetscFunctionReturn(0); 805 } 806 807 808 /*@ 809 DMMoabIsEntityOnBoundary - Check whether a given entity is on the boundary (vertex, edge, face, element) 810 811 Collective on MPI_Comm 812 813 Input Parameter: 814 . dm - The DMMoab object 815 . ent - Entity handle 816 817 Output Parameter: 818 . ent_on_boundary - PETSC_TRUE if entity on boundary; PETSC_FALSE otherwise 819 820 Level: beginner 821 822 .seealso: DMMoabCheckBoundaryVertices() 823 @*/ 824 PetscErrorCode DMMoabIsEntityOnBoundary(DM dm,const moab::EntityHandle ent,PetscBool* ent_on_boundary) 825 { 826 moab::EntityType etype; 827 DM_Moab *dmmoab; 828 PetscInt edim; 829 830 PetscFunctionBegin; 831 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 832 PetscValidPointer(ent_on_boundary,3); 833 dmmoab = (DM_Moab*)(dm)->data; 834 835 /* get the entity type and handle accordingly */ 836 etype=dmmoab->mbiface->type_from_handle(ent); 837 if(etype >= moab::MBPOLYHEDRON) SETERRQ1(PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE, "Entity type on the boundary skin is invalid. EntityType = %D\n",etype); 838 839 /* get the entity dimension */ 840 edim=dmmoab->mbiface->dimension_from_handle(ent); 841 842 *ent_on_boundary=PETSC_FALSE; 843 if(etype == moab::MBVERTEX && edim == 0) { 844 *ent_on_boundary=((dmmoab->bndyvtx->index(ent) >= 0) ? PETSC_TRUE:PETSC_FALSE); 845 } 846 else { 847 if (edim == dmmoab->dim) { /* check the higher-dimensional elements first */ 848 if (dmmoab->bndyelems->index(ent) >= 0) *ent_on_boundary=PETSC_TRUE; 849 } 850 else { /* next check the lower-dimensional faces */ 851 if (dmmoab->bndyfaces->index(ent) >= 0) *ent_on_boundary=PETSC_TRUE; 852 } 853 } 854 PetscFunctionReturn(0); 855 } 856 857 858 /*@ 859 DMMoabIsEntityOnBoundary - Check whether a given entity is on the boundary (vertex, edge, face, element) 860 861 Input Parameter: 862 . dm - The DMMoab object 863 . nconn - Number of handles 864 . cnt - Array of entity handles 865 866 Output Parameter: 867 . isbdvtx - Array of boundary markers - PETSC_TRUE if entity on boundary; PETSC_FALSE otherwise 868 869 Level: beginner 870 871 .seealso: DMMoabIsEntityOnBoundary() 872 @*/ 873 PetscErrorCode DMMoabCheckBoundaryVertices(DM dm,PetscInt nconn,const moab::EntityHandle *cnt,PetscBool* isbdvtx) 874 { 875 DM_Moab *dmmoab; 876 PetscInt i; 877 878 PetscFunctionBegin; 879 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 880 PetscValidPointer(cnt,3); 881 PetscValidPointer(isbdvtx,4); 882 dmmoab = (DM_Moab*)(dm)->data; 883 884 for (i=0; i < nconn; ++i) { 885 isbdvtx[i]=(dmmoab->bndyvtx->index(cnt[i]) >= 0 ? PETSC_TRUE:PETSC_FALSE); 886 } 887 PetscFunctionReturn(0); 888 } 889 890 891 /*@ 892 DMMoabGetBoundaryMarkers - Return references to the vertices, faces, elements on the boundary 893 894 Input Parameter: 895 . dm - The DMMoab object 896 897 Output Parameter: 898 . bdvtx - Boundary vertices 899 . bdelems - Boundary elements 900 . bdfaces - Boundary faces 901 902 Level: beginner 903 904 .seealso: DMMoabCheckBoundaryVertices(), DMMoabIsEntityOnBoundary() 905 @*/ 906 PetscErrorCode DMMoabGetBoundaryMarkers(DM dm,const moab::Range **bdvtx,const moab::Range** bdelems,const moab::Range** bdfaces) 907 { 908 DM_Moab *dmmoab; 909 910 PetscFunctionBegin; 911 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 912 dmmoab = (DM_Moab*)(dm)->data; 913 914 if (bdvtx) *bdvtx = dmmoab->bndyvtx; 915 if (bdfaces) *bdfaces = dmmoab->bndyfaces; 916 if (bdelems) *bdfaces = dmmoab->bndyelems; 917 PetscFunctionReturn(0); 918 } 919 920 921 PETSC_EXTERN PetscErrorCode DMDestroy_Moab(DM dm) 922 { 923 PetscErrorCode ierr; 924 PetscInt i; 925 moab::ErrorCode merr; 926 DM_Moab *dmmoab = (DM_Moab*)dm->data; 927 928 PetscFunctionBegin; 929 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 930 if (dmmoab->icreatedinstance) { 931 delete dmmoab->mbiface; 932 } 933 dmmoab->mbiface = NULL; 934 dmmoab->pcomm = NULL; 935 delete dmmoab->vlocal; 936 delete dmmoab->vowned; 937 delete dmmoab->vghost; 938 delete dmmoab->elocal; 939 delete dmmoab->eghost; 940 delete dmmoab->bndyvtx; 941 delete dmmoab->bndyfaces; 942 delete dmmoab->bndyelems; 943 944 ierr = PetscFree(dmmoab->gsindices);CHKERRQ(ierr); 945 ierr = PetscFree2(dmmoab->gidmap,dmmoab->lidmap);CHKERRQ(ierr); 946 ierr = PetscFree(dmmoab->dfill);CHKERRQ(ierr); 947 ierr = PetscFree(dmmoab->ofill);CHKERRQ(ierr); 948 if (dmmoab->fieldNames) { 949 for(i=0; i<dmmoab->numFields; i++) { 950 ierr = PetscFree(dmmoab->fieldNames[i]);CHKERRQ(ierr); 951 } 952 ierr = PetscFree(dmmoab->fieldNames);CHKERRQ(ierr); 953 } 954 955 if (dmmoab->nhlevels) { 956 ierr = PetscFree(dmmoab->hsets);CHKERRQ(ierr); 957 dmmoab->nhlevels=0; 958 if (!dmmoab->hlevel && dmmoab->icreatedinstance) delete dmmoab->hierarchy; 959 dmmoab->hierarchy=NULL; 960 } 961 962 if (dmmoab->icreatedinstance) { 963 merr = dmmoab->mbiface->delete_mesh();MBERRNM(merr); 964 delete dmmoab->mbiface; 965 } 966 dmmoab->mbiface = NULL; 967 dmmoab->pcomm = NULL; 968 969 ierr = VecScatterDestroy(&dmmoab->ltog_sendrecv);CHKERRQ(ierr); 970 ierr = ISLocalToGlobalMappingDestroy(&dmmoab->ltog_map);CHKERRQ(ierr); 971 ierr = PetscFree(dm->data);CHKERRQ(ierr); 972 PetscFunctionReturn(0); 973 } 974 975 976 PETSC_EXTERN PetscErrorCode DMSetFromOptions_Moab(PetscOptionItems *PetscOptionsObject,DM dm) 977 { 978 PetscErrorCode ierr; 979 DM_Moab *dmmoab = (DM_Moab*)dm->data; 980 981 PetscFunctionBegin; 982 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 983 ierr = PetscOptionsHead(PetscOptionsObject,"DMMoab Options");CHKERRQ(ierr); 984 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); 985 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); 986 /* TODO: typically, the read options are needed before a DM is completely created and available in which case, the options wont be available ?? */ 987 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); 988 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); 989 ierr = PetscOptionsEnum("-dm_moab_read_mode", "MOAB parallel read mode", "DMView", MoabReadModes, (PetscEnum)dmmoab->read_mode, (PetscEnum*)&dmmoab->read_mode, NULL);CHKERRQ(ierr); 990 ierr = PetscOptionsEnum("-dm_moab_write_mode", "MOAB parallel write mode", "DMView", MoabWriteModes, (PetscEnum)dmmoab->write_mode, (PetscEnum*)&dmmoab->write_mode, NULL);CHKERRQ(ierr); 991 PetscFunctionReturn(0); 992 } 993 994 995 PETSC_EXTERN PetscErrorCode DMSetUp_Moab(DM dm) 996 { 997 PetscErrorCode ierr; 998 moab::ErrorCode merr; 999 Vec local, global; 1000 IS from,to; 1001 moab::Range::iterator iter; 1002 PetscInt i,j,f,bs,gmin,lmin,lmax,vent,totsize,*lgmap; 1003 DM_Moab *dmmoab = (DM_Moab*)dm->data; 1004 moab::Range adjs; 1005 1006 PetscFunctionBegin; 1007 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1008 /* Get the local and shared vertices and cache it */ 1009 if (dmmoab->mbiface == NULL || dmmoab->pcomm == NULL) SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ORDER, "Set the MOAB Interface and ParallelComm objects before calling SetUp."); 1010 1011 /* Get the entities recursively in the current part of the mesh, if user did not set the local vertices explicitly */ 1012 if (dmmoab->vlocal->empty()) 1013 { 1014 //merr = dmmoab->mbiface->get_entities_by_type(dmmoab->fileset,moab::MBVERTEX,*dmmoab->vlocal,true);MBERRNM(merr); 1015 merr = dmmoab->mbiface->get_entities_by_dimension(dmmoab->fileset, 0, *dmmoab->vlocal, false);MBERRNM(merr); 1016 1017 /* filter based on parallel status */ 1018 merr = dmmoab->pcomm->filter_pstatus(*dmmoab->vlocal,PSTATUS_NOT_OWNED,PSTATUS_NOT,-1,dmmoab->vowned);MBERRNM(merr); 1019 1020 /* filter all the non-owned and shared entities out of the list */ 1021 adjs = moab::subtract(*dmmoab->vlocal, *dmmoab->vowned); 1022 merr = dmmoab->pcomm->filter_pstatus(adjs,PSTATUS_GHOST|PSTATUS_INTERFACE,PSTATUS_OR,-1,dmmoab->vghost);MBERRNM(merr); 1023 adjs = moab::subtract(adjs, *dmmoab->vghost); 1024 *dmmoab->vlocal = moab::subtract(*dmmoab->vlocal, adjs); 1025 1026 /* compute and cache the sizes of local and ghosted entities */ 1027 dmmoab->nloc = dmmoab->vowned->size(); 1028 dmmoab->nghost = dmmoab->vghost->size(); 1029 1030 ierr = MPIU_Allreduce(&dmmoab->nloc, &dmmoab->n, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm);CHKERRQ(ierr); 1031 PetscInfo4(NULL, "Filset ID: %u, Vertices: local - %D, owned - %D, ghosted - %D.\n", dmmoab->fileset, dmmoab->vlocal->size(), dmmoab->nloc, dmmoab->nghost); 1032 } 1033 1034 { 1035 /* get the information about the local elements in the mesh */ 1036 dmmoab->eghost->clear(); 1037 1038 /* first decipher the leading dimension */ 1039 for (i=3;i>0;i--) { 1040 dmmoab->elocal->clear(); 1041 merr = dmmoab->mbiface->get_entities_by_dimension(dmmoab->fileset, i, *dmmoab->elocal, false);MBERRNM(merr); 1042 1043 /* store the current mesh dimension */ 1044 if (dmmoab->elocal->size()) { 1045 dmmoab->dim=i; 1046 break; 1047 } 1048 } 1049 1050 ierr = DMSetDimension(dm, dmmoab->dim);CHKERRQ(ierr); 1051 1052 /* filter the ghosted and owned element list */ 1053 *dmmoab->eghost = *dmmoab->elocal; 1054 merr = dmmoab->pcomm->filter_pstatus(*dmmoab->elocal,PSTATUS_NOT_OWNED,PSTATUS_NOT);MBERRNM(merr); 1055 *dmmoab->eghost = moab::subtract(*dmmoab->eghost, *dmmoab->elocal); 1056 1057 dmmoab->neleloc = dmmoab->elocal->size(); 1058 dmmoab->neleghost = dmmoab->eghost->size(); 1059 1060 ierr = MPIU_Allreduce(&dmmoab->neleloc, &dmmoab->nele, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm);CHKERRQ(ierr); 1061 PetscInfo3(NULL, "%d-dim elements: owned - %D, ghosted - %D.\n", dmmoab->dim, dmmoab->neleloc, dmmoab->neleghost); 1062 } 1063 1064 bs = dmmoab->bs; 1065 if (!dmmoab->ltog_tag) { 1066 /* Get the global ID tag. The global ID tag is applied to each 1067 vertex. It acts as an global identifier which MOAB uses to 1068 assemble the individual pieces of the mesh */ 1069 merr = dmmoab->mbiface->tag_get_handle(GLOBAL_ID_TAG_NAME, dmmoab->ltog_tag);MBERRNM(merr); 1070 } 1071 1072 totsize=dmmoab->vlocal->size(); 1073 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); 1074 ierr = PetscCalloc1(totsize,&dmmoab->gsindices);CHKERRQ(ierr); 1075 { 1076 /* first get the local indices */ 1077 merr = dmmoab->mbiface->tag_get_data(dmmoab->ltog_tag,*dmmoab->vowned,&dmmoab->gsindices[0]);MBERRNM(merr); 1078 if (dmmoab->nghost) { /* next get the ghosted indices */ 1079 merr = dmmoab->mbiface->tag_get_data(dmmoab->ltog_tag,*dmmoab->vghost,&dmmoab->gsindices[dmmoab->nloc]);MBERRNM(merr); 1080 } 1081 1082 /* find out the local and global minima of GLOBAL_ID */ 1083 lmin=lmax=dmmoab->gsindices[0]; 1084 for (i=0; i<totsize; ++i) { 1085 if(lmin>dmmoab->gsindices[i]) lmin=dmmoab->gsindices[i]; 1086 if(lmax<dmmoab->gsindices[i]) lmax=dmmoab->gsindices[i]; 1087 } 1088 1089 ierr = MPIU_Allreduce(&lmin, &gmin, 1, MPI_INT, MPI_MIN, ((PetscObject)dm)->comm);CHKERRQ(ierr); 1090 1091 /* set the GID map */ 1092 for (i=0; i<totsize; ++i) { 1093 dmmoab->gsindices[i]-=gmin; /* zero based index needed for IS */ 1094 } 1095 lmin-=gmin; 1096 lmax-=gmin; 1097 1098 PetscInfo3(NULL, "GLOBAL_ID: Local minima - %D, Local maxima - %D, Global minima - %D.\n", lmin, lmax, gmin); 1099 } 1100 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); 1101 1102 { 1103 dmmoab->seqstart=((PetscInt)dmmoab->vlocal->front()); 1104 dmmoab->seqend=((PetscInt)dmmoab->vlocal->back()); 1105 PetscInfo2(NULL, "SEQUENCE: Local minima - %D, Local maxima - %D.\n", dmmoab->seqstart, dmmoab->seqend); 1106 1107 ierr = PetscMalloc2(dmmoab->seqend-dmmoab->seqstart+1,&dmmoab->gidmap,dmmoab->seqend-dmmoab->seqstart+1,&dmmoab->lidmap);CHKERRQ(ierr); 1108 ierr = PetscMalloc1(totsize*dmmoab->numFields,&lgmap);CHKERRQ(ierr); 1109 1110 i=j=0; 1111 /* set the owned vertex data first */ 1112 for(moab::Range::iterator iter = dmmoab->vowned->begin(); iter != dmmoab->vowned->end(); iter++,i++) { 1113 vent=(PetscInt)(*iter)-dmmoab->seqstart; 1114 dmmoab->gidmap[vent]=dmmoab->gsindices[i]; 1115 dmmoab->lidmap[vent]=i; 1116 for (f=0;f<dmmoab->numFields;f++,j++) { 1117 lgmap[j]=(bs > 1 ? dmmoab->gsindices[i]*dmmoab->numFields+f : totsize*f+dmmoab->gsindices[i]); 1118 } 1119 } 1120 /* next arrange all the ghosted data information */ 1121 for(moab::Range::iterator iter = dmmoab->vghost->begin(); iter != dmmoab->vghost->end(); iter++,i++) { 1122 vent=(PetscInt)(*iter)-dmmoab->seqstart; 1123 dmmoab->gidmap[vent]=dmmoab->gsindices[i]; 1124 dmmoab->lidmap[vent]=i; 1125 for (f=0;f<dmmoab->numFields;f++,j++) { 1126 lgmap[j]=(bs > 1 ? dmmoab->gsindices[i]*dmmoab->numFields+f : totsize*f+dmmoab->gsindices[i]); 1127 } 1128 } 1129 1130 /* We need to create the Global to Local Vector Scatter Contexts 1131 1) First create a local and global vector 1132 2) Create a local and global IS 1133 3) Create VecScatter and LtoGMapping objects 1134 4) Cleanup the IS and Vec objects 1135 */ 1136 ierr = DMCreateGlobalVector(dm, &global);CHKERRQ(ierr); 1137 ierr = DMCreateLocalVector(dm, &local);CHKERRQ(ierr); 1138 1139 ierr = VecGetOwnershipRange(global, &dmmoab->vstart, &dmmoab->vend);CHKERRQ(ierr); 1140 1141 /* global to local must retrieve ghost points */ 1142 ierr = ISCreateStride(((PetscObject)dm)->comm,dmmoab->nloc*dmmoab->numFields,dmmoab->vstart,1,&from);CHKERRQ(ierr); 1143 ierr = ISSetBlockSize(from,bs);CHKERRQ(ierr); 1144 1145 ierr = ISCreateGeneral(((PetscObject)dm)->comm,dmmoab->nloc*dmmoab->numFields,&lgmap[0],PETSC_COPY_VALUES,&to);CHKERRQ(ierr); 1146 ierr = ISSetBlockSize(to,bs);CHKERRQ(ierr); 1147 1148 if (!dmmoab->ltog_map) { 1149 /* create to the local to global mapping for vectors in order to use VecSetValuesLocal */ 1150 ierr = ISLocalToGlobalMappingCreate(((PetscObject)dm)->comm,dmmoab->bs,totsize*dmmoab->numFields,lgmap, 1151 PETSC_COPY_VALUES,&dmmoab->ltog_map);CHKERRQ(ierr); 1152 } 1153 1154 /* now create the scatter object from local to global vector */ 1155 ierr = VecScatterCreate(local,from,global,to,&dmmoab->ltog_sendrecv);CHKERRQ(ierr); 1156 1157 /* clean up IS, Vec */ 1158 ierr = PetscFree(lgmap);CHKERRQ(ierr); 1159 ierr = ISDestroy(&from);CHKERRQ(ierr); 1160 ierr = ISDestroy(&to);CHKERRQ(ierr); 1161 ierr = VecDestroy(&local);CHKERRQ(ierr); 1162 ierr = VecDestroy(&global);CHKERRQ(ierr); 1163 } 1164 1165 dmmoab->bndyvtx = new moab::Range(); 1166 dmmoab->bndyfaces = new moab::Range(); 1167 dmmoab->bndyelems = new moab::Range(); 1168 /* skin the boundary and store nodes */ 1169 { 1170 /* get the skin vertices of boundary faces for the current partition and then filter 1171 the local, boundary faces, vertices and elements alone via PSTATUS flags; 1172 this should not give us any ghosted boundary, but if user needs such a functionality 1173 it would be easy to add it based on the find_skin query below */ 1174 moab::Skinner skinner(dmmoab->mbiface); 1175 1176 /* get the entities on the skin - only the faces */ 1177 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 1178 1179 /* filter all the non-owned and shared entities out of the list */ 1180 merr = dmmoab->pcomm->filter_pstatus(*dmmoab->bndyfaces,PSTATUS_NOT_OWNED,PSTATUS_NOT);MBERRNM(merr); 1181 merr = dmmoab->pcomm->filter_pstatus(*dmmoab->bndyfaces,PSTATUS_SHARED,PSTATUS_NOT);MBERRNM(merr); 1182 1183 /* get all the nodes via connectivity and the parent elements via adjacency information */ 1184 merr = dmmoab->mbiface->get_connectivity(*dmmoab->bndyfaces, *dmmoab->bndyvtx, false);MBERRNM(ierr); 1185 merr = dmmoab->mbiface->get_adjacencies(*dmmoab->bndyvtx, dmmoab->dim, false, *dmmoab->bndyelems, moab::Interface::UNION);MBERRNM(ierr); 1186 } 1187 PetscInfo3(NULL, "Found %D boundary vertices, %D boundary faces and %D boundary elements.\n", dmmoab->bndyvtx->size(), dmmoab->bndyfaces->size(), dmmoab->bndyelems->size()); 1188 PetscFunctionReturn(0); 1189 } 1190 1191 PETSC_EXTERN PetscErrorCode DMCreate_Moab(DM dm) 1192 { 1193 PetscErrorCode ierr; 1194 1195 PetscFunctionBegin; 1196 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1197 ierr = PetscNewLog(dm,(DM_Moab**)&dm->data);CHKERRQ(ierr); 1198 1199 ((DM_Moab*)dm->data)->bs = 1; 1200 ((DM_Moab*)dm->data)->numFields = 1; 1201 ((DM_Moab*)dm->data)->n = 0; 1202 ((DM_Moab*)dm->data)->nloc = 0; 1203 ((DM_Moab*)dm->data)->nghost = 0; 1204 ((DM_Moab*)dm->data)->nele = 0; 1205 ((DM_Moab*)dm->data)->neleloc = 0; 1206 ((DM_Moab*)dm->data)->neleghost = 0; 1207 ((DM_Moab*)dm->data)->ltog_map = NULL; 1208 ((DM_Moab*)dm->data)->ltog_sendrecv = NULL; 1209 1210 ((DM_Moab*)dm->data)->vlocal = new moab::Range(); 1211 ((DM_Moab*)dm->data)->vowned = new moab::Range(); 1212 ((DM_Moab*)dm->data)->vghost = new moab::Range(); 1213 ((DM_Moab*)dm->data)->elocal = new moab::Range(); 1214 ((DM_Moab*)dm->data)->eghost = new moab::Range(); 1215 1216 dm->ops->createglobalvector = DMCreateGlobalVector_Moab; 1217 dm->ops->createlocalvector = DMCreateLocalVector_Moab; 1218 dm->ops->creatematrix = DMCreateMatrix_Moab; 1219 dm->ops->setup = DMSetUp_Moab; 1220 dm->ops->destroy = DMDestroy_Moab; 1221 dm->ops->coarsenhierarchy = DMCoarsenHierarchy_Moab; 1222 dm->ops->refinehierarchy = DMRefineHierarchy_Moab; 1223 dm->ops->createinterpolation = DMCreateInterpolation_Moab; 1224 //dm->ops->getinjection = DMCreateInjection_Moab; 1225 dm->ops->refine = DMRefine_Moab; 1226 dm->ops->coarsen = DMCoarsen_Moab; 1227 dm->ops->setfromoptions = DMSetFromOptions_Moab; 1228 dm->ops->globaltolocalbegin = DMGlobalToLocalBegin_Moab; 1229 dm->ops->globaltolocalend = DMGlobalToLocalEnd_Moab; 1230 dm->ops->localtoglobalbegin = DMLocalToGlobalBegin_Moab; 1231 dm->ops->localtoglobalend = DMLocalToGlobalEnd_Moab; 1232 PetscFunctionReturn(0); 1233 } 1234 1235