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