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