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