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