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