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