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