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