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