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 #include <moab/Skinner.hpp> 7 8 #undef __FUNCT__ 9 #define __FUNCT__ "DMDestroy_Moab" 10 PetscErrorCode DMDestroy_Moab(DM dm) 11 { 12 PetscErrorCode ierr; 13 DM_Moab *dmmoab = (DM_Moab*)dm->data; 14 15 PetscFunctionBegin; 16 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 17 if (dmmoab->icreatedinstance) { 18 delete dmmoab->mbiface; 19 } 20 dmmoab->mbiface = NULL; 21 dmmoab->pcomm = NULL; 22 delete dmmoab->vlocal; 23 delete dmmoab->vowned; 24 delete dmmoab->vghost; 25 delete dmmoab->elocal; 26 delete dmmoab->eghost; 27 delete dmmoab->bndyvtx; 28 delete dmmoab->bndyfaces; 29 delete dmmoab->bndyelems; 30 31 ierr = PetscFree(dmmoab->gsindices);CHKERRQ(ierr); 32 ierr = VecScatterDestroy(&dmmoab->ltog_sendrecv);CHKERRQ(ierr); 33 ierr = ISLocalToGlobalMappingDestroy(&dmmoab->ltog_map);CHKERRQ(ierr); 34 ierr = PetscFree(dm->data);CHKERRQ(ierr); 35 PetscFunctionReturn(0); 36 } 37 38 #undef __FUNCT__ 39 #define __FUNCT__ "DMSetUp_Moab" 40 PetscErrorCode DMSetUp_Moab(DM dm) 41 { 42 PetscErrorCode ierr; 43 moab::ErrorCode merr; 44 Vec local, global; 45 IS from; 46 moab::Range::iterator iter; 47 PetscInt i,j,bs,gsiz,lsiz; 48 DM_Moab *dmmoab = (DM_Moab*)dm->data; 49 PetscInt totsize; 50 PetscSection section; 51 PetscInt gmin,lmin,lmax; 52 53 moab::Range adj; 54 55 PetscFunctionBegin; 56 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 57 /* Get the local and shared vertices and cache it */ 58 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."); 59 60 /* Get the entities recursively in the current part of the mesh, if user did not set the local vertices explicitly */ 61 if (dmmoab->vlocal->empty()) { 62 merr = dmmoab->mbiface->get_entities_by_type(dmmoab->fileset,moab::MBVERTEX,*dmmoab->vlocal,true);MBERRNM(merr); 63 64 /* filter based on parallel status */ 65 merr = dmmoab->pcomm->filter_pstatus(*dmmoab->vlocal,PSTATUS_NOT_OWNED,PSTATUS_NOT,-1,dmmoab->vowned);MBERRNM(merr); 66 *dmmoab->vghost = moab::subtract(*dmmoab->vlocal, *dmmoab->vowned); 67 68 dmmoab->nloc = dmmoab->vowned->size(); 69 dmmoab->nghost = dmmoab->vghost->size(); 70 ierr = MPI_Allreduce(&dmmoab->nloc, &dmmoab->n, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm);CHKERRQ(ierr); 71 72 #if 0 73 if(dmmoab->pcomm->rank() || dmmoab->pcomm->size()==1) { 74 PetscPrintf(PETSC_COMM_SELF, "Vertices: global: %D, local: %D", dmmoab->n, dmmoab->nloc+dmmoab->nghost); 75 dmmoab->vlocal->print(0); 76 PetscPrintf(PETSC_COMM_SELF, "Vertices: owned: %D", dmmoab->nloc); 77 dmmoab->vowned->print(0); 78 PetscPrintf(PETSC_COMM_SELF, "Vertices: ghost: %D", dmmoab->nghost); 79 dmmoab->vghost->print(0); 80 } 81 #endif 82 } 83 84 /* get the information about the local elements in the mesh */ 85 { 86 dmmoab->eghost->clear(); 87 88 /* first decipher the leading dimension */ 89 for (i=3;i>0;i--) { 90 dmmoab->elocal->clear(); 91 merr = dmmoab->mbiface->get_entities_by_dimension(dmmoab->fileset, i, *dmmoab->elocal, true);CHKERRQ(merr); 92 93 /* store the current mesh dimension */ 94 if (dmmoab->elocal->size()) { 95 dmmoab->dim=i; 96 break; 97 } 98 } 99 100 *dmmoab->eghost = *dmmoab->elocal; 101 merr = dmmoab->pcomm->filter_pstatus(*dmmoab->elocal,PSTATUS_NOT_OWNED,PSTATUS_NOT);MBERRNM(merr); 102 *dmmoab->eghost = moab::subtract(*dmmoab->eghost, *dmmoab->elocal); 103 104 dmmoab->neleloc = dmmoab->elocal->size(); 105 ierr = MPI_Allreduce(&dmmoab->neleloc, &dmmoab->nele, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm);CHKERRQ(ierr); 106 } 107 108 bs = dmmoab->bs; 109 if (!dmmoab->ltog_tag) { 110 /* Get the global ID tag. The global ID tag is applied to each 111 vertex. It acts as an global identifier which MOAB uses to 112 assemble the individual pieces of the mesh */ 113 merr = dmmoab->mbiface->tag_get_handle(GLOBAL_ID_TAG_NAME, dmmoab->ltog_tag);MBERRNM(merr); 114 } 115 116 totsize=dmmoab->vlocal->size(); 117 ierr = PetscMalloc(totsize*sizeof(PetscInt), &dmmoab->gsindices);CHKERRQ(ierr); 118 { 119 /* first get the local indices */ 120 merr = dmmoab->mbiface->tag_get_data(dmmoab->ltog_tag,*dmmoab->vowned,&dmmoab->gsindices[0]);MBERRNM(merr); 121 /* next get the ghosted indices */ 122 if (dmmoab->nghost) { 123 merr = dmmoab->mbiface->tag_get_data(dmmoab->ltog_tag,*dmmoab->vghost,&dmmoab->gsindices[dmmoab->nloc]);MBERRNM(merr); 124 } 125 126 /* find out the local and global minima of GLOBAL_ID */ 127 lmin=lmax=dmmoab->gsindices[0]; 128 for (i=0; i<totsize; ++i) { 129 if(lmin>dmmoab->gsindices[i]) lmin=dmmoab->gsindices[i]; 130 if(lmax<dmmoab->gsindices[i]) lmax=dmmoab->gsindices[i]; 131 } 132 133 ierr = MPI_Allreduce(&lmin, &gmin, 1, MPI_INT, MPI_MIN, ((PetscObject)dm)->comm);CHKERRQ(ierr); 134 PetscInfo3(dm, "GLOBAL_ID: Local minima - %D, Local maxima - %D, Global minima - %D.\n", lmin, lmax, gmin); 135 } 136 137 { 138 ierr = PetscSectionCreate(((PetscObject)dm)->comm, §ion);CHKERRQ(ierr); 139 ierr = PetscSectionSetNumFields(section, dmmoab->nfields);CHKERRQ(ierr); 140 ierr = PetscSectionSetChart(section, lmin, lmax+1);CHKERRQ(ierr); 141 for (j=0; j<totsize; ++j) { 142 PetscInt locgid = dmmoab->gsindices[j]; 143 for (i=0; i < dmmoab->nfields; ++i) { 144 ierr = PetscSectionSetFieldName(section, i, dmmoab->fields[i]);CHKERRQ(ierr); 145 if (bs>1) { 146 ierr = PetscSectionSetFieldDof(section, locgid, i, (locgid-gmin)*dmmoab->nfields+i);CHKERRQ(ierr); 147 ierr = PetscSectionSetFieldOffset(section, locgid, i, (locgid-gmin)*dmmoab->nfields); 148 } 149 else { 150 ierr = PetscSectionSetFieldDof(section, locgid, i, dmmoab->n*i+locgid-gmin);CHKERRQ(ierr); 151 ierr = PetscSectionSetFieldOffset(section, locgid, i, i*dmmoab->n); 152 } 153 } 154 ierr = PetscSectionSetDof(section, locgid, dmmoab->nfields);CHKERRQ(ierr); 155 } 156 ierr = PetscSectionSetUp(section);CHKERRQ(ierr); 157 ierr = DMSetDefaultSection(dm, section);CHKERRQ(ierr); 158 } 159 160 { 161 for (i=0; i<totsize; ++i) { 162 dmmoab->gsindices[i]-=gmin; /* zero based index needed for IS */ 163 } 164 165 /* Create Global to Local Vector Scatter Context */ 166 ierr = DMCreateGlobalVector_Moab(dm, &global);CHKERRQ(ierr); 167 ierr = DMCreateLocalVector_Moab(dm, &local);CHKERRQ(ierr); 168 169 /* global to local must retrieve ghost points */ 170 ierr = ISCreateBlock(((PetscObject)dm)->comm,bs,totsize,&dmmoab->gsindices[0],PETSC_COPY_VALUES,&from);CHKERRQ(ierr); 171 172 ierr = VecGetLocalSize(global,&gsiz);CHKERRQ(ierr); 173 ierr = VecGetLocalSize(local,&lsiz);CHKERRQ(ierr); 174 175 ierr = VecScatterCreate(local,from,global,from,&dmmoab->ltog_sendrecv);CHKERRQ(ierr); 176 ierr = ISDestroy(&from);CHKERRQ(ierr); 177 ierr = VecDestroy(&local);CHKERRQ(ierr); 178 ierr = VecDestroy(&global);CHKERRQ(ierr); 179 } 180 181 /* skin the boundary and store nodes */ 182 { 183 /* get the skin vertices of boundary faces for the current partition and then filter 184 the local, boundary faces, vertices and elements alone via PSTATUS flags; 185 this should not give us any ghosted boundary, but if user needs such a functionality 186 it would be easy to add it based on the find_skin query below */ 187 moab::Skinner skinner(dmmoab->mbiface); 188 dmmoab->bndyvtx = new moab::Range(); 189 dmmoab->bndyfaces = new moab::Range(); 190 dmmoab->bndyelems = new moab::Range(); 191 192 /* get the entities on the skin - only the faces */ 193 merr = skinner.find_skin(dmmoab->fileset, *dmmoab->elocal, false, *dmmoab->bndyfaces, NULL, false, true, false, false);MBERRNM(merr); // 'false' param indicates we want faces back, not vertices 194 195 /* filter all the non-owned and shared entities out of the list */ 196 merr = dmmoab->pcomm->filter_pstatus(*dmmoab->bndyfaces,PSTATUS_NOT_OWNED,PSTATUS_NOT);MBERRNM(merr); 197 merr = dmmoab->pcomm->filter_pstatus(*dmmoab->bndyfaces,PSTATUS_SHARED,PSTATUS_NOT);MBERRNM(merr); 198 199 if (dmmoab->dim == 3) { 200 // get the edges from faces and then do the same if needed 201 } 202 203 /* get all the nodes via connectivity and the parent elements via adjacency information */ 204 merr = dmmoab->mbiface->get_connectivity(*dmmoab->bndyfaces, *dmmoab->bndyvtx, false);MBERRNM(ierr); 205 merr = dmmoab->mbiface->get_adjacencies(*dmmoab->bndyfaces, dmmoab->dim, false, *dmmoab->bndyelems, moab::Interface::UNION);MBERRNM(ierr); 206 PetscInfo3(dm, "Found %D boundary vertices, %D boundary faces and %D boundary elements.\n", dmmoab->bndyvtx->size(), dmmoab->bndyvtx->size(), dmmoab->bndyelems->size()); 207 } 208 PetscFunctionReturn(0); 209 } 210 211 212 #undef __FUNCT__ 213 #define __FUNCT__ "DMCreate_Moab" 214 PETSC_EXTERN PetscErrorCode DMCreate_Moab(DM dm) 215 { 216 PetscErrorCode ierr; 217 218 PetscFunctionBegin; 219 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 220 ierr = PetscNewLog(dm,&dm->data);CHKERRQ(ierr); 221 222 ((DM_Moab*)dm->data)->bs = 1; 223 ((DM_Moab*)dm->data)->n = 0; 224 ((DM_Moab*)dm->data)->nloc = 0; 225 ((DM_Moab*)dm->data)->nele = 0; 226 ((DM_Moab*)dm->data)->neleloc = 0; 227 ((DM_Moab*)dm->data)->nghost = 0; 228 ((DM_Moab*)dm->data)->ltog_map = PETSC_NULL; 229 ((DM_Moab*)dm->data)->ltog_sendrecv = PETSC_NULL; 230 231 ((DM_Moab*)dm->data)->vlocal = new moab::Range(); 232 ((DM_Moab*)dm->data)->vowned = new moab::Range(); 233 ((DM_Moab*)dm->data)->vghost = new moab::Range(); 234 ((DM_Moab*)dm->data)->elocal = new moab::Range(); 235 ((DM_Moab*)dm->data)->eghost = new moab::Range(); 236 237 dm->ops->createglobalvector = DMCreateGlobalVector_Moab; 238 dm->ops->createlocalvector = DMCreateLocalVector_Moab; 239 dm->ops->creatematrix = DMCreateMatrix_Moab; 240 dm->ops->setup = DMSetUp_Moab; 241 dm->ops->destroy = DMDestroy_Moab; 242 dm->ops->globaltolocalbegin = DMGlobalToLocalBegin_Moab; 243 dm->ops->globaltolocalend = DMGlobalToLocalEnd_Moab; 244 dm->ops->localtoglobalbegin = DMLocalToGlobalBegin_Moab; 245 dm->ops->localtoglobalend = DMLocalToGlobalEnd_Moab; 246 PetscFunctionReturn(0); 247 } 248 249 #undef __FUNCT__ 250 #define __FUNCT__ "DMMoabCreate" 251 /*@ 252 DMMoabCreate - Creates a DMMoab object, which encapsulates a moab instance 253 254 Collective on MPI_Comm 255 256 Input Parameter: 257 . comm - The communicator for the DMMoab object 258 259 Output Parameter: 260 . dmb - The DMMoab object 261 262 Level: beginner 263 264 .keywords: DMMoab, create 265 @*/ 266 PetscErrorCode DMMoabCreate(MPI_Comm comm, DM *dmb) 267 { 268 PetscErrorCode ierr; 269 270 PetscFunctionBegin; 271 PetscValidPointer(dmb,2); 272 ierr = DMCreate(comm, dmb);CHKERRQ(ierr); 273 ierr = DMSetType(*dmb, DMMOAB);CHKERRQ(ierr); 274 PetscFunctionReturn(0); 275 } 276 277 #undef __FUNCT__ 278 #define __FUNCT__ "DMMoabCreateMoab" 279 /*@ 280 DMMoabCreate - Creates a DMMoab object, optionally from an instance and other data 281 282 Collective on MPI_Comm 283 284 Input Parameter: 285 . comm - The communicator for the DMMoab object 286 . mbiface - (ptr to) the MOAB Instance; if passed in NULL, MOAB instance is created inside PETSc, and destroyed 287 along with the DMMoab 288 . pcomm - (ptr to) a ParallelComm; if NULL, creates one internally for the whole communicator 289 . ltog_tag - A tag to use to retrieve global id for an entity; if 0, will use GLOBAL_ID_TAG_NAME/tag 290 . range - If non-NULL, contains range of entities to which DOFs will be assigned 291 292 Output Parameter: 293 . dmb - The DMMoab object 294 295 Level: intermediate 296 297 .keywords: DMMoab, create 298 @*/ 299 PetscErrorCode DMMoabCreateMoab(MPI_Comm comm, moab::Interface *mbiface, moab::ParallelComm *pcomm, moab::Tag *ltog_tag, moab::Range *range, DM *dmb) 300 { 301 PetscErrorCode ierr; 302 moab::ErrorCode merr; 303 moab::EntityHandle partnset; 304 PetscInt rank, nprocs; 305 DM_Moab *dmmoab; 306 307 PetscFunctionBegin; 308 PetscValidPointer(dmb,6); 309 ierr = DMMoabCreate(comm, dmb);CHKERRQ(ierr); 310 dmmoab = (DM_Moab*)(*dmb)->data; 311 312 if (!mbiface) { 313 dmmoab->mbiface = new moab::Core(); 314 dmmoab->icreatedinstance = PETSC_TRUE; 315 } 316 else { 317 dmmoab->mbiface = mbiface; 318 dmmoab->icreatedinstance = PETSC_FALSE; 319 } 320 321 /* create a fileset to store the hierarchy of entities belonging to current DM */ 322 merr = dmmoab->mbiface->create_meshset(moab::MESHSET_ORDERED, dmmoab->fileset);MBERR("Creating file set failed", merr); 323 324 if (!pcomm) { 325 ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); 326 ierr = MPI_Comm_size(comm, &nprocs);CHKERRQ(ierr); 327 328 /* Create root sets for each mesh. Then pass these 329 to the load_file functions to be populated. */ 330 merr = dmmoab->mbiface->create_meshset(moab::MESHSET_SET, partnset); 331 MBERR("Creating partition set failed", merr); 332 333 /* Create the parallel communicator object with the partition handle associated with MOAB */ 334 dmmoab->pcomm = moab::ParallelComm::get_pcomm(dmmoab->mbiface, partnset, &comm); 335 } 336 else { 337 ierr = DMMoabSetParallelComm(*dmb, pcomm);CHKERRQ(ierr); 338 } 339 340 /* do the remaining initializations for DMMoab */ 341 dmmoab->bs = 1; 342 343 /* set global ID tag handle */ 344 if (!ltog_tag) { 345 merr = dmmoab->mbiface->tag_get_handle(GLOBAL_ID_TAG_NAME, dmmoab->ltog_tag);MBERRNM(merr); 346 } 347 else { 348 ierr = DMMoabSetLocalToGlobalTag(*dmb, *ltog_tag);CHKERRQ(ierr); 349 } 350 351 /* set the local range of entities (vertices) of interest */ 352 if (range) { 353 ierr = DMMoabSetLocalVertices(*dmb, range);CHKERRQ(ierr); 354 } 355 PetscFunctionReturn(0); 356 } 357 358 #undef __FUNCT__ 359 #define __FUNCT__ "DMMoabSetParallelComm" 360 /*@ 361 DMMoabSetParallelComm - Set the ParallelComm used with this DMMoab 362 363 Collective on MPI_Comm 364 365 Input Parameter: 366 . dm - The DMMoab object being set 367 . pcomm - The ParallelComm being set on the DMMoab 368 369 Level: beginner 370 371 .keywords: DMMoab, create 372 @*/ 373 PetscErrorCode DMMoabSetParallelComm(DM dm,moab::ParallelComm *pcomm) 374 { 375 DM_Moab *dmmoab = (DM_Moab*)(dm)->data; 376 377 PetscFunctionBegin; 378 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 379 PetscValidPointer(pcomm,2); 380 dmmoab->pcomm = pcomm; 381 dmmoab->mbiface = pcomm->get_moab(); 382 dmmoab->icreatedinstance = PETSC_FALSE; 383 PetscFunctionReturn(0); 384 } 385 386 387 #undef __FUNCT__ 388 #define __FUNCT__ "DMMoabGetParallelComm" 389 /*@ 390 DMMoabGetParallelComm - Get the ParallelComm used with this DMMoab 391 392 Collective on MPI_Comm 393 394 Input Parameter: 395 . dm - The DMMoab object being set 396 397 Output Parameter: 398 . pcomm - The ParallelComm for the DMMoab 399 400 Level: beginner 401 402 .keywords: DMMoab, create 403 @*/ 404 PetscErrorCode DMMoabGetParallelComm(DM dm,moab::ParallelComm **pcomm) 405 { 406 PetscFunctionBegin; 407 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 408 *pcomm = ((DM_Moab*)(dm)->data)->pcomm; 409 PetscFunctionReturn(0); 410 } 411 412 413 #undef __FUNCT__ 414 #define __FUNCT__ "DMMoabSetInterface" 415 /*@ 416 DMMoabSetInterface - Set the MOAB instance used with this DMMoab 417 418 Collective on MPI_Comm 419 420 Input Parameter: 421 . dm - The DMMoab object being set 422 . mbiface - The MOAB instance being set on this DMMoab 423 424 Level: beginner 425 426 .keywords: DMMoab, create 427 @*/ 428 PetscErrorCode DMMoabSetInterface(DM dm,moab::Interface *mbiface) 429 { 430 DM_Moab *dmmoab = (DM_Moab*)(dm)->data; 431 432 PetscFunctionBegin; 433 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 434 PetscValidPointer(mbiface,2); 435 dmmoab->pcomm = NULL; 436 dmmoab->mbiface = mbiface; 437 dmmoab->icreatedinstance = PETSC_FALSE; 438 PetscFunctionReturn(0); 439 } 440 441 442 #undef __FUNCT__ 443 #define __FUNCT__ "DMMoabGetInterface" 444 /*@ 445 DMMoabGetInterface - Get the MOAB instance used with this DMMoab 446 447 Collective on MPI_Comm 448 449 Input Parameter: 450 . dm - The DMMoab object being set 451 452 Output Parameter: 453 . mbiface - The MOAB instance set on this DMMoab 454 455 Level: beginner 456 457 .keywords: DMMoab, create 458 @*/ 459 PetscErrorCode DMMoabGetInterface(DM dm,moab::Interface **mbiface) 460 { 461 PetscErrorCode ierr; 462 static PetscBool cite = PETSC_FALSE; 463 464 PetscFunctionBegin; 465 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 466 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); 467 *mbiface = ((DM_Moab*)dm->data)->mbiface; 468 PetscFunctionReturn(0); 469 } 470 471 472 #undef __FUNCT__ 473 #define __FUNCT__ "DMMoabSetLocalVertices" 474 /*@ 475 DMMoabSetLocalVertices - Set the entities having DOFs on this DMMoab 476 477 Collective on MPI_Comm 478 479 Input Parameter: 480 . dm - The DMMoab object being set 481 . range - The entities treated by this DMMoab 482 483 Level: beginner 484 485 .keywords: DMMoab, create 486 @*/ 487 PetscErrorCode DMMoabSetLocalVertices(DM dm,moab::Range *range) 488 { 489 moab::ErrorCode merr; 490 PetscErrorCode ierr; 491 DM_Moab *dmmoab = (DM_Moab*)(dm)->data; 492 493 PetscFunctionBegin; 494 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 495 dmmoab->vlocal->clear(); 496 dmmoab->vowned->clear(); 497 dmmoab->vlocal->insert(range->begin(), range->end()); 498 *dmmoab->vowned = *dmmoab->vlocal; 499 merr = dmmoab->pcomm->filter_pstatus(*dmmoab->vowned,PSTATUS_NOT_OWNED,PSTATUS_NOT);MBERRNM(merr); 500 *dmmoab->vghost = moab::subtract(*range, *dmmoab->vowned); 501 dmmoab->nloc=dmmoab->vowned->size(); 502 dmmoab->nghost=dmmoab->vghost->size(); 503 ierr = MPI_Allreduce(&dmmoab->nloc, &dmmoab->n, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm);CHKERRQ(ierr); 504 PetscFunctionReturn(0); 505 } 506 507 508 #undef __FUNCT__ 509 #define __FUNCT__ "DMMoabGetLocalVertices" 510 /*@ 511 DMMoabGetLocalVertices - Get the entities having DOFs on this DMMoab 512 513 Collective on MPI_Comm 514 515 Input Parameter: 516 . dm - The DMMoab object being set 517 518 Output Parameter: 519 . owned - The owned vertex entities in this DMMoab 520 . ghost - The ghosted entities (non-owned) stored locally in this partition 521 522 Level: beginner 523 524 .keywords: DMMoab, create 525 @*/ 526 PetscErrorCode DMMoabGetLocalVertices(DM dm,moab::Range *owned,moab::Range *ghost) 527 { 528 PetscFunctionBegin; 529 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 530 if (owned) *owned = *((DM_Moab*)dm->data)->vowned; 531 if (ghost) *ghost = *((DM_Moab*)dm->data)->vghost; 532 PetscFunctionReturn(0); 533 } 534 535 #undef __FUNCT__ 536 #define __FUNCT__ "DMMoabGetLocalElements" 537 /*@ 538 DMMoabGetLocalElements - Get the higher-dimensional entities that are locally owned 539 540 Collective on MPI_Comm 541 542 Input Parameter: 543 . dm - The DMMoab object being set 544 545 Output Parameter: 546 . range - The entities owned locally 547 548 Level: beginner 549 550 .keywords: DMMoab, create 551 @*/ 552 PetscErrorCode DMMoabGetLocalElements(DM dm,moab::Range *range) 553 { 554 PetscFunctionBegin; 555 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 556 if (range) *range = *((DM_Moab*)dm->data)->elocal; 557 PetscFunctionReturn(0); 558 } 559 560 561 #undef __FUNCT__ 562 #define __FUNCT__ "DMMoabSetLocalElements" 563 /*@ 564 DMMoabSetLocalElements - Set the entities having DOFs on this DMMoab 565 566 Collective on MPI_Comm 567 568 Input Parameter: 569 . dm - The DMMoab object being set 570 . range - The entities treated by this DMMoab 571 572 Level: beginner 573 574 .keywords: DMMoab, create 575 @*/ 576 PetscErrorCode DMMoabSetLocalElements(DM dm,moab::Range *range) 577 { 578 moab::ErrorCode merr; 579 PetscErrorCode ierr; 580 DM_Moab *dmmoab = (DM_Moab*)(dm)->data; 581 582 PetscFunctionBegin; 583 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 584 dmmoab->elocal->clear(); 585 dmmoab->eghost->clear(); 586 dmmoab->elocal->insert(range->begin(), range->end()); 587 PetscInfo2(dm, "Range size = %D; elocal size = %D.\n", range->size(), dmmoab->elocal->size()); 588 merr = dmmoab->pcomm->filter_pstatus(*dmmoab->elocal,PSTATUS_NOT_OWNED,PSTATUS_NOT);MBERRNM(merr); 589 *dmmoab->eghost = moab::subtract(*range, *dmmoab->elocal); 590 dmmoab->neleloc=dmmoab->elocal->size(); 591 ierr = MPI_Allreduce(&dmmoab->nele, &dmmoab->neleloc, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm);CHKERRQ(ierr); 592 PetscInfo2(dm, "Created %D local and %D glocal elements.\n", dmmoab->neleloc, dmmoab->nele); 593 PetscFunctionReturn(0); 594 } 595 596 597 #undef __FUNCT__ 598 #define __FUNCT__ "DMMoabSetLocalToGlobalTag" 599 /*@ 600 DMMoabSetLocalToGlobalTag - Set the tag used for local to global numbering 601 602 Collective on MPI_Comm 603 604 Input Parameter: 605 . dm - The DMMoab object being set 606 . ltogtag - The MOAB tag used for local to global ids 607 608 Level: beginner 609 610 .keywords: DMMoab, create 611 @*/ 612 PetscErrorCode DMMoabSetLocalToGlobalTag(DM dm,moab::Tag ltogtag) 613 { 614 PetscFunctionBegin; 615 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 616 ((DM_Moab*)dm->data)->ltog_tag = ltogtag; 617 PetscFunctionReturn(0); 618 } 619 620 621 #undef __FUNCT__ 622 #define __FUNCT__ "DMMoabGetLocalToGlobalTag" 623 /*@ 624 DMMoabGetLocalToGlobalTag - Get the tag used for local to global numbering 625 626 Collective on MPI_Comm 627 628 Input Parameter: 629 . dm - The DMMoab object being set 630 631 Output Parameter: 632 . ltogtag - The MOAB tag used for local to global ids 633 634 Level: beginner 635 636 .keywords: DMMoab, create 637 @*/ 638 PetscErrorCode DMMoabGetLocalToGlobalTag(DM dm,moab::Tag *ltog_tag) 639 { 640 PetscFunctionBegin; 641 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 642 *ltog_tag = ((DM_Moab*)dm->data)->ltog_tag; 643 PetscFunctionReturn(0); 644 } 645 646 647 #undef __FUNCT__ 648 #define __FUNCT__ "DMMoabSetBlockSize" 649 /*@ 650 DMMoabSetBlockSize - Set the block size used with this DMMoab 651 652 Collective on MPI_Comm 653 654 Input Parameter: 655 . dm - The DMMoab object being set 656 . bs - The block size used with this DMMoab 657 658 Level: beginner 659 660 .keywords: DMMoab, create 661 @*/ 662 PetscErrorCode DMMoabSetBlockSize(DM dm,PetscInt bs) 663 { 664 PetscFunctionBegin; 665 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 666 ((DM_Moab*)dm->data)->bs = bs; 667 PetscFunctionReturn(0); 668 } 669 670 671 #undef __FUNCT__ 672 #define __FUNCT__ "DMMoabGetBlockSize" 673 /*@ 674 DMMoabGetBlockSize - Get the block size used with this DMMoab 675 676 Collective on MPI_Comm 677 678 Input Parameter: 679 . dm - The DMMoab object being set 680 681 Output Parameter: 682 . bs - The block size used with this DMMoab 683 684 Level: beginner 685 686 .keywords: DMMoab, create 687 @*/ 688 PetscErrorCode DMMoabGetBlockSize(DM dm,PetscInt *bs) 689 { 690 PetscFunctionBegin; 691 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 692 *bs = ((DM_Moab*)dm->data)->bs; 693 PetscFunctionReturn(0); 694 } 695 696 697 #undef __FUNCT__ 698 #define __FUNCT__ "DMMoabSetFieldVector" 699 PetscErrorCode DMMoabSetFieldVector(DM dm, PetscInt ifield, Vec fvec) 700 { 701 DM_Moab *dmmoab; 702 moab::Tag vtag,ntag; 703 PetscScalar *varray; 704 moab::ErrorCode merr; 705 PetscErrorCode ierr; 706 PetscSection section; 707 PetscInt doff; 708 std::string tag_name; 709 moab::Range::iterator iter; 710 711 PetscFunctionBegin; 712 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 713 dmmoab = (DM_Moab*)(dm)->data; 714 715 ierr = DMGetDefaultSection(dm, §ion);CHKERRQ(ierr); 716 717 /* Create a tag in MOAB mesh to index and keep track of number of Petsc vec tags */ 718 merr = dmmoab->mbiface->tag_get_handle(dmmoab->fields[ifield],1,moab::MB_TYPE_DOUBLE,ntag, 719 moab::MB_TAG_SPARSE | moab::MB_TAG_CREAT);MBERRNM(merr); 720 721 ierr = DMMoabGetVecTag(fvec,&vtag);CHKERRQ(ierr); 722 723 merr = dmmoab->mbiface->tag_get_name(vtag, tag_name); 724 if (!tag_name.length() && merr !=moab::MB_SUCCESS) { 725 ierr = DMMoabVecGetArray(dm,fvec,&varray);CHKERRQ(ierr); 726 for(iter = dmmoab->vowned->begin(); iter != dmmoab->vowned->end(); iter++) { 727 moab::EntityHandle vtx = (*iter); 728 729 /* get field dof index */ 730 ierr = PetscSectionGetFieldOffset(section, vtx, ifield, &doff); 731 732 /* use the entity handle and the Dof index to set the right value */ 733 merr = dmmoab->mbiface->tag_set_data(ntag, &vtx, 1, (const void*)&varray[doff]);MBERRNM(merr); 734 } 735 ierr = DMMoabVecRestoreArray(dm,fvec,&varray);CHKERRQ(ierr); 736 } 737 else { 738 ierr = PetscMalloc(dmmoab->nloc*sizeof(PetscScalar),&varray);CHKERRQ(ierr); 739 /* we are using a MOAB Vec - directly copy the tag data to new one */ 740 merr = dmmoab->mbiface->tag_get_data(vtag, *dmmoab->vowned, (void*)varray);MBERRNM(merr); 741 merr = dmmoab->mbiface->tag_set_data(ntag, *dmmoab->vowned, (const void*)varray);MBERRNM(merr); 742 /* make sure the parallel exchange for ghosts are done appropriately */ 743 merr = dmmoab->pcomm->exchange_tags(ntag, *dmmoab->vlocal);MBERRNM(merr); 744 ierr = PetscFree(varray);CHKERRQ(ierr); 745 } 746 PetscFunctionReturn(0); 747 } 748 749 750 #undef __FUNCT__ 751 #define __FUNCT__ "DMMoabGetVertexCoordinates" 752 PetscErrorCode DMMoabGetVertexCoordinates(DM dm,PetscInt nconn,const moab::EntityHandle *conn,PetscScalar *vpos) 753 { 754 DM_Moab *dmmoab; 755 PetscErrorCode ierr; 756 moab::ErrorCode merr; 757 758 PetscFunctionBegin; 759 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 760 PetscValidPointer(conn,3); 761 dmmoab = (DM_Moab*)(dm)->data; 762 763 if (!vpos) { 764 ierr = PetscMalloc(sizeof(PetscScalar)*nconn*3, &vpos);CHKERRQ(ierr); 765 } 766 767 /* Get connectivity information in MOAB canonical ordering */ 768 merr = dmmoab->mbiface->get_coords(conn, nconn, vpos);MBERRNM(merr); 769 PetscFunctionReturn(0); 770 } 771 772 773 #undef __FUNCT__ 774 #define __FUNCT__ "DMMoabGetElementConnectivity" 775 PetscErrorCode DMMoabGetElementConnectivity(DM dm,moab::EntityHandle ehandle,PetscInt* nconn,const moab::EntityHandle **conn) 776 { 777 DM_Moab *dmmoab; 778 const moab::EntityHandle *connect; 779 moab::ErrorCode merr; 780 PetscInt nnodes; 781 782 PetscFunctionBegin; 783 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 784 PetscValidPointer(conn,4); 785 dmmoab = (DM_Moab*)(dm)->data; 786 787 /* Get connectivity information in MOAB canonical ordering */ 788 merr = dmmoab->mbiface->get_connectivity(ehandle, connect, nnodes);MBERRNM(merr); 789 if (conn) *conn=connect; 790 if (nconn) *nconn=nnodes; 791 PetscFunctionReturn(0); 792 } 793 794 795 #undef __FUNCT__ 796 #define __FUNCT__ "DMMoabIsEntityOnBoundary" 797 PetscErrorCode DMMoabIsEntityOnBoundary(DM dm,const moab::EntityHandle ent,PetscBool* ent_on_boundary) 798 { 799 moab::EntityType etype; 800 DM_Moab *dmmoab; 801 PetscInt edim; 802 803 PetscFunctionBegin; 804 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 805 PetscValidPointer(ent_on_boundary,3); 806 dmmoab = (DM_Moab*)(dm)->data; 807 808 /* get the entity type and handle accordingly */ 809 etype=dmmoab->mbiface->type_from_handle(ent); 810 if(etype >= moab::MBPOLYHEDRON) SETERRQ1(PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE, "Entity type on the boundary skin is invalid. EntityType = %D\n",etype); 811 812 /* get the entity dimension */ 813 edim=dmmoab->mbiface->dimension_from_handle(ent); 814 815 *ent_on_boundary=PETSC_FALSE; 816 if(etype == moab::MBVERTEX && edim == 0) { 817 moab::Range::const_iterator giter = dmmoab->bndyvtx->find(ent); 818 if (giter != dmmoab->bndyvtx->end()) *ent_on_boundary=PETSC_TRUE; 819 } 820 else { 821 if (edim == dmmoab->dim) { /* check the higher-dimensional elements first */ 822 moab::Range::const_iterator geiter = dmmoab->bndyelems->find(ent); 823 if (geiter != dmmoab->bndyelems->end()) *ent_on_boundary=PETSC_TRUE; 824 } 825 else { /* next check the lower-dimensional faces */ 826 moab::Range::const_iterator gfiter = dmmoab->bndyfaces->find(ent); 827 if (gfiter != dmmoab->bndyfaces->end()) *ent_on_boundary=PETSC_TRUE; 828 } 829 } 830 PetscFunctionReturn(0); 831 } 832 833 834 #undef __FUNCT__ 835 #define __FUNCT__ "DMMoabCheckBoundaryVertices" 836 PetscErrorCode DMMoabCheckBoundaryVertices(DM dm,PetscInt nconn,const moab::EntityHandle *cnt,PetscBool* isbdvtx) 837 { 838 DM_Moab *dmmoab; 839 PetscInt i; 840 841 PetscFunctionBegin; 842 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 843 PetscValidPointer(cnt,3); 844 PetscValidPointer(isbdvtx,4); 845 dmmoab = (DM_Moab*)(dm)->data; 846 847 for (i=0; i < nconn; ++i) { 848 moab::Range::const_iterator giter = dmmoab->bndyvtx->find(cnt[i]); 849 if (giter != dmmoab->bndyvtx->end()) isbdvtx[i] = PETSC_TRUE; 850 else isbdvtx[i] = PETSC_FALSE; 851 } 852 PetscFunctionReturn(0); 853 } 854 855 856 #undef __FUNCT__ 857 #define __FUNCT__ "DMMoabGetBoundaryEntities" 858 PetscErrorCode DMMoabGetBoundaryEntities(DM dm,moab::Range *bdvtx,moab::Range* bdfaces,moab::Range* bdelems) 859 { 860 DM_Moab *dmmoab; 861 862 PetscFunctionBegin; 863 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 864 dmmoab = (DM_Moab*)(dm)->data; 865 866 if (bdvtx) *bdvtx = *dmmoab->bndyvtx; 867 if (bdfaces) *bdfaces = *dmmoab->bndyfaces; 868 if (bdelems) *bdfaces = *dmmoab->bndyelems; 869 PetscFunctionReturn(0); 870 } 871 872 873 #undef __FUNCT__ 874 #define __FUNCT__ "DMMoabSetFields" 875 PetscErrorCode DMMoabSetFields(DM dm,PetscInt nfields,const char** fields) 876 { 877 DM_Moab *dmmoab; 878 879 PetscFunctionBegin; 880 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 881 dmmoab = (DM_Moab*)(dm)->data; 882 883 dmmoab->fields = fields; 884 dmmoab->nfields = nfields; 885 PetscFunctionReturn(0); 886 } 887 888 889 #undef __FUNCT__ 890 #define __FUNCT__ "DMMoabGetFieldDof" 891 PetscErrorCode DMMoabGetFieldDof(DM dm,moab::EntityHandle point,PetscInt field,PetscInt* dof) 892 { 893 PetscSection section; 894 PetscInt gid; 895 PetscErrorCode ierr; 896 moab::ErrorCode merr; 897 DM_Moab *dmmoab; 898 899 PetscFunctionBegin; 900 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 901 dmmoab = (DM_Moab*)(dm)->data; 902 903 ierr = DMGetDefaultSection(dm, §ion);CHKERRQ(ierr); 904 905 /* first get the global ID for the point */ 906 merr = dmmoab->mbiface->tag_get_data(dmmoab->ltog_tag,&point,1,&gid);MBERRNM(merr); 907 908 /* get the dof value for the field */ 909 ierr = PetscSectionGetFieldDof(section, gid, field, dof);CHKERRQ(ierr); 910 PetscFunctionReturn(0); 911 } 912 913 914 #undef __FUNCT__ 915 #define __FUNCT__ "DMMoabGetFieldDofs" 916 PetscErrorCode DMMoabGetFieldDofs(DM dm,PetscInt npoints,const moab::EntityHandle* points,PetscInt field,PetscInt* dof) 917 { 918 PetscInt i,gid; 919 PetscSection section; 920 PetscErrorCode ierr; 921 moab::ErrorCode merr; 922 DM_Moab *dmmoab; 923 924 PetscFunctionBegin; 925 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 926 dmmoab = (DM_Moab*)(dm)->data; 927 928 ierr = DMGetDefaultSection(dm, §ion);CHKERRQ(ierr); 929 if (!dof) { 930 ierr = PetscMalloc(sizeof(PetscScalar)*npoints, &dof);CHKERRQ(ierr); 931 } 932 933 /* first get the local indices */ 934 merr = dmmoab->mbiface->tag_get_data(dmmoab->ltog_tag,points,npoints,dof);MBERRNM(merr); 935 936 for (i=0; i<npoints; ++i) { 937 gid=dof[i]; 938 ierr = PetscSectionGetFieldDof(section, gid, field, &dof[i]);CHKERRQ(ierr); 939 } 940 PetscFunctionReturn(0); 941 } 942 943 944 #undef __FUNCT__ 945 #define __FUNCT__ "DMMoabGetLocalFieldDofs" 946 PetscErrorCode DMMoabGetLocalFieldDofs(DM dm,PetscInt npoints,const moab::EntityHandle* points,PetscInt field,PetscInt* dof) 947 { 948 PetscInt i,offset; 949 PetscErrorCode ierr; 950 DM_Moab *dmmoab; 951 952 PetscFunctionBegin; 953 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 954 dmmoab = (DM_Moab*)(dm)->data; 955 956 if (!dof) { 957 ierr = PetscMalloc(sizeof(PetscScalar)*npoints, &dof);CHKERRQ(ierr); 958 } 959 960 if (dmmoab->bs > 1) { 961 for (i=0; i<npoints; ++i) 962 dof[i] = (points[i]-1)*dmmoab->bs+field; 963 } 964 else { 965 offset = field*dmmoab->n; /* assume all fields have equal distribution */ 966 for (i=0; i<npoints; ++i) 967 dof[i] = offset+points[i]-1; 968 } 969 PetscFunctionReturn(0); 970 } 971 972 973 #undef __FUNCT__ 974 #define __FUNCT__ "DMMoab_GetWriteOptions_Private" 975 PetscErrorCode DMMoab_GetWriteOptions_Private(PetscInt fsetid, PetscInt numproc, PetscInt dim, MoabWriteMode mode, PetscInt dbglevel, const char* extra_opts, const char** write_opts) 976 { 977 std::ostringstream str; 978 979 PetscFunctionBegin; 980 981 // do parallel read unless only one processor 982 if (numproc > 1) { 983 str << "PARALLEL=" << mode << ";"; 984 if (fsetid>=0) str << "PARALLEL_COMM=" << fsetid << ";"; 985 } 986 987 if (dbglevel) 988 str << "CPUTIME;DEBUG_IO=" << dbglevel << ";"; 989 990 if (extra_opts) 991 str << extra_opts ; 992 993 *write_opts = str.str().c_str(); 994 PetscFunctionReturn(0); 995 } 996 997 998 #undef __FUNCT__ 999 #define __FUNCT__ "DMMoabOutput" 1000 PetscErrorCode DMMoabOutput(DM dm,const char* filename,const char* usrwriteopts) 1001 { 1002 DM_Moab *dmmoab; 1003 PetscInt dbglevel=0; 1004 const char *writeopts; 1005 1006 PetscErrorCode ierr; 1007 moab::ErrorCode merr; 1008 1009 PetscFunctionBegin; 1010 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1011 dmmoab = (DM_Moab*)(dm)->data; 1012 1013 PetscBarrier((PetscObject)dm); 1014 1015 /* TODO: Use command-line options to control by_rank, verbosity, MoabReadMode and extra options */ 1016 ierr = PetscOptionsBegin(PETSC_COMM_WORLD, "", "Options for reading/writing MOAB based meshes from file", "DMMoab"); 1017 ierr = PetscOptionsInt("-dmmb_rw_dbg", "The verbosity level for reading and writing MOAB meshes", "dmmbutil.cxx", dbglevel, &dbglevel, NULL);CHKERRQ(ierr); 1018 ierr = PetscOptionsEnd(); 1019 1020 /* add mesh loading options specific to the DM */ 1021 ierr = DMMoab_GetWriteOptions_Private(dmmoab->pcomm->get_id(), dmmoab->pcomm->size(), dmmoab->dim, MOAB_PARWOPTS_WRITE_PART, dbglevel, usrwriteopts, &writeopts);CHKERRQ(ierr); 1022 PetscInfo2(dm, "Writing file %s with options: %s\n",filename,writeopts); 1023 1024 /* output file, using parallel write */ 1025 merr = dmmoab->mbiface->write_file(filename, NULL, writeopts, &dmmoab->fileset, 1);MBERRVM(dmmoab->mbiface,"Writing output of DMMoab failed.",merr); 1026 PetscFunctionReturn(0); 1027 } 1028 1029