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 15 PetscFunctionBegin; 16 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 17 if (dmmoab->icreatedinstance) { 18 delete dmmoab->mbiface; 19 } 20 dmmoab->mbiface = NULL; 21 dmmoab->pcomm = NULL; 22 delete dmmoab->vlocal; 23 delete dmmoab->vowned; 24 delete dmmoab->vghost; 25 delete dmmoab->elocal; 26 delete dmmoab->eghost; 27 delete dmmoab->bndyvtx; 28 delete dmmoab->bndyfaces; 29 ierr = VecScatterDestroy(&dmmoab->ltog_sendrecv);CHKERRQ(ierr); 30 ierr = ISLocalToGlobalMappingDestroy(&dmmoab->ltog_map);CHKERRQ(ierr); 31 ierr = PetscFree(dm->data);CHKERRQ(ierr); 32 PetscFunctionReturn(0); 33 } 34 35 #undef __FUNCT__ 36 #define __FUNCT__ "DMSetUp_Moab" 37 PetscErrorCode DMSetUp_Moab(DM dm) 38 { 39 PetscErrorCode ierr; 40 moab::ErrorCode merr; 41 Vec local, global; 42 IS from; 43 moab::Range::iterator iter; 44 PetscInt i,j,bs,gsiz,lsiz,*gsindices; 45 DM_Moab *dmmoab = (DM_Moab*)dm->data; 46 PetscInt totsize; 47 PetscSection section; 48 49 PetscFunctionBegin; 50 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 51 /* Get the local and shared vertices and cache it */ 52 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."); 53 54 /* store the current mesh dimension */ 55 merr = dmmoab->mbiface->get_dimension(dmmoab->dim);MBERRNM(merr); 56 57 /* Get the entities recursively in the current part of the mesh, if user did not set the local vertices explicitly */ 58 if (dmmoab->vlocal->empty()) { 59 merr = dmmoab->mbiface->get_entities_by_type(dmmoab->fileset,moab::MBVERTEX,*dmmoab->vlocal,true);MBERRNM(merr); 60 *dmmoab->vowned = *dmmoab->vlocal; 61 62 /* filter based on parallel status */ 63 merr = dmmoab->pcomm->filter_pstatus(*dmmoab->vowned,PSTATUS_NOT_OWNED,PSTATUS_NOT);MBERRNM(merr); 64 *dmmoab->vghost = moab::subtract(*dmmoab->vlocal, *dmmoab->vowned); 65 66 dmmoab->nloc = dmmoab->vowned->size(); 67 dmmoab->nghost = dmmoab->vghost->size(); 68 ierr = MPI_Allreduce(&dmmoab->nloc, &dmmoab->n, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm);CHKERRQ(ierr); 69 } 70 71 /* get the information about the local elements in the mesh */ 72 { 73 dmmoab->elocal->clear(); 74 dmmoab->eghost->clear(); 75 merr = dmmoab->mbiface->get_entities_by_dimension(dmmoab->fileset, dmmoab->dim, *dmmoab->elocal, true);CHKERRQ(merr); 76 *dmmoab->eghost = *dmmoab->elocal; 77 merr = dmmoab->pcomm->filter_pstatus(*dmmoab->elocal,PSTATUS_NOT_OWNED,PSTATUS_NOT);MBERRNM(merr); 78 *dmmoab->eghost = moab::subtract(*dmmoab->eghost, *dmmoab->elocal); 79 80 dmmoab->neleloc = dmmoab->elocal->size(); 81 ierr = MPI_Allreduce(&dmmoab->neleloc, &dmmoab->nele, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm);CHKERRQ(ierr); 82 } 83 84 bs = dmmoab->bs; 85 if (!dmmoab->ltog_tag) { 86 /* Get the global ID tag. The global ID tag is applied to each 87 vertex. It acts as an global identifier which MOAB uses to 88 assemble the individual pieces of the mesh */ 89 merr = dmmoab->mbiface->tag_get_handle(GLOBAL_ID_TAG_NAME, dmmoab->ltog_tag);MBERRNM(merr); 90 } 91 92 totsize=dmmoab->vlocal->size(); 93 ierr = PetscMalloc(totsize*sizeof(PetscInt), &gsindices);CHKERRQ(ierr); 94 { 95 /* first get the local indices */ 96 merr = dmmoab->mbiface->tag_get_data(dmmoab->ltog_tag,*dmmoab->vowned,&gsindices[0]);MBERRNM(merr); 97 /* next get the ghosted indices */ 98 if (dmmoab->vghost->size()) { 99 merr = dmmoab->mbiface->tag_get_data(dmmoab->ltog_tag,*dmmoab->vghost,&gsindices[dmmoab->nloc]);MBERRNM(merr); 100 } 101 } 102 103 { 104 ierr = PetscSectionCreate(((PetscObject)dm)->comm, §ion);CHKERRQ(ierr); 105 ierr = PetscSectionSetNumFields(section, dmmoab->nfields);CHKERRQ(ierr); 106 ierr = PetscSectionSetChart(section, gsindices[0], gsindices[dmmoab->nloc-1]+1);CHKERRQ(ierr); 107 for (j=gsindices[0]; j<=gsindices[dmmoab->nloc-1]; ++j) { 108 for (i=0; i < dmmoab->nfields; ++i) { 109 ierr = PetscSectionSetFieldName(section, i, dmmoab->fields[i]);CHKERRQ(ierr); 110 if (bs>1) { 111 ierr = PetscSectionSetFieldDof(section, j, i, j*dmmoab->nfields+i-1);CHKERRQ(ierr); 112 ierr = PetscSectionSetFieldOffset(section, j, i, dmmoab->nfields); 113 // PetscPrintf(PETSC_COMM_WORLD, "Point %D, Field %D, DOF %D, OFFSET = %D\n", j, i, j*dmmoab->nfields+i, dmmoab->nfields); 114 } 115 else { 116 ierr = PetscSectionSetFieldDof(section, j, i, totsize*i+j-1);CHKERRQ(ierr); 117 ierr = PetscSectionSetFieldOffset(section, j, i, totsize); 118 // PetscPrintf(PETSC_COMM_WORLD, "Point %D, Field %D, DOF %D, OFFSET = %D\n", j, i, totsize*i+j, totsize); 119 } 120 } 121 ierr = PetscSectionSetDof(section, j, dmmoab->nfields);CHKERRQ(ierr); 122 } 123 ierr = PetscSectionSetUp(section);CHKERRQ(ierr); 124 ierr = DMSetDefaultSection(dm, section);CHKERRQ(ierr); 125 } 126 127 { 128 /* Create Global to Local Vector Scatter Context */ 129 ierr = DMCreateGlobalVector_Moab(dm, &global);CHKERRQ(ierr); 130 ierr = DMCreateLocalVector_Moab(dm, &local);CHKERRQ(ierr); 131 132 for (i=0; i<totsize; ++i) { 133 gsindices[i]--; /* zero based index needed for IS */ 134 } 135 136 /* global to local must retrieve ghost points */ 137 ierr = ISCreateBlock(((PetscObject)dm)->comm,bs,totsize,&gsindices[0],PETSC_COPY_VALUES,&from);CHKERRQ(ierr); 138 139 ierr = VecGetLocalSize(global,&gsiz);CHKERRQ(ierr); 140 ierr = VecGetLocalSize(local,&lsiz);CHKERRQ(ierr); 141 142 ierr = VecScatterCreate(local,from,global,from,&dmmoab->ltog_sendrecv);CHKERRQ(ierr); 143 ierr = ISDestroy(&from);CHKERRQ(ierr); 144 ierr = VecDestroy(&local);CHKERRQ(ierr); 145 ierr = VecDestroy(&global);CHKERRQ(ierr); 146 } 147 148 /* skin the boundary and store nodes */ 149 { 150 // get the skin vertices of those faces and mark them as fixed; we don't want to fix the vertices on a 151 // part boundary, but since we exchanged a layer of ghost faces, those vertices aren't on the skin locally 152 // ok to mark non-owned skin vertices too, I won't move those anyway 153 // use MOAB's skinner class to find the skin 154 moab::Skinner skinner(dmmoab->mbiface); 155 dmmoab->bndyvtx = new moab::Range(); 156 dmmoab->bndyfaces = new moab::Range(); 157 merr = skinner.find_skin(dmmoab->fileset, *dmmoab->elocal, true, *dmmoab->bndyvtx);MBERRNM(merr); // 'true' param indicates we want vertices back, not faces 158 merr = skinner.find_skin(dmmoab->fileset, *dmmoab->elocal, false, *dmmoab->bndyfaces);MBERRNM(merr); // 'false' param indicates we want faces back, not vertices 159 PetscPrintf(PETSC_COMM_WORLD, "\nFound %D boundary vertices and %D faces.\n", dmmoab->bndyvtx->size(), dmmoab->bndyvtx->size()); 160 } 161 162 ierr = PetscFree(gsindices);CHKERRQ(ierr); 163 PetscFunctionReturn(0); 164 } 165 166 167 #undef __FUNCT__ 168 #define __FUNCT__ "DMCreate_Moab" 169 PETSC_EXTERN PetscErrorCode DMCreate_Moab(DM dm) 170 { 171 PetscErrorCode ierr; 172 173 PetscFunctionBegin; 174 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 175 ierr = PetscNewLog(dm,&dm->data);CHKERRQ(ierr); 176 177 ((DM_Moab*)dm->data)->bs = 1; 178 ((DM_Moab*)dm->data)->n = 0; 179 ((DM_Moab*)dm->data)->nloc = 0; 180 ((DM_Moab*)dm->data)->nele = 0; 181 ((DM_Moab*)dm->data)->neleloc = 0; 182 ((DM_Moab*)dm->data)->nghost = 0; 183 ((DM_Moab*)dm->data)->ltog_map = PETSC_NULL; 184 ((DM_Moab*)dm->data)->ltog_sendrecv = PETSC_NULL; 185 186 ((DM_Moab*)dm->data)->vlocal = new moab::Range(); 187 ((DM_Moab*)dm->data)->vowned = new moab::Range(); 188 ((DM_Moab*)dm->data)->vghost = new moab::Range(); 189 ((DM_Moab*)dm->data)->elocal = new moab::Range(); 190 ((DM_Moab*)dm->data)->eghost = new moab::Range(); 191 192 dm->ops->createglobalvector = DMCreateGlobalVector_Moab; 193 dm->ops->createlocalvector = DMCreateLocalVector_Moab; 194 dm->ops->creatematrix = DMCreateMatrix_Moab; 195 dm->ops->setup = DMSetUp_Moab; 196 dm->ops->destroy = DMDestroy_Moab; 197 dm->ops->globaltolocalbegin = DMGlobalToLocalBegin_Moab; 198 dm->ops->globaltolocalend = DMGlobalToLocalEnd_Moab; 199 dm->ops->localtoglobalbegin = DMLocalToGlobalBegin_Moab; 200 dm->ops->localtoglobalend = DMLocalToGlobalEnd_Moab; 201 PetscFunctionReturn(0); 202 } 203 204 #undef __FUNCT__ 205 #define __FUNCT__ "DMMoabCreate" 206 /*@ 207 DMMoabCreate - Creates a DMMoab object, which encapsulates a moab instance 208 209 Collective on MPI_Comm 210 211 Input Parameter: 212 . comm - The communicator for the DMMoab object 213 214 Output Parameter: 215 . dmb - The DMMoab object 216 217 Level: beginner 218 219 .keywords: DMMoab, create 220 @*/ 221 PetscErrorCode DMMoabCreate(MPI_Comm comm, DM *dmb) 222 { 223 PetscErrorCode ierr; 224 225 PetscFunctionBegin; 226 PetscValidPointer(dmb,2); 227 ierr = DMCreate(comm, dmb);CHKERRQ(ierr); 228 ierr = DMSetType(*dmb, DMMOAB);CHKERRQ(ierr); 229 PetscFunctionReturn(0); 230 } 231 232 #undef __FUNCT__ 233 #define __FUNCT__ "DMMoabCreateMoab" 234 /*@ 235 DMMoabCreate - Creates a DMMoab object, optionally from an instance and other data 236 237 Collective on MPI_Comm 238 239 Input Parameter: 240 . comm - The communicator for the DMMoab object 241 . mbiface - (ptr to) the MOAB Instance; if passed in NULL, MOAB instance is created inside PETSc, and destroyed 242 along with the DMMoab 243 . pcomm - (ptr to) a ParallelComm; if NULL, creates one internally for the whole communicator 244 . ltog_tag - A tag to use to retrieve global id for an entity; if 0, will use GLOBAL_ID_TAG_NAME/tag 245 . range - If non-NULL, contains range of entities to which DOFs will be assigned 246 247 Output Parameter: 248 . dmb - The DMMoab object 249 250 Level: intermediate 251 252 .keywords: DMMoab, create 253 @*/ 254 PetscErrorCode DMMoabCreateMoab(MPI_Comm comm, moab::Interface *mbiface, moab::ParallelComm *pcomm, moab::Tag *ltog_tag, moab::Range *range, DM *dmb) 255 { 256 PetscErrorCode ierr; 257 moab::ErrorCode merr; 258 moab::EntityHandle partnset; 259 PetscInt rank, nprocs; 260 DM_Moab *dmmoab; 261 262 PetscFunctionBegin; 263 PetscValidPointer(dmb,6); 264 ierr = DMMoabCreate(comm, dmb);CHKERRQ(ierr); 265 dmmoab = (DM_Moab*)(*dmb)->data; 266 267 if (!mbiface) { 268 dmmoab->mbiface = new moab::Core(); 269 dmmoab->icreatedinstance = PETSC_TRUE; 270 } 271 else { 272 dmmoab->mbiface = mbiface; 273 dmmoab->icreatedinstance = PETSC_FALSE; 274 } 275 276 /* create a fileset to store the hierarchy of entities belonging to current DM */ 277 merr = dmmoab->mbiface->create_meshset(moab::MESHSET_ORDERED, dmmoab->fileset);MBERR("Creating file set failed", merr); 278 279 if (!pcomm) { 280 ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); 281 ierr = MPI_Comm_size(comm, &nprocs);CHKERRQ(ierr); 282 283 /* Create root sets for each mesh. Then pass these 284 to the load_file functions to be populated. */ 285 merr = dmmoab->mbiface->create_meshset(moab::MESHSET_SET, partnset); 286 MBERR("Creating partition set failed", merr); 287 288 /* Create the parallel communicator object with the partition handle associated with MOAB */ 289 dmmoab->pcomm = moab::ParallelComm::get_pcomm(dmmoab->mbiface, partnset, &comm); 290 } 291 else { 292 ierr = DMMoabSetParallelComm(*dmb, pcomm);CHKERRQ(ierr); 293 } 294 295 /* do the remaining initializations for DMMoab */ 296 dmmoab->bs = 1; 297 298 /* set global ID tag handle */ 299 if (!ltog_tag) { 300 merr = dmmoab->mbiface->tag_get_handle(GLOBAL_ID_TAG_NAME, dmmoab->ltog_tag);MBERRNM(merr); 301 } 302 else { 303 ierr = DMMoabSetLocalToGlobalTag(*dmb, *ltog_tag);CHKERRQ(ierr); 304 } 305 306 /* set the local range of entities (vertices) of interest */ 307 if (range) { 308 ierr = DMMoabSetLocalVertices(*dmb, range);CHKERRQ(ierr); 309 } 310 PetscFunctionReturn(0); 311 } 312 313 #undef __FUNCT__ 314 #define __FUNCT__ "DMMoabSetParallelComm" 315 /*@ 316 DMMoabSetParallelComm - Set the ParallelComm used with this DMMoab 317 318 Collective on MPI_Comm 319 320 Input Parameter: 321 . dm - The DMMoab object being set 322 . pcomm - The ParallelComm being set on the DMMoab 323 324 Level: beginner 325 326 .keywords: DMMoab, create 327 @*/ 328 PetscErrorCode DMMoabSetParallelComm(DM dm,moab::ParallelComm *pcomm) 329 { 330 DM_Moab *dmmoab = (DM_Moab*)(dm)->data; 331 332 PetscFunctionBegin; 333 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 334 PetscValidPointer(pcomm,2); 335 dmmoab->pcomm = pcomm; 336 dmmoab->mbiface = pcomm->get_moab(); 337 dmmoab->icreatedinstance = PETSC_FALSE; 338 PetscFunctionReturn(0); 339 } 340 341 342 #undef __FUNCT__ 343 #define __FUNCT__ "DMMoabGetParallelComm" 344 /*@ 345 DMMoabGetParallelComm - Get the ParallelComm used with this DMMoab 346 347 Collective on MPI_Comm 348 349 Input Parameter: 350 . dm - The DMMoab object being set 351 352 Output Parameter: 353 . pcomm - The ParallelComm for the DMMoab 354 355 Level: beginner 356 357 .keywords: DMMoab, create 358 @*/ 359 PetscErrorCode DMMoabGetParallelComm(DM dm,moab::ParallelComm **pcomm) 360 { 361 PetscFunctionBegin; 362 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 363 *pcomm = ((DM_Moab*)(dm)->data)->pcomm; 364 PetscFunctionReturn(0); 365 } 366 367 368 #undef __FUNCT__ 369 #define __FUNCT__ "DMMoabSetInterface" 370 /*@ 371 DMMoabSetInterface - Set the MOAB instance used with this DMMoab 372 373 Collective on MPI_Comm 374 375 Input Parameter: 376 . dm - The DMMoab object being set 377 . mbiface - The MOAB instance being set on this DMMoab 378 379 Level: beginner 380 381 .keywords: DMMoab, create 382 @*/ 383 PetscErrorCode DMMoabSetInterface(DM dm,moab::Interface *mbiface) 384 { 385 DM_Moab *dmmoab = (DM_Moab*)(dm)->data; 386 387 PetscFunctionBegin; 388 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 389 PetscValidPointer(mbiface,2); 390 dmmoab->pcomm = NULL; 391 dmmoab->mbiface = mbiface; 392 dmmoab->icreatedinstance = PETSC_FALSE; 393 PetscFunctionReturn(0); 394 } 395 396 397 #undef __FUNCT__ 398 #define __FUNCT__ "DMMoabGetInterface" 399 /*@ 400 DMMoabGetInterface - Get the MOAB instance used with this DMMoab 401 402 Collective on MPI_Comm 403 404 Input Parameter: 405 . dm - The DMMoab object being set 406 407 Output Parameter: 408 . mbiface - The MOAB instance set on this DMMoab 409 410 Level: beginner 411 412 .keywords: DMMoab, create 413 @*/ 414 PetscErrorCode DMMoabGetInterface(DM dm,moab::Interface **mbiface) 415 { 416 PetscErrorCode ierr; 417 static PetscBool cite = PETSC_FALSE; 418 419 PetscFunctionBegin; 420 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 421 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); 422 *mbiface = ((DM_Moab*)dm->data)->mbiface; 423 PetscFunctionReturn(0); 424 } 425 426 427 #undef __FUNCT__ 428 #define __FUNCT__ "DMMoabSetLocalVertices" 429 /*@ 430 DMMoabSetLocalVertices - Set the entities having DOFs on this DMMoab 431 432 Collective on MPI_Comm 433 434 Input Parameter: 435 . dm - The DMMoab object being set 436 . range - The entities treated by this DMMoab 437 438 Level: beginner 439 440 .keywords: DMMoab, create 441 @*/ 442 PetscErrorCode DMMoabSetLocalVertices(DM dm,moab::Range *range) 443 { 444 moab::ErrorCode merr; 445 PetscErrorCode ierr; 446 DM_Moab *dmmoab = (DM_Moab*)(dm)->data; 447 448 PetscFunctionBegin; 449 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 450 dmmoab->vlocal->clear(); 451 dmmoab->vowned->clear(); 452 dmmoab->vlocal->insert(range->begin(), range->end()); 453 *dmmoab->vowned = *dmmoab->vlocal; 454 merr = dmmoab->pcomm->filter_pstatus(*dmmoab->vowned,PSTATUS_NOT_OWNED,PSTATUS_NOT);MBERRNM(merr); 455 *dmmoab->vghost = moab::subtract(*range, *dmmoab->vowned); 456 dmmoab->nloc=dmmoab->vowned->size(); 457 dmmoab->nghost=dmmoab->vghost->size(); 458 ierr = MPI_Allreduce(&dmmoab->nloc, &dmmoab->n, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm);CHKERRQ(ierr); 459 PetscFunctionReturn(0); 460 } 461 462 463 #undef __FUNCT__ 464 #define __FUNCT__ "DMMoabGetLocalVertices" 465 /*@ 466 DMMoabGetLocalVertices - Get the entities having DOFs on this DMMoab 467 468 Collective on MPI_Comm 469 470 Input Parameter: 471 . dm - The DMMoab object being set 472 473 Output Parameter: 474 . owned - The owned vertex entities in this DMMoab 475 . ghost - The ghosted entities (non-owned) stored locally in this partition 476 477 Level: beginner 478 479 .keywords: DMMoab, create 480 @*/ 481 PetscErrorCode DMMoabGetLocalVertices(DM dm,moab::Range *owned,moab::Range *ghost) 482 { 483 PetscFunctionBegin; 484 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 485 if (owned) *owned = *((DM_Moab*)dm->data)->vowned; 486 if (ghost) *ghost = *((DM_Moab*)dm->data)->vghost; 487 PetscFunctionReturn(0); 488 } 489 490 #undef __FUNCT__ 491 #define __FUNCT__ "DMMoabGetLocalElements" 492 /*@ 493 DMMoabGetLocalElements - Get the higher-dimensional entities that are locally owned 494 495 Collective on MPI_Comm 496 497 Input Parameter: 498 . dm - The DMMoab object being set 499 500 Output Parameter: 501 . range - The entities owned locally 502 503 Level: beginner 504 505 .keywords: DMMoab, create 506 @*/ 507 PetscErrorCode DMMoabGetLocalElements(DM dm,moab::Range *range) 508 { 509 PetscFunctionBegin; 510 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 511 if (range) *range = *((DM_Moab*)dm->data)->elocal; 512 PetscFunctionReturn(0); 513 } 514 515 516 #undef __FUNCT__ 517 #define __FUNCT__ "DMMoabSetLocalElements" 518 /*@ 519 DMMoabSetLocalElements - Set the entities having DOFs on this DMMoab 520 521 Collective on MPI_Comm 522 523 Input Parameter: 524 . dm - The DMMoab object being set 525 . range - The entities treated by this DMMoab 526 527 Level: beginner 528 529 .keywords: DMMoab, create 530 @*/ 531 PetscErrorCode DMMoabSetLocalElements(DM dm,moab::Range *range) 532 { 533 moab::ErrorCode merr; 534 PetscErrorCode ierr; 535 DM_Moab *dmmoab = (DM_Moab*)(dm)->data; 536 537 PetscFunctionBegin; 538 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 539 dmmoab->elocal->clear(); 540 dmmoab->eghost->clear(); 541 dmmoab->elocal->insert(range->begin(), range->end()); 542 PetscInfo2(dm, "Range size = %D; elocal size = %D.\n", range->size(), dmmoab->elocal->size()); 543 merr = dmmoab->pcomm->filter_pstatus(*dmmoab->elocal,PSTATUS_NOT_OWNED,PSTATUS_NOT);MBERRNM(merr); 544 *dmmoab->eghost = moab::subtract(*range, *dmmoab->elocal); 545 dmmoab->neleloc=dmmoab->elocal->size(); 546 ierr = MPI_Allreduce(&dmmoab->nele, &dmmoab->neleloc, 1, MPI_INTEGER, MPI_SUM, ((PetscObject)dm)->comm);CHKERRQ(ierr); 547 PetscInfo2(dm, "Created %D local and %D glocal elements.\n", dmmoab->neleloc, dmmoab->nele); 548 PetscFunctionReturn(0); 549 } 550 551 552 #undef __FUNCT__ 553 #define __FUNCT__ "DMMoabSetLocalToGlobalTag" 554 /*@ 555 DMMoabSetLocalToGlobalTag - Set the tag used for local to global numbering 556 557 Collective on MPI_Comm 558 559 Input Parameter: 560 . dm - The DMMoab object being set 561 . ltogtag - The MOAB tag used for local to global ids 562 563 Level: beginner 564 565 .keywords: DMMoab, create 566 @*/ 567 PetscErrorCode DMMoabSetLocalToGlobalTag(DM dm,moab::Tag ltogtag) 568 { 569 PetscFunctionBegin; 570 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 571 ((DM_Moab*)dm->data)->ltog_tag = ltogtag; 572 PetscFunctionReturn(0); 573 } 574 575 576 #undef __FUNCT__ 577 #define __FUNCT__ "DMMoabGetLocalToGlobalTag" 578 /*@ 579 DMMoabGetLocalToGlobalTag - Get the tag used for local to global numbering 580 581 Collective on MPI_Comm 582 583 Input Parameter: 584 . dm - The DMMoab object being set 585 586 Output Parameter: 587 . ltogtag - The MOAB tag used for local to global ids 588 589 Level: beginner 590 591 .keywords: DMMoab, create 592 @*/ 593 PetscErrorCode DMMoabGetLocalToGlobalTag(DM dm,moab::Tag *ltog_tag) 594 { 595 PetscFunctionBegin; 596 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 597 *ltog_tag = ((DM_Moab*)dm->data)->ltog_tag; 598 PetscFunctionReturn(0); 599 } 600 601 602 #undef __FUNCT__ 603 #define __FUNCT__ "DMMoabSetBlockSize" 604 /*@ 605 DMMoabSetBlockSize - Set the block size used with this DMMoab 606 607 Collective on MPI_Comm 608 609 Input Parameter: 610 . dm - The DMMoab object being set 611 . bs - The block size used with this DMMoab 612 613 Level: beginner 614 615 .keywords: DMMoab, create 616 @*/ 617 PetscErrorCode DMMoabSetBlockSize(DM dm,PetscInt bs) 618 { 619 PetscFunctionBegin; 620 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 621 ((DM_Moab*)dm->data)->bs = bs; 622 PetscFunctionReturn(0); 623 } 624 625 626 #undef __FUNCT__ 627 #define __FUNCT__ "DMMoabGetBlockSize" 628 /*@ 629 DMMoabGetBlockSize - Get the block size used with this DMMoab 630 631 Collective on MPI_Comm 632 633 Input Parameter: 634 . dm - The DMMoab object being set 635 636 Output Parameter: 637 . bs - The block size used with this DMMoab 638 639 Level: beginner 640 641 .keywords: DMMoab, create 642 @*/ 643 PetscErrorCode DMMoabGetBlockSize(DM dm,PetscInt *bs) 644 { 645 PetscFunctionBegin; 646 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 647 *bs = ((DM_Moab*)dm->data)->bs; 648 PetscFunctionReturn(0); 649 } 650 651 652 #undef __FUNCT__ 653 #define __FUNCT__ "DMMoabSetFieldVector" 654 PetscErrorCode DMMoabSetFieldVector(DM dm, PetscInt ifield, Vec fvec) 655 { 656 DM_Moab *dmmoab; 657 moab::Tag vtag,ntag; 658 PetscScalar *varray; 659 moab::ErrorCode merr; 660 PetscErrorCode ierr; 661 PetscSection section; 662 PetscInt doff; 663 std::string tag_name; 664 moab::Range::iterator iter; 665 666 PetscFunctionBegin; 667 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 668 dmmoab = (DM_Moab*)(dm)->data; 669 670 ierr = DMGetDefaultSection(dm, §ion);CHKERRQ(ierr); 671 672 /* Create a tag in MOAB mesh to index and keep track of number of Petsc vec tags */ 673 merr = dmmoab->mbiface->tag_get_handle(dmmoab->fields[ifield],1,moab::MB_TYPE_DOUBLE,ntag, 674 moab::MB_TAG_SPARSE | moab::MB_TAG_CREAT);MBERRNM(merr); 675 676 ierr = DMMoabGetVecTag(fvec,&vtag);CHKERRQ(ierr); 677 678 merr = dmmoab->mbiface->tag_get_name(vtag, tag_name); 679 if (!tag_name.length() && merr !=moab::MB_SUCCESS) { 680 ierr = DMMoabVecGetArray(dm,fvec,&varray);CHKERRQ(ierr); 681 for(iter = dmmoab->vowned->begin(); iter != dmmoab->vowned->end(); iter++) { 682 moab::EntityHandle vtx = (*iter); 683 684 /* get field dof index */ 685 ierr = PetscSectionGetFieldOffset(section, vtx, ifield, &doff); 686 687 /* use the entity handle and the Dof index to set the right value */ 688 merr = dmmoab->mbiface->tag_set_data(ntag, &vtx, 1, (const void*)&varray[doff]);MBERRNM(merr); 689 } 690 ierr = DMMoabVecRestoreArray(dm,fvec,&varray);CHKERRQ(ierr); 691 } 692 else { 693 ierr = PetscMalloc(dmmoab->nloc*sizeof(PetscScalar),&varray);CHKERRQ(ierr); 694 /* we are using a MOAB Vec - directly copy the tag data to new one */ 695 merr = dmmoab->mbiface->tag_get_data(vtag, *dmmoab->vowned, (void*)varray);MBERRNM(merr); 696 merr = dmmoab->mbiface->tag_set_data(ntag, *dmmoab->vowned, (const void*)varray);MBERRNM(merr); 697 /* make sure the parallel exchange for ghosts are done appropriately */ 698 merr = dmmoab->pcomm->exchange_tags(ntag, *dmmoab->vlocal);MBERRNM(merr); 699 ierr = PetscFree(varray);CHKERRQ(ierr); 700 } 701 PetscFunctionReturn(0); 702 } 703 704 705 #undef __FUNCT__ 706 #define __FUNCT__ "DMMoabGetBoundaryEntities" 707 PetscErrorCode DMMoabGetBoundaryEntities(DM dm,moab::Range *bdvtx,moab::Range* bdfaces) 708 { 709 DM_Moab *dmmoab; 710 711 PetscFunctionBegin; 712 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 713 dmmoab = (DM_Moab*)(dm)->data; 714 715 if (bdvtx) *bdvtx = *dmmoab->bndyvtx; 716 if (bdfaces) *bdfaces = *dmmoab->bndyfaces; 717 PetscFunctionReturn(0); 718 } 719 720 721 #undef __FUNCT__ 722 #define __FUNCT__ "DMMoabOutput" 723 PetscErrorCode DMMoabOutput(DM dm,const char* fname,const char* wopts) 724 { 725 DM_Moab *dmmoab; 726 moab::ErrorCode merr; 727 728 PetscFunctionBegin; 729 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 730 dmmoab = (DM_Moab*)(dm)->data; 731 732 // output file, using parallel write 733 merr = dmmoab->mbiface->write_file(fname, NULL, wopts);MBERRVM(dmmoab->mbiface,"Writing output of DMMoab failed.",merr); 734 PetscFunctionReturn(0); 735 } 736 737 738 #undef __FUNCT__ 739 #define __FUNCT__ "DMMoabSetFields" 740 PetscErrorCode DMMoabSetFields(DM dm,PetscInt nfields,const char** fields) 741 { 742 DM_Moab *dmmoab; 743 744 PetscFunctionBegin; 745 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 746 dmmoab = (DM_Moab*)(dm)->data; 747 748 dmmoab->fields = fields; 749 dmmoab->nfields = nfields; 750 PetscFunctionReturn(0); 751 } 752 753 754 #undef __FUNCT__ 755 #define __FUNCT__ "DMMoabGetFieldDof" 756 PetscErrorCode DMMoabGetFieldDof(DM dm,moab::EntityHandle point,PetscInt field,PetscInt* dof) 757 { 758 PetscSection section; 759 PetscErrorCode ierr; 760 761 PetscFunctionBegin; 762 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 763 ierr = DMGetDefaultSection(dm, §ion);CHKERRQ(ierr); 764 ierr = PetscSectionGetFieldDof(section, (PetscInt)point, field, dof);CHKERRQ(ierr); 765 PetscFunctionReturn(0); 766 } 767 768 769 #undef __FUNCT__ 770 #define __FUNCT__ "DMMoabGetFieldDofs" 771 PetscErrorCode DMMoabGetFieldDofs(DM dm,PetscInt npoints,const moab::EntityHandle* points,PetscInt field,PetscInt* dof) 772 { 773 PetscInt i; 774 PetscSection section; 775 PetscErrorCode ierr; 776 777 PetscFunctionBegin; 778 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 779 ierr = DMGetDefaultSection(dm, §ion);CHKERRQ(ierr); 780 if (!dof) { 781 ierr = PetscMalloc(sizeof(PetscScalar)*npoints, &dof);CHKERRQ(ierr); 782 } 783 for (i=0; i<npoints; ++i) { 784 ierr = PetscSectionGetFieldDof(section, (PetscInt)points[i], field, &dof[i]);CHKERRQ(ierr); 785 } 786 PetscFunctionReturn(0); 787 } 788 789 790