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