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