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 /* set the local range of entities (vertices) of interest */ 253 if (range) { 254 ierr = DMMoabSetRange(*dmb, range);CHKERRQ(ierr); 255 } 256 PetscFunctionReturn(0); 257 } 258 259 #undef __FUNCT__ 260 #define __FUNCT__ "DMMoabSetParallelComm" 261 /*@ 262 DMMoabSetParallelComm - Set the ParallelComm used with this DMMoab 263 264 Collective on MPI_Comm 265 266 Input Parameter: 267 . dm - The DMMoab object being set 268 . pcomm - The ParallelComm being set on the DMMoab 269 270 Level: beginner 271 272 .keywords: DMMoab, create 273 @*/ 274 PetscErrorCode DMMoabSetParallelComm(DM dm,moab::ParallelComm *pcomm) 275 { 276 DM_Moab *dmmoab = (DM_Moab*)(dm)->data; 277 278 PetscFunctionBegin; 279 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 280 dmmoab->pcomm = pcomm; 281 dmmoab->mbiface = pcomm->get_moab(); 282 dmmoab->icreatedinstance = PETSC_FALSE; 283 PetscFunctionReturn(0); 284 } 285 286 287 #undef __FUNCT__ 288 #define __FUNCT__ "DMMoabGetParallelComm" 289 /*@ 290 DMMoabGetParallelComm - Get the ParallelComm used with this DMMoab 291 292 Collective on MPI_Comm 293 294 Input Parameter: 295 . dm - The DMMoab object being set 296 297 Output Parameter: 298 . pcomm - The ParallelComm for the DMMoab 299 300 Level: beginner 301 302 .keywords: DMMoab, create 303 @*/ 304 PetscErrorCode DMMoabGetParallelComm(DM dm,moab::ParallelComm **pcomm) 305 { 306 PetscFunctionBegin; 307 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 308 *pcomm = ((DM_Moab*)(dm)->data)->pcomm; 309 PetscFunctionReturn(0); 310 } 311 312 313 #undef __FUNCT__ 314 #define __FUNCT__ "DMMoabSetInterface" 315 /*@ 316 DMMoabSetInterface - Set the MOAB instance used with this DMMoab 317 318 Collective on MPI_Comm 319 320 Input Parameter: 321 . dm - The DMMoab object being set 322 . mbiface - The MOAB instance being set on this DMMoab 323 324 Level: beginner 325 326 .keywords: DMMoab, create 327 @*/ 328 PetscErrorCode DMMoabSetInterface(DM dm,moab::Interface *mbiface) 329 { 330 DM_Moab *dmmoab = (DM_Moab*)(dm)->data; 331 332 PetscFunctionBegin; 333 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 334 dmmoab->pcomm = NULL; 335 dmmoab->mbiface = mbiface; 336 dmmoab->icreatedinstance = PETSC_FALSE; 337 PetscFunctionReturn(0); 338 } 339 340 341 #undef __FUNCT__ 342 #define __FUNCT__ "DMMoabGetInterface" 343 /*@ 344 DMMoabGetInterface - Get the MOAB instance used with this DMMoab 345 346 Collective on MPI_Comm 347 348 Input Parameter: 349 . dm - The DMMoab object being set 350 351 Output Parameter: 352 . mbiface - The MOAB instance set on this DMMoab 353 354 Level: beginner 355 356 .keywords: DMMoab, create 357 @*/ 358 PetscErrorCode DMMoabGetInterface(DM dm,moab::Interface **mbiface) 359 { 360 PetscErrorCode ierr; 361 static PetscBool cite = PETSC_FALSE; 362 363 PetscFunctionBegin; 364 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 365 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); 366 *mbiface = ((DM_Moab*)dm->data)->mbiface; 367 PetscFunctionReturn(0); 368 } 369 370 371 #undef __FUNCT__ 372 #define __FUNCT__ "DMMoabSetRange" 373 /*@ 374 DMMoabSetRange - Set the entities having DOFs on this DMMoab 375 376 Collective on MPI_Comm 377 378 Input Parameter: 379 . dm - The DMMoab object being set 380 . range - The entities treated by this DMMoab 381 382 Level: beginner 383 384 .keywords: DMMoab, create 385 @*/ 386 PetscErrorCode DMMoabSetRange(DM dm,moab::Range *range) 387 { 388 moab::ErrorCode merr; 389 PetscErrorCode ierr; 390 DM_Moab *dmmoab = (DM_Moab*)(dm)->data; 391 392 PetscFunctionBegin; 393 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 394 dmmoab->vlocal->clear(); 395 dmmoab->vowned->clear(); 396 dmmoab->vlocal->insert(range->begin(), range->end()); 397 *dmmoab->vowned = *dmmoab->vlocal; 398 merr = dmmoab->pcomm->filter_pstatus(*dmmoab->vowned,PSTATUS_NOT_OWNED,PSTATUS_NOT);MBERRNM(merr); 399 *dmmoab->vghost = moab::subtract(*range, *dmmoab->vowned); 400 dmmoab->nloc=dmmoab->vowned->size(); 401 dmmoab->nghost=dmmoab->vghost->size(); 402 ierr = MPI_Allreduce(&dmmoab->nloc, &dmmoab->n, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm);CHKERRQ(ierr); 403 PetscFunctionReturn(0); 404 } 405 406 407 #undef __FUNCT__ 408 #define __FUNCT__ "DMMoabGetRange" 409 /*@ 410 DMMoabGetRange - Get the entities having DOFs on this DMMoab 411 412 Collective on MPI_Comm 413 414 Input Parameter: 415 . dm - The DMMoab object being set 416 417 Output Parameter: 418 . range - The entities treated by this DMMoab 419 420 Level: beginner 421 422 .keywords: DMMoab, create 423 @*/ 424 PetscErrorCode DMMoabGetRange(DM dm,moab::Range **range) 425 { 426 PetscFunctionBegin; 427 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 428 *range = ((DM_Moab*)dm->data)->vowned; 429 PetscFunctionReturn(0); 430 } 431 432 #undef __FUNCT__ 433 #define __FUNCT__ "DMMoabSetLocalToGlobalTag" 434 /*@ 435 DMMoabSetLocalToGlobalTag - Set the tag used for local to global numbering 436 437 Collective on MPI_Comm 438 439 Input Parameter: 440 . dm - The DMMoab object being set 441 . ltogtag - The MOAB tag used for local to global ids 442 443 Level: beginner 444 445 .keywords: DMMoab, create 446 @*/ 447 PetscErrorCode DMMoabSetLocalToGlobalTag(DM dm,moab::Tag ltogtag) 448 { 449 PetscFunctionBegin; 450 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 451 ((DM_Moab*)dm->data)->ltog_tag = ltogtag; 452 PetscFunctionReturn(0); 453 } 454 455 456 #undef __FUNCT__ 457 #define __FUNCT__ "DMMoabGetLocalToGlobalTag" 458 /*@ 459 DMMoabGetLocalToGlobalTag - Get the tag used for local to global numbering 460 461 Collective on MPI_Comm 462 463 Input Parameter: 464 . dm - The DMMoab object being set 465 466 Output Parameter: 467 . ltogtag - The MOAB tag used for local to global ids 468 469 Level: beginner 470 471 .keywords: DMMoab, create 472 @*/ 473 PetscErrorCode DMMoabGetLocalToGlobalTag(DM dm,moab::Tag *ltog_tag) 474 { 475 PetscFunctionBegin; 476 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 477 *ltog_tag = ((DM_Moab*)dm->data)->ltog_tag; 478 PetscFunctionReturn(0); 479 } 480 481 482 #undef __FUNCT__ 483 #define __FUNCT__ "DMMoabSetBlockSize" 484 /*@ 485 DMMoabSetBlockSize - Set the block size used with this DMMoab 486 487 Collective on MPI_Comm 488 489 Input Parameter: 490 . dm - The DMMoab object being set 491 . bs - The block size used with this DMMoab 492 493 Level: beginner 494 495 .keywords: DMMoab, create 496 @*/ 497 PetscErrorCode DMMoabSetBlockSize(DM dm,PetscInt bs) 498 { 499 PetscFunctionBegin; 500 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 501 ((DM_Moab*)dm->data)->bs = bs; 502 PetscFunctionReturn(0); 503 } 504 505 506 #undef __FUNCT__ 507 #define __FUNCT__ "DMMoabGetBlockSize" 508 /*@ 509 DMMoabGetBlockSize - Get the block size used with this DMMoab 510 511 Collective on MPI_Comm 512 513 Input Parameter: 514 . dm - The DMMoab object being set 515 516 Output Parameter: 517 . bs - The block size used with this DMMoab 518 519 Level: beginner 520 521 .keywords: DMMoab, create 522 @*/ 523 PetscErrorCode DMMoabGetBlockSize(DM dm,PetscInt *bs) 524 { 525 PetscFunctionBegin; 526 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 527 *bs = ((DM_Moab*)dm->data)->bs; 528 PetscFunctionReturn(0); 529 } 530 531