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