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 merr = dmmoab->mbiface->tag_get_data(dmmoab->ltog_tag,*dmmoab->vowned,&gsindices[0]);MBERRNM(merr); 94 /* next get the ghosted indices */ 95 merr = dmmoab->mbiface->tag_get_data(dmmoab->ltog_tag,*dmmoab->vghost,&gsindices[dmmoab->nloc]);MBERRNM(merr); 96 97 /* Create Global to Local Vector Scatter Context */ 98 ierr = DMCreateGlobalVector_Moab(dm, &global);CHKERRQ(ierr); 99 ierr = DMCreateLocalVector_Moab(dm, &local);CHKERRQ(ierr); 100 101 /* global to local must retrieve ghost points */ 102 ierr = ISCreateBlock(((PetscObject)dm)->comm,bs,totsize,gsindices,PETSC_COPY_VALUES,&from);CHKERRQ(ierr); 103 104 ierr = VecGetLocalSize(global,&gsiz);CHKERRQ(ierr); 105 ierr = VecGetLocalSize(local,&lsiz);CHKERRQ(ierr); 106 107 ierr = VecScatterCreate(local,from,global,from,&dmmoab->ltog_sendrecv);CHKERRQ(ierr); 108 ierr = ISDestroy(&from);CHKERRQ(ierr); 109 ierr = VecDestroy(&local);CHKERRQ(ierr); 110 ierr = VecDestroy(&global);CHKERRQ(ierr); 111 ierr = PetscFree(gsindices);CHKERRQ(ierr); 112 } 113 114 PetscFunctionReturn(0); 115 } 116 117 #undef __FUNCT__ 118 #define __FUNCT__ "DMCreate_Moab" 119 PETSC_EXTERN PetscErrorCode DMCreate_Moab(DM dm) 120 { 121 PetscErrorCode ierr; 122 123 PetscFunctionBegin; 124 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 125 ierr = PetscNewLog(dm,&dm->data);CHKERRQ(ierr); 126 127 ((DM_Moab*)dm->data)->bs = 1; 128 ((DM_Moab*)dm->data)->n = 0; 129 ((DM_Moab*)dm->data)->nloc = 0; 130 ((DM_Moab*)dm->data)->nele = 0; 131 ((DM_Moab*)dm->data)->neleloc = 0; 132 ((DM_Moab*)dm->data)->nghost = 0; 133 ((DM_Moab*)dm->data)->ltog_map = PETSC_NULL; 134 ((DM_Moab*)dm->data)->ltog_sendrecv = PETSC_NULL; 135 136 ((DM_Moab*)dm->data)->vlocal = new moab::Range(); 137 ((DM_Moab*)dm->data)->vowned = new moab::Range(); 138 ((DM_Moab*)dm->data)->vghost = new moab::Range(); 139 ((DM_Moab*)dm->data)->elocal = new moab::Range(); 140 ((DM_Moab*)dm->data)->eghost = new moab::Range(); 141 142 dm->ops->createglobalvector = DMCreateGlobalVector_Moab; 143 dm->ops->createlocalvector = DMCreateLocalVector_Moab; 144 dm->ops->creatematrix = DMCreateMatrix_Moab; 145 dm->ops->setup = DMSetUp_Moab; 146 dm->ops->destroy = DMDestroy_Moab; 147 dm->ops->globaltolocalbegin = DMGlobalToLocalBegin_Moab; 148 dm->ops->globaltolocalend = DMGlobalToLocalEnd_Moab; 149 dm->ops->localtoglobalbegin = DMLocalToGlobalBegin_Moab; 150 dm->ops->localtoglobalend = DMLocalToGlobalEnd_Moab; 151 PetscFunctionReturn(0); 152 } 153 154 #undef __FUNCT__ 155 #define __FUNCT__ "DMMoabCreate" 156 /*@ 157 DMMoabCreate - Creates a DMMoab object, which encapsulates a moab instance 158 159 Collective on MPI_Comm 160 161 Input Parameter: 162 . comm - The communicator for the DMMoab object 163 164 Output Parameter: 165 . dmb - The DMMoab object 166 167 Level: beginner 168 169 .keywords: DMMoab, create 170 @*/ 171 PetscErrorCode DMMoabCreate(MPI_Comm comm, DM *dmb) 172 { 173 PetscErrorCode ierr; 174 175 PetscFunctionBegin; 176 PetscValidPointer(dmb,2); 177 ierr = DMCreate(comm, dmb);CHKERRQ(ierr); 178 ierr = DMSetType(*dmb, DMMOAB);CHKERRQ(ierr); 179 PetscFunctionReturn(0); 180 } 181 182 #undef __FUNCT__ 183 #define __FUNCT__ "DMMoabCreateMoab" 184 /*@ 185 DMMoabCreate - Creates a DMMoab object, optionally from an instance and other data 186 187 Collective on MPI_Comm 188 189 Input Parameter: 190 . comm - The communicator for the DMMoab object 191 . mbiface - (ptr to) the MOAB Instance; if passed in NULL, MOAB instance is created inside PETSc, and destroyed 192 along with the DMMoab 193 . pcomm - (ptr to) a ParallelComm; if NULL, creates one internally for the whole communicator 194 . ltog_tag - A tag to use to retrieve global id for an entity; if 0, will use GLOBAL_ID_TAG_NAME/tag 195 . range - If non-NULL, contains range of entities to which DOFs will be assigned 196 197 Output Parameter: 198 . dmb - The DMMoab object 199 200 Level: intermediate 201 202 .keywords: DMMoab, create 203 @*/ 204 PetscErrorCode DMMoabCreateMoab(MPI_Comm comm, moab::Interface *mbiface, moab::ParallelComm *pcomm, moab::Tag *ltog_tag, moab::Range *range, DM *dmb) 205 { 206 PetscErrorCode ierr; 207 moab::ErrorCode merr; 208 DM_Moab *dmmoab; 209 210 PetscFunctionBegin; 211 PetscValidPointer(dmb,6); 212 ierr = DMMoabCreate(comm, dmb);CHKERRQ(ierr); 213 dmmoab = (DM_Moab*)(*dmb)->data; 214 215 if (!mbiface) { 216 mbiface = new moab::Core(); 217 dmmoab->icreatedinstance = PETSC_TRUE; 218 } 219 else 220 dmmoab->icreatedinstance = PETSC_FALSE; 221 222 if (!pcomm) { 223 moab::EntityHandle rootset,partnset; 224 PetscInt rank, nprocs; 225 ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); 226 ierr = MPI_Comm_size(comm, &nprocs);CHKERRQ(ierr); 227 228 /* Create root sets for each mesh. Then pass these 229 to the load_file functions to be populated. */ 230 merr = mbiface->create_meshset(moab::MESHSET_SET, rootset); 231 MBERR("Creating root set failed", merr); 232 merr = mbiface->create_meshset(moab::MESHSET_SET, partnset); 233 MBERR("Creating partition set failed", merr); 234 235 /* Create the parallel communicator object with the partition handle associated with MOAB */ 236 pcomm = moab::ParallelComm::get_pcomm(mbiface, partnset, &comm); 237 } 238 239 if (!ltog_tag) { 240 merr = mbiface->tag_get_handle(GLOBAL_ID_TAG_NAME, *ltog_tag);MBERRNM(merr); 241 } 242 else { 243 ierr = DMMoabSetLocalToGlobalTag(*dmb, *ltog_tag);CHKERRQ(ierr); 244 } 245 246 /* do the initialization of the DM */ 247 dmmoab->bs = 1; 248 ierr = DMMoabSetParallelComm(*dmb, pcomm);CHKERRQ(ierr); 249 dmmoab->ltog_tag = *ltog_tag; 250 if (range) { 251 ierr = DMMoabSetRange(*dmb, range);CHKERRQ(ierr); 252 } 253 PetscFunctionReturn(0); 254 } 255 256 #undef __FUNCT__ 257 #define __FUNCT__ "DMMoabSetParallelComm" 258 /*@ 259 DMMoabSetParallelComm - Set the ParallelComm used with this DMMoab 260 261 Collective on MPI_Comm 262 263 Input Parameter: 264 . dm - The DMMoab object being set 265 . pcomm - The ParallelComm being set on the DMMoab 266 267 Level: beginner 268 269 .keywords: DMMoab, create 270 @*/ 271 PetscErrorCode DMMoabSetParallelComm(DM dm,moab::ParallelComm *pcomm) 272 { 273 DM_Moab *dmmoab = (DM_Moab*)(dm)->data; 274 275 PetscFunctionBegin; 276 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 277 dmmoab->pcomm = pcomm; 278 dmmoab->mbiface = pcomm->get_moab(); 279 dmmoab->icreatedinstance = PETSC_FALSE; 280 PetscFunctionReturn(0); 281 } 282 283 284 #undef __FUNCT__ 285 #define __FUNCT__ "DMMoabGetParallelComm" 286 /*@ 287 DMMoabGetParallelComm - Get the ParallelComm used with this DMMoab 288 289 Collective on MPI_Comm 290 291 Input Parameter: 292 . dm - The DMMoab object being set 293 294 Output Parameter: 295 . pcomm - The ParallelComm for the DMMoab 296 297 Level: beginner 298 299 .keywords: DMMoab, create 300 @*/ 301 PetscErrorCode DMMoabGetParallelComm(DM dm,moab::ParallelComm **pcomm) 302 { 303 PetscFunctionBegin; 304 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 305 *pcomm = ((DM_Moab*)(dm)->data)->pcomm; 306 PetscFunctionReturn(0); 307 } 308 309 310 #undef __FUNCT__ 311 #define __FUNCT__ "DMMoabSetInterface" 312 /*@ 313 DMMoabSetInterface - Set the MOAB instance used with this DMMoab 314 315 Collective on MPI_Comm 316 317 Input Parameter: 318 . dm - The DMMoab object being set 319 . mbiface - The MOAB instance being set on this DMMoab 320 321 Level: beginner 322 323 .keywords: DMMoab, create 324 @*/ 325 PetscErrorCode DMMoabSetInterface(DM dm,moab::Interface *mbiface) 326 { 327 DM_Moab *dmmoab = (DM_Moab*)(dm)->data; 328 329 PetscFunctionBegin; 330 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 331 dmmoab->pcomm = NULL; 332 dmmoab->mbiface = mbiface; 333 dmmoab->icreatedinstance = PETSC_FALSE; 334 PetscFunctionReturn(0); 335 } 336 337 338 #undef __FUNCT__ 339 #define __FUNCT__ "DMMoabGetInterface" 340 /*@ 341 DMMoabGetInterface - Get the MOAB instance used with this DMMoab 342 343 Collective on MPI_Comm 344 345 Input Parameter: 346 . dm - The DMMoab object being set 347 348 Output Parameter: 349 . mbiface - The MOAB instance set on this DMMoab 350 351 Level: beginner 352 353 .keywords: DMMoab, create 354 @*/ 355 PetscErrorCode DMMoabGetInterface(DM dm,moab::Interface **mbiface) 356 { 357 PetscErrorCode ierr; 358 static PetscBool cite = PETSC_FALSE; 359 360 PetscFunctionBegin; 361 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 362 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); 363 *mbiface = ((DM_Moab*)dm->data)->mbiface; 364 PetscFunctionReturn(0); 365 } 366 367 368 #undef __FUNCT__ 369 #define __FUNCT__ "DMMoabSetRange" 370 /*@ 371 DMMoabSetRange - Set the entities having DOFs on this DMMoab 372 373 Collective on MPI_Comm 374 375 Input Parameter: 376 . dm - The DMMoab object being set 377 . range - The entities treated by this DMMoab 378 379 Level: beginner 380 381 .keywords: DMMoab, create 382 @*/ 383 PetscErrorCode DMMoabSetRange(DM dm,moab::Range *range) 384 { 385 moab::ErrorCode merr; 386 PetscErrorCode ierr; 387 DM_Moab *dmmoab = (DM_Moab*)(dm)->data; 388 389 PetscFunctionBegin; 390 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 391 dmmoab->vlocal->clear(); 392 dmmoab->vowned->clear(); 393 dmmoab->vlocal->insert(range->begin(), range->end()); 394 *dmmoab->vowned = *dmmoab->vlocal; 395 merr = dmmoab->pcomm->filter_pstatus(*dmmoab->vowned,PSTATUS_NOT_OWNED,PSTATUS_NOT);MBERRNM(merr); 396 *dmmoab->vghost = moab::subtract(*range, *dmmoab->vowned); 397 dmmoab->nloc=dmmoab->vowned->size(); 398 dmmoab->nghost=dmmoab->vghost->size(); 399 ierr = MPI_Allreduce(&dmmoab->nloc, &dmmoab->n, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm);CHKERRQ(ierr); 400 PetscFunctionReturn(0); 401 } 402 403 404 #undef __FUNCT__ 405 #define __FUNCT__ "DMMoabGetRange" 406 /*@ 407 DMMoabGetRange - Get the entities having DOFs on this DMMoab 408 409 Collective on MPI_Comm 410 411 Input Parameter: 412 . dm - The DMMoab object being set 413 414 Output Parameter: 415 . range - The entities treated by this DMMoab 416 417 Level: beginner 418 419 .keywords: DMMoab, create 420 @*/ 421 PetscErrorCode DMMoabGetRange(DM dm,moab::Range **range) 422 { 423 PetscFunctionBegin; 424 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 425 *range = ((DM_Moab*)dm->data)->vowned; 426 PetscFunctionReturn(0); 427 } 428 429 #undef __FUNCT__ 430 #define __FUNCT__ "DMMoabSetLocalToGlobalTag" 431 /*@ 432 DMMoabSetLocalToGlobalTag - Set the tag used for local to global numbering 433 434 Collective on MPI_Comm 435 436 Input Parameter: 437 . dm - The DMMoab object being set 438 . ltogtag - The MOAB tag used for local to global ids 439 440 Level: beginner 441 442 .keywords: DMMoab, create 443 @*/ 444 PetscErrorCode DMMoabSetLocalToGlobalTag(DM dm,moab::Tag ltogtag) 445 { 446 PetscFunctionBegin; 447 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 448 ((DM_Moab*)dm->data)->ltog_tag = ltogtag; 449 PetscFunctionReturn(0); 450 } 451 452 453 #undef __FUNCT__ 454 #define __FUNCT__ "DMMoabGetLocalToGlobalTag" 455 /*@ 456 DMMoabGetLocalToGlobalTag - Get the tag used for local to global numbering 457 458 Collective on MPI_Comm 459 460 Input Parameter: 461 . dm - The DMMoab object being set 462 463 Output Parameter: 464 . ltogtag - The MOAB tag used for local to global ids 465 466 Level: beginner 467 468 .keywords: DMMoab, create 469 @*/ 470 PetscErrorCode DMMoabGetLocalToGlobalTag(DM dm,moab::Tag *ltog_tag) 471 { 472 PetscFunctionBegin; 473 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 474 *ltog_tag = ((DM_Moab*)dm->data)->ltog_tag; 475 PetscFunctionReturn(0); 476 } 477 478 479 #undef __FUNCT__ 480 #define __FUNCT__ "DMMoabSetBlockSize" 481 /*@ 482 DMMoabSetBlockSize - Set the block size used with this DMMoab 483 484 Collective on MPI_Comm 485 486 Input Parameter: 487 . dm - The DMMoab object being set 488 . bs - The block size used with this DMMoab 489 490 Level: beginner 491 492 .keywords: DMMoab, create 493 @*/ 494 PetscErrorCode DMMoabSetBlockSize(DM dm,PetscInt bs) 495 { 496 PetscFunctionBegin; 497 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 498 ((DM_Moab*)dm->data)->bs = bs; 499 PetscFunctionReturn(0); 500 } 501 502 503 #undef __FUNCT__ 504 #define __FUNCT__ "DMMoabGetBlockSize" 505 /*@ 506 DMMoabGetBlockSize - Get the block size used with this DMMoab 507 508 Collective on MPI_Comm 509 510 Input Parameter: 511 . dm - The DMMoab object being set 512 513 Output Parameter: 514 . bs - The block size used with this DMMoab 515 516 Level: beginner 517 518 .keywords: DMMoab, create 519 @*/ 520 PetscErrorCode DMMoabGetBlockSize(DM dm,PetscInt *bs) 521 { 522 PetscFunctionBegin; 523 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 524 *bs = ((DM_Moab*)dm->data)->bs; 525 PetscFunctionReturn(0); 526 } 527 528