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