1 #include <petsc-private/dmmbimpl.h> /*I "petscdm.h" I*/ 2 #include <petsc-private/vecimpl.h> /*I "petscdm.h" I*/ 3 4 #include <petscdmmoab.h> 5 #include <MBTagConventions.hpp> 6 #include <moab/Skinner.hpp> 7 8 #undef __FUNCT__ 9 #define __FUNCT__ "DMDestroy_Moab" 10 PetscErrorCode DMDestroy_Moab(DM dm) 11 { 12 PetscErrorCode ierr; 13 DM_Moab *dmmoab = (DM_Moab*)dm->data; 14 PetscSection section; 15 16 PetscFunctionBegin; 17 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 18 ierr = DMGetDefaultSection(dm, §ion);CHKERRQ(ierr); 19 ierr = PetscSectionDestroy(§ion);CHKERRQ(ierr); 20 if (dmmoab->icreatedinstance) { 21 delete dmmoab->mbiface; 22 } 23 dmmoab->mbiface = NULL; 24 dmmoab->pcomm = NULL; 25 delete dmmoab->vlocal; 26 delete dmmoab->vowned; 27 delete dmmoab->vghost; 28 delete dmmoab->elocal; 29 delete dmmoab->eghost; 30 31 ierr = PetscFree(dmmoab->isbndyvtx);CHKERRQ(ierr); 32 ierr = PetscFree(dmmoab->isbndyfaces);CHKERRQ(ierr); 33 ierr = PetscFree(dmmoab->isbndyelems);CHKERRQ(ierr); 34 ierr = PetscFree(dmmoab->gsindices);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; 49 moab::Range::iterator iter; 50 PetscInt i,j,bs,gsiz,lsiz; 51 DM_Moab *dmmoab = (DM_Moab*)dm->data; 52 PetscInt totsize; 53 PetscSection section; 54 PetscInt gmin,lmin,lmax; 55 56 moab::Range adj; 57 58 PetscFunctionBegin; 59 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 60 /* Get the local and shared vertices and cache it */ 61 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."); 62 63 /* Get the entities recursively in the current part of the mesh, if user did not set the local vertices explicitly */ 64 if (dmmoab->vlocal->empty()) { 65 merr = dmmoab->mbiface->get_entities_by_type(dmmoab->fileset,moab::MBVERTEX,*dmmoab->vlocal,true);MBERRNM(merr); 66 67 /* filter based on parallel status */ 68 merr = dmmoab->pcomm->filter_pstatus(*dmmoab->vlocal,PSTATUS_NOT_OWNED,PSTATUS_NOT,-1,dmmoab->vowned);MBERRNM(merr); 69 *dmmoab->vghost = moab::subtract(*dmmoab->vlocal, *dmmoab->vowned); 70 71 dmmoab->nloc = dmmoab->vowned->size(); 72 dmmoab->nghost = dmmoab->vghost->size(); 73 ierr = MPI_Allreduce(&dmmoab->nloc, &dmmoab->n, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm);CHKERRQ(ierr); 74 75 #if 0 76 if(dmmoab->pcomm->rank() || dmmoab->pcomm->size()==1) { 77 PetscPrintf(PETSC_COMM_SELF, "Vertices: global: %D, local: %D", dmmoab->n, dmmoab->nloc+dmmoab->nghost); 78 dmmoab->vlocal->print(0); 79 PetscPrintf(PETSC_COMM_SELF, "Vertices: owned: %D", dmmoab->nloc); 80 dmmoab->vowned->print(0); 81 PetscPrintf(PETSC_COMM_SELF, "Vertices: ghost: %D", dmmoab->nghost); 82 dmmoab->vghost->print(0); 83 } 84 #endif 85 } 86 87 /* get the information about the local elements in the mesh */ 88 { 89 dmmoab->eghost->clear(); 90 91 /* first decipher the leading dimension */ 92 for (i=3;i>0;i--) { 93 dmmoab->elocal->clear(); 94 merr = dmmoab->mbiface->get_entities_by_dimension(dmmoab->fileset, i, *dmmoab->elocal, true);CHKERRQ(merr); 95 96 /* store the current mesh dimension */ 97 if (dmmoab->elocal->size()) { 98 dmmoab->dim=i; 99 break; 100 } 101 } 102 103 *dmmoab->eghost = *dmmoab->elocal; 104 merr = dmmoab->pcomm->filter_pstatus(*dmmoab->elocal,PSTATUS_NOT_OWNED,PSTATUS_NOT);MBERRNM(merr); 105 *dmmoab->eghost = moab::subtract(*dmmoab->eghost, *dmmoab->elocal); 106 107 dmmoab->neleloc = dmmoab->elocal->size(); 108 ierr = MPI_Allreduce(&dmmoab->neleloc, &dmmoab->nele, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm);CHKERRQ(ierr); 109 } 110 111 bs = dmmoab->bs; 112 if (!dmmoab->ltog_tag) { 113 /* Get the global ID tag. The global ID tag is applied to each 114 vertex. It acts as an global identifier which MOAB uses to 115 assemble the individual pieces of the mesh */ 116 merr = dmmoab->mbiface->tag_get_handle(GLOBAL_ID_TAG_NAME, dmmoab->ltog_tag);MBERRNM(merr); 117 } 118 119 totsize=dmmoab->vlocal->size(); 120 ierr = PetscMalloc(totsize*sizeof(PetscInt), &dmmoab->gsindices);CHKERRQ(ierr); 121 { 122 /* first get the local indices */ 123 merr = dmmoab->mbiface->tag_get_data(dmmoab->ltog_tag,*dmmoab->vowned,&dmmoab->gsindices[0]);MBERRNM(merr); 124 /* next get the ghosted indices */ 125 if (dmmoab->nghost) { 126 merr = dmmoab->mbiface->tag_get_data(dmmoab->ltog_tag,*dmmoab->vghost,&dmmoab->gsindices[dmmoab->nloc]);MBERRNM(merr); 127 } 128 129 /* find out the local and global minima of GLOBAL_ID */ 130 lmin=lmax=dmmoab->gsindices[0]; 131 for (i=0; i<totsize; ++i) { 132 if(lmin>dmmoab->gsindices[i]) lmin=dmmoab->gsindices[i]; 133 if(lmax<dmmoab->gsindices[i]) lmax=dmmoab->gsindices[i]; 134 } 135 136 ierr = MPI_Allreduce(&lmin, &gmin, 1, MPI_INT, MPI_MIN, ((PetscObject)dm)->comm);CHKERRQ(ierr); 137 PetscInfo3(dm, "GLOBAL_ID: Local minima - %D, Local maxima - %D, Global minima - %D.\n", lmin, lmax, gmin); 138 } 139 140 { 141 ierr = PetscSectionCreate(((PetscObject)dm)->comm, §ion);CHKERRQ(ierr); 142 ierr = PetscSectionSetNumFields(section, dmmoab->nfields);CHKERRQ(ierr); 143 ierr = PetscSectionSetChart(section, lmin, lmax+1);CHKERRQ(ierr); 144 for (j=0; j<totsize; ++j) { 145 PetscInt locgid = dmmoab->gsindices[j]; 146 for (i=0; i < dmmoab->nfields; ++i) { 147 ierr = PetscSectionSetFieldName(section, i, dmmoab->fields[i]);CHKERRQ(ierr); 148 if (bs>1) { 149 ierr = PetscSectionSetFieldDof(section, locgid, i, (locgid-gmin)*dmmoab->nfields+i);CHKERRQ(ierr); 150 ierr = PetscSectionSetFieldOffset(section, locgid, i, (locgid-gmin)*dmmoab->nfields); 151 } 152 else { 153 ierr = PetscSectionSetFieldDof(section, locgid, i, dmmoab->n*i+locgid-gmin);CHKERRQ(ierr); 154 ierr = PetscSectionSetFieldOffset(section, locgid, i, i*dmmoab->n); 155 } 156 } 157 ierr = PetscSectionSetDof(section, locgid, dmmoab->nfields);CHKERRQ(ierr); 158 } 159 ierr = PetscSectionSetUp(section);CHKERRQ(ierr); 160 ierr = DMSetDefaultSection(dm, section);CHKERRQ(ierr); 161 } 162 163 { 164 for (i=0; i<totsize; ++i) { 165 dmmoab->gsindices[i]-=gmin; /* zero based index needed for IS */ 166 } 167 168 /* Create Global to Local Vector Scatter Context */ 169 ierr = DMCreateGlobalVector_Moab(dm, &global);CHKERRQ(ierr); 170 ierr = DMCreateLocalVector_Moab(dm, &local);CHKERRQ(ierr); 171 172 /* global to local must retrieve ghost points */ 173 ierr = ISCreateBlock(((PetscObject)dm)->comm,bs,totsize,&dmmoab->gsindices[0],PETSC_COPY_VALUES,&from);CHKERRQ(ierr); 174 175 ierr = VecGetLocalSize(global,&gsiz);CHKERRQ(ierr); 176 ierr = VecGetLocalSize(local,&lsiz);CHKERRQ(ierr); 177 178 ierr = VecScatterCreate(local,from,global,from,&dmmoab->ltog_sendrecv);CHKERRQ(ierr); 179 ierr = ISDestroy(&from);CHKERRQ(ierr); 180 ierr = VecDestroy(&local);CHKERRQ(ierr); 181 ierr = VecDestroy(&global);CHKERRQ(ierr); 182 } 183 184 /* skin the boundary and store nodes */ 185 { 186 moab::Range bndyfaces, bndyvtx, bndyelems; 187 /* get the skin vertices of boundary faces for the current partition and then filter 188 the local, boundary faces, vertices and elements alone via PSTATUS flags; 189 this should not give us any ghosted boundary, but if user needs such a functionality 190 it would be easy to add it based on the find_skin query below */ 191 moab::Skinner skinner(dmmoab->mbiface); 192 193 /* get the entities on the skin - only the faces */ 194 merr = skinner.find_skin(dmmoab->fileset, *dmmoab->elocal, false, bndyfaces, NULL, false, true, false, false);MBERRNM(merr); // 'false' param indicates we want faces back, not vertices 195 196 /* filter all the non-owned and shared entities out of the list */ 197 merr = dmmoab->pcomm->filter_pstatus(bndyfaces,PSTATUS_NOT_OWNED,PSTATUS_NOT);MBERRNM(merr); 198 merr = dmmoab->pcomm->filter_pstatus(bndyfaces,PSTATUS_SHARED,PSTATUS_NOT);MBERRNM(merr); 199 200 /* get all the nodes via connectivity and the parent elements via adjacency information */ 201 merr = dmmoab->mbiface->get_connectivity(bndyfaces, bndyvtx, false);MBERRNM(ierr); 202 merr = dmmoab->mbiface->get_adjacencies(bndyfaces, dmmoab->dim, false, bndyelems, moab::Interface::UNION);MBERRNM(ierr); 203 PetscInfo3(dm, "Found %D boundary vertices, %D boundary faces and %D boundary elements.\n", bndyvtx.size(), bndyvtx.size(), bndyelems.size()); 204 205 /* cache a bit-vector for easy query */ 206 ierr = PetscMalloc(sizeof(PetscBool)*((PetscInt)(*bndyvtx.rbegin())+1),&dmmoab->isbndyvtx);CHKERRQ(ierr); 207 ierr = PetscMemzero(dmmoab->isbndyvtx,sizeof(PetscBool)*((PetscInt)(*bndyvtx.rbegin())+1));CHKERRQ(ierr); 208 for(moab::Range::iterator iter = bndyvtx.begin(); iter != bndyvtx.end(); iter++) { 209 dmmoab->isbndyvtx[(PetscInt)*iter]=PETSC_TRUE; 210 } 211 212 ierr = PetscMalloc(sizeof(PetscBool)*((PetscInt)(*bndyelems.rbegin())+1),&dmmoab->isbndyelems);CHKERRQ(ierr); 213 ierr = PetscMemzero(dmmoab->isbndyelems,sizeof(PetscBool)*((PetscInt)(*bndyelems.rbegin())+1));CHKERRQ(ierr); 214 for(moab::Range::iterator iter = bndyelems.begin(); iter != bndyelems.end(); iter++) { 215 dmmoab->isbndyelems[(PetscInt)*iter]=PETSC_TRUE; 216 } 217 218 ierr = PetscMalloc(sizeof(PetscBool)*((PetscInt)(*bndyfaces.rbegin())+1),&dmmoab->isbndyfaces);CHKERRQ(ierr); 219 ierr = PetscMemzero(dmmoab->isbndyfaces,sizeof(PetscBool)*((PetscInt)(*bndyfaces.rbegin())+1));CHKERRQ(ierr); 220 for(moab::Range::iterator iter = bndyfaces.begin(); iter != bndyfaces.end(); iter++) { 221 dmmoab->isbndyfaces[(PetscInt)*iter]=PETSC_TRUE; 222 } 223 } 224 PetscFunctionReturn(0); 225 } 226 227 228 #undef __FUNCT__ 229 #define __FUNCT__ "DMCreate_Moab" 230 PETSC_EXTERN PetscErrorCode DMCreate_Moab(DM dm) 231 { 232 PetscErrorCode ierr; 233 234 PetscFunctionBegin; 235 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 236 ierr = PetscNewLog(dm,&dm->data);CHKERRQ(ierr); 237 238 ((DM_Moab*)dm->data)->bs = 1; 239 ((DM_Moab*)dm->data)->nfields = 1; 240 ((DM_Moab*)dm->data)->n = 0; 241 ((DM_Moab*)dm->data)->nloc = 0; 242 ((DM_Moab*)dm->data)->nele = 0; 243 ((DM_Moab*)dm->data)->neleloc = 0; 244 ((DM_Moab*)dm->data)->nghost = 0; 245 ((DM_Moab*)dm->data)->ltog_map = PETSC_NULL; 246 ((DM_Moab*)dm->data)->ltog_sendrecv = PETSC_NULL; 247 248 ((DM_Moab*)dm->data)->vlocal = new moab::Range(); 249 ((DM_Moab*)dm->data)->vowned = new moab::Range(); 250 ((DM_Moab*)dm->data)->vghost = new moab::Range(); 251 ((DM_Moab*)dm->data)->elocal = new moab::Range(); 252 ((DM_Moab*)dm->data)->eghost = new moab::Range(); 253 254 dm->ops->createglobalvector = DMCreateGlobalVector_Moab; 255 dm->ops->createlocalvector = DMCreateLocalVector_Moab; 256 dm->ops->creatematrix = DMCreateMatrix_Moab; 257 dm->ops->setup = DMSetUp_Moab; 258 dm->ops->destroy = DMDestroy_Moab; 259 dm->ops->globaltolocalbegin = DMGlobalToLocalBegin_Moab; 260 dm->ops->globaltolocalend = DMGlobalToLocalEnd_Moab; 261 dm->ops->localtoglobalbegin = DMLocalToGlobalBegin_Moab; 262 dm->ops->localtoglobalend = DMLocalToGlobalEnd_Moab; 263 PetscFunctionReturn(0); 264 } 265 266 #undef __FUNCT__ 267 #define __FUNCT__ "DMMoabCreate" 268 /*@ 269 DMMoabCreate - Creates a DMMoab object, which encapsulates a moab instance 270 271 Collective on MPI_Comm 272 273 Input Parameter: 274 . comm - The communicator for the DMMoab object 275 276 Output Parameter: 277 . dmb - The DMMoab object 278 279 Level: beginner 280 281 .keywords: DMMoab, create 282 @*/ 283 PetscErrorCode DMMoabCreate(MPI_Comm comm, DM *dmb) 284 { 285 PetscErrorCode ierr; 286 287 PetscFunctionBegin; 288 PetscValidPointer(dmb,2); 289 ierr = DMCreate(comm, dmb);CHKERRQ(ierr); 290 ierr = DMSetType(*dmb, DMMOAB);CHKERRQ(ierr); 291 PetscFunctionReturn(0); 292 } 293 294 #undef __FUNCT__ 295 #define __FUNCT__ "DMMoabCreateMoab" 296 /*@ 297 DMMoabCreate - Creates a DMMoab object, optionally from an instance and other data 298 299 Collective on MPI_Comm 300 301 Input Parameter: 302 . comm - The communicator for the DMMoab object 303 . mbiface - (ptr to) the MOAB Instance; if passed in NULL, MOAB instance is created inside PETSc, and destroyed 304 along with the DMMoab 305 . pcomm - (ptr to) a ParallelComm; if NULL, creates one internally for the whole communicator 306 . ltog_tag - A tag to use to retrieve global id for an entity; if 0, will use GLOBAL_ID_TAG_NAME/tag 307 . range - If non-NULL, contains range of entities to which DOFs will be assigned 308 309 Output Parameter: 310 . dmb - The DMMoab object 311 312 Level: intermediate 313 314 .keywords: DMMoab, create 315 @*/ 316 PetscErrorCode DMMoabCreateMoab(MPI_Comm comm, moab::Interface *mbiface, moab::ParallelComm *pcomm, moab::Tag *ltog_tag, moab::Range *range, DM *dmb) 317 { 318 PetscErrorCode ierr; 319 moab::ErrorCode merr; 320 moab::EntityHandle partnset; 321 PetscInt rank, nprocs; 322 DM_Moab *dmmoab; 323 324 PetscFunctionBegin; 325 PetscValidPointer(dmb,6); 326 ierr = DMMoabCreate(comm, dmb);CHKERRQ(ierr); 327 dmmoab = (DM_Moab*)(*dmb)->data; 328 329 if (!mbiface) { 330 dmmoab->mbiface = new moab::Core(); 331 dmmoab->icreatedinstance = PETSC_TRUE; 332 } 333 else { 334 dmmoab->mbiface = mbiface; 335 dmmoab->icreatedinstance = PETSC_FALSE; 336 } 337 338 /* create a fileset to store the hierarchy of entities belonging to current DM */ 339 merr = dmmoab->mbiface->create_meshset(moab::MESHSET_ORDERED, dmmoab->fileset);MBERR("Creating file set failed", merr); 340 341 if (!pcomm) { 342 ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); 343 ierr = MPI_Comm_size(comm, &nprocs);CHKERRQ(ierr); 344 345 /* Create root sets for each mesh. Then pass these 346 to the load_file functions to be populated. */ 347 merr = dmmoab->mbiface->create_meshset(moab::MESHSET_SET, partnset);MBERR("Creating partition set failed", merr); 348 349 /* Create the parallel communicator object with the partition handle associated with MOAB */ 350 dmmoab->pcomm = moab::ParallelComm::get_pcomm(dmmoab->mbiface, partnset, &comm); 351 } 352 else { 353 ierr = DMMoabSetParallelComm(*dmb, pcomm);CHKERRQ(ierr); 354 } 355 356 /* do the remaining initializations for DMMoab */ 357 dmmoab->bs = 1; 358 dmmoab->nfields = 1; 359 360 /* set global ID tag handle */ 361 if (!ltog_tag) { 362 merr = dmmoab->mbiface->tag_get_handle(GLOBAL_ID_TAG_NAME, dmmoab->ltog_tag);MBERRNM(merr); 363 } 364 else { 365 ierr = DMMoabSetLocalToGlobalTag(*dmb, *ltog_tag);CHKERRQ(ierr); 366 } 367 368 /* set the local range of entities (vertices) of interest */ 369 if (range) { 370 ierr = DMMoabSetLocalVertices(*dmb, range);CHKERRQ(ierr); 371 } 372 PetscFunctionReturn(0); 373 } 374 375 #undef __FUNCT__ 376 #define __FUNCT__ "DMMoabSetParallelComm" 377 /*@ 378 DMMoabSetParallelComm - Set the ParallelComm used with this DMMoab 379 380 Collective on MPI_Comm 381 382 Input Parameter: 383 . dm - The DMMoab object being set 384 . pcomm - The ParallelComm being set on the DMMoab 385 386 Level: beginner 387 388 .keywords: DMMoab, create 389 @*/ 390 PetscErrorCode DMMoabSetParallelComm(DM dm,moab::ParallelComm *pcomm) 391 { 392 DM_Moab *dmmoab = (DM_Moab*)(dm)->data; 393 394 PetscFunctionBegin; 395 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 396 PetscValidPointer(pcomm,2); 397 dmmoab->pcomm = pcomm; 398 dmmoab->mbiface = pcomm->get_moab(); 399 dmmoab->icreatedinstance = PETSC_FALSE; 400 PetscFunctionReturn(0); 401 } 402 403 404 #undef __FUNCT__ 405 #define __FUNCT__ "DMMoabGetParallelComm" 406 /*@ 407 DMMoabGetParallelComm - Get the ParallelComm used with this DMMoab 408 409 Collective on MPI_Comm 410 411 Input Parameter: 412 . dm - The DMMoab object being set 413 414 Output Parameter: 415 . pcomm - The ParallelComm for the DMMoab 416 417 Level: beginner 418 419 .keywords: DMMoab, create 420 @*/ 421 PetscErrorCode DMMoabGetParallelComm(DM dm,moab::ParallelComm **pcomm) 422 { 423 PetscFunctionBegin; 424 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 425 *pcomm = ((DM_Moab*)(dm)->data)->pcomm; 426 PetscFunctionReturn(0); 427 } 428 429 430 #undef __FUNCT__ 431 #define __FUNCT__ "DMMoabSetInterface" 432 /*@ 433 DMMoabSetInterface - Set the MOAB instance used with this DMMoab 434 435 Collective on MPI_Comm 436 437 Input Parameter: 438 . dm - The DMMoab object being set 439 . mbiface - The MOAB instance being set on this DMMoab 440 441 Level: beginner 442 443 .keywords: DMMoab, create 444 @*/ 445 PetscErrorCode DMMoabSetInterface(DM dm,moab::Interface *mbiface) 446 { 447 DM_Moab *dmmoab = (DM_Moab*)(dm)->data; 448 449 PetscFunctionBegin; 450 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 451 PetscValidPointer(mbiface,2); 452 dmmoab->pcomm = NULL; 453 dmmoab->mbiface = mbiface; 454 dmmoab->icreatedinstance = PETSC_FALSE; 455 PetscFunctionReturn(0); 456 } 457 458 459 #undef __FUNCT__ 460 #define __FUNCT__ "DMMoabGetInterface" 461 /*@ 462 DMMoabGetInterface - Get the MOAB instance used with this DMMoab 463 464 Collective on MPI_Comm 465 466 Input Parameter: 467 . dm - The DMMoab object being set 468 469 Output Parameter: 470 . mbiface - The MOAB instance set on this DMMoab 471 472 Level: beginner 473 474 .keywords: DMMoab, create 475 @*/ 476 PetscErrorCode DMMoabGetInterface(DM dm,moab::Interface **mbiface) 477 { 478 PetscErrorCode ierr; 479 static PetscBool cite = PETSC_FALSE; 480 481 PetscFunctionBegin; 482 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 483 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); 484 *mbiface = ((DM_Moab*)dm->data)->mbiface; 485 PetscFunctionReturn(0); 486 } 487 488 489 #undef __FUNCT__ 490 #define __FUNCT__ "DMMoabSetLocalVertices" 491 /*@ 492 DMMoabSetLocalVertices - Set the entities having DOFs on this DMMoab 493 494 Collective on MPI_Comm 495 496 Input Parameter: 497 . dm - The DMMoab object being set 498 . range - The entities treated by this DMMoab 499 500 Level: beginner 501 502 .keywords: DMMoab, create 503 @*/ 504 PetscErrorCode DMMoabSetLocalVertices(DM dm,moab::Range *range) 505 { 506 moab::ErrorCode merr; 507 PetscErrorCode ierr; 508 DM_Moab *dmmoab = (DM_Moab*)(dm)->data; 509 510 PetscFunctionBegin; 511 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 512 dmmoab->vlocal->clear(); 513 dmmoab->vowned->clear(); 514 dmmoab->vlocal->insert(range->begin(), range->end()); 515 *dmmoab->vowned = *dmmoab->vlocal; 516 merr = dmmoab->pcomm->filter_pstatus(*dmmoab->vowned,PSTATUS_NOT_OWNED,PSTATUS_NOT);MBERRNM(merr); 517 *dmmoab->vghost = moab::subtract(*range, *dmmoab->vowned); 518 dmmoab->nloc=dmmoab->vowned->size(); 519 dmmoab->nghost=dmmoab->vghost->size(); 520 ierr = MPI_Allreduce(&dmmoab->nloc, &dmmoab->n, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm);CHKERRQ(ierr); 521 PetscFunctionReturn(0); 522 } 523 524 525 #undef __FUNCT__ 526 #define __FUNCT__ "DMMoabGetAllVertices" 527 /*@ 528 DMMoabGetAllVertices - Get the entities having DOFs on this DMMoab 529 530 Collective on MPI_Comm 531 532 Input Parameter: 533 . dm - The DMMoab object being set 534 535 Output Parameter: 536 . owned - The local vertex entities in this DMMoab = (owned+ghosted) 537 538 Level: beginner 539 540 .keywords: DMMoab, create 541 @*/ 542 PetscErrorCode DMMoabGetAllVertices(DM dm,moab::Range *local) 543 { 544 PetscFunctionBegin; 545 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 546 if (local) *local = *((DM_Moab*)dm->data)->vlocal; 547 PetscFunctionReturn(0); 548 } 549 550 551 552 #undef __FUNCT__ 553 #define __FUNCT__ "DMMoabGetLocalVertices" 554 /*@ 555 DMMoabGetLocalVertices - Get the entities having DOFs on this DMMoab 556 557 Collective on MPI_Comm 558 559 Input Parameter: 560 . dm - The DMMoab object being set 561 562 Output Parameter: 563 . owned - The owned vertex entities in this DMMoab 564 . ghost - The ghosted entities (non-owned) stored locally in this partition 565 566 Level: beginner 567 568 .keywords: DMMoab, create 569 @*/ 570 PetscErrorCode DMMoabGetLocalVertices(DM dm,moab::Range *owned,moab::Range *ghost) 571 { 572 PetscFunctionBegin; 573 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 574 if (owned) *owned = *((DM_Moab*)dm->data)->vowned; 575 if (ghost) *ghost = *((DM_Moab*)dm->data)->vghost; 576 PetscFunctionReturn(0); 577 } 578 579 #undef __FUNCT__ 580 #define __FUNCT__ "DMMoabGetLocalElements" 581 /*@ 582 DMMoabGetLocalElements - Get the higher-dimensional entities that are locally owned 583 584 Collective on MPI_Comm 585 586 Input Parameter: 587 . dm - The DMMoab object being set 588 589 Output Parameter: 590 . range - The entities owned locally 591 592 Level: beginner 593 594 .keywords: DMMoab, create 595 @*/ 596 PetscErrorCode DMMoabGetLocalElements(DM dm,moab::Range *range) 597 { 598 PetscFunctionBegin; 599 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 600 if (range) *range = *((DM_Moab*)dm->data)->elocal; 601 PetscFunctionReturn(0); 602 } 603 604 605 #undef __FUNCT__ 606 #define __FUNCT__ "DMMoabSetLocalElements" 607 /*@ 608 DMMoabSetLocalElements - Set the entities having DOFs on this DMMoab 609 610 Collective on MPI_Comm 611 612 Input Parameter: 613 . dm - The DMMoab object being set 614 . range - The entities treated by this DMMoab 615 616 Level: beginner 617 618 .keywords: DMMoab, create 619 @*/ 620 PetscErrorCode DMMoabSetLocalElements(DM dm,moab::Range *range) 621 { 622 moab::ErrorCode merr; 623 PetscErrorCode ierr; 624 DM_Moab *dmmoab = (DM_Moab*)(dm)->data; 625 626 PetscFunctionBegin; 627 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 628 dmmoab->elocal->clear(); 629 dmmoab->eghost->clear(); 630 dmmoab->elocal->insert(range->begin(), range->end()); 631 PetscInfo2(dm, "Range size = %D; elocal size = %D.\n", range->size(), dmmoab->elocal->size()); 632 merr = dmmoab->pcomm->filter_pstatus(*dmmoab->elocal,PSTATUS_NOT_OWNED,PSTATUS_NOT);MBERRNM(merr); 633 *dmmoab->eghost = moab::subtract(*range, *dmmoab->elocal); 634 dmmoab->neleloc=dmmoab->elocal->size(); 635 ierr = MPI_Allreduce(&dmmoab->nele, &dmmoab->neleloc, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm);CHKERRQ(ierr); 636 PetscInfo2(dm, "Created %D local and %D glocal elements.\n", dmmoab->neleloc, dmmoab->nele); 637 PetscFunctionReturn(0); 638 } 639 640 641 #undef __FUNCT__ 642 #define __FUNCT__ "DMMoabSetLocalToGlobalTag" 643 /*@ 644 DMMoabSetLocalToGlobalTag - Set the tag used for local to global numbering 645 646 Collective on MPI_Comm 647 648 Input Parameter: 649 . dm - The DMMoab object being set 650 . ltogtag - The MOAB tag used for local to global ids 651 652 Level: beginner 653 654 .keywords: DMMoab, create 655 @*/ 656 PetscErrorCode DMMoabSetLocalToGlobalTag(DM dm,moab::Tag ltogtag) 657 { 658 PetscFunctionBegin; 659 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 660 ((DM_Moab*)dm->data)->ltog_tag = ltogtag; 661 PetscFunctionReturn(0); 662 } 663 664 665 #undef __FUNCT__ 666 #define __FUNCT__ "DMMoabGetLocalToGlobalTag" 667 /*@ 668 DMMoabGetLocalToGlobalTag - Get the tag used for local to global numbering 669 670 Collective on MPI_Comm 671 672 Input Parameter: 673 . dm - The DMMoab object being set 674 675 Output Parameter: 676 . ltogtag - The MOAB tag used for local to global ids 677 678 Level: beginner 679 680 .keywords: DMMoab, create 681 @*/ 682 PetscErrorCode DMMoabGetLocalToGlobalTag(DM dm,moab::Tag *ltog_tag) 683 { 684 PetscFunctionBegin; 685 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 686 *ltog_tag = ((DM_Moab*)dm->data)->ltog_tag; 687 PetscFunctionReturn(0); 688 } 689 690 691 #undef __FUNCT__ 692 #define __FUNCT__ "DMMoabSetBlockSize" 693 /*@ 694 DMMoabSetBlockSize - Set the block size used with this DMMoab 695 696 Collective on MPI_Comm 697 698 Input Parameter: 699 . dm - The DMMoab object being set 700 . bs - The block size used with this DMMoab 701 702 Level: beginner 703 704 .keywords: DMMoab, create 705 @*/ 706 PetscErrorCode DMMoabSetBlockSize(DM dm,PetscInt bs) 707 { 708 PetscFunctionBegin; 709 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 710 ((DM_Moab*)dm->data)->bs = bs; 711 PetscFunctionReturn(0); 712 } 713 714 715 #undef __FUNCT__ 716 #define __FUNCT__ "DMMoabGetBlockSize" 717 /*@ 718 DMMoabGetBlockSize - Get the block size used with this DMMoab 719 720 Collective on MPI_Comm 721 722 Input Parameter: 723 . dm - The DMMoab object being set 724 725 Output Parameter: 726 . bs - The block size used with this DMMoab 727 728 Level: beginner 729 730 .keywords: DMMoab, create 731 @*/ 732 PetscErrorCode DMMoabGetBlockSize(DM dm,PetscInt *bs) 733 { 734 PetscFunctionBegin; 735 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 736 *bs = ((DM_Moab*)dm->data)->bs; 737 PetscFunctionReturn(0); 738 } 739 740 741 #undef __FUNCT__ 742 #define __FUNCT__ "DMMoabGetSize" 743 /*@ 744 DMMoabGetSize - Get the global vertex size used with this DMMoab 745 746 Collective on MPI_Comm 747 748 Input Parameter: 749 . dm - The DMMoab object being set 750 751 Output Parameter: 752 . ng - The global size of the DMMoab instance 753 754 Level: beginner 755 756 .keywords: DMMoab, create 757 @*/ 758 PetscErrorCode DMMoabGetSize(DM dm,PetscInt *ng) 759 { 760 PetscFunctionBegin; 761 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 762 if(ng) *ng = ((DM_Moab*)dm->data)->n; 763 PetscFunctionReturn(0); 764 } 765 766 767 #undef __FUNCT__ 768 #define __FUNCT__ "DMMoabGetLocalSize" 769 /*@ 770 DMMoabGetLocalSize - Get the local and ghosted vertex size used with this DMMoab 771 772 Collective on MPI_Comm 773 774 Input Parameter: 775 . dm - The DMMoab object being set 776 777 Output Parameter: 778 . nl - The local size of the DMMoab instance 779 . ng - The ghosted size of the DMMoab instance 780 781 Level: beginner 782 783 .keywords: DMMoab, create 784 @*/ 785 PetscErrorCode DMMoabGetLocalSize(DM dm,PetscInt *nl,PetscInt *ng) 786 { 787 PetscFunctionBegin; 788 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 789 if(nl) *nl = ((DM_Moab*)dm->data)->nloc; 790 if(ng) *ng = ((DM_Moab*)dm->data)->nghost; 791 PetscFunctionReturn(0); 792 } 793 794 795 #undef __FUNCT__ 796 #define __FUNCT__ "DMMoabGetDimension" 797 /*@ 798 DMMoabGetDimension - Get the dimension of the DM Mesh 799 800 Collective on MPI_Comm 801 802 Input Parameter: 803 . dm - The DMMoab object being set 804 805 Output Parameter: 806 . dim - The dimension of DM 807 808 Level: beginner 809 810 .keywords: DMMoab, create 811 @*/ 812 PetscErrorCode DMMoabGetDimension(DM dm,PetscInt *dim) 813 { 814 PetscFunctionBegin; 815 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 816 *dim = ((DM_Moab*)dm->data)->dim; 817 PetscFunctionReturn(0); 818 } 819 820 821 822 #undef __FUNCT__ 823 #define __FUNCT__ "DMMoabSetFieldVector" 824 PetscErrorCode DMMoabSetFieldVector(DM dm, PetscInt ifield, Vec fvec) 825 { 826 DM_Moab *dmmoab; 827 moab::Tag vtag,ntag; 828 const PetscScalar *varray; 829 PetscScalar *farray; 830 moab::ErrorCode merr; 831 PetscErrorCode ierr; 832 PetscInt doff; 833 std::string tag_name; 834 moab::Range::iterator iter; 835 836 PetscFunctionBegin; 837 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 838 dmmoab = (DM_Moab*)(dm)->data; 839 840 /* Create a tag in MOAB mesh to index and keep track of number of Petsc vec tags */ 841 merr = dmmoab->mbiface->tag_get_handle(dmmoab->fields[ifield],1,moab::MB_TYPE_DOUBLE,ntag, 842 moab::MB_TAG_SPARSE | moab::MB_TAG_CREAT);MBERRNM(merr); 843 844 ierr = DMMoabGetVecTag(fvec,&vtag);CHKERRQ(ierr); 845 846 merr = dmmoab->mbiface->tag_get_name(vtag, tag_name); 847 if (!tag_name.length() && merr !=moab::MB_SUCCESS) { 848 ierr = VecGetArrayRead(fvec,&varray);CHKERRQ(ierr); 849 850 for(iter = dmmoab->vowned->begin(); iter != dmmoab->vowned->end(); iter++) { 851 moab::EntityHandle vtx = (*iter); 852 853 /* get field dof index */ 854 ierr = DMMoabGetFieldDof(dm, vtx, ifield, &doff); 855 856 /* use the entity handle and the Dof index to set the right value */ 857 merr = dmmoab->mbiface->tag_set_data(ntag, &vtx, 1, (const void*)&varray[doff]);MBERRNM(merr); 858 } 859 ierr = VecRestoreArrayRead(fvec,&varray);CHKERRQ(ierr); 860 } 861 else { 862 ierr = PetscMalloc(dmmoab->nloc*sizeof(PetscScalar),&farray);CHKERRQ(ierr); 863 /* we are using a MOAB Vec - directly copy the tag data to new one */ 864 merr = dmmoab->mbiface->tag_get_data(vtag, *dmmoab->vowned, (void*)farray);MBERRNM(merr); 865 merr = dmmoab->mbiface->tag_set_data(ntag, *dmmoab->vowned, (const void*)farray);MBERRNM(merr); 866 /* make sure the parallel exchange for ghosts are done appropriately */ 867 merr = dmmoab->pcomm->exchange_tags(ntag, *dmmoab->vlocal);MBERRNM(merr); 868 ierr = PetscFree(farray);CHKERRQ(ierr); 869 } 870 PetscFunctionReturn(0); 871 } 872 873 874 #undef __FUNCT__ 875 #define __FUNCT__ "DMMoabSetGlobalFieldVector" 876 PetscErrorCode DMMoabSetGlobalFieldVector(DM dm, Vec fvec) 877 { 878 DM_Moab *dmmoab; 879 moab::Tag vtag,ntag; 880 const PetscScalar *varray; 881 PetscScalar *farray; 882 moab::ErrorCode merr; 883 PetscErrorCode ierr; 884 PetscSection section; 885 PetscInt i,doff,ifield; 886 std::string tag_name; 887 moab::Range::iterator iter; 888 889 PetscFunctionBegin; 890 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 891 dmmoab = (DM_Moab*)(dm)->data; 892 893 ierr = DMGetDefaultSection(dm, §ion);CHKERRQ(ierr); 894 895 /* get the Tag corresponding to the global vector - possible that there is no tag associated.. */ 896 ierr = DMMoabGetVecTag(fvec,&vtag);CHKERRQ(ierr); 897 merr = dmmoab->mbiface->tag_get_name(vtag, tag_name); 898 if (!tag_name.length() && merr !=moab::MB_SUCCESS) { 899 /* not a MOAB vector - use VecGetSubVector to get the parts as needed */ 900 901 ierr = VecGetArrayRead(fvec,&varray);CHKERRQ(ierr); 902 for (ifield=0; ifield<dmmoab->nfields; ++ifield) { 903 904 /* Create a tag in MOAB mesh to index and keep track of number of Petsc vec tags */ 905 merr = dmmoab->mbiface->tag_get_handle(dmmoab->fields[ifield],1,moab::MB_TYPE_DOUBLE,ntag, 906 moab::MB_TAG_SPARSE | moab::MB_TAG_CREAT);MBERRNM(merr); 907 908 for(iter = dmmoab->vowned->begin(); iter != dmmoab->vowned->end(); iter++) { 909 moab::EntityHandle vtx = (*iter); 910 911 /* get field dof index */ 912 ierr = DMMoabGetFieldDof(dm, vtx, ifield, &doff); 913 914 /* use the entity handle and the Dof index to set the right value */ 915 merr = dmmoab->mbiface->tag_set_data(ntag, &vtx, 1, (const void*)&varray[doff]);MBERRNM(merr); 916 } 917 } 918 ierr = VecRestoreArrayRead(fvec,&varray);CHKERRQ(ierr); 919 } 920 else { 921 ierr = PetscMalloc(dmmoab->nloc*sizeof(PetscScalar),&farray);CHKERRQ(ierr); 922 ierr = PetscMalloc(dmmoab->nloc*dmmoab->bs*sizeof(PetscScalar),&varray);CHKERRQ(ierr); 923 924 /* we are using a MOAB Vec - directly copy the tag data to new one */ 925 merr = dmmoab->mbiface->tag_get_data(vtag, *dmmoab->vowned, (void*)varray);MBERRNM(merr); 926 for (ifield=0; ifield<dmmoab->nfields; ++ifield) { 927 928 /* Create a tag in MOAB mesh to index and keep track of number of Petsc vec tags */ 929 merr = dmmoab->mbiface->tag_get_handle(dmmoab->fields[ifield],1,moab::MB_TYPE_DOUBLE,ntag, 930 moab::MB_TAG_SPARSE | moab::MB_TAG_CREAT);MBERRNM(merr); 931 932 /* we are using a MOAB Vec - directly copy the tag data to new one */ 933 for(i=0; i < dmmoab->nloc; i++) { 934 farray[i] = varray[i*dmmoab->bs+ifield]; 935 } 936 937 merr = dmmoab->mbiface->tag_set_data(ntag, *dmmoab->vowned, (const void*)farray);MBERRNM(merr); 938 /* make sure the parallel exchange for ghosts are done appropriately */ 939 merr = dmmoab->pcomm->exchange_tags(ntag, *dmmoab->vlocal);MBERRNM(merr); 940 } 941 ierr = PetscFree(farray);CHKERRQ(ierr); 942 ierr = PetscFree(varray);CHKERRQ(ierr); 943 } 944 PetscFunctionReturn(0); 945 } 946 947 948 949 #undef __FUNCT__ 950 #define __FUNCT__ "DMMoabGetVertexCoordinates" 951 PetscErrorCode DMMoabGetVertexCoordinates(DM dm,PetscInt nconn,const moab::EntityHandle *conn,PetscScalar *vpos) 952 { 953 DM_Moab *dmmoab; 954 PetscErrorCode ierr; 955 moab::ErrorCode merr; 956 957 PetscFunctionBegin; 958 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 959 PetscValidPointer(conn,3); 960 dmmoab = (DM_Moab*)(dm)->data; 961 962 if (!vpos) { 963 ierr = PetscMalloc(sizeof(PetscScalar)*nconn*3, &vpos);CHKERRQ(ierr); 964 } 965 966 /* Get connectivity information in MOAB canonical ordering */ 967 merr = dmmoab->mbiface->get_coords(conn, nconn, vpos);MBERRNM(merr); 968 PetscFunctionReturn(0); 969 } 970 971 972 #undef __FUNCT__ 973 #define __FUNCT__ "DMMoabGetVertexConnectivity" 974 PetscErrorCode DMMoabGetVertexConnectivity(DM dm,moab::EntityHandle ehandle,PetscInt* nconn, moab::EntityHandle **conn) 975 { 976 DM_Moab *dmmoab; 977 std::vector<moab::EntityHandle> adj_entities,connect; 978 PetscErrorCode ierr; 979 moab::ErrorCode merr; 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_adjacencies(&ehandle, 1, 1, true, adj_entities, moab::Interface::UNION);MBERRNM(merr); 988 merr = dmmoab->mbiface->get_connectivity(&adj_entities[0],adj_entities.size(),connect);MBERRNM(merr); 989 990 #if 0 991 for(unsigned int jter = 0; jter < connect.size(); jter++) { 992 PetscPrintf(PETSC_COMM_SELF,"Handle=%D\tAdj_Size=%D\tAdj_Entity=%D\n",ehandle,connect.size(),connect[jter]); 993 } 994 #endif 995 996 if (conn) { 997 ierr = PetscMalloc(sizeof(moab::EntityHandle)*connect.size(), conn);CHKERRQ(ierr); 998 ierr = PetscMemcpy(*conn, &connect[0], sizeof(moab::EntityHandle)*connect.size());CHKERRQ(ierr); 999 } 1000 if (nconn) *nconn=connect.size(); 1001 PetscFunctionReturn(0); 1002 } 1003 1004 1005 #undef __FUNCT__ 1006 #define __FUNCT__ "DMMoabRestoreVertexConnectivity" 1007 PetscErrorCode DMMoabRestoreVertexConnectivity(DM dm,moab::EntityHandle ehandle,PetscInt* nconn, moab::EntityHandle **conn) 1008 { 1009 PetscErrorCode ierr; 1010 1011 PetscFunctionBegin; 1012 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1013 PetscValidPointer(conn,4); 1014 1015 if (conn) { 1016 ierr = PetscFree(*conn);CHKERRQ(ierr); 1017 } 1018 if (nconn) *nconn=0; 1019 PetscFunctionReturn(0); 1020 } 1021 1022 1023 1024 #undef __FUNCT__ 1025 #define __FUNCT__ "DMMoabGetElementConnectivity" 1026 PetscErrorCode DMMoabGetElementConnectivity(DM dm,moab::EntityHandle ehandle,PetscInt* nconn,const moab::EntityHandle **conn) 1027 { 1028 DM_Moab *dmmoab; 1029 const moab::EntityHandle *connect; 1030 moab::ErrorCode merr; 1031 PetscInt nnodes; 1032 1033 PetscFunctionBegin; 1034 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1035 PetscValidPointer(conn,4); 1036 dmmoab = (DM_Moab*)(dm)->data; 1037 1038 /* Get connectivity information in MOAB canonical ordering */ 1039 merr = dmmoab->mbiface->get_connectivity(ehandle, connect, nnodes);MBERRNM(merr); 1040 if (conn) *conn=connect; 1041 if (nconn) *nconn=nnodes; 1042 PetscFunctionReturn(0); 1043 } 1044 1045 1046 #undef __FUNCT__ 1047 #define __FUNCT__ "DMMoabIsEntityOnBoundary" 1048 PetscErrorCode DMMoabIsEntityOnBoundary(DM dm,const moab::EntityHandle ent,PetscBool* ent_on_boundary) 1049 { 1050 moab::EntityType etype; 1051 DM_Moab *dmmoab; 1052 PetscInt edim; 1053 1054 PetscFunctionBegin; 1055 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1056 PetscValidPointer(ent_on_boundary,3); 1057 dmmoab = (DM_Moab*)(dm)->data; 1058 1059 /* get the entity type and handle accordingly */ 1060 etype=dmmoab->mbiface->type_from_handle(ent); 1061 if(etype >= moab::MBPOLYHEDRON) SETERRQ1(PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE, "Entity type on the boundary skin is invalid. EntityType = %D\n",etype); 1062 1063 /* get the entity dimension */ 1064 edim=dmmoab->mbiface->dimension_from_handle(ent); 1065 1066 *ent_on_boundary=PETSC_FALSE; 1067 if(etype == moab::MBVERTEX && edim == 0) { 1068 if (ent < (*dmmoab->vlocal)[0] || ent > (*dmmoab->vlocal)[dmmoab->nloc-1]) SETERRQ1(PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE, "Invalid boundary vertex entity handle: %D\n",ent); 1069 *ent_on_boundary=dmmoab->isbndyvtx[(PetscInt)ent]; 1070 } 1071 else { 1072 if (edim == dmmoab->dim) { /* check the higher-dimensional elements first */ 1073 if (ent < (*dmmoab->elocal)[0] || ent > (*dmmoab->elocal)[dmmoab->neleloc-1]) SETERRQ1(PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE, "Invalid boundary element entity handle: %D\n",ent); 1074 *ent_on_boundary=dmmoab->isbndyelems[(PetscInt)ent]; 1075 } 1076 else { /* next check the lower-dimensional faces */ 1077 /* how do we check the bounds before accessing ? will segfault for non-boundary faces */ 1078 *ent_on_boundary=dmmoab->isbndyfaces[(PetscInt)ent]; 1079 } 1080 } 1081 PetscFunctionReturn(0); 1082 } 1083 1084 1085 #undef __FUNCT__ 1086 #define __FUNCT__ "DMMoabCheckBoundaryVertices" 1087 PetscErrorCode DMMoabCheckBoundaryVertices(DM dm,PetscInt nconn,const moab::EntityHandle *cnt,PetscBool* isbdvtx) 1088 { 1089 DM_Moab *dmmoab; 1090 PetscInt i; 1091 1092 PetscFunctionBegin; 1093 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1094 PetscValidPointer(cnt,3); 1095 PetscValidPointer(isbdvtx,4); 1096 dmmoab = (DM_Moab*)(dm)->data; 1097 1098 for (i=0; i < nconn; ++i) { 1099 isbdvtx[i]=dmmoab->isbndyvtx[(PetscInt)cnt[i]]; 1100 } 1101 PetscFunctionReturn(0); 1102 } 1103 1104 1105 #undef __FUNCT__ 1106 #define __FUNCT__ "DMMoabGetBoundaryMarkers" 1107 PetscErrorCode DMMoabGetBoundaryMarkers(DM dm,PetscBool **bdvtx,PetscBool** bdelems,PetscBool** bdfaces) 1108 { 1109 DM_Moab *dmmoab; 1110 1111 PetscFunctionBegin; 1112 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1113 dmmoab = (DM_Moab*)(dm)->data; 1114 1115 if (bdvtx) *bdvtx = dmmoab->isbndyvtx; 1116 if (bdfaces) *bdfaces = dmmoab->isbndyfaces; 1117 if (bdelems) *bdfaces = dmmoab->isbndyelems; 1118 PetscFunctionReturn(0); 1119 } 1120 1121 1122 #undef __FUNCT__ 1123 #define __FUNCT__ "DMMoabSetFields" 1124 PetscErrorCode DMMoabSetFields(DM dm,PetscInt nfields,const char** fields) 1125 { 1126 DM_Moab *dmmoab; 1127 1128 PetscFunctionBegin; 1129 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1130 dmmoab = (DM_Moab*)(dm)->data; 1131 1132 dmmoab->fields = fields; 1133 dmmoab->nfields = nfields; 1134 PetscFunctionReturn(0); 1135 } 1136 1137 1138 #undef __FUNCT__ 1139 #define __FUNCT__ "DMMoabGetFieldDof" 1140 PetscErrorCode DMMoabGetFieldDof(DM dm,moab::EntityHandle point,PetscInt field,PetscInt* dof) 1141 { 1142 PetscSection section; 1143 PetscInt gid; 1144 PetscErrorCode ierr; 1145 moab::ErrorCode merr; 1146 DM_Moab *dmmoab; 1147 1148 PetscFunctionBegin; 1149 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1150 dmmoab = (DM_Moab*)(dm)->data; 1151 1152 ierr = DMGetDefaultSection(dm, §ion);CHKERRQ(ierr); 1153 1154 /* first get the global ID for the point */ 1155 merr = dmmoab->mbiface->tag_get_data(dmmoab->ltog_tag,&point,1,&gid);MBERRNM(merr); 1156 1157 /* get the dof value for the field */ 1158 ierr = PetscSectionGetFieldDof(section, gid, field, dof);CHKERRQ(ierr); 1159 PetscFunctionReturn(0); 1160 } 1161 1162 1163 #undef __FUNCT__ 1164 #define __FUNCT__ "DMMoabGetFieldDofs" 1165 PetscErrorCode DMMoabGetFieldDofs(DM dm,PetscInt npoints,const moab::EntityHandle* points,PetscInt field,PetscInt* dof) 1166 { 1167 PetscInt i,gid; 1168 PetscSection section; 1169 PetscErrorCode ierr; 1170 moab::ErrorCode merr; 1171 DM_Moab *dmmoab; 1172 1173 PetscFunctionBegin; 1174 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1175 PetscValidPointer(points,2); 1176 dmmoab = (DM_Moab*)(dm)->data; 1177 1178 ierr = DMGetDefaultSection(dm, §ion);CHKERRQ(ierr); 1179 if (!dof) { 1180 ierr = PetscMalloc(sizeof(PetscInt)*npoints, &dof);CHKERRQ(ierr); 1181 } 1182 1183 /* first get the local indices */ 1184 merr = dmmoab->mbiface->tag_get_data(dmmoab->ltog_tag,points,npoints,dof);MBERRNM(merr); 1185 1186 for (i=0; i<npoints; ++i) { 1187 gid=dof[i]; 1188 ierr = PetscSectionGetFieldDof(section, gid, field, &dof[i]);CHKERRQ(ierr); 1189 } 1190 PetscFunctionReturn(0); 1191 } 1192 1193 1194 #undef __FUNCT__ 1195 #define __FUNCT__ "DMMoabGetFieldDofsLocal" 1196 PetscErrorCode DMMoabGetFieldDofsLocal(DM dm,PetscInt npoints,const moab::EntityHandle* points,PetscInt field,PetscInt* dof) 1197 { 1198 PetscInt i,offset; 1199 PetscErrorCode ierr; 1200 DM_Moab *dmmoab; 1201 1202 PetscFunctionBegin; 1203 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1204 PetscValidPointer(points,2); 1205 dmmoab = (DM_Moab*)(dm)->data; 1206 1207 if (!dof) { 1208 ierr = PetscMalloc(sizeof(PetscInt)*npoints, &dof);CHKERRQ(ierr); 1209 } 1210 1211 if (dmmoab->bs > 1) { 1212 for (i=0; i<npoints; ++i) 1213 dof[i] = (points[i]-1)*dmmoab->bs+field; 1214 } 1215 else { 1216 offset = field*dmmoab->n; /* assume all fields have equal distribution */ 1217 for (i=0; i<npoints; ++i) 1218 dof[i] = offset+points[i]-1; 1219 } 1220 PetscFunctionReturn(0); 1221 } 1222 1223 1224 #undef __FUNCT__ 1225 #define __FUNCT__ "DMMoabGetDofs" 1226 PetscErrorCode DMMoabGetDofs(DM dm,PetscInt npoints,const moab::EntityHandle* points,PetscInt* dof) 1227 { 1228 PetscInt i,f,gid; 1229 PetscSection section; 1230 PetscErrorCode ierr; 1231 moab::ErrorCode merr; 1232 DM_Moab *dmmoab; 1233 1234 PetscFunctionBegin; 1235 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1236 PetscValidPointer(points,2); 1237 dmmoab = (DM_Moab*)(dm)->data; 1238 1239 ierr = DMGetDefaultSection(dm, §ion);CHKERRQ(ierr); 1240 if (!dof) { 1241 ierr = PetscMalloc(sizeof(PetscInt)*dmmoab->nfields*npoints, &dof);CHKERRQ(ierr); 1242 } 1243 1244 /* first get the local indices */ 1245 merr = dmmoab->mbiface->tag_get_data(dmmoab->ltog_tag,points,npoints,dof);MBERRNM(merr); 1246 1247 for (i=0; i<npoints; ++i) { 1248 gid=dof[i]; 1249 for (f=0; f<dmmoab->nfields; ++f) { 1250 ierr = PetscSectionGetFieldDof(section, gid, f, &dof[i*dmmoab->nfields+f]);CHKERRQ(ierr); 1251 } 1252 } 1253 PetscFunctionReturn(0); 1254 } 1255 1256 1257 #undef __FUNCT__ 1258 #define __FUNCT__ "DMMoabGetDofsLocal" 1259 PetscErrorCode DMMoabGetDofsLocal(DM dm,PetscInt npoints,const moab::EntityHandle* points,PetscInt* dof) 1260 { 1261 PetscInt i,f,offset; 1262 PetscErrorCode ierr; 1263 DM_Moab *dmmoab; 1264 1265 PetscFunctionBegin; 1266 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1267 PetscValidPointer(points,2); 1268 dmmoab = (DM_Moab*)(dm)->data; 1269 1270 if (!dof) { 1271 ierr = PetscMalloc(sizeof(PetscInt)*dmmoab->nfields*npoints, &dof);CHKERRQ(ierr); 1272 } 1273 1274 if (dmmoab->bs > 1) { 1275 for (f=0; f<dmmoab->nfields; ++f) 1276 for (i=0; i<npoints; ++i) 1277 dof[i*dmmoab->nfields+f] = (points[i]-1)*dmmoab->bs+f; 1278 } 1279 else { 1280 for (f=0; f<dmmoab->nfields; ++f) { 1281 offset = f*dmmoab->n; /* assume all fields have equal distribution - say all vertex based */ 1282 for (i=0; i<npoints; ++i) 1283 dof[i*dmmoab->nfields+f] = offset+points[i]-1; 1284 } 1285 } 1286 PetscFunctionReturn(0); 1287 } 1288 1289 1290 #undef __FUNCT__ 1291 #define __FUNCT__ "DMMoabGetDofsBlocked" 1292 PetscErrorCode DMMoabGetDofsBlocked(DM dm,PetscInt npoints,const moab::EntityHandle* points,PetscInt* dof) 1293 { 1294 PetscInt i,gid,dofindx; 1295 PetscSection section; 1296 PetscErrorCode ierr; 1297 moab::ErrorCode merr; 1298 DM_Moab *dmmoab; 1299 1300 PetscFunctionBegin; 1301 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1302 PetscValidPointer(points,2); 1303 dmmoab = (DM_Moab*)(dm)->data; 1304 1305 ierr = DMGetDefaultSection(dm, §ion);CHKERRQ(ierr); 1306 if (!dof) { 1307 ierr = PetscMalloc(sizeof(PetscInt)*npoints, &dof);CHKERRQ(ierr); 1308 } 1309 1310 /* first get the local indices */ 1311 merr = dmmoab->mbiface->tag_get_data(dmmoab->ltog_tag,points,npoints,dof);MBERRNM(merr); 1312 1313 for (i=0; i<npoints; ++i) { 1314 gid=dof[i]; 1315 ierr = PetscSectionGetFieldDof(section, gid, 0, &dofindx);CHKERRQ(ierr); 1316 if (dmmoab->bs > 1) dof[i]=dofindx/dmmoab->bs; 1317 else dof[i]=dofindx; 1318 } 1319 PetscFunctionReturn(0); 1320 } 1321 1322 1323 #undef __FUNCT__ 1324 #define __FUNCT__ "DMMoabGetDofsBlockedLocal" 1325 PetscErrorCode DMMoabGetDofsBlockedLocal(DM dm,PetscInt npoints,const moab::EntityHandle* points,PetscInt* dof) 1326 { 1327 PetscInt i; 1328 PetscErrorCode ierr; 1329 1330 PetscFunctionBegin; 1331 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1332 PetscValidPointer(points,2); 1333 1334 if (!dof) { 1335 ierr = PetscMalloc(sizeof(PetscInt)*npoints, &dof);CHKERRQ(ierr); 1336 } 1337 1338 for (i=0; i<npoints; ++i) 1339 dof[i] = points[i]-1; 1340 PetscFunctionReturn(0); 1341 } 1342 1343 1344 #undef __FUNCT__ 1345 #define __FUNCT__ "DMMoabGetVertexDofsBlocked" 1346 PetscErrorCode DMMoabGetVertexDofsBlocked(DM dm,PetscInt** dof) 1347 { 1348 PetscInt i,gid; 1349 DM_Moab *dmmoab; 1350 PetscSection section; 1351 PetscErrorCode ierr; 1352 moab::ErrorCode merr; 1353 1354 PetscFunctionBegin; 1355 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1356 dmmoab = (DM_Moab*)(dm)->data; 1357 1358 *dof = dmmoab->gsindices; 1359 1360 if (false) { 1361 if (!dof) { 1362 ierr = PetscMalloc(sizeof(PetscInt)*(dmmoab->nloc+dmmoab->nghost), dof);CHKERRQ(ierr); 1363 } 1364 1365 /* first get the local indices */ 1366 merr = dmmoab->mbiface->tag_get_data(dmmoab->ltog_tag,*dmmoab->vlocal,*dof);MBERRNM(merr); 1367 1368 ierr = DMGetDefaultSection(dm, §ion);CHKERRQ(ierr); 1369 1370 /* Compute function over the locally owned part of the grid */ 1371 for(i=0; i<dmmoab->nloc+dmmoab->nghost; i++) { 1372 gid=(*dof)[i]; 1373 ierr = PetscSectionGetFieldDof(section, gid, 0, &(*dof)[i]);CHKERRQ(ierr); 1374 } 1375 } 1376 PetscFunctionReturn(0); 1377 } 1378 1379 1380 #undef __FUNCT__ 1381 #define __FUNCT__ "DMMoabGetVertexDofsBlockedLocal" 1382 PetscErrorCode DMMoabGetVertexDofsBlockedLocal(DM dm,PetscInt** dof) 1383 { 1384 PetscInt i; 1385 DM_Moab *dmmoab; 1386 PetscErrorCode ierr; 1387 1388 PetscFunctionBegin; 1389 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1390 PetscValidPointer(dof,2); 1391 dmmoab = (DM_Moab*)(dm)->data; 1392 1393 if (!(*dof)) { 1394 ierr = PetscMalloc(sizeof(PetscInt)*(dmmoab->nloc+dmmoab->nghost), dof);CHKERRQ(ierr); 1395 } 1396 1397 i=0; 1398 /* Compute function over the locally owned part of the grid */ 1399 for(moab::Range::iterator iter = dmmoab->vowned->begin(); iter != dmmoab->vowned->end(); iter++,i++) { 1400 (*dof)[i] = (*iter)-1; 1401 } 1402 for(moab::Range::iterator iter = dmmoab->vghost->begin(); iter != dmmoab->vghost->end(); iter++,i++) { 1403 (*dof)[i] = (*iter)-1; 1404 } 1405 PetscFunctionReturn(0); 1406 } 1407 1408 1409 #undef __FUNCT__ 1410 #define __FUNCT__ "DMMoab_GetWriteOptions_Private" 1411 PetscErrorCode DMMoab_GetWriteOptions_Private(PetscInt fsetid, PetscInt numproc, PetscInt dim, MoabWriteMode mode, PetscInt dbglevel, const char* extra_opts, const char** write_opts) 1412 { 1413 std::ostringstream str; 1414 1415 PetscFunctionBegin; 1416 1417 // do parallel read unless only one processor 1418 if (numproc > 1) { 1419 str << "PARALLEL=" << mode << ";"; 1420 if (fsetid>=0) str << "PARALLEL_COMM=" << fsetid << ";"; 1421 } 1422 1423 if (dbglevel) 1424 str << "CPUTIME;DEBUG_IO=" << dbglevel << ";"; 1425 1426 if (extra_opts) 1427 str << extra_opts ; 1428 1429 *write_opts = str.str().c_str(); 1430 PetscFunctionReturn(0); 1431 } 1432 1433 1434 #undef __FUNCT__ 1435 #define __FUNCT__ "DMMoabOutput" 1436 PetscErrorCode DMMoabOutput(DM dm,const char* filename,const char* usrwriteopts) 1437 { 1438 DM_Moab *dmmoab; 1439 PetscInt dbglevel=0; 1440 const char *writeopts; 1441 1442 PetscErrorCode ierr; 1443 moab::ErrorCode merr; 1444 1445 PetscFunctionBegin; 1446 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1447 dmmoab = (DM_Moab*)(dm)->data; 1448 1449 PetscBarrier((PetscObject)dm); 1450 1451 /* TODO: Use command-line options to control by_rank, verbosity, MoabReadMode and extra options */ 1452 ierr = PetscOptionsBegin(PETSC_COMM_WORLD, "", "Options for reading/writing MOAB based meshes from file", "DMMoab"); 1453 ierr = PetscOptionsInt("-dmmb_rw_dbg", "The verbosity level for reading and writing MOAB meshes", "dmmbutil.cxx", dbglevel, &dbglevel, NULL);CHKERRQ(ierr); 1454 ierr = PetscOptionsEnd(); 1455 1456 /* add mesh loading options specific to the DM */ 1457 ierr = DMMoab_GetWriteOptions_Private(dmmoab->pcomm->get_id(), dmmoab->pcomm->size(), dmmoab->dim, MOAB_PARWOPTS_WRITE_PART, dbglevel, usrwriteopts, &writeopts);CHKERRQ(ierr); 1458 PetscInfo2(dm, "Writing file %s with options: %s\n",filename,writeopts); 1459 1460 /* output file, using parallel write */ 1461 merr = dmmoab->mbiface->write_file(filename, NULL, writeopts, &dmmoab->fileset, 1);MBERRVM(dmmoab->mbiface,"Writing output of DMMoab failed.",merr); 1462 PetscFunctionReturn(0); 1463 } 1464 1465