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 #undef __FUNCT__ 617 #define __FUNCT__ "DMMoabGetHierarchyLevel" 618 /*@ 619 DMMoabGetHierarchyLevel - Get the current level of the mesh hierarchy 620 generated through uniform refinement. 621 622 Collective on DM 623 624 Input Parameter: 625 . dm - The DMMoab object being set 626 627 Output Parameter: 628 . nvg - The current mesh hierarchy level 629 630 Level: beginner 631 632 .keywords: DMMoab, multigrid 633 @*/ 634 PetscErrorCode DMMoabGetHierarchyLevel(DM dm, PetscInt *nlevel) 635 { 636 PetscFunctionBegin; 637 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 638 if (nlevel) *nlevel = ((DM_Moab*)dm->data)->hlevel; 639 PetscFunctionReturn(0); 640 } 641 642 643 #undef __FUNCT__ 644 #define __FUNCT__ "DMMoabGetMaterialBlock" 645 /*@ 646 DMMoabGetMaterialBlock - Get the material ID corresponding to the current entity of the DM Mesh 647 648 Collective on MPI_Comm 649 650 Input Parameter: 651 . dm - The DMMoab object 652 . ehandle - The element entity handle 653 654 Output Parameter: 655 . mat - The material ID for the current entity 656 657 Level: beginner 658 659 .keywords: DMMoab, create 660 @*/ 661 PetscErrorCode DMMoabGetMaterialBlock(DM dm, const moab::EntityHandle ehandle, PetscInt *mat) 662 { 663 DM_Moab *dmmoab; 664 moab::ErrorCode merr; 665 666 PetscFunctionBegin; 667 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 668 if (*mat) { 669 dmmoab = (DM_Moab*)(dm)->data; 670 merr = dmmoab->mbiface->tag_get_data(dmmoab->material_tag, &ehandle, 1, mat); MBERRNM(merr); 671 } 672 PetscFunctionReturn(0); 673 } 674 675 676 /*@ 677 DMMoabGetVertexCoordinates - Get the coordinates corresponding to the requested vertex entities 678 679 Collective on MPI_Comm 680 681 Input Parameter: 682 . dm - The DMMoab object 683 . nconn - Number of entities whose coordinates are needed 684 . conn - The vertex entity handles 685 686 Output Parameter: 687 . vpos - The coordinates of the requested vertex entities 688 689 Level: beginner 690 691 .seealso: DMMoabGetVertexConnectivity() 692 @*/ 693 PetscErrorCode DMMoabGetVertexCoordinates(DM dm, PetscInt nconn, const moab::EntityHandle *conn, PetscReal *vpos) 694 { 695 DM_Moab *dmmoab; 696 moab::ErrorCode merr; 697 698 PetscFunctionBegin; 699 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 700 PetscValidPointer(conn, 3); 701 PetscValidPointer(vpos, 4); 702 dmmoab = (DM_Moab*)(dm)->data; 703 704 /* Get connectivity information in MOAB canonical ordering */ 705 if (dmmoab->hlevel) { 706 merr = dmmoab->hierarchy->get_coordinates(const_cast<moab::EntityHandle*>(conn), nconn, dmmoab->hlevel, vpos);MBERRNM(merr); 707 } 708 else { 709 merr = dmmoab->mbiface->get_coords(conn, nconn, vpos);MBERRNM(merr); 710 } 711 PetscFunctionReturn(0); 712 } 713 714 715 /*@ 716 DMMoabGetVertexConnectivity - Get the vertex adjacency for the given entity 717 718 Collective on MPI_Comm 719 720 Input Parameter: 721 . dm - The DMMoab object 722 . vhandle - Vertex entity handle 723 724 Output Parameter: 725 . nconn - Number of entities whose coordinates are needed 726 . conn - The vertex entity handles 727 728 Level: beginner 729 730 .seealso: DMMoabGetVertexCoordinates(), DMMoabRestoreVertexConnectivity() 731 @*/ 732 PetscErrorCode DMMoabGetVertexConnectivity(DM dm, moab::EntityHandle vhandle, PetscInt* nconn, moab::EntityHandle **conn) 733 { 734 DM_Moab *dmmoab; 735 std::vector<moab::EntityHandle> adj_entities, connect; 736 PetscErrorCode ierr; 737 moab::ErrorCode merr; 738 739 PetscFunctionBegin; 740 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 741 PetscValidPointer(conn, 4); 742 dmmoab = (DM_Moab*)(dm)->data; 743 744 /* Get connectivity information in MOAB canonical ordering */ 745 merr = dmmoab->mbiface->get_adjacencies(&vhandle, 1, 1, true, adj_entities, moab::Interface::UNION); MBERRNM(merr); 746 merr = dmmoab->mbiface->get_connectivity(&adj_entities[0], adj_entities.size(), connect); MBERRNM(merr); 747 748 if (conn) { 749 ierr = PetscMalloc(sizeof(moab::EntityHandle) * connect.size(), conn);CHKERRQ(ierr); 750 ierr = PetscMemcpy(*conn, &connect[0], sizeof(moab::EntityHandle) * connect.size());CHKERRQ(ierr); 751 } 752 if (nconn) *nconn = connect.size(); 753 PetscFunctionReturn(0); 754 } 755 756 757 /*@ 758 DMMoabRestoreVertexConnectivity - Restore the vertex connectivity for the given entity 759 760 Collective on MPI_Comm 761 762 Input Parameter: 763 . dm - The DMMoab object 764 . vhandle - Vertex entity handle 765 . nconn - Number of entities whose coordinates are needed 766 . conn - The vertex entity handles 767 768 Level: beginner 769 770 .seealso: DMMoabGetVertexCoordinates(), DMMoabGetVertexConnectivity() 771 @*/ 772 PetscErrorCode DMMoabRestoreVertexConnectivity(DM dm, moab::EntityHandle ehandle, PetscInt* nconn, moab::EntityHandle **conn) 773 { 774 PetscErrorCode ierr; 775 776 PetscFunctionBegin; 777 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 778 PetscValidPointer(conn, 4); 779 780 if (conn) { 781 ierr = PetscFree(*conn);CHKERRQ(ierr); 782 } 783 if (nconn) *nconn = 0; 784 PetscFunctionReturn(0); 785 } 786 787 788 /*@ 789 DMMoabGetElementConnectivity - Get the vertex adjacency for the given entity 790 791 Collective on MPI_Comm 792 793 Input Parameter: 794 . dm - The DMMoab object 795 . ehandle - Vertex entity handle 796 797 Output Parameter: 798 . nconn - Number of entities whose coordinates are needed 799 . conn - The vertex entity handles 800 801 Level: beginner 802 803 .seealso: DMMoabGetVertexCoordinates(), DMMoabGetVertexConnectivity(), DMMoabRestoreVertexConnectivity() 804 @*/ 805 PetscErrorCode DMMoabGetElementConnectivity(DM dm, moab::EntityHandle ehandle, PetscInt* nconn, const moab::EntityHandle **conn) 806 { 807 DM_Moab *dmmoab; 808 const moab::EntityHandle *connect; 809 std::vector<moab::EntityHandle> vconn; 810 moab::ErrorCode merr; 811 PetscInt nnodes; 812 813 PetscFunctionBegin; 814 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 815 PetscValidPointer(conn, 4); 816 dmmoab = (DM_Moab*)(dm)->data; 817 818 /* Get connectivity information in MOAB canonical ordering */ 819 merr = dmmoab->mbiface->get_connectivity(ehandle, connect, nnodes); MBERRNM(merr); 820 if (conn) *conn = connect; 821 if (nconn) *nconn = nnodes; 822 PetscFunctionReturn(0); 823 } 824 825 826 /*@ 827 DMMoabIsEntityOnBoundary - Check whether a given entity is on the boundary (vertex, edge, face, element) 828 829 Collective on MPI_Comm 830 831 Input Parameter: 832 . dm - The DMMoab object 833 . ent - Entity handle 834 835 Output Parameter: 836 . ent_on_boundary - PETSC_TRUE if entity on boundary; PETSC_FALSE otherwise 837 838 Level: beginner 839 840 .seealso: DMMoabCheckBoundaryVertices() 841 @*/ 842 PetscErrorCode DMMoabIsEntityOnBoundary(DM dm, const moab::EntityHandle ent, PetscBool* ent_on_boundary) 843 { 844 moab::EntityType etype; 845 DM_Moab *dmmoab; 846 PetscInt edim; 847 848 PetscFunctionBegin; 849 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 850 PetscValidPointer(ent_on_boundary, 3); 851 dmmoab = (DM_Moab*)(dm)->data; 852 853 /* get the entity type and handle accordingly */ 854 etype = dmmoab->mbiface->type_from_handle(ent); 855 if (etype >= moab::MBPOLYHEDRON) SETERRQ1(PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE, "Entity type on the boundary skin is invalid. EntityType = %D\n", etype); 856 857 /* get the entity dimension */ 858 edim = dmmoab->mbiface->dimension_from_handle(ent); 859 860 *ent_on_boundary = PETSC_FALSE; 861 if (etype == moab::MBVERTEX && edim == 0) { 862 *ent_on_boundary = ((dmmoab->bndyvtx->index(ent) >= 0) ? PETSC_TRUE : PETSC_FALSE); 863 } 864 else { 865 if (edim == dmmoab->dim) { /* check the higher-dimensional elements first */ 866 if (dmmoab->bndyelems->index(ent) >= 0) *ent_on_boundary = PETSC_TRUE; 867 } 868 else { /* next check the lower-dimensional faces */ 869 if (dmmoab->bndyfaces->index(ent) >= 0) *ent_on_boundary = PETSC_TRUE; 870 } 871 } 872 PetscFunctionReturn(0); 873 } 874 875 876 /*@ 877 DMMoabIsEntityOnBoundary - Check whether a given entity is on the boundary (vertex, edge, face, element) 878 879 Input Parameter: 880 . dm - The DMMoab object 881 . nconn - Number of handles 882 . cnt - Array of entity handles 883 884 Output Parameter: 885 . isbdvtx - Array of boundary markers - PETSC_TRUE if entity on boundary; PETSC_FALSE otherwise 886 887 Level: beginner 888 889 .seealso: DMMoabIsEntityOnBoundary() 890 @*/ 891 PetscErrorCode DMMoabCheckBoundaryVertices(DM dm, PetscInt nconn, const moab::EntityHandle *cnt, PetscBool* isbdvtx) 892 { 893 DM_Moab *dmmoab; 894 PetscInt i; 895 896 PetscFunctionBegin; 897 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 898 PetscValidPointer(cnt, 3); 899 PetscValidPointer(isbdvtx, 4); 900 dmmoab = (DM_Moab*)(dm)->data; 901 902 for (i = 0; i < nconn; ++i) { 903 isbdvtx[i] = (dmmoab->bndyvtx->index(cnt[i]) >= 0 ? PETSC_TRUE : PETSC_FALSE); 904 } 905 PetscFunctionReturn(0); 906 } 907 908 909 /*@ 910 DMMoabGetBoundaryMarkers - Return references to the vertices, faces, elements on the boundary 911 912 Input Parameter: 913 . dm - The DMMoab object 914 915 Output Parameter: 916 . bdvtx - Boundary vertices 917 . bdelems - Boundary elements 918 . bdfaces - Boundary faces 919 920 Level: beginner 921 922 .seealso: DMMoabCheckBoundaryVertices(), DMMoabIsEntityOnBoundary() 923 @*/ 924 PetscErrorCode DMMoabGetBoundaryMarkers(DM dm, const moab::Range **bdvtx, const moab::Range** bdelems, const moab::Range** bdfaces) 925 { 926 DM_Moab *dmmoab; 927 928 PetscFunctionBegin; 929 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 930 dmmoab = (DM_Moab*)(dm)->data; 931 932 if (bdvtx) *bdvtx = dmmoab->bndyvtx; 933 if (bdfaces) *bdfaces = dmmoab->bndyfaces; 934 if (bdelems) *bdfaces = dmmoab->bndyelems; 935 PetscFunctionReturn(0); 936 } 937 938 939 PETSC_EXTERN PetscErrorCode DMDestroy_Moab(DM dm) 940 { 941 PetscErrorCode ierr; 942 PetscInt i; 943 moab::ErrorCode merr; 944 DM_Moab *dmmoab = (DM_Moab*)dm->data; 945 946 PetscFunctionBegin; 947 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 948 949 dmmoab->refct--; 950 if (!dmmoab->refct) { 951 delete dmmoab->vlocal; 952 delete dmmoab->vowned; 953 delete dmmoab->vghost; 954 delete dmmoab->elocal; 955 delete dmmoab->eghost; 956 delete dmmoab->bndyvtx; 957 delete dmmoab->bndyfaces; 958 delete dmmoab->bndyelems; 959 960 ierr = PetscFree(dmmoab->gsindices);CHKERRQ(ierr); 961 ierr = PetscFree2(dmmoab->gidmap, dmmoab->lidmap);CHKERRQ(ierr); 962 ierr = PetscFree(dmmoab->dfill);CHKERRQ(ierr); 963 ierr = PetscFree(dmmoab->ofill);CHKERRQ(ierr); 964 ierr = PetscFree(dmmoab->materials);CHKERRQ(ierr); 965 if (dmmoab->fieldNames) { 966 for (i = 0; i < dmmoab->numFields; i++) { 967 ierr = PetscFree(dmmoab->fieldNames[i]);CHKERRQ(ierr); 968 } 969 ierr = PetscFree(dmmoab->fieldNames);CHKERRQ(ierr); 970 } 971 972 if (dmmoab->nhlevels) { 973 ierr = PetscFree(dmmoab->hsets);CHKERRQ(ierr); 974 dmmoab->nhlevels = 0; 975 if (!dmmoab->hlevel && dmmoab->icreatedinstance) delete dmmoab->hierarchy; 976 dmmoab->hierarchy = NULL; 977 } 978 979 if (dmmoab->icreatedinstance) { 980 delete dmmoab->pcomm; 981 merr = dmmoab->mbiface->delete_mesh(); MBERRNM(merr); 982 delete dmmoab->mbiface; 983 } 984 dmmoab->mbiface = NULL; 985 #ifdef MOAB_HAVE_MPI 986 dmmoab->pcomm = NULL; 987 #endif 988 ierr = VecScatterDestroy(&dmmoab->ltog_sendrecv);CHKERRQ(ierr); 989 ierr = ISLocalToGlobalMappingDestroy(&dmmoab->ltog_map);CHKERRQ(ierr); 990 ierr = PetscFree(dm->data);CHKERRQ(ierr); 991 } 992 PetscFunctionReturn(0); 993 } 994 995 996 #undef __FUNCT__ 997 #define __FUNCT__ "DMSetFromOptions_Moab" 998 PETSC_EXTERN PetscErrorCode DMSetFromOptions_Moab(PetscOptionItems *PetscOptionsObject, DM dm) 999 { 1000 PetscErrorCode ierr; 1001 DM_Moab *dmmoab = (DM_Moab*)dm->data; 1002 1003 PetscFunctionBegin; 1004 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1005 ierr = PetscOptionsHead(PetscOptionsObject, "DMMoab Options");CHKERRQ(ierr); 1006 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); 1007 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); 1008 /* TODO: typically, the read options are needed before a DM is completely created and available in which case, the options wont be available ?? */ 1009 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); 1010 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); 1011 ierr = PetscOptionsEnum("-dm_moab_read_mode", "MOAB parallel read mode", "DMView", MoabReadModes, (PetscEnum)dmmoab->read_mode, (PetscEnum*)&dmmoab->read_mode, NULL);CHKERRQ(ierr); 1012 ierr = PetscOptionsEnum("-dm_moab_write_mode", "MOAB parallel write mode", "DMView", MoabWriteModes, (PetscEnum)dmmoab->write_mode, (PetscEnum*)&dmmoab->write_mode, NULL);CHKERRQ(ierr); 1013 PetscFunctionReturn(0); 1014 } 1015 1016 1017 PETSC_EXTERN PetscErrorCode DMSetUp_Moab(DM dm) 1018 { 1019 PetscErrorCode ierr; 1020 moab::ErrorCode merr; 1021 Vec local, global; 1022 IS from, to; 1023 moab::Range::iterator iter; 1024 PetscInt i, j, f, bs, vent, totsize, *lgmap; 1025 DM_Moab *dmmoab = (DM_Moab*)dm->data; 1026 moab::Range adjs; 1027 1028 PetscFunctionBegin; 1029 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1030 /* Get the local and shared vertices and cache it */ 1031 if (dmmoab->mbiface == NULL) SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ORDER, "Set the MOAB Interface before calling SetUp."); 1032 #ifdef MOAB_HAVE_MPI 1033 if (dmmoab->pcomm == NULL) SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ORDER, "Set the MOAB ParallelComm object before calling SetUp."); 1034 #endif 1035 1036 /* Get the entities recursively in the current part of the mesh, if user did not set the local vertices explicitly */ 1037 if (dmmoab->vlocal->empty()) 1038 { 1039 //merr = dmmoab->mbiface->get_entities_by_type(dmmoab->fileset,moab::MBVERTEX,*dmmoab->vlocal,true);MBERRNM(merr); 1040 merr = dmmoab->mbiface->get_entities_by_dimension(dmmoab->fileset, 0, *dmmoab->vlocal, false); MBERRNM(merr); 1041 1042 #ifdef MOAB_HAVE_MPI 1043 /* filter based on parallel status */ 1044 merr = dmmoab->pcomm->filter_pstatus(*dmmoab->vlocal, PSTATUS_NOT_OWNED, PSTATUS_NOT, -1, dmmoab->vowned); MBERRNM(merr); 1045 1046 /* filter all the non-owned and shared entities out of the list */ 1047 // *dmmoab->vghost = moab::subtract(*dmmoab->vlocal, *dmmoab->vowned); 1048 adjs = moab::subtract(*dmmoab->vlocal, *dmmoab->vowned); 1049 merr = dmmoab->pcomm->filter_pstatus(adjs, PSTATUS_GHOST | PSTATUS_INTERFACE, PSTATUS_OR, -1, dmmoab->vghost); MBERRNM(merr); 1050 adjs = moab::subtract(adjs, *dmmoab->vghost); 1051 *dmmoab->vlocal = moab::subtract(*dmmoab->vlocal, adjs); 1052 #else 1053 *dmmoab->vowned = *dmmoab->vlocal; 1054 #endif 1055 1056 /* compute and cache the sizes of local and ghosted entities */ 1057 dmmoab->nloc = dmmoab->vowned->size(); 1058 dmmoab->nghost = dmmoab->vghost->size(); 1059 1060 #ifdef MOAB_HAVE_MPI 1061 ierr = MPIU_Allreduce(&dmmoab->nloc, &dmmoab->n, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm);CHKERRQ(ierr); 1062 PetscInfo4(NULL, "Filset ID: %u, Vertices: local - %D, owned - %D, ghosted - %D.\n", dmmoab->fileset, dmmoab->vlocal->size(), dmmoab->nloc, dmmoab->nghost); 1063 #else 1064 dmmoab->n = dmmoab->nloc; 1065 #endif 1066 } 1067 1068 { 1069 /* get the information about the local elements in the mesh */ 1070 dmmoab->eghost->clear(); 1071 1072 /* first decipher the leading dimension */ 1073 for (i = 3; i > 0; i--) { 1074 dmmoab->elocal->clear(); 1075 merr = dmmoab->mbiface->get_entities_by_dimension(dmmoab->fileset, i, *dmmoab->elocal, false); MBERRNM(merr); 1076 1077 /* store the current mesh dimension */ 1078 if (dmmoab->elocal->size()) { 1079 dmmoab->dim = i; 1080 break; 1081 } 1082 } 1083 1084 ierr = DMSetDimension(dm, dmmoab->dim);CHKERRQ(ierr); 1085 1086 #ifdef MOAB_HAVE_MPI 1087 /* filter the ghosted and owned element list */ 1088 *dmmoab->eghost = *dmmoab->elocal; 1089 merr = dmmoab->pcomm->filter_pstatus(*dmmoab->elocal, PSTATUS_NOT_OWNED, PSTATUS_NOT); MBERRNM(merr); 1090 *dmmoab->eghost = moab::subtract(*dmmoab->eghost, *dmmoab->elocal); 1091 #endif 1092 1093 dmmoab->neleloc = dmmoab->elocal->size(); 1094 dmmoab->neleghost = dmmoab->eghost->size(); 1095 1096 #ifdef MOAB_HAVE_MPI 1097 ierr = MPIU_Allreduce(&dmmoab->neleloc, &dmmoab->nele, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm);CHKERRQ(ierr); 1098 PetscInfo3(NULL, "%d-dim elements: owned - %D, ghosted - %D.\n", dmmoab->dim, dmmoab->neleloc, dmmoab->neleghost); 1099 #else 1100 dmmoab->nele = dmmoab->neleloc; 1101 #endif 1102 } 1103 1104 bs = dmmoab->bs; 1105 if (!dmmoab->ltog_tag) { 1106 /* Get the global ID tag. The global ID tag is applied to each 1107 vertex. It acts as an global identifier which MOAB uses to 1108 assemble the individual pieces of the mesh */ 1109 merr = dmmoab->mbiface->tag_get_handle(GLOBAL_ID_TAG_NAME, dmmoab->ltog_tag); MBERRNM(merr); 1110 } 1111 1112 totsize = dmmoab->vlocal->size(); 1113 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); 1114 ierr = PetscCalloc1(totsize, &dmmoab->gsindices);CHKERRQ(ierr); 1115 { 1116 /* first get the local indices */ 1117 merr = dmmoab->mbiface->tag_get_data(dmmoab->ltog_tag, *dmmoab->vowned, &dmmoab->gsindices[0]); MBERRNM(merr); 1118 if (dmmoab->nghost) { /* next get the ghosted indices */ 1119 merr = dmmoab->mbiface->tag_get_data(dmmoab->ltog_tag, *dmmoab->vghost, &dmmoab->gsindices[dmmoab->nloc]); MBERRNM(merr); 1120 } 1121 1122 /* find out the local and global minima of GLOBAL_ID */ 1123 dmmoab->lminmax[0] = dmmoab->lminmax[1] = dmmoab->gsindices[0]; 1124 for (i = 0; i < totsize; ++i) { 1125 if (dmmoab->lminmax[0] > dmmoab->gsindices[i]) dmmoab->lminmax[0] = dmmoab->gsindices[i]; 1126 if (dmmoab->lminmax[1] < dmmoab->gsindices[i]) dmmoab->lminmax[1] = dmmoab->gsindices[i]; 1127 } 1128 1129 ierr = MPIU_Allreduce(&dmmoab->lminmax[0], &dmmoab->gminmax[0], 1, MPI_INT, MPI_MIN, ((PetscObject)dm)->comm);CHKERRQ(ierr); 1130 ierr = MPIU_Allreduce(&dmmoab->lminmax[1], &dmmoab->gminmax[1], 1, MPI_INT, MPI_MAX, ((PetscObject)dm)->comm);CHKERRQ(ierr); 1131 1132 /* set the GID map */ 1133 for (i = 0; i < totsize; ++i) { 1134 dmmoab->gsindices[i] -= dmmoab->gminmax[0]; /* zero based index needed for IS */ 1135 1136 } 1137 dmmoab->lminmax[0] -= dmmoab->gminmax[0]; 1138 dmmoab->lminmax[1] -= dmmoab->gminmax[0]; 1139 1140 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]); 1141 } 1142 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); 1143 1144 { 1145 dmmoab->seqstart = dmmoab->mbiface->id_from_handle(dmmoab->vlocal->front()); 1146 dmmoab->seqend = dmmoab->mbiface->id_from_handle(dmmoab->vlocal->back()); 1147 PetscInfo2(NULL, "SEQUENCE: Local [min, max] - [%D, %D]\n", dmmoab->seqstart, dmmoab->seqend); 1148 1149 ierr = PetscMalloc2(dmmoab->seqend - dmmoab->seqstart + 1, &dmmoab->gidmap, dmmoab->seqend - dmmoab->seqstart + 1, &dmmoab->lidmap);CHKERRQ(ierr); 1150 ierr = PetscMalloc1(totsize * dmmoab->numFields, &lgmap);CHKERRQ(ierr); 1151 1152 i = j = 0; 1153 /* set the owned vertex data first */ 1154 for (moab::Range::iterator iter = dmmoab->vowned->begin(); iter != dmmoab->vowned->end(); iter++, i++) { 1155 vent = dmmoab->mbiface->id_from_handle(*iter) - dmmoab->seqstart; 1156 dmmoab->gidmap[vent] = dmmoab->gsindices[i]; 1157 dmmoab->lidmap[vent] = i; 1158 for (f = 0; f < dmmoab->numFields; f++, j++) { 1159 lgmap[j] = (bs > 1 ? dmmoab->gsindices[i] * dmmoab->numFields + f : totsize * f + dmmoab->gsindices[i]); 1160 } 1161 } 1162 /* next arrange all the ghosted data information */ 1163 for (moab::Range::iterator iter = dmmoab->vghost->begin(); iter != dmmoab->vghost->end(); iter++, i++) { 1164 vent = dmmoab->mbiface->id_from_handle(*iter) - dmmoab->seqstart; 1165 dmmoab->gidmap[vent] = dmmoab->gsindices[i]; 1166 dmmoab->lidmap[vent] = i; 1167 for (f = 0; f < dmmoab->numFields; f++, j++) { 1168 lgmap[j] = (bs > 1 ? dmmoab->gsindices[i] * dmmoab->numFields + f : totsize * f + dmmoab->gsindices[i]); 1169 } 1170 } 1171 1172 /* We need to create the Global to Local Vector Scatter Contexts 1173 1) First create a local and global vector 1174 2) Create a local and global IS 1175 3) Create VecScatter and LtoGMapping objects 1176 4) Cleanup the IS and Vec objects 1177 */ 1178 ierr = DMCreateGlobalVector(dm, &global);CHKERRQ(ierr); 1179 ierr = DMCreateLocalVector(dm, &local);CHKERRQ(ierr); 1180 1181 ierr = VecGetOwnershipRange(global, &dmmoab->vstart, &dmmoab->vend);CHKERRQ(ierr); 1182 1183 /* global to local must retrieve ghost points */ 1184 ierr = ISCreateStride(((PetscObject)dm)->comm, dmmoab->nloc * dmmoab->numFields, dmmoab->vstart, 1, &from);CHKERRQ(ierr); 1185 ierr = ISSetBlockSize(from, bs);CHKERRQ(ierr); 1186 1187 ierr = ISCreateGeneral(((PetscObject)dm)->comm, dmmoab->nloc * dmmoab->numFields, &lgmap[0], PETSC_COPY_VALUES, &to);CHKERRQ(ierr); 1188 ierr = ISSetBlockSize(to, bs);CHKERRQ(ierr); 1189 1190 if (!dmmoab->ltog_map) { 1191 /* create to the local to global mapping for vectors in order to use VecSetValuesLocal */ 1192 ierr = ISLocalToGlobalMappingCreate(((PetscObject)dm)->comm, dmmoab->bs, totsize * dmmoab->numFields, lgmap, 1193 PETSC_COPY_VALUES, &dmmoab->ltog_map);CHKERRQ(ierr); 1194 } 1195 1196 /* now create the scatter object from local to global vector */ 1197 ierr = VecScatterCreate(local, from, global, to, &dmmoab->ltog_sendrecv);CHKERRQ(ierr); 1198 1199 /* clean up IS, Vec */ 1200 ierr = PetscFree(lgmap);CHKERRQ(ierr); 1201 ierr = ISDestroy(&from);CHKERRQ(ierr); 1202 ierr = ISDestroy(&to);CHKERRQ(ierr); 1203 ierr = VecDestroy(&local);CHKERRQ(ierr); 1204 ierr = VecDestroy(&global);CHKERRQ(ierr); 1205 } 1206 1207 dmmoab->bndyvtx = new moab::Range(); 1208 dmmoab->bndyfaces = new moab::Range(); 1209 dmmoab->bndyelems = new moab::Range(); 1210 /* skin the boundary and store nodes */ 1211 if (!dmmoab->hlevel) { 1212 /* get the skin vertices of boundary faces for the current partition and then filter 1213 the local, boundary faces, vertices and elements alone via PSTATUS flags; 1214 this should not give us any ghosted boundary, but if user needs such a functionality 1215 it would be easy to add it based on the find_skin query below */ 1216 moab::Skinner skinner(dmmoab->mbiface); 1217 1218 /* get the entities on the skin - only the faces */ 1219 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 1220 1221 #ifdef MOAB_HAVE_MPI 1222 /* filter all the non-owned and shared entities out of the list */ 1223 merr = dmmoab->pcomm->filter_pstatus(*dmmoab->bndyfaces, PSTATUS_NOT_OWNED, PSTATUS_NOT); MBERRNM(merr); 1224 merr = dmmoab->pcomm->filter_pstatus(*dmmoab->bndyfaces, PSTATUS_INTERFACE, PSTATUS_NOT); MBERRNM(merr); 1225 #endif 1226 1227 /* get all the nodes via connectivity and the parent elements via adjacency information */ 1228 merr = dmmoab->mbiface->get_connectivity(*dmmoab->bndyfaces, *dmmoab->bndyvtx, false); MBERRNM(ierr); 1229 merr = dmmoab->mbiface->get_adjacencies(*dmmoab->bndyvtx, dmmoab->dim, false, *dmmoab->bndyelems, moab::Interface::UNION); MBERRNM(ierr); 1230 } 1231 else { 1232 /* Let us query the hierarchy manager and get the results directly for this level */ 1233 for (moab::Range::iterator iter = dmmoab->elocal->begin(); iter != dmmoab->elocal->end(); iter++) { 1234 moab::EntityHandle elemHandle = *iter; 1235 if (dmmoab->hierarchy->is_entity_on_boundary(elemHandle)) { 1236 dmmoab->bndyelems->insert(elemHandle); 1237 /* For this boundary element, query the vertices and add them to the list */ 1238 std::vector<moab::EntityHandle> connect; 1239 merr = dmmoab->hierarchy->get_connectivity(elemHandle, dmmoab->hlevel, connect); MBERRNM(ierr); 1240 for (unsigned iv=0; iv < connect.size(); ++iv) 1241 if (dmmoab->hierarchy->is_entity_on_boundary(connect[iv])) 1242 dmmoab->bndyvtx->insert(connect[iv]); 1243 /* Next, let us query the boundary faces and add them also to the list */ 1244 std::vector<moab::EntityHandle> faces; 1245 merr = dmmoab->hierarchy->get_adjacencies(elemHandle, dmmoab->dim-1, faces); MBERRNM(ierr); 1246 for (unsigned ifa=0; ifa < faces.size(); ++ifa) 1247 if (dmmoab->hierarchy->is_entity_on_boundary(faces[ifa])) 1248 dmmoab->bndyfaces->insert(faces[ifa]); 1249 } 1250 } 1251 #ifdef MOAB_HAVE_MPI 1252 /* filter all the non-owned and shared entities out of the list */ 1253 // merr = dmmoab->pcomm->filter_pstatus(*dmmoab->bndyfaces, PSTATUS_NOT_OWNED, PSTATUS_NOT); MBERRNM(merr); 1254 // merr = dmmoab->pcomm->filter_pstatus(*dmmoab->bndyfaces, PSTATUS_INTERFACE, PSTATUS_NOT); MBERRNM(merr); 1255 merr = dmmoab->pcomm->filter_pstatus(*dmmoab->bndyvtx, PSTATUS_NOT_OWNED, PSTATUS_NOT); MBERRNM(merr); 1256 merr = dmmoab->pcomm->filter_pstatus(*dmmoab->bndyfaces, PSTATUS_NOT_OWNED, PSTATUS_NOT); MBERRNM(merr); 1257 merr = dmmoab->pcomm->filter_pstatus(*dmmoab->bndyelems, PSTATUS_NOT_OWNED, PSTATUS_NOT); MBERRNM(merr); 1258 #endif 1259 1260 } 1261 PetscInfo3(NULL, "Found %D boundary vertices, %D boundary faces and %D boundary elements.\n", dmmoab->bndyvtx->size(), dmmoab->bndyfaces->size(), dmmoab->bndyelems->size()); 1262 PetscFunctionReturn(0); 1263 } 1264 1265 1266 #undef __FUNCT__ 1267 #define __FUNCT__ "DMMoabCreateVertices" 1268 /*@ 1269 DMMoabCreateVertices - Creates and adds several vertices to the primary set represented by the DM. 1270 1271 Collective on MPI_Comm 1272 1273 Input Parameters: 1274 + dm - The DM object 1275 . type - The type of element to create and add (Edge/Tri/Quad/Tet/Hex/Prism/Pyramid/Polygon/Polyhedra) 1276 . conn - The connectivity of the element 1277 . nverts - The number of vertices that form the element 1278 1279 Output Parameter: 1280 . overts - The list of vertices that were created (can be NULL) 1281 1282 Level: beginner 1283 1284 .keywords: DM, create vertices 1285 1286 .seealso: DMMoabCreateSubmesh(), DMMoabCreateElement() 1287 @*/ 1288 PetscErrorCode DMMoabCreateVertices(DM dm, const PetscReal* coords, PetscInt nverts, moab::Range* overts) 1289 { 1290 moab::ErrorCode merr; 1291 DM_Moab *dmmoab; 1292 moab::Range verts; 1293 1294 PetscFunctionBegin; 1295 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1296 PetscValidPointer(coords, 2); 1297 1298 dmmoab = (DM_Moab*) dm->data; 1299 1300 /* Insert new points */ 1301 merr = dmmoab->mbiface->create_vertices(&coords[0], nverts, verts); MBERRNM(merr); 1302 merr = dmmoab->mbiface->add_entities(dmmoab->fileset, verts); MBERRNM(merr); 1303 1304 if (overts) *overts = verts; 1305 PetscFunctionReturn(0); 1306 } 1307 1308 1309 #undef __FUNCT__ 1310 #define __FUNCT__ "DMMoabCreateElement" 1311 /*@ 1312 DMMoabCreateElement - Adds an element of specified type to the primary set represented by the DM. 1313 1314 Collective on MPI_Comm 1315 1316 Input Parameters: 1317 + dm - The DM object 1318 . type - The type of element to create and add (Edge/Tri/Quad/Tet/Hex/Prism/Pyramid/Polygon/Polyhedra) 1319 . conn - The connectivity of the element 1320 . nverts - The number of vertices that form the element 1321 1322 Output Parameter: 1323 . oelem - The handle to the element created and added to the DM object 1324 1325 Level: beginner 1326 1327 .keywords: DM, create element 1328 1329 .seealso: DMMoabCreateSubmesh(), DMMoabCreateVertices() 1330 @*/ 1331 PetscErrorCode DMMoabCreateElement(DM dm, const moab::EntityType type, const moab::EntityHandle* conn, PetscInt nverts, moab::EntityHandle* oelem) 1332 { 1333 moab::ErrorCode merr; 1334 DM_Moab *dmmoab; 1335 moab::EntityHandle elem; 1336 1337 PetscFunctionBegin; 1338 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1339 PetscValidPointer(conn, 3); 1340 1341 dmmoab = (DM_Moab*) dm->data; 1342 1343 /* Insert new element */ 1344 merr = dmmoab->mbiface->create_element(type, conn, nverts, elem); MBERRNM(merr); 1345 merr = dmmoab->mbiface->add_entities(dmmoab->fileset, &elem, 1); MBERRNM(merr); 1346 1347 if (oelem) *oelem = elem; 1348 PetscFunctionReturn(0); 1349 } 1350 1351 1352 #undef __FUNCT__ 1353 #define __FUNCT__ "DMMoabCreateSubmesh" 1354 /*@ 1355 DMMoabCreateSubmesh - Creates a sub-DM object with a set that contains all vertices/elements of the parent 1356 in addition to providing support for dynamic mesh modifications. This is useful for AMR calculations to 1357 create a DM object on a refined level. 1358 1359 Collective on MPI_Comm 1360 1361 Input Parameters: 1362 + dm - The DM object 1363 1364 Output Parameter: 1365 . newdm - The sub DM object with updated set information 1366 1367 Level: advanced 1368 1369 .keywords: DM, sub-DM 1370 1371 .seealso: DMCreate(), DMMoabCreateVertices(), DMMoabCreateElement() 1372 @*/ 1373 PetscErrorCode DMMoabCreateSubmesh(DM dm, DM *newdm) 1374 { 1375 DM_Moab *dmmoab; 1376 DM_Moab *ndmmoab; 1377 moab::ErrorCode merr; 1378 PetscErrorCode ierr; 1379 1380 PetscFunctionBegin; 1381 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1382 1383 dmmoab = (DM_Moab*) dm->data; 1384 1385 /* Create the basic DMMoab object and keep the default parameters created by DM impls */ 1386 ierr = DMMoabCreateMoab(((PetscObject)dm)->comm, dmmoab->mbiface, &dmmoab->ltog_tag, PETSC_NULL, newdm);CHKERRQ(ierr); 1387 1388 /* get all the necessary handles from the private DM object */ 1389 ndmmoab = (DM_Moab*) (*newdm)->data; 1390 1391 /* set the sub-mesh's parent DM reference */ 1392 ndmmoab->parent = &dm; 1393 1394 /* create a file set to associate all entities in current mesh */ 1395 merr = ndmmoab->mbiface->create_meshset(moab::MESHSET_SET, ndmmoab->fileset); MBERR("Creating file set failed", merr); 1396 1397 /* create a meshset and then add old fileset as child */ 1398 merr = ndmmoab->mbiface->add_entities(ndmmoab->fileset, *dmmoab->vlocal); MBERR("Adding child vertices to parent failed", merr); 1399 merr = ndmmoab->mbiface->add_entities(ndmmoab->fileset, *dmmoab->elocal); MBERR("Adding child elements to parent failed", merr); 1400 1401 /* preserve the field association between the parent and sub-mesh objects */ 1402 ierr = DMMoabSetFieldNames(*newdm, dmmoab->numFields, dmmoab->fieldNames);CHKERRQ(ierr); 1403 PetscFunctionReturn(0); 1404 } 1405 1406 1407 #undef __FUNCT__ 1408 #define __FUNCT__ "DMMoabView_Ascii" 1409 PETSC_EXTERN PetscErrorCode DMMoabView_Ascii(DM dm, PetscViewer viewer) 1410 { 1411 DM_Moab *dmmoab = (DM_Moab*)(dm)->data; 1412 const char *name; 1413 MPI_Comm comm; 1414 PetscMPIInt size; 1415 PetscErrorCode ierr; 1416 1417 PetscFunctionBegin; 1418 ierr = PetscObjectGetComm((PetscObject)dm, &comm);CHKERRQ(ierr); 1419 ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr); 1420 ierr = PetscObjectGetName((PetscObject) dm, &name);CHKERRQ(ierr); 1421 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1422 if (name) {ierr = PetscViewerASCIIPrintf(viewer, "%s in %D dimensions:\n", name, dmmoab->dim);CHKERRQ(ierr);} 1423 else {ierr = PetscViewerASCIIPrintf(viewer, "Mesh in %D dimensions:\n", dmmoab->dim);CHKERRQ(ierr);} 1424 /* print details about the global mesh */ 1425 { 1426 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1427 ierr = PetscViewerASCIIPrintf(viewer, "Sizes: cells=%D, vertices=%D, blocks=%D\n", dmmoab->nele, dmmoab->n, dmmoab->bs);CHKERRQ(ierr); 1428 /* print boundary data */ 1429 ierr = PetscViewerASCIIPrintf(viewer, "Boundary trace:\n", dmmoab->bndyelems->size(), dmmoab->bndyfaces->size(), dmmoab->bndyvtx->size());CHKERRQ(ierr); 1430 { 1431 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1432 ierr = PetscViewerASCIIPrintf(viewer, "cells=%D, faces=%D, vertices=%D\n", dmmoab->bndyelems->size(), dmmoab->bndyfaces->size(), dmmoab->bndyvtx->size());CHKERRQ(ierr); 1433 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1434 } 1435 /* print field data */ 1436 ierr = PetscViewerASCIIPrintf(viewer, "Fields: %D components\n", dmmoab->numFields);CHKERRQ(ierr); 1437 { 1438 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1439 for (int i = 0; i < dmmoab->numFields; ++i) { 1440 ierr = PetscViewerASCIIPrintf(viewer, "[%D] - %s\n", i, dmmoab->fieldNames[i]);CHKERRQ(ierr); 1441 } 1442 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1443 } 1444 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1445 } 1446 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1447 ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 1448 PetscFunctionReturn(0); 1449 } 1450 1451 #undef __FUNCT__ 1452 #define __FUNCT__ "DMMoabView_VTK" 1453 PETSC_EXTERN PetscErrorCode DMMoabView_VTK(DM dm, PetscViewer v) 1454 { 1455 PetscFunctionReturn(0); 1456 } 1457 1458 #undef __FUNCT__ 1459 #define __FUNCT__ "DMMoabView_HDF5" 1460 PETSC_EXTERN PetscErrorCode DMMoabView_HDF5(DM dm, PetscViewer v) 1461 { 1462 PetscFunctionReturn(0); 1463 } 1464 1465 #undef __FUNCT__ 1466 #define __FUNCT__ "DMView_Moab" 1467 PETSC_EXTERN PetscErrorCode DMView_Moab(DM dm, PetscViewer viewer) 1468 { 1469 PetscBool iascii, ishdf5, isvtk; 1470 PetscErrorCode ierr; 1471 1472 PetscFunctionBegin; 1473 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1474 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 1475 ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr); 1476 ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERVTK, &isvtk);CHKERRQ(ierr); 1477 ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 1478 if (iascii) { 1479 ierr = DMMoabView_Ascii(dm, viewer);CHKERRQ(ierr); 1480 } else if (ishdf5) { 1481 #if defined(PETSC_HAVE_HDF5) && defined(MOAB_HAVE_HDF5) 1482 ierr = PetscViewerPushFormat(viewer, PETSC_VIEWER_HDF5_VIZ);CHKERRQ(ierr); 1483 ierr = DMMoabView_HDF5(dm, viewer);CHKERRQ(ierr); 1484 ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 1485 #else 1486 SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 1487 #endif 1488 } 1489 else if (isvtk) { 1490 ierr = DMMoabView_VTK(dm, viewer);CHKERRQ(ierr); 1491 } 1492 PetscFunctionReturn(0); 1493 } 1494 1495 1496 #undef __FUNCT__ 1497 #define __FUNCT__ "DMInitialize_Moab" 1498 PETSC_EXTERN PetscErrorCode DMInitialize_Moab(DM dm) 1499 { 1500 PetscFunctionBegin; 1501 dm->ops->view = DMView_Moab; 1502 dm->ops->load = NULL /*DMLoad_Moab*/; 1503 dm->ops->setfromoptions = DMSetFromOptions_Moab; 1504 dm->ops->clone = DMClone_Moab; 1505 dm->ops->setup = DMSetUp_Moab; 1506 dm->ops->createdefaultsection = NULL; 1507 dm->ops->createdefaultconstraints = NULL; 1508 dm->ops->createglobalvector = DMCreateGlobalVector_Moab; 1509 dm->ops->createlocalvector = DMCreateLocalVector_Moab; 1510 dm->ops->getlocaltoglobalmapping = NULL; 1511 dm->ops->createfieldis = NULL; 1512 dm->ops->createcoordinatedm = NULL /*DMCreateCoordinateDM_Moab*/; 1513 dm->ops->getcoloring = NULL; 1514 dm->ops->creatematrix = DMCreateMatrix_Moab; 1515 dm->ops->createinterpolation = DMCreateInterpolation_Moab; 1516 dm->ops->getaggregates = NULL; 1517 dm->ops->getinjection = NULL /*DMCreateInjection_Moab*/; 1518 dm->ops->refine = DMRefine_Moab; 1519 dm->ops->coarsen = DMCoarsen_Moab; 1520 dm->ops->refinehierarchy = DMRefineHierarchy_Moab; 1521 dm->ops->coarsenhierarchy = DMCoarsenHierarchy_Moab; 1522 dm->ops->globaltolocalbegin = DMGlobalToLocalBegin_Moab; 1523 dm->ops->globaltolocalend = DMGlobalToLocalEnd_Moab; 1524 dm->ops->localtoglobalbegin = DMLocalToGlobalBegin_Moab; 1525 dm->ops->localtoglobalend = DMLocalToGlobalEnd_Moab; 1526 dm->ops->destroy = DMDestroy_Moab; 1527 dm->ops->createsubdm = NULL /*DMCreateSubDM_Moab*/; 1528 dm->ops->getdimpoints = NULL /*DMGetDimPoints_Moab*/; 1529 dm->ops->locatepoints = NULL /*DMLocatePoints_Moab*/; 1530 PetscFunctionReturn(0); 1531 } 1532 1533 1534 #undef __FUNCT__ 1535 #define __FUNCT__ "DMClone_Moab" 1536 PETSC_EXTERN PetscErrorCode DMClone_Moab(DM dm, DM *newdm) 1537 { 1538 PetscErrorCode ierr; 1539 1540 PetscFunctionBegin; 1541 ierr = PetscObjectChangeTypeName((PetscObject) * newdm, DMMOAB);CHKERRQ(ierr); 1542 1543 /* get all the necessary handles from the private DM object */ 1544 (*newdm)->data = (DM_Moab*) dm->data; 1545 ((DM_Moab*)dm->data)->refct++; 1546 1547 ierr = DMInitialize_Moab(*newdm);CHKERRQ(ierr); 1548 PetscFunctionReturn(0); 1549 } 1550 1551 1552 #undef __FUNCT__ 1553 #define __FUNCT__ "DMCreate_Moab" 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