1 #include <petsc-private/dmmbimpl.h> /*I "petscdm.h" I*/ 2 #include <petsc-private/vecimpl.h> /*I "petscdm.h" I*/ 3 4 #include <petscdmmoab.h> 5 #include <MBTagConventions.hpp> 6 7 #undef __FUNCT__ 8 #define __FUNCT__ "DMDestroy_Moab" 9 PetscErrorCode DMDestroy_Moab(DM dm) 10 { 11 PetscErrorCode ierr; 12 DM_Moab *dmmoab = (DM_Moab*)dm->data; 13 14 PetscFunctionBegin; 15 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 16 if (dmmoab->icreatedinstance) { 17 delete dmmoab->mbiface; 18 } 19 dmmoab->mbiface = NULL; 20 dmmoab->pcomm = NULL; 21 delete dmmoab->vlocal; 22 delete dmmoab->vowned; 23 delete dmmoab->vghost; 24 delete dmmoab->elocal; 25 delete dmmoab->eghost; 26 ierr = VecScatterDestroy(&dmmoab->ltog_sendrecv);CHKERRQ(ierr); 27 ierr = ISLocalToGlobalMappingDestroy(&dmmoab->ltog_map);CHKERRQ(ierr); 28 ierr = PetscFree(dm->data);CHKERRQ(ierr); 29 PetscFunctionReturn(0); 30 } 31 32 #undef __FUNCT__ 33 #define __FUNCT__ "DMSetUp_Moab" 34 PetscErrorCode DMSetUp_Moab(DM dm) 35 { 36 PetscErrorCode ierr; 37 moab::ErrorCode merr; 38 Vec local, global; 39 IS from; 40 moab::Range::iterator iter; 41 PetscInt bs, *gsindices,gsiz,lsiz; 42 DM_Moab *dmmoab = (DM_Moab*)dm->data; 43 PetscInt totsize; 44 45 PetscFunctionBegin; 46 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 47 /* Get the local and shared vertices and cache it */ 48 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."); 49 50 /* store the current mesh dimension */ 51 merr = dmmoab->mbiface->get_dimension(dmmoab->dim);MBERRNM(merr); 52 53 /* Get the entities recursively in the current part of the mesh */ 54 if (dmmoab->vlocal->empty()) { 55 merr = dmmoab->mbiface->get_entities_by_type(0,moab::MBVERTEX,*dmmoab->vlocal,true);MBERRNM(merr); 56 *dmmoab->vowned = *dmmoab->vlocal; 57 58 /* filter based on parallel status */ 59 merr = dmmoab->pcomm->filter_pstatus(*dmmoab->vowned,PSTATUS_NOT_OWNED,PSTATUS_NOT);MBERRNM(merr); 60 *dmmoab->vghost = moab::subtract(*dmmoab->vlocal, *dmmoab->vowned); 61 62 dmmoab->nloc = dmmoab->vowned->size(); 63 dmmoab->nghost = dmmoab->vghost->size(); 64 ierr = MPI_Allreduce(&dmmoab->nloc, &dmmoab->n, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm);CHKERRQ(ierr); 65 } 66 67 /* get the information about the local elements in the mesh */ 68 { 69 dmmoab->elocal->clear(); 70 dmmoab->eghost->clear(); 71 merr = dmmoab->mbiface->get_entities_by_dimension(0, dmmoab->dim, *dmmoab->elocal, true);CHKERRQ(merr); 72 *dmmoab->eghost = *dmmoab->elocal; 73 merr = dmmoab->pcomm->filter_pstatus(*dmmoab->elocal,PSTATUS_NOT_OWNED,PSTATUS_NOT);MBERRNM(merr); 74 *dmmoab->eghost = moab::subtract(*dmmoab->eghost, *dmmoab->elocal); 75 76 dmmoab->neleloc = dmmoab->elocal->size(); 77 ierr = MPI_Allreduce(&dmmoab->neleloc, &dmmoab->nele, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm);CHKERRQ(ierr); 78 } 79 80 bs = dmmoab->bs; 81 if (!dmmoab->ltog_tag) { 82 /* Get the global ID tag. The global ID tag is applied to each 83 vertex. It acts as an global identifier which MOAB uses to 84 assemble the individual pieces of the mesh */ 85 merr = dmmoab->mbiface->tag_get_handle(GLOBAL_ID_TAG_NAME, dmmoab->ltog_tag);MBERRNM(merr); 86 } 87 88 { 89 totsize=dmmoab->vlocal->size(); 90 ierr = PetscMalloc(totsize*sizeof(PetscInt), &gsindices);CHKERRQ(ierr); 91 /* first get the local indices */ 92 merr = dmmoab->mbiface->tag_get_data(dmmoab->ltog_tag,*dmmoab->vowned,&gsindices[0]);MBERRNM(merr); 93 /* next get the ghosted indices */ 94 merr = dmmoab->mbiface->tag_get_data(dmmoab->ltog_tag,*dmmoab->vghost,&gsindices[dmmoab->nloc]);MBERRNM(merr); 95 96 /* Create Global to Local Vector Scatter Context */ 97 ierr = DMCreateGlobalVector_Moab(dm, &global);CHKERRQ(ierr); 98 ierr = DMCreateLocalVector_Moab(dm, &local);CHKERRQ(ierr); 99 100 /* global to local must retrieve ghost points */ 101 ierr = ISCreateBlock(((PetscObject)dm)->comm,bs,totsize,gsindices,PETSC_COPY_VALUES,&from);CHKERRQ(ierr); 102 103 ierr = VecGetLocalSize(global,&gsiz);CHKERRQ(ierr); 104 ierr = VecGetLocalSize(local,&lsiz);CHKERRQ(ierr); 105 106 ierr = VecScatterCreate(local,from,global,from,&dmmoab->ltog_sendrecv);CHKERRQ(ierr); 107 ierr = ISDestroy(&from);CHKERRQ(ierr); 108 ierr = VecDestroy(&local);CHKERRQ(ierr); 109 ierr = VecDestroy(&global);CHKERRQ(ierr); 110 ierr = PetscFree(gsindices);CHKERRQ(ierr); 111 } 112 113 PetscFunctionReturn(0); 114 } 115 116 #undef __FUNCT__ 117 #define __FUNCT__ "DMCreate_Moab" 118 PETSC_EXTERN PetscErrorCode DMCreate_Moab(DM dm) 119 { 120 PetscErrorCode ierr; 121 122 PetscFunctionBegin; 123 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 124 ierr = PetscNewLog(dm,&dm->data);CHKERRQ(ierr); 125 126 ((DM_Moab*)dm->data)->bs = 1; 127 ((DM_Moab*)dm->data)->n = 0; 128 ((DM_Moab*)dm->data)->nloc = 0; 129 ((DM_Moab*)dm->data)->nele = 0; 130 ((DM_Moab*)dm->data)->neleloc = 0; 131 ((DM_Moab*)dm->data)->nghost = 0; 132 ((DM_Moab*)dm->data)->ltog_map = PETSC_NULL; 133 ((DM_Moab*)dm->data)->ltog_sendrecv = PETSC_NULL; 134 135 ((DM_Moab*)dm->data)->vlocal = new moab::Range(); 136 ((DM_Moab*)dm->data)->vowned = new moab::Range(); 137 ((DM_Moab*)dm->data)->vghost = new moab::Range(); 138 ((DM_Moab*)dm->data)->elocal = new moab::Range(); 139 ((DM_Moab*)dm->data)->eghost = new moab::Range(); 140 141 dm->ops->createglobalvector = DMCreateGlobalVector_Moab; 142 dm->ops->createlocalvector = DMCreateLocalVector_Moab; 143 dm->ops->creatematrix = DMCreateMatrix_Moab; 144 dm->ops->setup = DMSetUp_Moab; 145 dm->ops->destroy = DMDestroy_Moab; 146 dm->ops->globaltolocalbegin = DMGlobalToLocalBegin_Moab; 147 dm->ops->globaltolocalend = DMGlobalToLocalEnd_Moab; 148 dm->ops->localtoglobalbegin = DMLocalToGlobalBegin_Moab; 149 dm->ops->localtoglobalend = DMLocalToGlobalEnd_Moab; 150 PetscFunctionReturn(0); 151 } 152 153 #undef __FUNCT__ 154 #define __FUNCT__ "DMMoabCreate" 155 /*@ 156 DMMoabCreate - Creates a DMMoab object, which encapsulates a moab instance 157 158 Collective on MPI_Comm 159 160 Input Parameter: 161 . comm - The communicator for the DMMoab object 162 163 Output Parameter: 164 . dmb - The DMMoab object 165 166 Level: beginner 167 168 .keywords: DMMoab, create 169 @*/ 170 PetscErrorCode DMMoabCreate(MPI_Comm comm, DM *dmb) 171 { 172 PetscErrorCode ierr; 173 174 PetscFunctionBegin; 175 PetscValidPointer(dmb,2); 176 ierr = DMCreate(comm, dmb);CHKERRQ(ierr); 177 ierr = DMSetType(*dmb, DMMOAB);CHKERRQ(ierr); 178 PetscFunctionReturn(0); 179 } 180 181 #undef __FUNCT__ 182 #define __FUNCT__ "DMMoabCreateMoab" 183 /*@ 184 DMMoabCreate - Creates a DMMoab object, optionally from an instance and other data 185 186 Collective on MPI_Comm 187 188 Input Parameter: 189 . comm - The communicator for the DMMoab object 190 . mbiface - (ptr to) the MOAB Instance; if passed in NULL, MOAB instance is created inside PETSc, and destroyed 191 along with the DMMoab 192 . pcomm - (ptr to) a ParallelComm; if NULL, creates one internally for the whole communicator 193 . ltog_tag - A tag to use to retrieve global id for an entity; if 0, will use GLOBAL_ID_TAG_NAME/tag 194 . range - If non-NULL, contains range of entities to which DOFs will be assigned 195 196 Output Parameter: 197 . dmb - The DMMoab object 198 199 Level: intermediate 200 201 .keywords: DMMoab, create 202 @*/ 203 PetscErrorCode DMMoabCreateMoab(MPI_Comm comm, moab::Interface *mbiface, moab::ParallelComm *pcomm, moab::Tag *ltog_tag, moab::Range *range, DM *dmb) 204 { 205 PetscErrorCode ierr; 206 moab::ErrorCode merr; 207 DM_Moab *dmmoab; 208 209 PetscFunctionBegin; 210 PetscValidPointer(dmb,6); 211 ierr = DMMoabCreate(comm, dmb);CHKERRQ(ierr); 212 dmmoab = (DM_Moab*)(*dmb)->data; 213 214 if (!mbiface) { 215 dmmoab->mbiface = new moab::Core(); 216 dmmoab->icreatedinstance = PETSC_TRUE; 217 } 218 else 219 dmmoab->icreatedinstance = PETSC_FALSE; 220 221 if (!pcomm) { 222 moab::EntityHandle rootset,partnset; 223 PetscInt rank, nprocs; 224 ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); 225 ierr = MPI_Comm_size(comm, &nprocs);CHKERRQ(ierr); 226 227 /* Create root sets for each mesh. Then pass these 228 to the load_file functions to be populated. */ 229 merr = dmmoab->mbiface->create_meshset(moab::MESHSET_SET, rootset); 230 MBERR("Creating root set failed", merr); 231 merr = dmmoab->mbiface->create_meshset(moab::MESHSET_SET, partnset); 232 MBERR("Creating partition set failed", merr); 233 234 /* Create the parallel communicator object with the partition handle associated with MOAB */ 235 dmmoab->pcomm = moab::ParallelComm::get_pcomm(dmmoab->mbiface, partnset, &comm); 236 } 237 else { 238 ierr = DMMoabSetParallelComm(*dmb, pcomm);CHKERRQ(ierr); 239 } 240 241 /* do the remaining initializations for DMMoab */ 242 dmmoab->bs = 1; 243 244 /* set global ID tag handle */ 245 if (!ltog_tag) { 246 merr = dmmoab->mbiface->tag_get_handle(GLOBAL_ID_TAG_NAME, dmmoab->ltog_tag);MBERRNM(merr); 247 } 248 else { 249 ierr = DMMoabSetLocalToGlobalTag(*dmb, *ltog_tag);CHKERRQ(ierr); 250 } 251 252 /* create a fileset to store the hierarchy of entities belonging to current DM */ 253 merr = mbiface->create_meshset(MESHSET_ORDERED, dmmoab->file_set);MBERRNM(ierr); 254 255 /* set the local range of entities (vertices) of interest */ 256 if (range) { 257 ierr = DMMoabSetLocalVertices(*dmb, range);CHKERRQ(ierr); 258 } 259 PetscFunctionReturn(0); 260 } 261 262 #undef __FUNCT__ 263 #define __FUNCT__ "DMMoabSetParallelComm" 264 /*@ 265 DMMoabSetParallelComm - Set the ParallelComm used with this DMMoab 266 267 Collective on MPI_Comm 268 269 Input Parameter: 270 . dm - The DMMoab object being set 271 . pcomm - The ParallelComm being set on the DMMoab 272 273 Level: beginner 274 275 .keywords: DMMoab, create 276 @*/ 277 PetscErrorCode DMMoabSetParallelComm(DM dm,moab::ParallelComm *pcomm) 278 { 279 DM_Moab *dmmoab = (DM_Moab*)(dm)->data; 280 281 PetscFunctionBegin; 282 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 283 dmmoab->pcomm = pcomm; 284 dmmoab->mbiface = pcomm->get_moab(); 285 dmmoab->icreatedinstance = PETSC_FALSE; 286 PetscFunctionReturn(0); 287 } 288 289 290 #undef __FUNCT__ 291 #define __FUNCT__ "DMMoabGetParallelComm" 292 /*@ 293 DMMoabGetParallelComm - Get the ParallelComm used with this DMMoab 294 295 Collective on MPI_Comm 296 297 Input Parameter: 298 . dm - The DMMoab object being set 299 300 Output Parameter: 301 . pcomm - The ParallelComm for the DMMoab 302 303 Level: beginner 304 305 .keywords: DMMoab, create 306 @*/ 307 PetscErrorCode DMMoabGetParallelComm(DM dm,moab::ParallelComm **pcomm) 308 { 309 PetscFunctionBegin; 310 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 311 *pcomm = ((DM_Moab*)(dm)->data)->pcomm; 312 PetscFunctionReturn(0); 313 } 314 315 316 #undef __FUNCT__ 317 #define __FUNCT__ "DMMoabSetInterface" 318 /*@ 319 DMMoabSetInterface - Set the MOAB instance used with this DMMoab 320 321 Collective on MPI_Comm 322 323 Input Parameter: 324 . dm - The DMMoab object being set 325 . mbiface - The MOAB instance being set on this DMMoab 326 327 Level: beginner 328 329 .keywords: DMMoab, create 330 @*/ 331 PetscErrorCode DMMoabSetInterface(DM dm,moab::Interface *mbiface) 332 { 333 DM_Moab *dmmoab = (DM_Moab*)(dm)->data; 334 335 PetscFunctionBegin; 336 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 337 dmmoab->pcomm = NULL; 338 dmmoab->mbiface = mbiface; 339 dmmoab->icreatedinstance = PETSC_FALSE; 340 PetscFunctionReturn(0); 341 } 342 343 344 #undef __FUNCT__ 345 #define __FUNCT__ "DMMoabGetInterface" 346 /*@ 347 DMMoabGetInterface - Get the MOAB instance used with this DMMoab 348 349 Collective on MPI_Comm 350 351 Input Parameter: 352 . dm - The DMMoab object being set 353 354 Output Parameter: 355 . mbiface - The MOAB instance set on this DMMoab 356 357 Level: beginner 358 359 .keywords: DMMoab, create 360 @*/ 361 PetscErrorCode DMMoabGetInterface(DM dm,moab::Interface **mbiface) 362 { 363 PetscErrorCode ierr; 364 static PetscBool cite = PETSC_FALSE; 365 366 PetscFunctionBegin; 367 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 368 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); 369 *mbiface = ((DM_Moab*)dm->data)->mbiface; 370 PetscFunctionReturn(0); 371 } 372 373 374 #undef __FUNCT__ 375 #define __FUNCT__ "DMMoabSetLocalVertices" 376 /*@ 377 DMMoabSetLocalVertices - Set the entities having DOFs on this DMMoab 378 379 Collective on MPI_Comm 380 381 Input Parameter: 382 . dm - The DMMoab object being set 383 . range - The entities treated by this DMMoab 384 385 Level: beginner 386 387 .keywords: DMMoab, create 388 @*/ 389 PetscErrorCode DMMoabSetLocalVertices(DM dm,moab::Range *range) 390 { 391 moab::ErrorCode merr; 392 PetscErrorCode ierr; 393 DM_Moab *dmmoab = (DM_Moab*)(dm)->data; 394 395 PetscFunctionBegin; 396 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 397 dmmoab->vlocal->clear(); 398 dmmoab->vowned->clear(); 399 dmmoab->vlocal->insert(range->begin(), range->end()); 400 *dmmoab->vowned = *dmmoab->vlocal; 401 merr = dmmoab->pcomm->filter_pstatus(*dmmoab->vowned,PSTATUS_NOT_OWNED,PSTATUS_NOT);MBERRNM(merr); 402 *dmmoab->vghost = moab::subtract(*range, *dmmoab->vowned); 403 dmmoab->nloc=dmmoab->vowned->size(); 404 dmmoab->nghost=dmmoab->vghost->size(); 405 ierr = MPI_Allreduce(&dmmoab->nloc, &dmmoab->n, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm);CHKERRQ(ierr); 406 PetscFunctionReturn(0); 407 } 408 409 410 #undef __FUNCT__ 411 #define __FUNCT__ "DMMoabGetLocalVertices" 412 /*@ 413 DMMoabGetLocalVertices - Get the entities having DOFs on this DMMoab 414 415 Collective on MPI_Comm 416 417 Input Parameter: 418 . dm - The DMMoab object being set 419 420 Output Parameter: 421 . owned - The owned vertex entities in this DMMoab 422 . ghost - The ghosted entities (non-owned) stored locally in this partition 423 424 Level: beginner 425 426 .keywords: DMMoab, create 427 @*/ 428 PetscErrorCode DMMoabGetLocalVertices(DM dm,moab::Range **owned,moab::Range **ghost) 429 { 430 PetscFunctionBegin; 431 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 432 if (*owned) *owned = ((DM_Moab*)dm->data)->vowned; 433 if (*ghost) *ghost = ((DM_Moab*)dm->data)->vghost; 434 PetscFunctionReturn(0); 435 } 436 437 #undef __FUNCT__ 438 #define __FUNCT__ "DMMoabGetLocalElements" 439 /*@ 440 DMMoabGetLocalElements - Get the higher-dimensional entities that are locally owned 441 442 Collective on MPI_Comm 443 444 Input Parameter: 445 . dm - The DMMoab object being set 446 447 Output Parameter: 448 . range - The entities owned locally 449 450 Level: beginner 451 452 .keywords: DMMoab, create 453 @*/ 454 PetscErrorCode DMMoabGetLocalElements(DM dm,moab::Range **range) 455 { 456 PetscFunctionBegin; 457 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 458 *range = ((DM_Moab*)dm->data)->elocal; 459 PetscFunctionReturn(0); 460 } 461 462 463 #undef __FUNCT__ 464 #define __FUNCT__ "DMMoabSetLocalToGlobalTag" 465 /*@ 466 DMMoabSetLocalToGlobalTag - Set the tag used for local to global numbering 467 468 Collective on MPI_Comm 469 470 Input Parameter: 471 . dm - The DMMoab object being set 472 . ltogtag - The MOAB tag used for local to global ids 473 474 Level: beginner 475 476 .keywords: DMMoab, create 477 @*/ 478 PetscErrorCode DMMoabSetLocalToGlobalTag(DM dm,moab::Tag ltogtag) 479 { 480 PetscFunctionBegin; 481 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 482 ((DM_Moab*)dm->data)->ltog_tag = ltogtag; 483 PetscFunctionReturn(0); 484 } 485 486 487 #undef __FUNCT__ 488 #define __FUNCT__ "DMMoabGetLocalToGlobalTag" 489 /*@ 490 DMMoabGetLocalToGlobalTag - Get the tag used for local to global numbering 491 492 Collective on MPI_Comm 493 494 Input Parameter: 495 . dm - The DMMoab object being set 496 497 Output Parameter: 498 . ltogtag - The MOAB tag used for local to global ids 499 500 Level: beginner 501 502 .keywords: DMMoab, create 503 @*/ 504 PetscErrorCode DMMoabGetLocalToGlobalTag(DM dm,moab::Tag *ltog_tag) 505 { 506 PetscFunctionBegin; 507 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 508 *ltog_tag = ((DM_Moab*)dm->data)->ltog_tag; 509 PetscFunctionReturn(0); 510 } 511 512 513 #undef __FUNCT__ 514 #define __FUNCT__ "DMMoabSetBlockSize" 515 /*@ 516 DMMoabSetBlockSize - Set the block size used with this DMMoab 517 518 Collective on MPI_Comm 519 520 Input Parameter: 521 . dm - The DMMoab object being set 522 . bs - The block size used with this DMMoab 523 524 Level: beginner 525 526 .keywords: DMMoab, create 527 @*/ 528 PetscErrorCode DMMoabSetBlockSize(DM dm,PetscInt bs) 529 { 530 PetscFunctionBegin; 531 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 532 ((DM_Moab*)dm->data)->bs = bs; 533 PetscFunctionReturn(0); 534 } 535 536 537 #undef __FUNCT__ 538 #define __FUNCT__ "DMMoabGetBlockSize" 539 /*@ 540 DMMoabGetBlockSize - Get the block size used with this DMMoab 541 542 Collective on MPI_Comm 543 544 Input Parameter: 545 . dm - The DMMoab object being set 546 547 Output Parameter: 548 . bs - The block size used with this DMMoab 549 550 Level: beginner 551 552 .keywords: DMMoab, create 553 @*/ 554 PetscErrorCode DMMoabGetBlockSize(DM dm,PetscInt *bs) 555 { 556 PetscFunctionBegin; 557 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 558 *bs = ((DM_Moab*)dm->data)->bs; 559 PetscFunctionReturn(0); 560 } 561 562