1 #include <petsc/private/dmmbimpl.h> /*I "petscdmmoab.h" I*/ 2 3 #include <petscdmmoab.h> 4 #include <MBTagConventions.hpp> 5 #include <moab/NestedRefine.hpp> 6 #include <moab/Skinner.hpp> 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 /* External function declarations here */ 25 PETSC_EXTERN PetscErrorCode DMCreateInterpolation_Moab(DM dmCoarse, DM dmFine, Mat *interpolation, Vec *scaling); 26 PETSC_EXTERN PetscErrorCode DMCreateDefaultConstraints_Moab(DM dm); 27 PETSC_EXTERN PetscErrorCode DMCreateMatrix_Moab(DM dm, Mat *J); 28 PETSC_EXTERN PetscErrorCode DMCreateCoordinateDM_Moab(DM dm, DM *cdm); 29 PETSC_EXTERN PetscErrorCode DMRefine_Moab(DM dm, MPI_Comm comm, DM *dmRefined); 30 PETSC_EXTERN PetscErrorCode DMCoarsen_Moab(DM dm, MPI_Comm comm, DM *dmCoarsened); 31 PETSC_EXTERN PetscErrorCode DMRefineHierarchy_Moab(DM dm, PetscInt nlevels, DM dmRefined[]); 32 PETSC_EXTERN PetscErrorCode DMCoarsenHierarchy_Moab(DM dm, PetscInt nlevels, DM dmCoarsened[]); 33 PETSC_EXTERN PetscErrorCode DMClone_Moab(DM dm, DM *newdm); 34 PETSC_EXTERN PetscErrorCode DMCreateGlobalVector_Moab(DM, Vec *); 35 PETSC_EXTERN PetscErrorCode DMCreateLocalVector_Moab(DM, Vec *); 36 PETSC_EXTERN PetscErrorCode DMCreateMatrix_Moab(DM dm, Mat *J); 37 PETSC_EXTERN PetscErrorCode DMGlobalToLocalBegin_Moab(DM, Vec, InsertMode, Vec); 38 PETSC_EXTERN PetscErrorCode DMGlobalToLocalEnd_Moab(DM, Vec, InsertMode, Vec); 39 PETSC_EXTERN PetscErrorCode DMLocalToGlobalBegin_Moab(DM, Vec, InsertMode, Vec); 40 PETSC_EXTERN PetscErrorCode DMLocalToGlobalEnd_Moab(DM, Vec, InsertMode, Vec); 41 42 43 /* Un-implemented routines */ 44 /* 45 PETSC_EXTERN PetscErrorCode DMCreateDefaultSection_Moab(DM dm); 46 PETSC_EXTERN PetscErrorCode DMCreateInjection_Moab(DM dmCoarse, DM dmFine, Mat *mat); 47 PETSC_EXTERN PetscErrorCode DMLoad_Moab(DM dm, PetscViewer viewer); 48 PETSC_EXTERN PetscErrorCode DMGetDimPoints_Moab(DM dm, PetscInt dim, PetscInt *pStart, PetscInt *pEnd); 49 PETSC_EXTERN PetscErrorCode DMCreateSubDM_Moab(DM dm, PetscInt numFields, PetscInt fields[], IS *is, DM *subdm); 50 PETSC_EXTERN PetscErrorCode DMLocatePoints_Moab(DM dm, Vec v, IS *cellIS); 51 */ 52 53 /*@ 54 DMMoabCreate - Creates a DMMoab object, which encapsulates a moab instance 55 56 Collective on MPI_Comm 57 58 Input Parameter: 59 . comm - The communicator for the DMMoab object 60 61 Output Parameter: 62 . dmb - The DMMoab object 63 64 Level: beginner 65 66 .keywords: DMMoab, create 67 @*/ 68 PetscErrorCode DMMoabCreate(MPI_Comm comm, DM *dmb) 69 { 70 PetscErrorCode ierr; 71 72 PetscFunctionBegin; 73 PetscValidPointer(dmb, 2); 74 ierr = DMCreate(comm, dmb);CHKERRQ(ierr); 75 ierr = DMSetType(*dmb, DMMOAB);CHKERRQ(ierr); 76 PetscFunctionReturn(0); 77 } 78 79 /*@ 80 DMMoabCreateMoab - Creates a DMMoab object, optionally from an instance and other data 81 82 Collective on MPI_Comm 83 84 Input Parameter: 85 . comm - The communicator for the DMMoab object 86 . mbiface - (ptr to) the MOAB Instance; if passed in NULL, MOAB instance is created inside PETSc, and destroyed 87 along with the DMMoab 88 . pcomm - (ptr to) a ParallelComm; if NULL, creates one internally for the whole communicator 89 . ltog_tag - A tag to use to retrieve global id for an entity; if 0, will use GLOBAL_ID_TAG_NAME/tag 90 . range - If non-NULL, contains range of entities to which DOFs will be assigned 91 92 Output Parameter: 93 . dmb - The DMMoab object 94 95 Level: intermediate 96 97 .keywords: DMMoab, create 98 @*/ 99 PetscErrorCode DMMoabCreateMoab(MPI_Comm comm, moab::Interface *mbiface, moab::Tag *ltog_tag, moab::Range *range, DM *dmb) 100 { 101 PetscErrorCode ierr; 102 moab::ErrorCode merr; 103 DM dmmb; 104 DM_Moab *dmmoab; 105 106 PetscFunctionBegin; 107 PetscValidPointer(dmb, 6); 108 109 ierr = DMMoabCreate(comm, &dmmb);CHKERRQ(ierr); 110 dmmoab = (DM_Moab*)(dmmb)->data; 111 112 if (!mbiface) { 113 dmmoab->mbiface = new moab::Core(); 114 dmmoab->icreatedinstance = PETSC_TRUE; 115 } 116 else { 117 dmmoab->mbiface = mbiface; 118 dmmoab->icreatedinstance = PETSC_FALSE; 119 } 120 121 /* by default the fileset = root set. This set stores the hierarchy of entities belonging to current DM */ 122 dmmoab->fileset = 0; 123 dmmoab->hlevel = 0; 124 dmmoab->nghostrings = 0; 125 126 #ifdef MOAB_HAVE_MPI 127 moab::EntityHandle partnset; 128 129 /* Create root sets for each mesh. Then pass these 130 to the load_file functions to be populated. */ 131 merr = dmmoab->mbiface->create_meshset(moab::MESHSET_SET, partnset); MBERR("Creating partition set failed", merr); 132 133 /* Create the parallel communicator object with the partition handle associated with MOAB */ 134 dmmoab->pcomm = moab::ParallelComm::get_pcomm(dmmoab->mbiface, partnset, &comm); 135 #endif 136 137 /* do the remaining initializations for DMMoab */ 138 dmmoab->bs = 1; 139 dmmoab->numFields = 1; 140 ierr = PetscMalloc(dmmoab->numFields * sizeof(char*), &dmmoab->fieldNames);CHKERRQ(ierr); 141 ierr = PetscStrallocpy("DEFAULT", (char**) &dmmoab->fieldNames[0]);CHKERRQ(ierr); 142 dmmoab->rw_dbglevel = 0; 143 dmmoab->partition_by_rank = PETSC_FALSE; 144 dmmoab->extra_read_options[0] = '\0'; 145 dmmoab->extra_write_options[0] = '\0'; 146 dmmoab->read_mode = READ_PART; 147 dmmoab->write_mode = WRITE_PART; 148 149 /* set global ID tag handle */ 150 if (ltog_tag && *ltog_tag) { 151 ierr = DMMoabSetLocalToGlobalTag(dmmb, *ltog_tag);CHKERRQ(ierr); 152 } 153 else { 154 merr = dmmoab->mbiface->tag_get_handle(GLOBAL_ID_TAG_NAME, dmmoab->ltog_tag); MBERRNM(merr); 155 if (ltog_tag) *ltog_tag = dmmoab->ltog_tag; 156 } 157 158 merr = dmmoab->mbiface->tag_get_handle(MATERIAL_SET_TAG_NAME, dmmoab->material_tag); MBERRNM(merr); 159 160 /* set the local range of entities (vertices) of interest */ 161 if (range) { 162 ierr = DMMoabSetLocalVertices(dmmb, range);CHKERRQ(ierr); 163 } 164 *dmb = dmmb; 165 PetscFunctionReturn(0); 166 } 167 168 169 #ifdef MOAB_HAVE_MPI 170 171 /*@ 172 DMMoabGetParallelComm - Get the ParallelComm used with this DMMoab 173 174 Collective on MPI_Comm 175 176 Input Parameter: 177 . dm - The DMMoab object being set 178 179 Output Parameter: 180 . pcomm - The ParallelComm for the DMMoab 181 182 Level: beginner 183 184 .keywords: DMMoab, create 185 @*/ 186 PetscErrorCode DMMoabGetParallelComm(DM dm, moab::ParallelComm **pcomm) 187 { 188 PetscFunctionBegin; 189 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 190 *pcomm = ((DM_Moab*)(dm)->data)->pcomm; 191 PetscFunctionReturn(0); 192 } 193 194 #endif /* MOAB_HAVE_MPI */ 195 196 197 /*@ 198 DMMoabSetInterface - Set the MOAB instance used with this DMMoab 199 200 Collective on MPI_Comm 201 202 Input Parameter: 203 . dm - The DMMoab object being set 204 . mbiface - The MOAB instance being set on this DMMoab 205 206 Level: beginner 207 208 .keywords: DMMoab, create 209 @*/ 210 PetscErrorCode DMMoabSetInterface(DM dm, moab::Interface *mbiface) 211 { 212 DM_Moab *dmmoab = (DM_Moab*)(dm)->data; 213 214 PetscFunctionBegin; 215 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 216 PetscValidPointer(mbiface, 2); 217 #ifdef MOAB_HAVE_MPI 218 dmmoab->pcomm = NULL; 219 #endif 220 dmmoab->mbiface = mbiface; 221 dmmoab->icreatedinstance = PETSC_FALSE; 222 PetscFunctionReturn(0); 223 } 224 225 226 /*@ 227 DMMoabGetInterface - Get the MOAB instance used with this DMMoab 228 229 Collective on MPI_Comm 230 231 Input Parameter: 232 . dm - The DMMoab object being set 233 234 Output Parameter: 235 . mbiface - The MOAB instance set on this DMMoab 236 237 Level: beginner 238 239 .keywords: DMMoab, create 240 @*/ 241 PetscErrorCode DMMoabGetInterface(DM dm, moab::Interface **mbiface) 242 { 243 PetscErrorCode ierr; 244 static PetscBool cite = PETSC_FALSE; 245 246 PetscFunctionBegin; 247 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 248 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); 249 *mbiface = ((DM_Moab*)dm->data)->mbiface; 250 PetscFunctionReturn(0); 251 } 252 253 254 /*@ 255 DMMoabSetLocalVertices - Set the entities having DOFs on this DMMoab 256 257 Collective on MPI_Comm 258 259 Input Parameter: 260 . dm - The DMMoab object being set 261 . range - The entities treated by this DMMoab 262 263 Level: beginner 264 265 .keywords: DMMoab, create 266 @*/ 267 PetscErrorCode DMMoabSetLocalVertices(DM dm, moab::Range *range) 268 { 269 moab::Range tmpvtxs; 270 DM_Moab *dmmoab = (DM_Moab*)(dm)->data; 271 272 PetscFunctionBegin; 273 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 274 dmmoab->vlocal->clear(); 275 dmmoab->vowned->clear(); 276 277 dmmoab->vlocal->insert(range->begin(), range->end()); 278 279 #ifdef MOAB_HAVE_MPI 280 moab::ErrorCode merr; 281 /* filter based on parallel status */ 282 merr = dmmoab->pcomm->filter_pstatus(*dmmoab->vlocal, PSTATUS_NOT_OWNED, PSTATUS_NOT, -1, dmmoab->vowned); MBERRNM(merr); 283 284 /* filter all the non-owned and shared entities out of the list */ 285 tmpvtxs = moab::subtract(*dmmoab->vlocal, *dmmoab->vowned); 286 merr = dmmoab->pcomm->filter_pstatus(tmpvtxs, PSTATUS_INTERFACE, PSTATUS_OR, -1, dmmoab->vghost); MBERRNM(merr); 287 tmpvtxs = moab::subtract(tmpvtxs, *dmmoab->vghost); 288 *dmmoab->vlocal = moab::subtract(*dmmoab->vlocal, tmpvtxs); 289 #else 290 *dmmoab->vowned = *dmmoab->vlocal; 291 #endif 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 #ifdef MOAB_HAVE_MPI 297 PetscErrorCode ierr; 298 ierr = MPIU_Allreduce(&dmmoab->nloc, &dmmoab->n, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm);CHKERRQ(ierr); 299 #else 300 dmmoab->n = dmmoab->nloc; 301 #endif 302 PetscFunctionReturn(0); 303 } 304 305 306 /*@ 307 DMMoabGetAllVertices - Get the entities having DOFs on this DMMoab 308 309 Collective on MPI_Comm 310 311 Input Parameter: 312 . dm - The DMMoab object being set 313 314 Output Parameter: 315 . owned - The local vertex entities in this DMMoab = (owned+ghosted) 316 317 Level: beginner 318 319 .keywords: DMMoab, create 320 @*/ 321 PetscErrorCode DMMoabGetAllVertices(DM dm, moab::Range *local) 322 { 323 PetscFunctionBegin; 324 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 325 if (local) *local = *((DM_Moab*)dm->data)->vlocal; 326 PetscFunctionReturn(0); 327 } 328 329 330 331 /*@ 332 DMMoabGetLocalVertices - Get the entities having DOFs on this DMMoab 333 334 Collective on MPI_Comm 335 336 Input Parameter: 337 . dm - The DMMoab object being set 338 339 Output Parameter: 340 . owned - The owned vertex entities in this DMMoab 341 . ghost - The ghosted entities (non-owned) stored locally in this partition 342 343 Level: beginner 344 345 .keywords: DMMoab, create 346 @*/ 347 PetscErrorCode DMMoabGetLocalVertices(DM dm, const moab::Range **owned, const moab::Range **ghost) 348 { 349 PetscFunctionBegin; 350 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 351 if (owned) *owned = ((DM_Moab*)dm->data)->vowned; 352 if (ghost) *ghost = ((DM_Moab*)dm->data)->vghost; 353 PetscFunctionReturn(0); 354 } 355 356 /*@ 357 DMMoabGetLocalElements - Get the higher-dimensional entities that are locally owned 358 359 Collective on MPI_Comm 360 361 Input Parameter: 362 . dm - The DMMoab object being set 363 364 Output Parameter: 365 . range - The entities owned locally 366 367 Level: beginner 368 369 .keywords: DMMoab, create 370 @*/ 371 PetscErrorCode DMMoabGetLocalElements(DM dm, const moab::Range **range) 372 { 373 PetscFunctionBegin; 374 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 375 if (range) *range = ((DM_Moab*)dm->data)->elocal; 376 PetscFunctionReturn(0); 377 } 378 379 380 /*@ 381 DMMoabSetLocalElements - Set the entities having DOFs on this DMMoab 382 383 Collective on MPI_Comm 384 385 Input Parameter: 386 . dm - The DMMoab object being set 387 . range - The entities treated by this DMMoab 388 389 Level: beginner 390 391 .keywords: DMMoab, create 392 @*/ 393 PetscErrorCode DMMoabSetLocalElements(DM dm, moab::Range *range) 394 { 395 DM_Moab *dmmoab = (DM_Moab*)(dm)->data; 396 397 PetscFunctionBegin; 398 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 399 dmmoab->elocal->clear(); 400 dmmoab->eghost->clear(); 401 dmmoab->elocal->insert(range->begin(), range->end()); 402 #ifdef MOAB_HAVE_MPI 403 moab::ErrorCode merr; 404 merr = dmmoab->pcomm->filter_pstatus(*dmmoab->elocal, PSTATUS_NOT_OWNED, PSTATUS_NOT); MBERRNM(merr); 405 *dmmoab->eghost = moab::subtract(*range, *dmmoab->elocal); 406 #endif 407 dmmoab->neleloc = dmmoab->elocal->size(); 408 dmmoab->neleghost = dmmoab->eghost->size(); 409 #ifdef MOAB_HAVE_MPI 410 PetscErrorCode ierr; 411 ierr = MPIU_Allreduce(&dmmoab->neleloc, &dmmoab->nele, 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 #else 414 dmmoab->nele = dmmoab->neleloc; 415 #endif 416 PetscFunctionReturn(0); 417 } 418 419 420 /*@ 421 DMMoabSetLocalToGlobalTag - Set the tag used for local to global numbering 422 423 Collective on MPI_Comm 424 425 Input Parameter: 426 . dm - The DMMoab object being set 427 . ltogtag - The MOAB tag used for local to global ids 428 429 Level: beginner 430 431 .keywords: DMMoab, create 432 @*/ 433 PetscErrorCode DMMoabSetLocalToGlobalTag(DM dm, moab::Tag ltogtag) 434 { 435 PetscFunctionBegin; 436 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 437 ((DM_Moab*)dm->data)->ltog_tag = ltogtag; 438 PetscFunctionReturn(0); 439 } 440 441 442 /*@ 443 DMMoabGetLocalToGlobalTag - Get the tag used for local to global numbering 444 445 Collective on MPI_Comm 446 447 Input Parameter: 448 . dm - The DMMoab object being set 449 450 Output Parameter: 451 . ltogtag - The MOAB tag used for local to global ids 452 453 Level: beginner 454 455 .keywords: DMMoab, create 456 @*/ 457 PetscErrorCode DMMoabGetLocalToGlobalTag(DM dm, moab::Tag *ltog_tag) 458 { 459 PetscFunctionBegin; 460 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 461 *ltog_tag = ((DM_Moab*)dm->data)->ltog_tag; 462 PetscFunctionReturn(0); 463 } 464 465 466 /*@ 467 DMMoabSetBlockSize - Set the block size used with this DMMoab 468 469 Collective on MPI_Comm 470 471 Input Parameter: 472 . dm - The DMMoab object being set 473 . bs - The block size used with this DMMoab 474 475 Level: beginner 476 477 .keywords: DMMoab, create 478 @*/ 479 PetscErrorCode DMMoabSetBlockSize(DM dm, PetscInt bs) 480 { 481 PetscFunctionBegin; 482 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 483 ((DM_Moab*)dm->data)->bs = bs; 484 PetscFunctionReturn(0); 485 } 486 487 488 /*@ 489 DMMoabGetBlockSize - Get the block size used with this DMMoab 490 491 Collective on MPI_Comm 492 493 Input Parameter: 494 . dm - The DMMoab object being set 495 496 Output Parameter: 497 . bs - The block size used with this DMMoab 498 499 Level: beginner 500 501 .keywords: DMMoab, create 502 @*/ 503 PetscErrorCode DMMoabGetBlockSize(DM dm, PetscInt *bs) 504 { 505 PetscFunctionBegin; 506 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 507 *bs = ((DM_Moab*)dm->data)->bs; 508 PetscFunctionReturn(0); 509 } 510 511 512 /*@ 513 DMMoabGetSize - Get the global vertex size used with this DMMoab 514 515 Collective on DM 516 517 Input Parameter: 518 . dm - The DMMoab object being set 519 520 Output Parameter: 521 . neg - The number of global elements in the DMMoab instance 522 . nvg - The number of global vertices in the DMMoab instance 523 524 Level: beginner 525 526 .keywords: DMMoab, create 527 @*/ 528 PetscErrorCode DMMoabGetSize(DM dm, PetscInt *neg, PetscInt *nvg) 529 { 530 PetscFunctionBegin; 531 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 532 if (neg) *neg = ((DM_Moab*)dm->data)->nele; 533 if (nvg) *nvg = ((DM_Moab*)dm->data)->n; 534 PetscFunctionReturn(0); 535 } 536 537 538 /*@ 539 DMMoabGetLocalSize - Get the local and ghosted vertex size used with this DMMoab 540 541 Collective on DM 542 543 Input Parameter: 544 . dm - The DMMoab object being set 545 546 Output Parameter: 547 + nel - The number of owned elements in this processor 548 . neg - The number of ghosted elements in this processor 549 . nvl - The number of owned vertices in this processor 550 . nvg - The number of ghosted vertices in this processor 551 552 Level: beginner 553 554 .keywords: DMMoab, create 555 @*/ 556 PetscErrorCode DMMoabGetLocalSize(DM dm, PetscInt *nel, PetscInt *neg, PetscInt *nvl, PetscInt *nvg) 557 { 558 PetscFunctionBegin; 559 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 560 if (nel) *nel = ((DM_Moab*)dm->data)->neleloc; 561 if (neg) *neg = ((DM_Moab*)dm->data)->neleghost; 562 if (nvl) *nvl = ((DM_Moab*)dm->data)->nloc; 563 if (nvg) *nvg = ((DM_Moab*)dm->data)->nghost; 564 PetscFunctionReturn(0); 565 } 566 567 568 /*@ 569 DMMoabGetOffset - Get the local offset for the global vector 570 571 Collective on MPI_Comm 572 573 Input Parameter: 574 . dm - The DMMoab object being set 575 576 Output Parameter: 577 . offset - The local offset for the global vector 578 579 Level: beginner 580 581 .keywords: DMMoab, create 582 @*/ 583 PetscErrorCode DMMoabGetOffset(DM dm, PetscInt *offset) 584 { 585 PetscFunctionBegin; 586 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 587 *offset = ((DM_Moab*)dm->data)->vstart; 588 PetscFunctionReturn(0); 589 } 590 591 592 /*@ 593 DMMoabGetDimension - Get the dimension of the DM Mesh 594 595 Collective on MPI_Comm 596 597 Input Parameter: 598 . dm - The DMMoab object 599 600 Output Parameter: 601 . dim - The dimension of DM 602 603 Level: beginner 604 605 .keywords: DMMoab, create 606 @*/ 607 PetscErrorCode DMMoabGetDimension(DM dm, PetscInt *dim) 608 { 609 PetscFunctionBegin; 610 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 611 *dim = ((DM_Moab*)dm->data)->dim; 612 PetscFunctionReturn(0); 613 } 614 615 616 /*@ 617 DMMoabGetHierarchyLevel - Get the current level of the mesh hierarchy 618 generated through uniform refinement. 619 620 Collective on DM 621 622 Input Parameter: 623 . dm - The DMMoab object being set 624 625 Output Parameter: 626 . nvg - The current mesh hierarchy level 627 628 Level: beginner 629 630 .keywords: DMMoab, multigrid 631 @*/ 632 PetscErrorCode DMMoabGetHierarchyLevel(DM dm, PetscInt *nlevel) 633 { 634 PetscFunctionBegin; 635 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 636 if (nlevel) *nlevel = ((DM_Moab*)dm->data)->hlevel; 637 PetscFunctionReturn(0); 638 } 639 640 641 /*@ 642 DMMoabGetMaterialBlock - Get the material ID corresponding to the current entity of the DM Mesh 643 644 Collective on MPI_Comm 645 646 Input Parameter: 647 . dm - The DMMoab object 648 . ehandle - The element entity handle 649 650 Output Parameter: 651 . mat - The material ID for the current entity 652 653 Level: beginner 654 655 .keywords: DMMoab, create 656 @*/ 657 PetscErrorCode DMMoabGetMaterialBlock(DM dm, const moab::EntityHandle ehandle, PetscInt *mat) 658 { 659 DM_Moab *dmmoab; 660 661 PetscFunctionBegin; 662 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 663 if (*mat) { 664 dmmoab = (DM_Moab*)(dm)->data; 665 *mat = dmmoab->materials[dmmoab->elocal->index(ehandle)]; 666 } 667 PetscFunctionReturn(0); 668 } 669 670 671 /*@ 672 DMMoabGetVertexCoordinates - Get the coordinates corresponding to the requested vertex entities 673 674 Collective on MPI_Comm 675 676 Input Parameter: 677 . dm - The DMMoab object 678 . nconn - Number of entities whose coordinates are needed 679 . conn - The vertex entity handles 680 681 Output Parameter: 682 . vpos - The coordinates of the requested vertex entities 683 684 Level: beginner 685 686 .seealso: DMMoabGetVertexConnectivity() 687 @*/ 688 PetscErrorCode DMMoabGetVertexCoordinates(DM dm, PetscInt nconn, const moab::EntityHandle *conn, PetscReal *vpos) 689 { 690 DM_Moab *dmmoab; 691 moab::ErrorCode merr; 692 693 PetscFunctionBegin; 694 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 695 PetscValidPointer(conn, 3); 696 PetscValidPointer(vpos, 4); 697 dmmoab = (DM_Moab*)(dm)->data; 698 699 /* Get connectivity information in MOAB canonical ordering */ 700 if (dmmoab->hlevel) { 701 merr = dmmoab->hierarchy->get_coordinates(const_cast<moab::EntityHandle*>(conn), nconn, dmmoab->hlevel, vpos);MBERRNM(merr); 702 } 703 else { 704 merr = dmmoab->mbiface->get_coords(conn, nconn, vpos);MBERRNM(merr); 705 } 706 PetscFunctionReturn(0); 707 } 708 709 710 /*@ 711 DMMoabGetVertexConnectivity - Get the vertex adjacency 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 719 Output Parameter: 720 . nconn - Number of entities whose coordinates are needed 721 . conn - The vertex entity handles 722 723 Level: beginner 724 725 .seealso: DMMoabGetVertexCoordinates(), DMMoabRestoreVertexConnectivity() 726 @*/ 727 PetscErrorCode DMMoabGetVertexConnectivity(DM dm, moab::EntityHandle vhandle, PetscInt* nconn, moab::EntityHandle **conn) 728 { 729 DM_Moab *dmmoab; 730 std::vector<moab::EntityHandle> adj_entities, connect; 731 PetscErrorCode ierr; 732 moab::ErrorCode merr; 733 734 PetscFunctionBegin; 735 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 736 PetscValidPointer(conn, 4); 737 dmmoab = (DM_Moab*)(dm)->data; 738 739 /* Get connectivity information in MOAB canonical ordering */ 740 merr = dmmoab->mbiface->get_adjacencies(&vhandle, 1, 1, true, adj_entities, moab::Interface::UNION); MBERRNM(merr); 741 merr = dmmoab->mbiface->get_connectivity(&adj_entities[0], adj_entities.size(), connect); MBERRNM(merr); 742 743 if (conn) { 744 ierr = PetscMalloc(sizeof(moab::EntityHandle) * connect.size(), conn);CHKERRQ(ierr); 745 ierr = PetscMemcpy(*conn, &connect[0], sizeof(moab::EntityHandle) * connect.size());CHKERRQ(ierr); 746 } 747 if (nconn) *nconn = connect.size(); 748 PetscFunctionReturn(0); 749 } 750 751 752 /*@ 753 DMMoabRestoreVertexConnectivity - Restore the vertex connectivity for the given entity 754 755 Collective on MPI_Comm 756 757 Input Parameter: 758 . dm - The DMMoab object 759 . vhandle - Vertex entity handle 760 . nconn - Number of entities whose coordinates are needed 761 . conn - The vertex entity handles 762 763 Level: beginner 764 765 .seealso: DMMoabGetVertexCoordinates(), DMMoabGetVertexConnectivity() 766 @*/ 767 PetscErrorCode DMMoabRestoreVertexConnectivity(DM dm, moab::EntityHandle ehandle, PetscInt* nconn, moab::EntityHandle **conn) 768 { 769 PetscErrorCode ierr; 770 771 PetscFunctionBegin; 772 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 773 PetscValidPointer(conn, 4); 774 775 if (conn) { 776 ierr = PetscFree(*conn);CHKERRQ(ierr); 777 } 778 if (nconn) *nconn = 0; 779 PetscFunctionReturn(0); 780 } 781 782 783 /*@ 784 DMMoabGetElementConnectivity - Get the vertex adjacency for the given entity 785 786 Collective on MPI_Comm 787 788 Input Parameter: 789 . dm - The DMMoab object 790 . ehandle - Vertex entity handle 791 792 Output Parameter: 793 . nconn - Number of entities whose coordinates are needed 794 . conn - The vertex entity handles 795 796 Level: beginner 797 798 .seealso: DMMoabGetVertexCoordinates(), DMMoabGetVertexConnectivity(), DMMoabRestoreVertexConnectivity() 799 @*/ 800 PetscErrorCode DMMoabGetElementConnectivity(DM dm, moab::EntityHandle ehandle, PetscInt* nconn, const moab::EntityHandle **conn) 801 { 802 DM_Moab *dmmoab; 803 const moab::EntityHandle *connect; 804 std::vector<moab::EntityHandle> vconn; 805 moab::ErrorCode merr; 806 PetscInt nnodes; 807 808 PetscFunctionBegin; 809 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 810 PetscValidPointer(conn, 4); 811 dmmoab = (DM_Moab*)(dm)->data; 812 813 /* Get connectivity information in MOAB canonical ordering */ 814 merr = dmmoab->mbiface->get_connectivity(ehandle, connect, nnodes); MBERRNM(merr); 815 if (conn) *conn = connect; 816 if (nconn) *nconn = nnodes; 817 PetscFunctionReturn(0); 818 } 819 820 821 /*@ 822 DMMoabIsEntityOnBoundary - Check whether a given entity is on the boundary (vertex, edge, face, element) 823 824 Collective on MPI_Comm 825 826 Input Parameter: 827 . dm - The DMMoab object 828 . ent - Entity handle 829 830 Output Parameter: 831 . ent_on_boundary - PETSC_TRUE if entity on boundary; PETSC_FALSE otherwise 832 833 Level: beginner 834 835 .seealso: DMMoabCheckBoundaryVertices() 836 @*/ 837 PetscErrorCode DMMoabIsEntityOnBoundary(DM dm, const moab::EntityHandle ent, PetscBool* ent_on_boundary) 838 { 839 moab::EntityType etype; 840 DM_Moab *dmmoab; 841 PetscInt edim; 842 843 PetscFunctionBegin; 844 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 845 PetscValidPointer(ent_on_boundary, 3); 846 dmmoab = (DM_Moab*)(dm)->data; 847 848 /* get the entity type and handle accordingly */ 849 etype = dmmoab->mbiface->type_from_handle(ent); 850 if (etype >= moab::MBPOLYHEDRON) SETERRQ1(PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE, "Entity type on the boundary skin is invalid. EntityType = %D\n", etype); 851 852 /* get the entity dimension */ 853 edim = dmmoab->mbiface->dimension_from_handle(ent); 854 855 *ent_on_boundary = PETSC_FALSE; 856 if (etype == moab::MBVERTEX && edim == 0) { 857 *ent_on_boundary = ((dmmoab->bndyvtx->index(ent) >= 0) ? PETSC_TRUE : PETSC_FALSE); 858 } 859 else { 860 if (edim == dmmoab->dim) { /* check the higher-dimensional elements first */ 861 if (dmmoab->bndyelems->index(ent) >= 0) *ent_on_boundary = PETSC_TRUE; 862 } 863 else { /* next check the lower-dimensional faces */ 864 if (dmmoab->bndyfaces->index(ent) >= 0) *ent_on_boundary = PETSC_TRUE; 865 } 866 } 867 PetscFunctionReturn(0); 868 } 869 870 871 /*@ 872 DMMoabIsEntityOnBoundary - Check whether a given entity is on the boundary (vertex, edge, face, element) 873 874 Input Parameter: 875 . dm - The DMMoab object 876 . nconn - Number of handles 877 . cnt - Array of entity handles 878 879 Output Parameter: 880 . isbdvtx - Array of boundary markers - PETSC_TRUE if entity on boundary; PETSC_FALSE otherwise 881 882 Level: beginner 883 884 .seealso: DMMoabIsEntityOnBoundary() 885 @*/ 886 PetscErrorCode DMMoabCheckBoundaryVertices(DM dm, PetscInt nconn, const moab::EntityHandle *cnt, PetscBool* isbdvtx) 887 { 888 DM_Moab *dmmoab; 889 PetscInt i; 890 891 PetscFunctionBegin; 892 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 893 PetscValidPointer(cnt, 3); 894 PetscValidPointer(isbdvtx, 4); 895 dmmoab = (DM_Moab*)(dm)->data; 896 897 for (i = 0; i < nconn; ++i) { 898 isbdvtx[i] = (dmmoab->bndyvtx->index(cnt[i]) >= 0 ? PETSC_TRUE : PETSC_FALSE); 899 } 900 PetscFunctionReturn(0); 901 } 902 903 904 /*@ 905 DMMoabGetBoundaryMarkers - Return references to the vertices, faces, elements on the boundary 906 907 Input Parameter: 908 . dm - The DMMoab object 909 910 Output Parameter: 911 . bdvtx - Boundary vertices 912 . bdelems - Boundary elements 913 . bdfaces - Boundary faces 914 915 Level: beginner 916 917 .seealso: DMMoabCheckBoundaryVertices(), DMMoabIsEntityOnBoundary() 918 @*/ 919 PetscErrorCode DMMoabGetBoundaryMarkers(DM dm, const moab::Range **bdvtx, const moab::Range** bdelems, const moab::Range** bdfaces) 920 { 921 DM_Moab *dmmoab; 922 923 PetscFunctionBegin; 924 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 925 dmmoab = (DM_Moab*)(dm)->data; 926 927 if (bdvtx) *bdvtx = dmmoab->bndyvtx; 928 if (bdfaces) *bdfaces = dmmoab->bndyfaces; 929 if (bdelems) *bdfaces = dmmoab->bndyelems; 930 PetscFunctionReturn(0); 931 } 932 933 934 PETSC_EXTERN PetscErrorCode DMDestroy_Moab(DM dm) 935 { 936 PetscErrorCode ierr; 937 PetscInt i; 938 moab::ErrorCode merr; 939 DM_Moab *dmmoab = (DM_Moab*)dm->data; 940 941 PetscFunctionBegin; 942 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 943 944 dmmoab->refct--; 945 if (!dmmoab->refct) { 946 delete dmmoab->vlocal; 947 delete dmmoab->vowned; 948 delete dmmoab->vghost; 949 delete dmmoab->elocal; 950 delete dmmoab->eghost; 951 delete dmmoab->bndyvtx; 952 delete dmmoab->bndyfaces; 953 delete dmmoab->bndyelems; 954 955 ierr = PetscFree(dmmoab->gsindices);CHKERRQ(ierr); 956 ierr = PetscFree2(dmmoab->gidmap, dmmoab->lidmap);CHKERRQ(ierr); 957 ierr = PetscFree(dmmoab->dfill);CHKERRQ(ierr); 958 ierr = PetscFree(dmmoab->ofill);CHKERRQ(ierr); 959 ierr = PetscFree(dmmoab->materials);CHKERRQ(ierr); 960 if (dmmoab->fieldNames) { 961 for (i = 0; i < dmmoab->numFields; i++) { 962 ierr = PetscFree(dmmoab->fieldNames[i]);CHKERRQ(ierr); 963 } 964 ierr = PetscFree(dmmoab->fieldNames);CHKERRQ(ierr); 965 } 966 967 if (dmmoab->nhlevels) { 968 ierr = PetscFree(dmmoab->hsets);CHKERRQ(ierr); 969 dmmoab->nhlevels = 0; 970 if (!dmmoab->hlevel && dmmoab->icreatedinstance) delete dmmoab->hierarchy; 971 dmmoab->hierarchy = NULL; 972 } 973 974 if (dmmoab->icreatedinstance) { 975 delete dmmoab->pcomm; 976 merr = dmmoab->mbiface->delete_mesh(); MBERRNM(merr); 977 delete dmmoab->mbiface; 978 } 979 dmmoab->mbiface = NULL; 980 #ifdef MOAB_HAVE_MPI 981 dmmoab->pcomm = NULL; 982 #endif 983 ierr = VecScatterDestroy(&dmmoab->ltog_sendrecv);CHKERRQ(ierr); 984 ierr = ISLocalToGlobalMappingDestroy(&dmmoab->ltog_map);CHKERRQ(ierr); 985 ierr = PetscFree(dm->data);CHKERRQ(ierr); 986 } 987 PetscFunctionReturn(0); 988 } 989 990 991 PETSC_EXTERN PetscErrorCode DMSetFromOptions_Moab(PetscOptionItems *PetscOptionsObject, DM dm) 992 { 993 PetscErrorCode ierr; 994 DM_Moab *dmmoab = (DM_Moab*)dm->data; 995 996 PetscFunctionBegin; 997 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 998 ierr = PetscOptionsHead(PetscOptionsObject, "DMMoab Options");CHKERRQ(ierr); 999 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); 1000 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); 1001 /* TODO: typically, the read options are needed before a DM is completely created and available in which case, the options wont be available ?? */ 1002 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); 1003 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); 1004 ierr = PetscOptionsEnum("-dm_moab_read_mode", "MOAB parallel read mode", "DMView", MoabReadModes, (PetscEnum)dmmoab->read_mode, (PetscEnum*)&dmmoab->read_mode, NULL);CHKERRQ(ierr); 1005 ierr = PetscOptionsEnum("-dm_moab_write_mode", "MOAB parallel write mode", "DMView", MoabWriteModes, (PetscEnum)dmmoab->write_mode, (PetscEnum*)&dmmoab->write_mode, NULL);CHKERRQ(ierr); 1006 PetscFunctionReturn(0); 1007 } 1008 1009 1010 PETSC_EXTERN PetscErrorCode DMSetUp_Moab(DM dm) 1011 { 1012 PetscErrorCode ierr; 1013 moab::ErrorCode merr; 1014 Vec local, global; 1015 IS from, to; 1016 moab::Range::iterator iter; 1017 PetscInt i, j, f, bs, vent, totsize, *lgmap; 1018 DM_Moab *dmmoab = (DM_Moab*)dm->data; 1019 moab::Range adjs; 1020 1021 PetscFunctionBegin; 1022 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1023 /* Get the local and shared vertices and cache it */ 1024 if (dmmoab->mbiface == NULL) SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ORDER, "Set the MOAB Interface before calling SetUp."); 1025 #ifdef MOAB_HAVE_MPI 1026 if (dmmoab->pcomm == NULL) SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ORDER, "Set the MOAB ParallelComm object before calling SetUp."); 1027 #endif 1028 1029 /* Get the entities recursively in the current part of the mesh, if user did not set the local vertices explicitly */ 1030 if (dmmoab->vlocal->empty()) 1031 { 1032 //merr = dmmoab->mbiface->get_entities_by_type(dmmoab->fileset,moab::MBVERTEX,*dmmoab->vlocal,true);MBERRNM(merr); 1033 merr = dmmoab->mbiface->get_entities_by_dimension(dmmoab->fileset, 0, *dmmoab->vlocal, false); MBERRNM(merr); 1034 1035 #ifdef MOAB_HAVE_MPI 1036 /* filter based on parallel status */ 1037 merr = dmmoab->pcomm->filter_pstatus(*dmmoab->vlocal, PSTATUS_NOT_OWNED, PSTATUS_NOT, -1, dmmoab->vowned); MBERRNM(merr); 1038 1039 /* filter all the non-owned and shared entities out of the list */ 1040 // *dmmoab->vghost = moab::subtract(*dmmoab->vlocal, *dmmoab->vowned); 1041 adjs = moab::subtract(*dmmoab->vlocal, *dmmoab->vowned); 1042 merr = dmmoab->pcomm->filter_pstatus(adjs, PSTATUS_GHOST | PSTATUS_INTERFACE, PSTATUS_OR, -1, dmmoab->vghost); MBERRNM(merr); 1043 adjs = moab::subtract(adjs, *dmmoab->vghost); 1044 *dmmoab->vlocal = moab::subtract(*dmmoab->vlocal, adjs); 1045 #else 1046 *dmmoab->vowned = *dmmoab->vlocal; 1047 #endif 1048 1049 /* compute and cache the sizes of local and ghosted entities */ 1050 dmmoab->nloc = dmmoab->vowned->size(); 1051 dmmoab->nghost = dmmoab->vghost->size(); 1052 1053 #ifdef MOAB_HAVE_MPI 1054 ierr = MPIU_Allreduce(&dmmoab->nloc, &dmmoab->n, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm);CHKERRQ(ierr); 1055 PetscInfo4(NULL, "Filset ID: %u, Vertices: local - %D, owned - %D, ghosted - %D.\n", dmmoab->fileset, dmmoab->vlocal->size(), dmmoab->nloc, dmmoab->nghost); 1056 #else 1057 dmmoab->n = dmmoab->nloc; 1058 #endif 1059 } 1060 1061 { 1062 /* get the information about the local elements in the mesh */ 1063 dmmoab->eghost->clear(); 1064 1065 /* first decipher the leading dimension */ 1066 for (i = 3; i > 0; i--) { 1067 dmmoab->elocal->clear(); 1068 merr = dmmoab->mbiface->get_entities_by_dimension(dmmoab->fileset, i, *dmmoab->elocal, false); MBERRNM(merr); 1069 1070 /* store the current mesh dimension */ 1071 if (dmmoab->elocal->size()) { 1072 dmmoab->dim = i; 1073 break; 1074 } 1075 } 1076 1077 ierr = DMSetDimension(dm, dmmoab->dim);CHKERRQ(ierr); 1078 1079 #ifdef MOAB_HAVE_MPI 1080 /* filter the ghosted and owned element list */ 1081 *dmmoab->eghost = *dmmoab->elocal; 1082 merr = dmmoab->pcomm->filter_pstatus(*dmmoab->elocal, PSTATUS_NOT_OWNED, PSTATUS_NOT); MBERRNM(merr); 1083 *dmmoab->eghost = moab::subtract(*dmmoab->eghost, *dmmoab->elocal); 1084 #endif 1085 1086 dmmoab->neleloc = dmmoab->elocal->size(); 1087 dmmoab->neleghost = dmmoab->eghost->size(); 1088 1089 #ifdef MOAB_HAVE_MPI 1090 ierr = MPIU_Allreduce(&dmmoab->neleloc, &dmmoab->nele, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm);CHKERRQ(ierr); 1091 PetscInfo3(NULL, "%d-dim elements: owned - %D, ghosted - %D.\n", dmmoab->dim, dmmoab->neleloc, dmmoab->neleghost); 1092 #else 1093 dmmoab->nele = dmmoab->neleloc; 1094 #endif 1095 } 1096 1097 bs = dmmoab->bs; 1098 if (!dmmoab->ltog_tag) { 1099 /* Get the global ID tag. The global ID tag is applied to each 1100 vertex. It acts as an global identifier which MOAB uses to 1101 assemble the individual pieces of the mesh */ 1102 merr = dmmoab->mbiface->tag_get_handle(GLOBAL_ID_TAG_NAME, dmmoab->ltog_tag); MBERRNM(merr); 1103 } 1104 1105 totsize = dmmoab->vlocal->size(); 1106 if (totsize != dmmoab->nloc + dmmoab->nghost) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Mismatch between local and owned+ghost vertices. %D != %D.", totsize, dmmoab->nloc + dmmoab->nghost); 1107 ierr = PetscCalloc1(totsize, &dmmoab->gsindices);CHKERRQ(ierr); 1108 { 1109 /* first get the local indices */ 1110 merr = dmmoab->mbiface->tag_get_data(dmmoab->ltog_tag, *dmmoab->vowned, &dmmoab->gsindices[0]); MBERRNM(merr); 1111 if (dmmoab->nghost) { /* next get the ghosted indices */ 1112 merr = dmmoab->mbiface->tag_get_data(dmmoab->ltog_tag, *dmmoab->vghost, &dmmoab->gsindices[dmmoab->nloc]); MBERRNM(merr); 1113 } 1114 1115 /* find out the local and global minima of GLOBAL_ID */ 1116 dmmoab->lminmax[0] = dmmoab->lminmax[1] = dmmoab->gsindices[0]; 1117 for (i = 0; i < totsize; ++i) { 1118 if (dmmoab->lminmax[0] > dmmoab->gsindices[i]) dmmoab->lminmax[0] = dmmoab->gsindices[i]; 1119 if (dmmoab->lminmax[1] < dmmoab->gsindices[i]) dmmoab->lminmax[1] = dmmoab->gsindices[i]; 1120 } 1121 1122 ierr = MPIU_Allreduce(&dmmoab->lminmax[0], &dmmoab->gminmax[0], 1, MPI_INT, MPI_MIN, ((PetscObject)dm)->comm);CHKERRQ(ierr); 1123 ierr = MPIU_Allreduce(&dmmoab->lminmax[1], &dmmoab->gminmax[1], 1, MPI_INT, MPI_MAX, ((PetscObject)dm)->comm);CHKERRQ(ierr); 1124 1125 /* set the GID map */ 1126 for (i = 0; i < totsize; ++i) { 1127 dmmoab->gsindices[i] -= dmmoab->gminmax[0]; /* zero based index needed for IS */ 1128 1129 } 1130 dmmoab->lminmax[0] -= dmmoab->gminmax[0]; 1131 dmmoab->lminmax[1] -= dmmoab->gminmax[0]; 1132 1133 PetscInfo4(NULL, "GLOBAL_ID: Local [min, max] - [%D, %D], Global [min, max] - [%D, %D]\n", dmmoab->lminmax[0], dmmoab->lminmax[1], dmmoab->gminmax[0], dmmoab->gminmax[1]); 1134 } 1135 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); 1136 1137 { 1138 dmmoab->seqstart = dmmoab->mbiface->id_from_handle(dmmoab->vlocal->front()); 1139 dmmoab->seqend = dmmoab->mbiface->id_from_handle(dmmoab->vlocal->back()); 1140 PetscInfo2(NULL, "SEQUENCE: Local [min, max] - [%D, %D]\n", dmmoab->seqstart, dmmoab->seqend); 1141 1142 ierr = PetscMalloc2(dmmoab->seqend - dmmoab->seqstart + 1, &dmmoab->gidmap, dmmoab->seqend - dmmoab->seqstart + 1, &dmmoab->lidmap);CHKERRQ(ierr); 1143 ierr = PetscMalloc1(totsize * dmmoab->numFields, &lgmap);CHKERRQ(ierr); 1144 1145 i = j = 0; 1146 /* set the owned vertex data first */ 1147 for (moab::Range::iterator iter = dmmoab->vowned->begin(); iter != dmmoab->vowned->end(); iter++, i++) { 1148 vent = dmmoab->mbiface->id_from_handle(*iter) - dmmoab->seqstart; 1149 dmmoab->gidmap[vent] = dmmoab->gsindices[i]; 1150 dmmoab->lidmap[vent] = i; 1151 for (f = 0; f < dmmoab->numFields; f++, j++) { 1152 lgmap[j] = (bs > 1 ? dmmoab->gsindices[i] * dmmoab->numFields + f : totsize * f + dmmoab->gsindices[i]); 1153 } 1154 } 1155 /* next arrange all the ghosted data information */ 1156 for (moab::Range::iterator iter = dmmoab->vghost->begin(); iter != dmmoab->vghost->end(); iter++, i++) { 1157 vent = dmmoab->mbiface->id_from_handle(*iter) - dmmoab->seqstart; 1158 dmmoab->gidmap[vent] = dmmoab->gsindices[i]; 1159 dmmoab->lidmap[vent] = i; 1160 for (f = 0; f < dmmoab->numFields; f++, j++) { 1161 lgmap[j] = (bs > 1 ? dmmoab->gsindices[i] * dmmoab->numFields + f : totsize * f + dmmoab->gsindices[i]); 1162 } 1163 } 1164 1165 /* We need to create the Global to Local Vector Scatter Contexts 1166 1) First create a local and global vector 1167 2) Create a local and global IS 1168 3) Create VecScatter and LtoGMapping objects 1169 4) Cleanup the IS and Vec objects 1170 */ 1171 ierr = DMCreateGlobalVector(dm, &global);CHKERRQ(ierr); 1172 ierr = DMCreateLocalVector(dm, &local);CHKERRQ(ierr); 1173 1174 ierr = VecGetOwnershipRange(global, &dmmoab->vstart, &dmmoab->vend);CHKERRQ(ierr); 1175 1176 /* global to local must retrieve ghost points */ 1177 ierr = ISCreateStride(((PetscObject)dm)->comm, dmmoab->nloc * dmmoab->numFields, dmmoab->vstart, 1, &from);CHKERRQ(ierr); 1178 ierr = ISSetBlockSize(from, bs);CHKERRQ(ierr); 1179 1180 ierr = ISCreateGeneral(((PetscObject)dm)->comm, dmmoab->nloc * dmmoab->numFields, &lgmap[0], PETSC_COPY_VALUES, &to);CHKERRQ(ierr); 1181 ierr = ISSetBlockSize(to, bs);CHKERRQ(ierr); 1182 1183 if (!dmmoab->ltog_map) { 1184 /* create to the local to global mapping for vectors in order to use VecSetValuesLocal */ 1185 ierr = ISLocalToGlobalMappingCreate(((PetscObject)dm)->comm, dmmoab->bs, totsize * dmmoab->numFields, lgmap, 1186 PETSC_COPY_VALUES, &dmmoab->ltog_map);CHKERRQ(ierr); 1187 } 1188 1189 /* now create the scatter object from local to global vector */ 1190 ierr = VecScatterCreate(local, from, global, to, &dmmoab->ltog_sendrecv);CHKERRQ(ierr); 1191 1192 /* clean up IS, Vec */ 1193 ierr = PetscFree(lgmap);CHKERRQ(ierr); 1194 ierr = ISDestroy(&from);CHKERRQ(ierr); 1195 ierr = ISDestroy(&to);CHKERRQ(ierr); 1196 ierr = VecDestroy(&local);CHKERRQ(ierr); 1197 ierr = VecDestroy(&global);CHKERRQ(ierr); 1198 } 1199 1200 dmmoab->bndyvtx = new moab::Range(); 1201 dmmoab->bndyfaces = new moab::Range(); 1202 dmmoab->bndyelems = new moab::Range(); 1203 /* skin the boundary and store nodes */ 1204 if (!dmmoab->hlevel) { 1205 /* get the skin vertices of boundary faces for the current partition and then filter 1206 the local, boundary faces, vertices and elements alone via PSTATUS flags; 1207 this should not give us any ghosted boundary, but if user needs such a functionality 1208 it would be easy to add it based on the find_skin query below */ 1209 moab::Skinner skinner(dmmoab->mbiface); 1210 1211 /* get the entities on the skin - only the faces */ 1212 merr = skinner.find_skin(dmmoab->fileset, *dmmoab->elocal, false, *dmmoab->bndyfaces, NULL, true, true, false); MBERRNM(merr); // 'false' param indicates we want faces back, not vertices 1213 1214 #ifdef MOAB_HAVE_MPI 1215 /* filter all the non-owned and shared entities out of the list */ 1216 merr = dmmoab->pcomm->filter_pstatus(*dmmoab->bndyfaces, PSTATUS_NOT_OWNED, PSTATUS_NOT); MBERRNM(merr); 1217 merr = dmmoab->pcomm->filter_pstatus(*dmmoab->bndyfaces, PSTATUS_INTERFACE, PSTATUS_NOT); MBERRNM(merr); 1218 #endif 1219 1220 /* get all the nodes via connectivity and the parent elements via adjacency information */ 1221 merr = dmmoab->mbiface->get_connectivity(*dmmoab->bndyfaces, *dmmoab->bndyvtx, false); MBERRNM(ierr); 1222 merr = dmmoab->mbiface->get_adjacencies(*dmmoab->bndyvtx, dmmoab->dim, false, *dmmoab->bndyelems, moab::Interface::UNION); MBERRNM(ierr); 1223 } 1224 else { 1225 /* Let us query the hierarchy manager and get the results directly for this level */ 1226 for (moab::Range::iterator iter = dmmoab->elocal->begin(); iter != dmmoab->elocal->end(); iter++) { 1227 moab::EntityHandle elemHandle = *iter; 1228 if (dmmoab->hierarchy->is_entity_on_boundary(elemHandle)) { 1229 dmmoab->bndyelems->insert(elemHandle); 1230 /* For this boundary element, query the vertices and add them to the list */ 1231 std::vector<moab::EntityHandle> connect; 1232 merr = dmmoab->hierarchy->get_connectivity(elemHandle, dmmoab->hlevel, connect); MBERRNM(ierr); 1233 for (unsigned iv=0; iv < connect.size(); ++iv) 1234 if (dmmoab->hierarchy->is_entity_on_boundary(connect[iv])) 1235 dmmoab->bndyvtx->insert(connect[iv]); 1236 /* Next, let us query the boundary faces and add them also to the list */ 1237 std::vector<moab::EntityHandle> faces; 1238 merr = dmmoab->hierarchy->get_adjacencies(elemHandle, dmmoab->dim-1, faces); MBERRNM(ierr); 1239 for (unsigned ifa=0; ifa < faces.size(); ++ifa) 1240 if (dmmoab->hierarchy->is_entity_on_boundary(faces[ifa])) 1241 dmmoab->bndyfaces->insert(faces[ifa]); 1242 } 1243 } 1244 #ifdef MOAB_HAVE_MPI 1245 /* filter all the non-owned and shared entities out of the list */ 1246 merr = dmmoab->pcomm->filter_pstatus(*dmmoab->bndyvtx, PSTATUS_NOT_OWNED, PSTATUS_NOT); MBERRNM(merr); 1247 merr = dmmoab->pcomm->filter_pstatus(*dmmoab->bndyfaces, PSTATUS_NOT_OWNED, PSTATUS_NOT); MBERRNM(merr); 1248 merr = dmmoab->pcomm->filter_pstatus(*dmmoab->bndyelems, PSTATUS_NOT_OWNED, PSTATUS_NOT); MBERRNM(merr); 1249 #endif 1250 1251 } 1252 PetscInfo3(NULL, "Found %D boundary vertices, %D boundary faces and %D boundary elements.\n", dmmoab->bndyvtx->size(), dmmoab->bndyfaces->size(), dmmoab->bndyelems->size()); 1253 1254 /* Get the material sets and populate the data for all locally owned elements */ 1255 { 1256 ierr = PetscCalloc1(dmmoab->elocal->size(), &dmmoab->materials);CHKERRQ(ierr); 1257 /* Get the count of entities of particular type from dmmoab->elocal 1258 -- Then, for each non-zero type, loop through and query the fileset to get the material tag data */ 1259 moab::Range msets; 1260 merr = dmmoab->mbiface->get_entities_by_type_and_tag(dmmoab->fileset, moab::MBENTITYSET, &dmmoab->material_tag, NULL, 1, msets, moab::Interface::UNION);MB_CHK_ERR(merr); 1261 if (msets.size() == 0) { 1262 PetscInfo(NULL, "No material sets found in the fileset."); 1263 } 1264 1265 for (unsigned i=0; i < msets.size(); ++i) { 1266 moab::Range msetelems; 1267 merr = dmmoab->mbiface->get_entities_by_dimension(msets[i], dmmoab->dim, msetelems, true);MB_CHK_ERR(merr); 1268 #ifdef MOAB_HAVE_MPI 1269 /* filter all the non-owned and shared entities out of the list */ 1270 merr = dmmoab->pcomm->filter_pstatus(msetelems, PSTATUS_NOT_OWNED, PSTATUS_NOT); MBERRNM(merr); 1271 #endif 1272 1273 int partID; 1274 moab::EntityHandle mset=msets[i]; 1275 merr = dmmoab->mbiface->tag_get_data(dmmoab->material_tag, &mset, 1, &partID);MB_CHK_ERR(merr); 1276 1277 for (unsigned j=0; j < msetelems.size(); ++j) 1278 dmmoab->materials[dmmoab->elocal->index(msetelems[j])]=partID; 1279 } 1280 } 1281 1282 PetscFunctionReturn(0); 1283 } 1284 1285 1286 /*@ 1287 DMMoabCreateVertices - Creates and adds several vertices to the primary set represented by the DM. 1288 1289 Collective on MPI_Comm 1290 1291 Input Parameters: 1292 + dm - The DM object 1293 . type - The type of element to create and add (Edge/Tri/Quad/Tet/Hex/Prism/Pyramid/Polygon/Polyhedra) 1294 . conn - The connectivity of the element 1295 . nverts - The number of vertices that form the element 1296 1297 Output Parameter: 1298 . overts - The list of vertices that were created (can be NULL) 1299 1300 Level: beginner 1301 1302 .keywords: DM, create vertices 1303 1304 .seealso: DMMoabCreateSubmesh(), DMMoabCreateElement() 1305 @*/ 1306 PetscErrorCode DMMoabCreateVertices(DM dm, const PetscReal* coords, PetscInt nverts, moab::Range* overts) 1307 { 1308 moab::ErrorCode merr; 1309 DM_Moab *dmmoab; 1310 moab::Range verts; 1311 1312 PetscFunctionBegin; 1313 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1314 PetscValidPointer(coords, 2); 1315 1316 dmmoab = (DM_Moab*) dm->data; 1317 1318 /* Insert new points */ 1319 merr = dmmoab->mbiface->create_vertices(&coords[0], nverts, verts); MBERRNM(merr); 1320 merr = dmmoab->mbiface->add_entities(dmmoab->fileset, verts); MBERRNM(merr); 1321 1322 if (overts) *overts = verts; 1323 PetscFunctionReturn(0); 1324 } 1325 1326 1327 /*@ 1328 DMMoabCreateElement - Adds an element of specified type to the primary set represented by the DM. 1329 1330 Collective on MPI_Comm 1331 1332 Input Parameters: 1333 + dm - The DM object 1334 . type - The type of element to create and add (Edge/Tri/Quad/Tet/Hex/Prism/Pyramid/Polygon/Polyhedra) 1335 . conn - The connectivity of the element 1336 . nverts - The number of vertices that form the element 1337 1338 Output Parameter: 1339 . oelem - The handle to the element created and added to the DM object 1340 1341 Level: beginner 1342 1343 .keywords: DM, create element 1344 1345 .seealso: DMMoabCreateSubmesh(), DMMoabCreateVertices() 1346 @*/ 1347 PetscErrorCode DMMoabCreateElement(DM dm, const moab::EntityType type, const moab::EntityHandle* conn, PetscInt nverts, moab::EntityHandle* oelem) 1348 { 1349 moab::ErrorCode merr; 1350 DM_Moab *dmmoab; 1351 moab::EntityHandle elem; 1352 1353 PetscFunctionBegin; 1354 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1355 PetscValidPointer(conn, 3); 1356 1357 dmmoab = (DM_Moab*) dm->data; 1358 1359 /* Insert new element */ 1360 merr = dmmoab->mbiface->create_element(type, conn, nverts, elem); MBERRNM(merr); 1361 merr = dmmoab->mbiface->add_entities(dmmoab->fileset, &elem, 1); MBERRNM(merr); 1362 1363 if (oelem) *oelem = elem; 1364 PetscFunctionReturn(0); 1365 } 1366 1367 1368 /*@ 1369 DMMoabCreateSubmesh - Creates a sub-DM object with a set that contains all vertices/elements of the parent 1370 in addition to providing support for dynamic mesh modifications. This is useful for AMR calculations to 1371 create a DM object on a refined level. 1372 1373 Collective on MPI_Comm 1374 1375 Input Parameters: 1376 + dm - The DM object 1377 1378 Output Parameter: 1379 . newdm - The sub DM object with updated set information 1380 1381 Level: advanced 1382 1383 .keywords: DM, sub-DM 1384 1385 .seealso: DMCreate(), DMMoabCreateVertices(), DMMoabCreateElement() 1386 @*/ 1387 PetscErrorCode DMMoabCreateSubmesh(DM dm, DM *newdm) 1388 { 1389 DM_Moab *dmmoab; 1390 DM_Moab *ndmmoab; 1391 moab::ErrorCode merr; 1392 PetscErrorCode ierr; 1393 1394 PetscFunctionBegin; 1395 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1396 1397 dmmoab = (DM_Moab*) dm->data; 1398 1399 /* Create the basic DMMoab object and keep the default parameters created by DM impls */ 1400 ierr = DMMoabCreateMoab(((PetscObject)dm)->comm, dmmoab->mbiface, &dmmoab->ltog_tag, PETSC_NULL, newdm);CHKERRQ(ierr); 1401 1402 /* get all the necessary handles from the private DM object */ 1403 ndmmoab = (DM_Moab*) (*newdm)->data; 1404 1405 /* set the sub-mesh's parent DM reference */ 1406 ndmmoab->parent = &dm; 1407 1408 /* create a file set to associate all entities in current mesh */ 1409 merr = ndmmoab->mbiface->create_meshset(moab::MESHSET_SET, ndmmoab->fileset); MBERR("Creating file set failed", merr); 1410 1411 /* create a meshset and then add old fileset as child */ 1412 merr = ndmmoab->mbiface->add_entities(ndmmoab->fileset, *dmmoab->vlocal); MBERR("Adding child vertices to parent failed", merr); 1413 merr = ndmmoab->mbiface->add_entities(ndmmoab->fileset, *dmmoab->elocal); MBERR("Adding child elements to parent failed", merr); 1414 1415 /* preserve the field association between the parent and sub-mesh objects */ 1416 ierr = DMMoabSetFieldNames(*newdm, dmmoab->numFields, dmmoab->fieldNames);CHKERRQ(ierr); 1417 PetscFunctionReturn(0); 1418 } 1419 1420 1421 PETSC_EXTERN PetscErrorCode DMMoabView_Ascii(DM dm, PetscViewer viewer) 1422 { 1423 DM_Moab *dmmoab = (DM_Moab*)(dm)->data; 1424 const char *name; 1425 MPI_Comm comm; 1426 PetscMPIInt size; 1427 PetscErrorCode ierr; 1428 1429 PetscFunctionBegin; 1430 ierr = PetscObjectGetComm((PetscObject)dm, &comm);CHKERRQ(ierr); 1431 ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr); 1432 ierr = PetscObjectGetName((PetscObject) dm, &name);CHKERRQ(ierr); 1433 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1434 if (name) {ierr = PetscViewerASCIIPrintf(viewer, "%s in %D dimensions:\n", name, dmmoab->dim);CHKERRQ(ierr);} 1435 else {ierr = PetscViewerASCIIPrintf(viewer, "Mesh in %D dimensions:\n", dmmoab->dim);CHKERRQ(ierr);} 1436 /* print details about the global mesh */ 1437 { 1438 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1439 ierr = PetscViewerASCIIPrintf(viewer, "Sizes: cells=%D, vertices=%D, blocks=%D\n", dmmoab->nele, dmmoab->n, dmmoab->bs);CHKERRQ(ierr); 1440 /* print boundary data */ 1441 ierr = PetscViewerASCIIPrintf(viewer, "Boundary trace:\n", dmmoab->bndyelems->size(), dmmoab->bndyfaces->size(), dmmoab->bndyvtx->size());CHKERRQ(ierr); 1442 { 1443 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1444 ierr = PetscViewerASCIIPrintf(viewer, "cells=%D, faces=%D, vertices=%D\n", dmmoab->bndyelems->size(), dmmoab->bndyfaces->size(), dmmoab->bndyvtx->size());CHKERRQ(ierr); 1445 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1446 } 1447 /* print field data */ 1448 ierr = PetscViewerASCIIPrintf(viewer, "Fields: %D components\n", dmmoab->numFields);CHKERRQ(ierr); 1449 { 1450 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1451 for (int i = 0; i < dmmoab->numFields; ++i) { 1452 ierr = PetscViewerASCIIPrintf(viewer, "[%D] - %s\n", i, dmmoab->fieldNames[i]);CHKERRQ(ierr); 1453 } 1454 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1455 } 1456 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1457 } 1458 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1459 ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 1460 PetscFunctionReturn(0); 1461 } 1462 1463 PETSC_EXTERN PetscErrorCode DMMoabView_VTK(DM dm, PetscViewer v) 1464 { 1465 PetscFunctionReturn(0); 1466 } 1467 1468 PETSC_EXTERN PetscErrorCode DMMoabView_HDF5(DM dm, PetscViewer v) 1469 { 1470 PetscFunctionReturn(0); 1471 } 1472 1473 PETSC_EXTERN PetscErrorCode DMView_Moab(DM dm, PetscViewer viewer) 1474 { 1475 PetscBool iascii, ishdf5, isvtk; 1476 PetscErrorCode ierr; 1477 1478 PetscFunctionBegin; 1479 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1480 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 1481 ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr); 1482 ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERVTK, &isvtk);CHKERRQ(ierr); 1483 ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 1484 if (iascii) { 1485 ierr = DMMoabView_Ascii(dm, viewer);CHKERRQ(ierr); 1486 } else if (ishdf5) { 1487 #if defined(PETSC_HAVE_HDF5) && defined(MOAB_HAVE_HDF5) 1488 ierr = PetscViewerPushFormat(viewer, PETSC_VIEWER_HDF5_VIZ);CHKERRQ(ierr); 1489 ierr = DMMoabView_HDF5(dm, viewer);CHKERRQ(ierr); 1490 ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 1491 #else 1492 SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 1493 #endif 1494 } 1495 else if (isvtk) { 1496 ierr = DMMoabView_VTK(dm, viewer);CHKERRQ(ierr); 1497 } 1498 PetscFunctionReturn(0); 1499 } 1500 1501 1502 PETSC_EXTERN PetscErrorCode DMInitialize_Moab(DM dm) 1503 { 1504 PetscFunctionBegin; 1505 dm->ops->view = DMView_Moab; 1506 dm->ops->load = NULL /* DMLoad_Moab */; 1507 dm->ops->setfromoptions = DMSetFromOptions_Moab; 1508 dm->ops->clone = DMClone_Moab; 1509 dm->ops->setup = DMSetUp_Moab; 1510 dm->ops->createdefaultsection = NULL; 1511 dm->ops->createdefaultconstraints = NULL; 1512 dm->ops->createglobalvector = DMCreateGlobalVector_Moab; 1513 dm->ops->createlocalvector = DMCreateLocalVector_Moab; 1514 dm->ops->getlocaltoglobalmapping = NULL; 1515 dm->ops->createfieldis = NULL; 1516 dm->ops->createcoordinatedm = NULL /* DMCreateCoordinateDM_Moab */; 1517 dm->ops->getcoloring = NULL; 1518 dm->ops->creatematrix = DMCreateMatrix_Moab; 1519 dm->ops->createinterpolation = DMCreateInterpolation_Moab; 1520 dm->ops->getaggregates = NULL; 1521 dm->ops->getinjection = NULL /* DMCreateInjection_Moab */; 1522 dm->ops->refine = DMRefine_Moab; 1523 dm->ops->coarsen = DMCoarsen_Moab; 1524 dm->ops->refinehierarchy = DMRefineHierarchy_Moab; 1525 dm->ops->coarsenhierarchy = DMCoarsenHierarchy_Moab; 1526 dm->ops->globaltolocalbegin = DMGlobalToLocalBegin_Moab; 1527 dm->ops->globaltolocalend = DMGlobalToLocalEnd_Moab; 1528 dm->ops->localtoglobalbegin = DMLocalToGlobalBegin_Moab; 1529 dm->ops->localtoglobalend = DMLocalToGlobalEnd_Moab; 1530 dm->ops->destroy = DMDestroy_Moab; 1531 dm->ops->createsubdm = NULL /* DMCreateSubDM_Moab */; 1532 dm->ops->getdimpoints = NULL /* DMGetDimPoints_Moab */; 1533 dm->ops->locatepoints = NULL /* DMLocatePoints_Moab */; 1534 PetscFunctionReturn(0); 1535 } 1536 1537 1538 PETSC_EXTERN PetscErrorCode DMClone_Moab(DM dm, DM *newdm) 1539 { 1540 PetscErrorCode ierr; 1541 1542 PetscFunctionBegin; 1543 ierr = PetscObjectChangeTypeName((PetscObject) * newdm, DMMOAB);CHKERRQ(ierr); 1544 1545 /* get all the necessary handles from the private DM object */ 1546 (*newdm)->data = (DM_Moab*) dm->data; 1547 ((DM_Moab*)dm->data)->refct++; 1548 1549 ierr = DMInitialize_Moab(*newdm);CHKERRQ(ierr); 1550 PetscFunctionReturn(0); 1551 } 1552 1553 1554 PETSC_EXTERN PetscErrorCode DMCreate_Moab(DM dm) 1555 { 1556 PetscErrorCode ierr; 1557 1558 PetscFunctionBegin; 1559 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1560 ierr = PetscNewLog(dm, (DM_Moab**)&dm->data);CHKERRQ(ierr); 1561 1562 ((DM_Moab*)dm->data)->bs = 1; 1563 ((DM_Moab*)dm->data)->numFields = 1; 1564 ((DM_Moab*)dm->data)->n = 0; 1565 ((DM_Moab*)dm->data)->nloc = 0; 1566 ((DM_Moab*)dm->data)->nghost = 0; 1567 ((DM_Moab*)dm->data)->nele = 0; 1568 ((DM_Moab*)dm->data)->neleloc = 0; 1569 ((DM_Moab*)dm->data)->neleghost = 0; 1570 ((DM_Moab*)dm->data)->ltog_map = NULL; 1571 ((DM_Moab*)dm->data)->ltog_sendrecv = NULL; 1572 1573 ((DM_Moab*)dm->data)->refct = 1; 1574 ((DM_Moab*)dm->data)->parent = NULL; 1575 ((DM_Moab*)dm->data)->vlocal = new moab::Range(); 1576 ((DM_Moab*)dm->data)->vowned = new moab::Range(); 1577 ((DM_Moab*)dm->data)->vghost = new moab::Range(); 1578 ((DM_Moab*)dm->data)->elocal = new moab::Range(); 1579 ((DM_Moab*)dm->data)->eghost = new moab::Range(); 1580 1581 ierr = DMInitialize_Moab(dm);CHKERRQ(ierr); 1582 PetscFunctionReturn(0); 1583 } 1584 1585