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 count,dof,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 count=0; 90 totsize=dmmoab->vlocal->size(); 91 ierr = PetscMalloc(totsize*sizeof(PetscInt), &gsindices);CHKERRQ(ierr); 92 /* first get the local indices */ 93 for(iter = dmmoab->vowned->begin(); iter != dmmoab->vowned->end(); iter++) { 94 merr = dmmoab->mbiface->tag_get_data(dmmoab->ltog_tag,&(*iter),1,&dof);MBERRNM(merr); 95 gsindices[count++] = (dof); 96 } 97 /* now get the ghosted indices */ 98 for(iter = dmmoab->vghost->begin(); iter != dmmoab->vghost->end(); iter++) { 99 merr = dmmoab->mbiface->tag_get_data(dmmoab->ltog_tag,&(*iter),1,&dof);MBERRNM(merr); 100 gsindices[count++] = (dof); 101 } 102 103 /* Create Global to Local Vector Scatter Context */ 104 ierr = DMCreateGlobalVector_Moab(dm, &global);CHKERRQ(ierr); 105 ierr = DMCreateLocalVector_Moab(dm, &local);CHKERRQ(ierr); 106 107 /* global to local must retrieve ghost points */ 108 ierr = ISCreateBlock(((PetscObject)dm)->comm,bs,totsize,gsindices,PETSC_COPY_VALUES,&from);CHKERRQ(ierr); 109 110 ierr = VecGetLocalSize(global,&gsiz);CHKERRQ(ierr); 111 ierr = VecGetLocalSize(local,&lsiz);CHKERRQ(ierr); 112 113 ierr = VecScatterCreate(local,from,global,from,&dmmoab->ltog_sendrecv);CHKERRQ(ierr); 114 ierr = ISDestroy(&from);CHKERRQ(ierr); 115 ierr = VecDestroy(&local);CHKERRQ(ierr); 116 ierr = VecDestroy(&global);CHKERRQ(ierr); 117 ierr = PetscFree(gsindices);CHKERRQ(ierr); 118 } 119 120 PetscFunctionReturn(0); 121 } 122 123 #undef __FUNCT__ 124 #define __FUNCT__ "DMCreate_Moab" 125 PETSC_EXTERN PetscErrorCode DMCreate_Moab(DM dm) 126 { 127 PetscErrorCode ierr; 128 129 PetscFunctionBegin; 130 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 131 ierr = PetscNewLog(dm,&dm->data);CHKERRQ(ierr); 132 133 ((DM_Moab*)dm->data)->bs = 1; 134 ((DM_Moab*)dm->data)->n = 0; 135 ((DM_Moab*)dm->data)->nloc = 0; 136 ((DM_Moab*)dm->data)->nele = 0; 137 ((DM_Moab*)dm->data)->neleloc = 0; 138 ((DM_Moab*)dm->data)->nghost = 0; 139 ((DM_Moab*)dm->data)->ltog_map = PETSC_NULL; 140 ((DM_Moab*)dm->data)->ltog_sendrecv = PETSC_NULL; 141 142 ((DM_Moab*)dm->data)->vlocal = new moab::Range(); 143 ((DM_Moab*)dm->data)->vowned = new moab::Range(); 144 ((DM_Moab*)dm->data)->vghost = new moab::Range(); 145 ((DM_Moab*)dm->data)->elocal = new moab::Range(); 146 ((DM_Moab*)dm->data)->eghost = new moab::Range(); 147 148 dm->ops->createglobalvector = DMCreateGlobalVector_Moab; 149 dm->ops->createlocalvector = DMCreateLocalVector_Moab; 150 dm->ops->creatematrix = DMCreateMatrix_Moab; 151 dm->ops->setup = DMSetUp_Moab; 152 dm->ops->destroy = DMDestroy_Moab; 153 dm->ops->globaltolocalbegin = DMGlobalToLocalBegin_Moab; 154 dm->ops->globaltolocalend = DMGlobalToLocalEnd_Moab; 155 dm->ops->localtoglobalbegin = DMLocalToGlobalBegin_Moab; 156 dm->ops->localtoglobalend = DMLocalToGlobalEnd_Moab; 157 PetscFunctionReturn(0); 158 } 159 160 #undef __FUNCT__ 161 #define __FUNCT__ "DMMoabCreate" 162 /*@ 163 DMMoabCreate - Creates a DMMoab object, which encapsulates a moab instance 164 165 Collective on MPI_Comm 166 167 Input Parameter: 168 . comm - The communicator for the DMMoab object 169 170 Output Parameter: 171 . dmb - The DMMoab object 172 173 Level: beginner 174 175 .keywords: DMMoab, create 176 @*/ 177 PetscErrorCode DMMoabCreate(MPI_Comm comm, DM *dmb) 178 { 179 PetscErrorCode ierr; 180 181 PetscFunctionBegin; 182 PetscValidPointer(dmb,2); 183 ierr = DMCreate(comm, dmb);CHKERRQ(ierr); 184 ierr = DMSetType(*dmb, DMMOAB);CHKERRQ(ierr); 185 PetscFunctionReturn(0); 186 } 187 188 #undef __FUNCT__ 189 #define __FUNCT__ "DMMoabCreateMoab" 190 /*@ 191 DMMoabCreate - Creates a DMMoab object, optionally from an instance and other data 192 193 Collective on MPI_Comm 194 195 Input Parameter: 196 . comm - The communicator for the DMMoab object 197 . mbiface - (ptr to) the MOAB Instance; if passed in NULL, MOAB instance is created inside PETSc, and destroyed 198 along with the DMMoab 199 . pcomm - (ptr to) a ParallelComm; if NULL, creates one internally for the whole communicator 200 . ltog_tag - A tag to use to retrieve global id for an entity; if 0, will use GLOBAL_ID_TAG_NAME/tag 201 . range - If non-NULL, contains range of entities to which DOFs will be assigned 202 203 Output Parameter: 204 . dmb - The DMMoab object 205 206 Level: intermediate 207 208 .keywords: DMMoab, create 209 @*/ 210 PetscErrorCode DMMoabCreateMoab(MPI_Comm comm, moab::Interface *mbiface, moab::ParallelComm *pcomm, moab::Tag *ltog_tag, moab::Range *range, DM *dmb) 211 { 212 PetscErrorCode ierr; 213 moab::ErrorCode merr; 214 DM_Moab *dmmoab; 215 216 PetscFunctionBegin; 217 PetscValidPointer(dmb,6); 218 ierr = DMMoabCreate(comm, dmb);CHKERRQ(ierr); 219 dmmoab = (DM_Moab*)(*dmb)->data; 220 221 if (!mbiface) { 222 mbiface = new moab::Core(); 223 dmmoab->icreatedinstance = PETSC_TRUE; 224 } 225 else 226 dmmoab->icreatedinstance = PETSC_FALSE; 227 228 if (!pcomm) { 229 moab::EntityHandle rootset,partnset; 230 PetscInt rank, nprocs; 231 ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); 232 ierr = MPI_Comm_size(comm, &nprocs);CHKERRQ(ierr); 233 234 /* Create root sets for each mesh. Then pass these 235 to the load_file functions to be populated. */ 236 merr = mbiface->create_meshset(moab::MESHSET_SET, rootset); 237 MBERR("Creating root set failed", merr); 238 merr = mbiface->create_meshset(moab::MESHSET_SET, partnset); 239 MBERR("Creating partition set failed", merr); 240 241 /* Create the parallel communicator object with the partition handle associated with MOAB */ 242 pcomm = moab::ParallelComm::get_pcomm(mbiface, partnset, &comm); 243 } 244 245 if (!ltog_tag) { 246 merr = mbiface->tag_get_handle(GLOBAL_ID_TAG_NAME, *ltog_tag);MBERRNM(merr); 247 } 248 else { 249 ierr = DMMoabSetLocalToGlobalTag(*dmb, *ltog_tag);CHKERRQ(ierr); 250 } 251 252 /* do the initialization of the DM */ 253 dmmoab->bs = 1; 254 ierr = DMMoabSetParallelComm(*dmb, pcomm);CHKERRQ(ierr); 255 dmmoab->ltog_tag = *ltog_tag; 256 if (range) { 257 ierr = DMMoabSetRange(*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__ "DMMoabSetRange" 376 /*@ 377 DMMoabSetRange - 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 DMMoabSetRange(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__ "DMMoabGetRange" 412 /*@ 413 DMMoabGetRange - 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 . range - The entities treated by this DMMoab 422 423 Level: beginner 424 425 .keywords: DMMoab, create 426 @*/ 427 PetscErrorCode DMMoabGetRange(DM dm,moab::Range **range) 428 { 429 PetscFunctionBegin; 430 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 431 *range = ((DM_Moab*)dm->data)->vowned; 432 PetscFunctionReturn(0); 433 } 434 435 #undef __FUNCT__ 436 #define __FUNCT__ "DMMoabSetLocalToGlobalTag" 437 /*@ 438 DMMoabSetLocalToGlobalTag - Set the tag used for local to global numbering 439 440 Collective on MPI_Comm 441 442 Input Parameter: 443 . dm - The DMMoab object being set 444 . ltogtag - The MOAB tag used for local to global ids 445 446 Level: beginner 447 448 .keywords: DMMoab, create 449 @*/ 450 PetscErrorCode DMMoabSetLocalToGlobalTag(DM dm,moab::Tag ltogtag) 451 { 452 PetscFunctionBegin; 453 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 454 ((DM_Moab*)dm->data)->ltog_tag = ltogtag; 455 PetscFunctionReturn(0); 456 } 457 458 459 #undef __FUNCT__ 460 #define __FUNCT__ "DMMoabGetLocalToGlobalTag" 461 /*@ 462 DMMoabGetLocalToGlobalTag - Get the tag used for local to global numbering 463 464 Collective on MPI_Comm 465 466 Input Parameter: 467 . dm - The DMMoab object being set 468 469 Output Parameter: 470 . ltogtag - The MOAB tag used for local to global ids 471 472 Level: beginner 473 474 .keywords: DMMoab, create 475 @*/ 476 PetscErrorCode DMMoabGetLocalToGlobalTag(DM dm,moab::Tag *ltog_tag) 477 { 478 PetscFunctionBegin; 479 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 480 *ltog_tag = ((DM_Moab*)dm->data)->ltog_tag; 481 PetscFunctionReturn(0); 482 } 483 484 485 #undef __FUNCT__ 486 #define __FUNCT__ "DMMoabSetBlockSize" 487 /*@ 488 DMMoabSetBlockSize - Set the block size used with this DMMoab 489 490 Collective on MPI_Comm 491 492 Input Parameter: 493 . dm - The DMMoab object being set 494 . bs - The block size used with this DMMoab 495 496 Level: beginner 497 498 .keywords: DMMoab, create 499 @*/ 500 PetscErrorCode DMMoabSetBlockSize(DM dm,PetscInt bs) 501 { 502 PetscFunctionBegin; 503 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 504 ((DM_Moab*)dm->data)->bs = bs; 505 PetscFunctionReturn(0); 506 } 507 508 509 #undef __FUNCT__ 510 #define __FUNCT__ "DMMoabGetBlockSize" 511 /*@ 512 DMMoabGetBlockSize - Get the block size used with this DMMoab 513 514 Collective on MPI_Comm 515 516 Input Parameter: 517 . dm - The DMMoab object being set 518 519 Output Parameter: 520 . bs - The block size used with this DMMoab 521 522 Level: beginner 523 524 .keywords: DMMoab, create 525 @*/ 526 PetscErrorCode DMMoabGetBlockSize(DM dm,PetscInt *bs) 527 { 528 PetscFunctionBegin; 529 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 530 *bs = ((DM_Moab*)dm->data)->bs; 531 PetscFunctionReturn(0); 532 } 533 534