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