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