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 /*@ 601 DMMoabGetMaterialBlock - Get the material ID corresponding to the current entity of the DM Mesh 602 603 Collective on MPI_Comm 604 605 Input Parameter: 606 . dm - The DMMoab object 607 . ehandle - The element entity handle 608 609 Output Parameter: 610 . mat - The material ID for the current entity 611 612 Level: beginner 613 614 .keywords: DMMoab, create 615 @*/ 616 PetscErrorCode DMMoabGetMaterialBlock(DM dm,const moab::EntityHandle ehandle, PetscInt *mat) 617 { 618 DM_Moab *dmmoab; 619 moab::ErrorCode merr; 620 621 PetscFunctionBegin; 622 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 623 if (*mat) { 624 dmmoab = (DM_Moab*)(dm)->data; 625 merr=dmmoab->mbiface->tag_get_data(dmmoab->material_tag, &ehandle, 1, mat);MBERRNM(merr); 626 } 627 PetscFunctionReturn(0); 628 } 629 630 631 /*@ 632 DMMoabGetVertexCoordinates - Get the coordinates corresponding to the requested vertex entities 633 634 Collective on MPI_Comm 635 636 Input Parameter: 637 . dm - The DMMoab object 638 . nconn - Number of entities whose coordinates are needed 639 . conn - The vertex entity handles 640 641 Output Parameter: 642 . vpos - The coordinates of the requested vertex entities 643 644 Level: beginner 645 646 .seealso: DMMoabGetVertexConnectivity() 647 @*/ 648 PetscErrorCode DMMoabGetVertexCoordinates(DM dm,PetscInt nconn,const moab::EntityHandle *conn,PetscReal *vpos) 649 { 650 DM_Moab *dmmoab; 651 PetscErrorCode ierr; 652 moab::ErrorCode merr; 653 654 PetscFunctionBegin; 655 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 656 PetscValidPointer(conn,3); 657 dmmoab = (DM_Moab*)(dm)->data; 658 659 if (!vpos) { 660 ierr = PetscMalloc1(nconn*3, &vpos);CHKERRQ(ierr); 661 } 662 663 /* Get connectivity information in MOAB canonical ordering */ 664 merr = dmmoab->mbiface->get_coords(conn, nconn, vpos);MBERRNM(merr); 665 PetscFunctionReturn(0); 666 } 667 668 669 /*@ 670 DMMoabGetVertexConnectivity - Get the vertex adjacency for the given entity 671 672 Collective on MPI_Comm 673 674 Input Parameter: 675 . dm - The DMMoab object 676 . vhandle - Vertex entity handle 677 678 Output Parameter: 679 . nconn - Number of entities whose coordinates are needed 680 . conn - The vertex entity handles 681 682 Level: beginner 683 684 .seealso: DMMoabGetVertexCoordinates(), DMMoabRestoreVertexConnectivity() 685 @*/ 686 PetscErrorCode DMMoabGetVertexConnectivity(DM dm,moab::EntityHandle vhandle,PetscInt* nconn, moab::EntityHandle **conn) 687 { 688 DM_Moab *dmmoab; 689 std::vector<moab::EntityHandle> adj_entities,connect; 690 PetscErrorCode ierr; 691 moab::ErrorCode merr; 692 693 PetscFunctionBegin; 694 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 695 PetscValidPointer(conn,4); 696 dmmoab = (DM_Moab*)(dm)->data; 697 698 /* Get connectivity information in MOAB canonical ordering */ 699 merr = dmmoab->mbiface->get_adjacencies(&vhandle, 1, 1, true, adj_entities, moab::Interface::UNION);MBERRNM(merr); 700 merr = dmmoab->mbiface->get_connectivity(&adj_entities[0],adj_entities.size(),connect);MBERRNM(merr); 701 702 if (conn) { 703 ierr = PetscMalloc(sizeof(moab::EntityHandle)*connect.size(), conn);CHKERRQ(ierr); 704 ierr = PetscMemcpy(*conn, &connect[0], sizeof(moab::EntityHandle)*connect.size());CHKERRQ(ierr); 705 } 706 if (nconn) *nconn=connect.size(); 707 PetscFunctionReturn(0); 708 } 709 710 711 /*@ 712 DMMoabRestoreVertexConnectivity - Restore the vertex connectivity for the given entity 713 714 Collective on MPI_Comm 715 716 Input Parameter: 717 . dm - The DMMoab object 718 . vhandle - Vertex entity handle 719 . nconn - Number of entities whose coordinates are needed 720 . conn - The vertex entity handles 721 722 Level: beginner 723 724 .seealso: DMMoabGetVertexCoordinates(), DMMoabGetVertexConnectivity() 725 @*/ 726 PetscErrorCode DMMoabRestoreVertexConnectivity(DM dm,moab::EntityHandle ehandle,PetscInt* nconn, moab::EntityHandle **conn) 727 { 728 PetscErrorCode ierr; 729 730 PetscFunctionBegin; 731 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 732 PetscValidPointer(conn,4); 733 734 if (conn) { 735 ierr = PetscFree(*conn);CHKERRQ(ierr); 736 } 737 if (nconn) *nconn=0; 738 PetscFunctionReturn(0); 739 } 740 741 742 /*@ 743 DMMoabGetElementConnectivity - Get the vertex adjacency for the given entity 744 745 Collective on MPI_Comm 746 747 Input Parameter: 748 . dm - The DMMoab object 749 . ehandle - Vertex entity handle 750 751 Output Parameter: 752 . nconn - Number of entities whose coordinates are needed 753 . conn - The vertex entity handles 754 755 Level: beginner 756 757 .seealso: DMMoabGetVertexCoordinates(), DMMoabGetVertexConnectivity(), DMMoabRestoreVertexConnectivity() 758 @*/ 759 PetscErrorCode DMMoabGetElementConnectivity(DM dm,moab::EntityHandle ehandle,PetscInt* nconn,const moab::EntityHandle **conn) 760 { 761 DM_Moab *dmmoab; 762 const moab::EntityHandle *connect; 763 moab::ErrorCode merr; 764 PetscInt nnodes; 765 766 PetscFunctionBegin; 767 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 768 PetscValidPointer(conn,4); 769 dmmoab = (DM_Moab*)(dm)->data; 770 771 /* Get connectivity information in MOAB canonical ordering */ 772 merr = dmmoab->mbiface->get_connectivity(ehandle, connect, nnodes);MBERRNM(merr); 773 if (conn) *conn=connect; 774 if (nconn) *nconn=nnodes; 775 PetscFunctionReturn(0); 776 } 777 778 779 /*@ 780 DMMoabIsEntityOnBoundary - Check whether a given entity is on the boundary (vertex, edge, face, element) 781 782 Collective on MPI_Comm 783 784 Input Parameter: 785 . dm - The DMMoab object 786 . ent - Entity handle 787 788 Output Parameter: 789 . ent_on_boundary - PETSC_TRUE if entity on boundary; PETSC_FALSE otherwise 790 791 Level: beginner 792 793 .seealso: DMMoabCheckBoundaryVertices() 794 @*/ 795 PetscErrorCode DMMoabIsEntityOnBoundary(DM dm,const moab::EntityHandle ent,PetscBool* ent_on_boundary) 796 { 797 moab::EntityType etype; 798 DM_Moab *dmmoab; 799 PetscInt edim; 800 801 PetscFunctionBegin; 802 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 803 PetscValidPointer(ent_on_boundary,3); 804 dmmoab = (DM_Moab*)(dm)->data; 805 806 /* get the entity type and handle accordingly */ 807 etype=dmmoab->mbiface->type_from_handle(ent); 808 if(etype >= moab::MBPOLYHEDRON) SETERRQ1(PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE, "Entity type on the boundary skin is invalid. EntityType = %D\n",etype); 809 810 /* get the entity dimension */ 811 edim=dmmoab->mbiface->dimension_from_handle(ent); 812 813 *ent_on_boundary=PETSC_FALSE; 814 if(etype == moab::MBVERTEX && edim == 0) { 815 *ent_on_boundary=((dmmoab->bndyvtx->index(ent) >= 0) ? PETSC_TRUE:PETSC_FALSE); 816 } 817 else { 818 if (edim == dmmoab->dim) { /* check the higher-dimensional elements first */ 819 if (dmmoab->bndyelems->index(ent) >= 0) *ent_on_boundary=PETSC_TRUE; 820 } 821 else { /* next check the lower-dimensional faces */ 822 if (dmmoab->bndyfaces->index(ent) >= 0) *ent_on_boundary=PETSC_TRUE; 823 } 824 } 825 PetscFunctionReturn(0); 826 } 827 828 829 /*@ 830 DMMoabIsEntityOnBoundary - Check whether a given entity is on the boundary (vertex, edge, face, element) 831 832 Input Parameter: 833 . dm - The DMMoab object 834 . nconn - Number of handles 835 . cnt - Array of entity handles 836 837 Output Parameter: 838 . isbdvtx - Array of boundary markers - PETSC_TRUE if entity on boundary; PETSC_FALSE otherwise 839 840 Level: beginner 841 842 .seealso: DMMoabIsEntityOnBoundary() 843 @*/ 844 PetscErrorCode DMMoabCheckBoundaryVertices(DM dm,PetscInt nconn,const moab::EntityHandle *cnt,PetscBool* isbdvtx) 845 { 846 DM_Moab *dmmoab; 847 PetscInt i; 848 849 PetscFunctionBegin; 850 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 851 PetscValidPointer(cnt,3); 852 PetscValidPointer(isbdvtx,4); 853 dmmoab = (DM_Moab*)(dm)->data; 854 855 for (i=0; i < nconn; ++i) { 856 isbdvtx[i]=(dmmoab->bndyvtx->index(cnt[i]) >= 0 ? PETSC_TRUE:PETSC_FALSE); 857 } 858 PetscFunctionReturn(0); 859 } 860 861 862 /*@ 863 DMMoabGetBoundaryMarkers - Return references to the vertices, faces, elements on the boundary 864 865 Input Parameter: 866 . dm - The DMMoab object 867 868 Output Parameter: 869 . bdvtx - Boundary vertices 870 . bdelems - Boundary elements 871 . bdfaces - Boundary faces 872 873 Level: beginner 874 875 .seealso: DMMoabCheckBoundaryVertices(), DMMoabIsEntityOnBoundary() 876 @*/ 877 PetscErrorCode DMMoabGetBoundaryMarkers(DM dm,const moab::Range **bdvtx,const moab::Range** bdelems,const moab::Range** bdfaces) 878 { 879 DM_Moab *dmmoab; 880 881 PetscFunctionBegin; 882 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 883 dmmoab = (DM_Moab*)(dm)->data; 884 885 if (bdvtx) *bdvtx = dmmoab->bndyvtx; 886 if (bdfaces) *bdfaces = dmmoab->bndyfaces; 887 if (bdelems) *bdfaces = dmmoab->bndyelems; 888 PetscFunctionReturn(0); 889 } 890 891 892 PETSC_EXTERN PetscErrorCode DMDestroy_Moab(DM dm) 893 { 894 PetscErrorCode ierr; 895 PetscInt i; 896 moab::ErrorCode merr; 897 DM_Moab *dmmoab = (DM_Moab*)dm->data; 898 899 PetscFunctionBegin; 900 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 901 if (dmmoab->icreatedinstance) { 902 delete dmmoab->mbiface; 903 } 904 dmmoab->mbiface = NULL; 905 dmmoab->pcomm = NULL; 906 delete dmmoab->vlocal; 907 delete dmmoab->vowned; 908 delete dmmoab->vghost; 909 delete dmmoab->elocal; 910 delete dmmoab->eghost; 911 delete dmmoab->bndyvtx; 912 delete dmmoab->bndyfaces; 913 delete dmmoab->bndyelems; 914 915 ierr = PetscFree(dmmoab->gsindices);CHKERRQ(ierr); 916 ierr = PetscFree2(dmmoab->gidmap,dmmoab->lidmap);CHKERRQ(ierr); 917 ierr = PetscFree(dmmoab->dfill);CHKERRQ(ierr); 918 ierr = PetscFree(dmmoab->ofill);CHKERRQ(ierr); 919 if (dmmoab->fieldNames) { 920 for(i=0; i<dmmoab->numFields; i++) { 921 ierr = PetscFree(dmmoab->fieldNames[i]);CHKERRQ(ierr); 922 } 923 ierr = PetscFree(dmmoab->fieldNames);CHKERRQ(ierr); 924 } 925 926 if (dmmoab->nhlevels) { 927 ierr = PetscFree(dmmoab->hsets);CHKERRQ(ierr); 928 dmmoab->nhlevels=0; 929 if (!dmmoab->hlevel && dmmoab->icreatedinstance) delete dmmoab->hierarchy; 930 dmmoab->hierarchy=NULL; 931 } 932 933 if (dmmoab->icreatedinstance) { 934 merr = dmmoab->mbiface->delete_mesh();MBERRNM(merr); 935 delete dmmoab->mbiface; 936 } 937 dmmoab->mbiface = NULL; 938 dmmoab->pcomm = NULL; 939 940 ierr = VecScatterDestroy(&dmmoab->ltog_sendrecv);CHKERRQ(ierr); 941 ierr = ISLocalToGlobalMappingDestroy(&dmmoab->ltog_map);CHKERRQ(ierr); 942 ierr = PetscFree(dm->data);CHKERRQ(ierr); 943 PetscFunctionReturn(0); 944 } 945 946 947 PETSC_EXTERN PetscErrorCode DMSetFromOptions_Moab(PetscOptionItems *PetscOptionsObject,DM dm) 948 { 949 PetscErrorCode ierr; 950 DM_Moab *dmmoab = (DM_Moab*)dm->data; 951 952 PetscFunctionBegin; 953 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 954 ierr = PetscOptionsHead(PetscOptionsObject,"DMMoab Options");CHKERRQ(ierr); 955 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); 956 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); 957 /* TODO: typically, the read options are needed before a DM is completely created and available in which case, the options wont be available ?? */ 958 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); 959 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); 960 ierr = PetscOptionsEnum("-dm_moab_read_mode", "MOAB parallel read mode", "DMView", MoabReadModes, (PetscEnum)dmmoab->read_mode, (PetscEnum*)&dmmoab->read_mode, NULL);CHKERRQ(ierr); 961 ierr = PetscOptionsEnum("-dm_moab_write_mode", "MOAB parallel write mode", "DMView", MoabWriteModes, (PetscEnum)dmmoab->write_mode, (PetscEnum*)&dmmoab->write_mode, NULL);CHKERRQ(ierr); 962 PetscFunctionReturn(0); 963 } 964 965 966 PETSC_EXTERN PetscErrorCode DMSetUp_Moab(DM dm) 967 { 968 PetscErrorCode ierr; 969 moab::ErrorCode merr; 970 Vec local, global; 971 IS from,to; 972 moab::Range::iterator iter; 973 PetscInt i,j,f,bs,gmin,lmin,lmax,vent,totsize,*lgmap; 974 DM_Moab *dmmoab = (DM_Moab*)dm->data; 975 moab::Range adjs; 976 977 PetscFunctionBegin; 978 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 979 /* Get the local and shared vertices and cache it */ 980 if (dmmoab->mbiface == NULL || dmmoab->pcomm == NULL) SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ORDER, "Set the MOAB Interface and ParallelComm objects before calling SetUp."); 981 982 /* Get the entities recursively in the current part of the mesh, if user did not set the local vertices explicitly */ 983 if (dmmoab->vlocal->empty()) 984 { 985 //merr = dmmoab->mbiface->get_entities_by_type(dmmoab->fileset,moab::MBVERTEX,*dmmoab->vlocal,true);MBERRNM(merr); 986 merr = dmmoab->mbiface->get_entities_by_dimension(dmmoab->fileset, 0, *dmmoab->vlocal, false);MBERRNM(merr); 987 988 /* filter based on parallel status */ 989 merr = dmmoab->pcomm->filter_pstatus(*dmmoab->vlocal,PSTATUS_NOT_OWNED,PSTATUS_NOT,-1,dmmoab->vowned);MBERRNM(merr); 990 991 /* filter all the non-owned and shared entities out of the list */ 992 adjs = moab::subtract(*dmmoab->vlocal, *dmmoab->vowned); 993 merr = dmmoab->pcomm->filter_pstatus(adjs,PSTATUS_GHOST|PSTATUS_INTERFACE,PSTATUS_OR,-1,dmmoab->vghost);MBERRNM(merr); 994 adjs = moab::subtract(adjs, *dmmoab->vghost); 995 *dmmoab->vlocal = moab::subtract(*dmmoab->vlocal, adjs); 996 997 /* compute and cache the sizes of local and ghosted entities */ 998 dmmoab->nloc = dmmoab->vowned->size(); 999 dmmoab->nghost = dmmoab->vghost->size(); 1000 1001 ierr = MPIU_Allreduce(&dmmoab->nloc, &dmmoab->n, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm);CHKERRQ(ierr); 1002 PetscInfo4(NULL, "Filset ID: %u, Vertices: local - %D, owned - %D, ghosted - %D.\n", dmmoab->fileset, dmmoab->vlocal->size(), dmmoab->nloc, dmmoab->nghost); 1003 } 1004 1005 { 1006 /* get the information about the local elements in the mesh */ 1007 dmmoab->eghost->clear(); 1008 1009 /* first decipher the leading dimension */ 1010 for (i=3;i>0;i--) { 1011 dmmoab->elocal->clear(); 1012 merr = dmmoab->mbiface->get_entities_by_dimension(dmmoab->fileset, i, *dmmoab->elocal, false);MBERRNM(merr); 1013 1014 /* store the current mesh dimension */ 1015 if (dmmoab->elocal->size()) { 1016 dmmoab->dim=i; 1017 break; 1018 } 1019 } 1020 1021 ierr = DMSetDimension(dm, dmmoab->dim);CHKERRQ(ierr); 1022 1023 /* filter the ghosted and owned element list */ 1024 *dmmoab->eghost = *dmmoab->elocal; 1025 merr = dmmoab->pcomm->filter_pstatus(*dmmoab->elocal,PSTATUS_NOT_OWNED,PSTATUS_NOT);MBERRNM(merr); 1026 *dmmoab->eghost = moab::subtract(*dmmoab->eghost, *dmmoab->elocal); 1027 1028 dmmoab->neleloc = dmmoab->elocal->size(); 1029 dmmoab->neleghost = dmmoab->eghost->size(); 1030 1031 ierr = MPIU_Allreduce(&dmmoab->neleloc, &dmmoab->nele, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm);CHKERRQ(ierr); 1032 PetscInfo3(NULL, "%d-dim elements: owned - %D, ghosted - %D.\n", dmmoab->dim, dmmoab->neleloc, dmmoab->neleghost); 1033 } 1034 1035 bs = dmmoab->bs; 1036 if (!dmmoab->ltog_tag) { 1037 /* Get the global ID tag. The global ID tag is applied to each 1038 vertex. It acts as an global identifier which MOAB uses to 1039 assemble the individual pieces of the mesh */ 1040 merr = dmmoab->mbiface->tag_get_handle(GLOBAL_ID_TAG_NAME, dmmoab->ltog_tag);MBERRNM(merr); 1041 } 1042 1043 totsize=dmmoab->vlocal->size(); 1044 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); 1045 ierr = PetscCalloc1(totsize,&dmmoab->gsindices);CHKERRQ(ierr); 1046 { 1047 /* first get the local indices */ 1048 merr = dmmoab->mbiface->tag_get_data(dmmoab->ltog_tag,*dmmoab->vowned,&dmmoab->gsindices[0]);MBERRNM(merr); 1049 if (dmmoab->nghost) { /* next get the ghosted indices */ 1050 merr = dmmoab->mbiface->tag_get_data(dmmoab->ltog_tag,*dmmoab->vghost,&dmmoab->gsindices[dmmoab->nloc]);MBERRNM(merr); 1051 } 1052 1053 /* find out the local and global minima of GLOBAL_ID */ 1054 lmin=lmax=dmmoab->gsindices[0]; 1055 for (i=0; i<totsize; ++i) { 1056 if(lmin>dmmoab->gsindices[i]) lmin=dmmoab->gsindices[i]; 1057 if(lmax<dmmoab->gsindices[i]) lmax=dmmoab->gsindices[i]; 1058 } 1059 1060 ierr = MPIU_Allreduce(&lmin, &gmin, 1, MPI_INT, MPI_MIN, ((PetscObject)dm)->comm);CHKERRQ(ierr); 1061 1062 /* set the GID map */ 1063 for (i=0; i<totsize; ++i) { 1064 dmmoab->gsindices[i]-=gmin; /* zero based index needed for IS */ 1065 } 1066 lmin-=gmin; 1067 lmax-=gmin; 1068 1069 PetscInfo3(NULL, "GLOBAL_ID: Local minima - %D, Local maxima - %D, Global minima - %D.\n", lmin, lmax, gmin); 1070 } 1071 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); 1072 1073 { 1074 dmmoab->seqstart=((PetscInt)dmmoab->vlocal->front()); 1075 dmmoab->seqend=((PetscInt)dmmoab->vlocal->back()); 1076 PetscInfo2(NULL, "SEQUENCE: Local minima - %D, Local maxima - %D.\n", dmmoab->seqstart, dmmoab->seqend); 1077 1078 ierr = PetscMalloc2(dmmoab->seqend-dmmoab->seqstart+1,&dmmoab->gidmap,dmmoab->seqend-dmmoab->seqstart+1,&dmmoab->lidmap);CHKERRQ(ierr); 1079 ierr = PetscMalloc1(totsize*dmmoab->numFields,&lgmap);CHKERRQ(ierr); 1080 1081 i=j=0; 1082 /* set the owned vertex data first */ 1083 for(moab::Range::iterator iter = dmmoab->vowned->begin(); iter != dmmoab->vowned->end(); iter++,i++) { 1084 vent=(PetscInt)(*iter)-dmmoab->seqstart; 1085 dmmoab->gidmap[vent]=dmmoab->gsindices[i]; 1086 dmmoab->lidmap[vent]=i; 1087 for (f=0;f<dmmoab->numFields;f++,j++) { 1088 lgmap[j]=(bs > 1 ? dmmoab->gsindices[i]*dmmoab->numFields+f : totsize*f+dmmoab->gsindices[i]); 1089 } 1090 } 1091 /* next arrange all the ghosted data information */ 1092 for(moab::Range::iterator iter = dmmoab->vghost->begin(); iter != dmmoab->vghost->end(); iter++,i++) { 1093 vent=(PetscInt)(*iter)-dmmoab->seqstart; 1094 dmmoab->gidmap[vent]=dmmoab->gsindices[i]; 1095 dmmoab->lidmap[vent]=i; 1096 for (f=0;f<dmmoab->numFields;f++,j++) { 1097 lgmap[j]=(bs > 1 ? dmmoab->gsindices[i]*dmmoab->numFields+f : totsize*f+dmmoab->gsindices[i]); 1098 } 1099 } 1100 1101 /* We need to create the Global to Local Vector Scatter Contexts 1102 1) First create a local and global vector 1103 2) Create a local and global IS 1104 3) Create VecScatter and LtoGMapping objects 1105 4) Cleanup the IS and Vec objects 1106 */ 1107 ierr = DMCreateGlobalVector(dm, &global);CHKERRQ(ierr); 1108 ierr = DMCreateLocalVector(dm, &local);CHKERRQ(ierr); 1109 1110 ierr = VecGetOwnershipRange(global, &dmmoab->vstart, &dmmoab->vend);CHKERRQ(ierr); 1111 1112 /* global to local must retrieve ghost points */ 1113 ierr = ISCreateStride(((PetscObject)dm)->comm,dmmoab->nloc*dmmoab->numFields,dmmoab->vstart,1,&from);CHKERRQ(ierr); 1114 ierr = ISSetBlockSize(from,bs);CHKERRQ(ierr); 1115 1116 ierr = ISCreateGeneral(((PetscObject)dm)->comm,dmmoab->nloc*dmmoab->numFields,&lgmap[0],PETSC_COPY_VALUES,&to);CHKERRQ(ierr); 1117 ierr = ISSetBlockSize(to,bs);CHKERRQ(ierr); 1118 1119 if (!dmmoab->ltog_map) { 1120 /* create to the local to global mapping for vectors in order to use VecSetValuesLocal */ 1121 ierr = ISLocalToGlobalMappingCreate(((PetscObject)dm)->comm,dmmoab->bs,totsize*dmmoab->numFields,lgmap, 1122 PETSC_COPY_VALUES,&dmmoab->ltog_map);CHKERRQ(ierr); 1123 } 1124 1125 /* now create the scatter object from local to global vector */ 1126 ierr = VecScatterCreate(local,from,global,to,&dmmoab->ltog_sendrecv);CHKERRQ(ierr); 1127 1128 /* clean up IS, Vec */ 1129 ierr = PetscFree(lgmap);CHKERRQ(ierr); 1130 ierr = ISDestroy(&from);CHKERRQ(ierr); 1131 ierr = ISDestroy(&to);CHKERRQ(ierr); 1132 ierr = VecDestroy(&local);CHKERRQ(ierr); 1133 ierr = VecDestroy(&global);CHKERRQ(ierr); 1134 } 1135 1136 dmmoab->bndyvtx = new moab::Range(); 1137 dmmoab->bndyfaces = new moab::Range(); 1138 dmmoab->bndyelems = new moab::Range(); 1139 /* skin the boundary and store nodes */ 1140 { 1141 /* get the skin vertices of boundary faces for the current partition and then filter 1142 the local, boundary faces, vertices and elements alone via PSTATUS flags; 1143 this should not give us any ghosted boundary, but if user needs such a functionality 1144 it would be easy to add it based on the find_skin query below */ 1145 moab::Skinner skinner(dmmoab->mbiface); 1146 1147 /* get the entities on the skin - only the faces */ 1148 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 1149 1150 /* filter all the non-owned and shared entities out of the list */ 1151 merr = dmmoab->pcomm->filter_pstatus(*dmmoab->bndyfaces,PSTATUS_NOT_OWNED,PSTATUS_NOT);MBERRNM(merr); 1152 merr = dmmoab->pcomm->filter_pstatus(*dmmoab->bndyfaces,PSTATUS_SHARED,PSTATUS_NOT);MBERRNM(merr); 1153 1154 /* get all the nodes via connectivity and the parent elements via adjacency information */ 1155 merr = dmmoab->mbiface->get_connectivity(*dmmoab->bndyfaces, *dmmoab->bndyvtx, false);MBERRNM(ierr); 1156 merr = dmmoab->mbiface->get_adjacencies(*dmmoab->bndyfaces, dmmoab->dim, false, *dmmoab->bndyelems, moab::Interface::UNION);MBERRNM(ierr); 1157 } 1158 PetscInfo3(NULL, "Found %D boundary vertices, %D boundary faces and %D boundary elements.\n", dmmoab->bndyvtx->size(), dmmoab->bndyfaces->size(), dmmoab->bndyelems->size()); 1159 PetscFunctionReturn(0); 1160 } 1161 1162 PETSC_EXTERN PetscErrorCode DMCreate_Moab(DM dm) 1163 { 1164 PetscErrorCode ierr; 1165 1166 PetscFunctionBegin; 1167 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1168 ierr = PetscNewLog(dm,(DM_Moab**)&dm->data);CHKERRQ(ierr); 1169 1170 ((DM_Moab*)dm->data)->bs = 1; 1171 ((DM_Moab*)dm->data)->numFields = 1; 1172 ((DM_Moab*)dm->data)->n = 0; 1173 ((DM_Moab*)dm->data)->nloc = 0; 1174 ((DM_Moab*)dm->data)->nghost = 0; 1175 ((DM_Moab*)dm->data)->nele = 0; 1176 ((DM_Moab*)dm->data)->neleloc = 0; 1177 ((DM_Moab*)dm->data)->neleghost = 0; 1178 ((DM_Moab*)dm->data)->ltog_map = NULL; 1179 ((DM_Moab*)dm->data)->ltog_sendrecv = NULL; 1180 1181 ((DM_Moab*)dm->data)->vlocal = new moab::Range(); 1182 ((DM_Moab*)dm->data)->vowned = new moab::Range(); 1183 ((DM_Moab*)dm->data)->vghost = new moab::Range(); 1184 ((DM_Moab*)dm->data)->elocal = new moab::Range(); 1185 ((DM_Moab*)dm->data)->eghost = new moab::Range(); 1186 1187 dm->ops->createglobalvector = DMCreateGlobalVector_Moab; 1188 dm->ops->createlocalvector = DMCreateLocalVector_Moab; 1189 dm->ops->creatematrix = DMCreateMatrix_Moab; 1190 dm->ops->setup = DMSetUp_Moab; 1191 dm->ops->destroy = DMDestroy_Moab; 1192 dm->ops->coarsenhierarchy = DMCoarsenHierarchy_Moab; 1193 dm->ops->refinehierarchy = DMRefineHierarchy_Moab; 1194 dm->ops->createinterpolation = DMCreateInterpolation_Moab; 1195 //dm->ops->getinjection = DMCreateInjection_Moab; 1196 dm->ops->refine = DMRefine_Moab; 1197 dm->ops->coarsen = DMCoarsen_Moab; 1198 dm->ops->setfromoptions = DMSetFromOptions_Moab; 1199 dm->ops->globaltolocalbegin = DMGlobalToLocalBegin_Moab; 1200 dm->ops->globaltolocalend = DMGlobalToLocalEnd_Moab; 1201 dm->ops->localtoglobalbegin = DMLocalToGlobalBegin_Moab; 1202 dm->ops->localtoglobalend = DMLocalToGlobalEnd_Moab; 1203 PetscFunctionReturn(0); 1204 } 1205 1206