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 DM_Moab *dmmoab = (DM_Moab*)dm->data; 902 903 PetscFunctionBegin; 904 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 905 if (dmmoab->icreatedinstance) { 906 delete dmmoab->mbiface; 907 } 908 dmmoab->mbiface = NULL; 909 dmmoab->pcomm = NULL; 910 delete dmmoab->vlocal; 911 delete dmmoab->vowned; 912 delete dmmoab->vghost; 913 delete dmmoab->elocal; 914 delete dmmoab->eghost; 915 delete dmmoab->bndyvtx; 916 delete dmmoab->bndyfaces; 917 delete dmmoab->bndyelems; 918 919 ierr = PetscFree(dmmoab->gsindices);CHKERRQ(ierr); 920 ierr = PetscFree2(dmmoab->gidmap,dmmoab->lidmap);CHKERRQ(ierr); 921 ierr = PetscFree2(dmmoab->lgmap,dmmoab->llmap);CHKERRQ(ierr); 922 ierr = PetscFree(dmmoab->dfill);CHKERRQ(ierr); 923 ierr = PetscFree(dmmoab->ofill);CHKERRQ(ierr); 924 if (dmmoab->fieldNames) { 925 for(i=0; i<dmmoab->numFields; i++) { 926 ierr = PetscFree(dmmoab->fieldNames[i]);CHKERRQ(ierr); 927 } 928 ierr = PetscFree(dmmoab->fieldNames);CHKERRQ(ierr); 929 } 930 931 if (dmmoab->nhlevels) { 932 ierr = PetscFree(dmmoab->hsets);CHKERRQ(ierr); 933 } 934 ierr = VecScatterDestroy(&dmmoab->ltog_sendrecv);CHKERRQ(ierr); 935 ierr = ISLocalToGlobalMappingDestroy(&dmmoab->ltog_map);CHKERRQ(ierr); 936 ierr = PetscFree(dm->data);CHKERRQ(ierr); 937 PetscFunctionReturn(0); 938 } 939 940 941 PETSC_EXTERN PetscErrorCode DMSetFromOptions_Moab(PetscOptionItems *PetscOptionsObject,DM dm) 942 { 943 PetscErrorCode ierr; 944 DM_Moab *dmmoab = (DM_Moab*)dm->data; 945 946 PetscFunctionBegin; 947 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 948 ierr = PetscOptionsHead(PetscOptionsObject,"DMMoab Options");CHKERRQ(ierr); 949 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); 950 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); 951 /* TODO: typically, the read options are needed before a DM is completely created and available in which case, the options wont be available ?? */ 952 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); 953 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); 954 ierr = PetscOptionsEnum("-dm_moab_read_mode", "MOAB parallel read mode", "DMView", MoabReadModes, (PetscEnum)dmmoab->read_mode, (PetscEnum*)&dmmoab->read_mode, NULL);CHKERRQ(ierr); 955 ierr = PetscOptionsEnum("-dm_moab_write_mode", "MOAB parallel write mode", "DMView", MoabWriteModes, (PetscEnum)dmmoab->write_mode, (PetscEnum*)&dmmoab->write_mode, NULL);CHKERRQ(ierr); 956 PetscFunctionReturn(0); 957 } 958 959 960 PETSC_EXTERN PetscErrorCode DMSetUp_Moab(DM dm) 961 { 962 PetscErrorCode ierr; 963 moab::ErrorCode merr; 964 Vec local, global; 965 IS from,to; 966 moab::Range::iterator iter; 967 PetscInt i,j,f,bs,gmin,lmin,lmax,vent,totsize; 968 DM_Moab *dmmoab = (DM_Moab*)dm->data; 969 moab::Range adjs; 970 971 PetscFunctionBegin; 972 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 973 /* Get the local and shared vertices and cache it */ 974 if (dmmoab->mbiface == NULL || dmmoab->pcomm == NULL) SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ORDER, "Set the MOAB Interface and ParallelComm objects before calling SetUp."); 975 976 /* Get the entities recursively in the current part of the mesh, if user did not set the local vertices explicitly */ 977 if (dmmoab->vlocal->empty()) 978 { 979 merr = dmmoab->mbiface->get_entities_by_type(dmmoab->fileset,moab::MBVERTEX,*dmmoab->vlocal,true);MBERRNM(merr); 980 981 /* filter based on parallel status */ 982 merr = dmmoab->pcomm->filter_pstatus(*dmmoab->vlocal,PSTATUS_NOT_OWNED,PSTATUS_NOT,-1,dmmoab->vowned);MBERRNM(merr); 983 984 /* filter all the non-owned and shared entities out of the list */ 985 adjs = moab::subtract(*dmmoab->vlocal, *dmmoab->vowned); 986 merr = dmmoab->pcomm->filter_pstatus(adjs,PSTATUS_INTERFACE,PSTATUS_OR,-1,dmmoab->vghost);MBERRNM(merr); 987 adjs = moab::subtract(adjs, *dmmoab->vghost); 988 *dmmoab->vlocal = moab::subtract(*dmmoab->vlocal, adjs); 989 990 /* compute and cache the sizes of local and ghosted entities */ 991 dmmoab->nloc = dmmoab->vowned->size(); 992 dmmoab->nghost = dmmoab->vghost->size(); 993 ierr = MPIU_Allreduce(&dmmoab->nloc, &dmmoab->n, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm);CHKERRQ(ierr); 994 } 995 996 { 997 /* get the information about the local elements in the mesh */ 998 dmmoab->eghost->clear(); 999 1000 /* first decipher the leading dimension */ 1001 for (i=3;i>0;i--) { 1002 dmmoab->elocal->clear(); 1003 merr = dmmoab->mbiface->get_entities_by_dimension(dmmoab->fileset, i, *dmmoab->elocal, true);CHKERRQ(merr); 1004 1005 /* store the current mesh dimension */ 1006 if (dmmoab->elocal->size()) { 1007 dmmoab->dim=i; 1008 break; 1009 } 1010 } 1011 1012 ierr = DMSetDimension(dm, dmmoab->dim);CHKERRQ(ierr); 1013 1014 /* filter the ghosted and owned element list */ 1015 *dmmoab->eghost = *dmmoab->elocal; 1016 merr = dmmoab->pcomm->filter_pstatus(*dmmoab->elocal,PSTATUS_NOT_OWNED,PSTATUS_NOT);MBERRNM(merr); 1017 *dmmoab->eghost = moab::subtract(*dmmoab->eghost, *dmmoab->elocal); 1018 1019 dmmoab->neleloc = dmmoab->elocal->size(); 1020 dmmoab->neleghost = dmmoab->eghost->size(); 1021 ierr = MPIU_Allreduce(&dmmoab->neleloc, &dmmoab->nele, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm);CHKERRQ(ierr); 1022 } 1023 1024 bs = dmmoab->bs; 1025 if (!dmmoab->ltog_tag) { 1026 /* Get the global ID tag. The global ID tag is applied to each 1027 vertex. It acts as an global identifier which MOAB uses to 1028 assemble the individual pieces of the mesh */ 1029 merr = dmmoab->mbiface->tag_get_handle(GLOBAL_ID_TAG_NAME, dmmoab->ltog_tag);MBERRNM(merr); 1030 } 1031 1032 totsize=dmmoab->vlocal->size(); 1033 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); 1034 ierr = PetscMalloc1(totsize,&dmmoab->gsindices);CHKERRQ(ierr); 1035 { 1036 /* first get the local indices */ 1037 merr = dmmoab->mbiface->tag_get_data(dmmoab->ltog_tag,*dmmoab->vowned,&dmmoab->gsindices[0]);MBERRNM(merr); 1038 /* next get the ghosted indices */ 1039 if (dmmoab->nghost) { 1040 merr = dmmoab->mbiface->tag_get_data(dmmoab->ltog_tag,*dmmoab->vghost,&dmmoab->gsindices[dmmoab->nloc]);MBERRNM(merr); 1041 } 1042 1043 /* find out the local and global minima of GLOBAL_ID */ 1044 lmin=lmax=dmmoab->gsindices[0]; 1045 for (i=0; i<totsize; ++i) { 1046 if(lmin>dmmoab->gsindices[i]) lmin=dmmoab->gsindices[i]; 1047 if(lmax<dmmoab->gsindices[i]) lmax=dmmoab->gsindices[i]; 1048 } 1049 1050 ierr = MPIU_Allreduce(&lmin, &gmin, 1, MPI_INT, MPI_MIN, ((PetscObject)dm)->comm);CHKERRQ(ierr); 1051 1052 /* set the GID map */ 1053 for (i=0; i<totsize; ++i) { 1054 dmmoab->gsindices[i]-=gmin; /* zero based index needed for IS */ 1055 } 1056 lmin-=gmin; 1057 lmax-=gmin; 1058 1059 PetscInfo3(NULL, "GLOBAL_ID: Local minima - %D, Local maxima - %D, Global minima - %D.\n", lmin, lmax, gmin); 1060 } 1061 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); 1062 1063 { 1064 i=(PetscInt)dmmoab->vlocal->back()+1; 1065 //i=(PetscInt)(dmmoab->vlocal->back()-dmmoab->vlocal->front())+1; 1066 j=totsize*dmmoab->numFields; 1067 ierr = PetscMalloc2(i,&dmmoab->gidmap,i,&dmmoab->lidmap);CHKERRQ(ierr); 1068 ierr = PetscMalloc2(j,&dmmoab->lgmap,j,&dmmoab->llmap);CHKERRQ(ierr); 1069 1070 i=j=0; 1071 /* set the owned vertex data first */ 1072 for(moab::Range::iterator iter = dmmoab->vowned->begin(); iter != dmmoab->vowned->end(); iter++,i++) { 1073 vent=(PetscInt)(*iter); 1074 dmmoab->gidmap[vent]=dmmoab->gsindices[i]; 1075 dmmoab->lidmap[vent]=i; 1076 if (bs > 1) { 1077 for (f=0;f<dmmoab->numFields;f++,j++) { 1078 dmmoab->lgmap[j]=dmmoab->gsindices[i]*dmmoab->numFields+f; 1079 dmmoab->llmap[j]=i*dmmoab->numFields+f; 1080 } 1081 } 1082 else { 1083 for (f=0;f<dmmoab->numFields;f++,j++) { 1084 dmmoab->lgmap[j]=totsize*f+dmmoab->gsindices[i]; 1085 dmmoab->llmap[j]=totsize*f+i; 1086 } 1087 } 1088 } 1089 /* next arrange all the ghosted data information */ 1090 for(moab::Range::iterator iter = dmmoab->vghost->begin(); iter != dmmoab->vghost->end(); iter++,i++) { 1091 vent=(PetscInt)(*iter); 1092 dmmoab->gidmap[vent]=dmmoab->gsindices[i]; 1093 dmmoab->lidmap[vent]=i; 1094 if (bs > 1) { 1095 for (f=0;f<dmmoab->numFields;f++,j++) { 1096 dmmoab->lgmap[j]=dmmoab->gsindices[i]*dmmoab->numFields+f; 1097 dmmoab->llmap[j]=i*dmmoab->numFields+f; 1098 } 1099 } 1100 else { 1101 for (f=0;f<dmmoab->numFields;f++,j++) { 1102 dmmoab->lgmap[j]=totsize*f+dmmoab->gsindices[i]; 1103 dmmoab->llmap[j]=totsize*f+i; 1104 } 1105 } 1106 } 1107 1108 /* We need to create the Global to Local Vector Scatter Contexts 1109 1) First create a local and global vector 1110 2) Create a local and global IS 1111 3) Create VecScatter and LtoGMapping objects 1112 4) Cleanup the IS and Vec objects 1113 */ 1114 ierr = DMCreateGlobalVector(dm, &global);CHKERRQ(ierr); 1115 ierr = DMCreateLocalVector(dm, &local);CHKERRQ(ierr); 1116 1117 ierr = VecGetOwnershipRange(global, &dmmoab->vstart, &dmmoab->vend);CHKERRQ(ierr); 1118 PetscInfo3(NULL, "Total-size = %D\t Owned = %D, Ghosted = %D.\n", totsize, dmmoab->nloc, dmmoab->nghost); 1119 1120 /* global to local must retrieve ghost points */ 1121 ierr = ISCreateStride(((PetscObject)dm)->comm,dmmoab->nloc*dmmoab->numFields,dmmoab->vstart,1,&from);CHKERRQ(ierr); 1122 ierr = ISSetBlockSize(from,bs);CHKERRQ(ierr); 1123 1124 ierr = ISCreateGeneral(((PetscObject)dm)->comm,dmmoab->nloc*dmmoab->numFields,&dmmoab->lgmap[0],PETSC_COPY_VALUES,&to);CHKERRQ(ierr); 1125 ierr = ISSetBlockSize(to,bs);CHKERRQ(ierr); 1126 1127 if (!dmmoab->ltog_map) { 1128 /* create to the local to global mapping for vectors in order to use VecSetValuesLocal */ 1129 ierr = ISLocalToGlobalMappingCreate(((PetscObject)dm)->comm,dmmoab->bs,totsize*dmmoab->numFields,dmmoab->lgmap, 1130 PETSC_COPY_VALUES,&dmmoab->ltog_map);CHKERRQ(ierr); 1131 } 1132 1133 /* now create the scatter object from local to global vector */ 1134 ierr = VecScatterCreate(local,from,global,to,&dmmoab->ltog_sendrecv);CHKERRQ(ierr); 1135 1136 /* clean up IS, Vec */ 1137 ierr = ISDestroy(&from);CHKERRQ(ierr); 1138 ierr = ISDestroy(&to);CHKERRQ(ierr); 1139 ierr = VecDestroy(&local);CHKERRQ(ierr); 1140 ierr = VecDestroy(&global);CHKERRQ(ierr); 1141 } 1142 1143 /* skin the boundary and store nodes */ 1144 { 1145 /* get the skin vertices of boundary faces for the current partition and then filter 1146 the local, boundary faces, vertices and elements alone via PSTATUS flags; 1147 this should not give us any ghosted boundary, but if user needs such a functionality 1148 it would be easy to add it based on the find_skin query below */ 1149 moab::Skinner skinner(dmmoab->mbiface); 1150 1151 dmmoab->bndyvtx = new moab::Range(); 1152 dmmoab->bndyfaces = new moab::Range(); 1153 dmmoab->bndyelems = new moab::Range(); 1154 1155 /* get the entities on the skin - only the faces */ 1156 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 1157 1158 /* filter all the non-owned and shared entities out of the list */ 1159 merr = dmmoab->pcomm->filter_pstatus(*dmmoab->bndyfaces,PSTATUS_NOT_OWNED,PSTATUS_NOT);MBERRNM(merr); 1160 merr = dmmoab->pcomm->filter_pstatus(*dmmoab->bndyfaces,PSTATUS_SHARED,PSTATUS_NOT);MBERRNM(merr); 1161 1162 /* get all the nodes via connectivity and the parent elements via adjacency information */ 1163 merr = dmmoab->mbiface->get_connectivity(*dmmoab->bndyfaces, *dmmoab->bndyvtx, false);MBERRNM(ierr); 1164 merr = dmmoab->mbiface->get_adjacencies(*dmmoab->bndyfaces, dmmoab->dim, false, *dmmoab->bndyelems, moab::Interface::UNION);MBERRNM(ierr); 1165 PetscInfo3(NULL, "Found %D boundary vertices, %D boundary faces and %D boundary elements.\n", dmmoab->bndyvtx->size(), dmmoab->bndyvtx->size(), dmmoab->bndyelems->size()); 1166 } 1167 PetscFunctionReturn(0); 1168 } 1169 1170 PETSC_EXTERN PetscErrorCode DMCreate_Moab(DM dm) 1171 { 1172 PetscErrorCode ierr; 1173 1174 PetscFunctionBegin; 1175 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1176 ierr = PetscNewLog(dm,(DM_Moab**)&dm->data);CHKERRQ(ierr); 1177 1178 ((DM_Moab*)dm->data)->bs = 1; 1179 ((DM_Moab*)dm->data)->numFields = 1; 1180 ((DM_Moab*)dm->data)->n = 0; 1181 ((DM_Moab*)dm->data)->nloc = 0; 1182 ((DM_Moab*)dm->data)->nghost = 0; 1183 ((DM_Moab*)dm->data)->nele = 0; 1184 ((DM_Moab*)dm->data)->neleloc = 0; 1185 ((DM_Moab*)dm->data)->neleghost = 0; 1186 ((DM_Moab*)dm->data)->ltog_map = NULL; 1187 ((DM_Moab*)dm->data)->ltog_sendrecv = NULL; 1188 1189 ((DM_Moab*)dm->data)->vlocal = new moab::Range(); 1190 ((DM_Moab*)dm->data)->vowned = new moab::Range(); 1191 ((DM_Moab*)dm->data)->vghost = new moab::Range(); 1192 ((DM_Moab*)dm->data)->elocal = new moab::Range(); 1193 ((DM_Moab*)dm->data)->eghost = new moab::Range(); 1194 1195 dm->ops->createglobalvector = DMCreateGlobalVector_Moab; 1196 dm->ops->createlocalvector = DMCreateLocalVector_Moab; 1197 dm->ops->creatematrix = DMCreateMatrix_Moab; 1198 dm->ops->setup = DMSetUp_Moab; 1199 dm->ops->destroy = DMDestroy_Moab; 1200 //dm->ops->coarsenhierarchy = DMCoarsenHierarchy_Moab; 1201 //dm->ops->refinehierarchy = DMRefineHierarchy_Moab; 1202 dm->ops->createinterpolation = DMCreateInterpolation_Moab; 1203 //dm->ops->getinjection = DMCreateInjection_Moab; 1204 dm->ops->refine = DMRefine_Moab; 1205 dm->ops->coarsen = DMCoarsen_Moab; 1206 dm->ops->setfromoptions = DMSetFromOptions_Moab; 1207 dm->ops->globaltolocalbegin = DMGlobalToLocalBegin_Moab; 1208 dm->ops->globaltolocalend = DMGlobalToLocalEnd_Moab; 1209 dm->ops->localtoglobalbegin = DMLocalToGlobalBegin_Moab; 1210 dm->ops->localtoglobalend = DMLocalToGlobalEnd_Moab; 1211 PetscFunctionReturn(0); 1212 } 1213 1214