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,moab::Range *owned,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,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 MPI_Comm 796 797 Input Parameter: 798 . dm - The DMMoab object being set 799 800 Output Parameter: 801 . ng - The global size of the DMMoab instance 802 803 Level: beginner 804 805 .keywords: DMMoab, create 806 @*/ 807 PetscErrorCode DMMoabGetSize(DM dm,PetscInt *neg,PetscInt *nvg) 808 { 809 PetscFunctionBegin; 810 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 811 if(neg) *neg = ((DM_Moab*)dm->data)->nele; 812 if(nvg) *nvg = ((DM_Moab*)dm->data)->n; 813 PetscFunctionReturn(0); 814 } 815 816 817 #undef __FUNCT__ 818 #define __FUNCT__ "DMMoabGetLocalSize" 819 /*@ 820 DMMoabGetLocalSize - Get the local and ghosted vertex size used with this DMMoab 821 822 Collective on MPI_Comm 823 824 Input Parameter: 825 . dm - The DMMoab object being set 826 827 Output Parameter: 828 . nl - The local size of the DMMoab instance 829 . ng - The ghosted size of the DMMoab instance 830 831 Level: beginner 832 833 .keywords: DMMoab, create 834 @*/ 835 PetscErrorCode DMMoabGetLocalSize(DM dm,PetscInt *nel,PetscInt *neg,PetscInt *nvl,PetscInt *nvg) 836 { 837 PetscFunctionBegin; 838 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 839 if(nel) *nel = ((DM_Moab*)dm->data)->neleloc; 840 if(neg) *neg = ((DM_Moab*)dm->data)->neleghost; 841 if(nvl) *nvl = ((DM_Moab*)dm->data)->nloc; 842 if(nvg) *nvg = ((DM_Moab*)dm->data)->nghost; 843 PetscFunctionReturn(0); 844 } 845 846 847 #undef __FUNCT__ 848 #define __FUNCT__ "DMMoabGetDimension" 849 /*@ 850 DMMoabGetDimension - Get the dimension of the DM Mesh 851 852 Collective on MPI_Comm 853 854 Input Parameter: 855 . dm - The DMMoab object being set 856 857 Output Parameter: 858 . dim - The dimension of DM 859 860 Level: beginner 861 862 .keywords: DMMoab, create 863 @*/ 864 PetscErrorCode DMMoabGetDimension(DM dm,PetscInt *dim) 865 { 866 PetscFunctionBegin; 867 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 868 *dim = ((DM_Moab*)dm->data)->dim; 869 PetscFunctionReturn(0); 870 } 871 872 873 874 #undef __FUNCT__ 875 #define __FUNCT__ "DMMoabGetVertexCoordinates" 876 PetscErrorCode DMMoabGetVertexCoordinates(DM dm,PetscInt nconn,const moab::EntityHandle *conn,PetscScalar *vpos) 877 { 878 DM_Moab *dmmoab; 879 PetscErrorCode ierr; 880 moab::ErrorCode merr; 881 882 PetscFunctionBegin; 883 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 884 PetscValidPointer(conn,3); 885 dmmoab = (DM_Moab*)(dm)->data; 886 887 if (!vpos) { 888 ierr = PetscMalloc(sizeof(PetscScalar)*nconn*3, &vpos);CHKERRQ(ierr); 889 } 890 891 /* Get connectivity information in MOAB canonical ordering */ 892 merr = dmmoab->mbiface->get_coords(conn, nconn, vpos);MBERRNM(merr); 893 PetscFunctionReturn(0); 894 } 895 896 897 #undef __FUNCT__ 898 #define __FUNCT__ "DMMoabGetVertexConnectivity" 899 PetscErrorCode DMMoabGetVertexConnectivity(DM dm,moab::EntityHandle ehandle,PetscInt* nconn, moab::EntityHandle **conn) 900 { 901 DM_Moab *dmmoab; 902 std::vector<moab::EntityHandle> adj_entities,connect; 903 PetscErrorCode ierr; 904 moab::ErrorCode merr; 905 906 PetscFunctionBegin; 907 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 908 PetscValidPointer(conn,4); 909 dmmoab = (DM_Moab*)(dm)->data; 910 911 /* Get connectivity information in MOAB canonical ordering */ 912 merr = dmmoab->mbiface->get_adjacencies(&ehandle, 1, 1, true, adj_entities, moab::Interface::UNION);MBERRNM(merr); 913 merr = dmmoab->mbiface->get_connectivity(&adj_entities[0],adj_entities.size(),connect);MBERRNM(merr); 914 915 if (conn) { 916 ierr = PetscMalloc(sizeof(moab::EntityHandle)*connect.size(), conn);CHKERRQ(ierr); 917 ierr = PetscMemcpy(*conn, &connect[0], sizeof(moab::EntityHandle)*connect.size());CHKERRQ(ierr); 918 } 919 if (nconn) *nconn=connect.size(); 920 PetscFunctionReturn(0); 921 } 922 923 924 #undef __FUNCT__ 925 #define __FUNCT__ "DMMoabRestoreVertexConnectivity" 926 PetscErrorCode DMMoabRestoreVertexConnectivity(DM dm,moab::EntityHandle ehandle,PetscInt* nconn, moab::EntityHandle **conn) 927 { 928 PetscErrorCode ierr; 929 930 PetscFunctionBegin; 931 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 932 PetscValidPointer(conn,4); 933 934 if (conn) { 935 ierr = PetscFree(*conn);CHKERRQ(ierr); 936 } 937 if (nconn) *nconn=0; 938 PetscFunctionReturn(0); 939 } 940 941 942 943 #undef __FUNCT__ 944 #define __FUNCT__ "DMMoabGetElementConnectivity" 945 PetscErrorCode DMMoabGetElementConnectivity(DM dm,moab::EntityHandle ehandle,PetscInt* nconn,const moab::EntityHandle **conn) 946 { 947 DM_Moab *dmmoab; 948 const moab::EntityHandle *connect; 949 moab::ErrorCode merr; 950 PetscInt nnodes; 951 952 PetscFunctionBegin; 953 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 954 PetscValidPointer(conn,4); 955 dmmoab = (DM_Moab*)(dm)->data; 956 957 /* Get connectivity information in MOAB canonical ordering */ 958 merr = dmmoab->mbiface->get_connectivity(ehandle, connect, nnodes);MBERRNM(merr); 959 if (conn) *conn=connect; 960 if (nconn) *nconn=nnodes; 961 PetscFunctionReturn(0); 962 } 963 964 965 #undef __FUNCT__ 966 #define __FUNCT__ "DMMoabIsEntityOnBoundary" 967 PetscErrorCode DMMoabIsEntityOnBoundary(DM dm,const moab::EntityHandle ent,PetscBool* ent_on_boundary) 968 { 969 moab::EntityType etype; 970 DM_Moab *dmmoab; 971 PetscInt edim; 972 973 PetscFunctionBegin; 974 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 975 PetscValidPointer(ent_on_boundary,3); 976 dmmoab = (DM_Moab*)(dm)->data; 977 978 /* get the entity type and handle accordingly */ 979 etype=dmmoab->mbiface->type_from_handle(ent); 980 if(etype >= moab::MBPOLYHEDRON) SETERRQ1(PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE, "Entity type on the boundary skin is invalid. EntityType = %D\n",etype); 981 982 /* get the entity dimension */ 983 edim=dmmoab->mbiface->dimension_from_handle(ent); 984 985 *ent_on_boundary=PETSC_FALSE; 986 if(etype == moab::MBVERTEX && edim == 0) { 987 if (dmmoab->bndyvtx->index(ent) >= 0) *ent_on_boundary=PETSC_TRUE; 988 } 989 else { 990 if (edim == dmmoab->dim) { /* check the higher-dimensional elements first */ 991 if (dmmoab->bndyelems->index(ent) >= 0) *ent_on_boundary=PETSC_TRUE; 992 } 993 else { /* next check the lower-dimensional faces */ 994 if (dmmoab->bndyfaces->index(ent) >= 0) *ent_on_boundary=PETSC_TRUE; 995 } 996 } 997 PetscFunctionReturn(0); 998 } 999 1000 1001 #undef __FUNCT__ 1002 #define __FUNCT__ "DMMoabCheckBoundaryVertices" 1003 PetscErrorCode DMMoabCheckBoundaryVertices(DM dm,PetscInt nconn,const moab::EntityHandle *cnt,PetscBool* isbdvtx) 1004 { 1005 DM_Moab *dmmoab; 1006 PetscInt i; 1007 1008 PetscFunctionBegin; 1009 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1010 PetscValidPointer(cnt,3); 1011 PetscValidPointer(isbdvtx,4); 1012 dmmoab = (DM_Moab*)(dm)->data; 1013 1014 for (i=0; i < nconn; ++i) { 1015 isbdvtx[i]=(dmmoab->bndyvtx->index(cnt[i]) >= 0 ? PETSC_TRUE:PETSC_FALSE); 1016 } 1017 PetscFunctionReturn(0); 1018 } 1019 1020 1021 #undef __FUNCT__ 1022 #define __FUNCT__ "DMMoabGetBoundaryMarkers" 1023 PetscErrorCode DMMoabGetBoundaryMarkers(DM dm,const moab::Range **bdvtx,const moab::Range** bdelems,const moab::Range** bdfaces) 1024 { 1025 DM_Moab *dmmoab; 1026 1027 PetscFunctionBegin; 1028 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1029 dmmoab = (DM_Moab*)(dm)->data; 1030 1031 if (bdvtx) *bdvtx = dmmoab->bndyvtx; 1032 if (bdfaces) *bdfaces = dmmoab->bndyfaces; 1033 if (bdelems) *bdfaces = dmmoab->bndyelems; 1034 PetscFunctionReturn(0); 1035 } 1036 1037