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