1 #include <petsc-private/dmimpl.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 <sstream> 7 8 typedef struct { 9 PetscInt bs; /* Number of degrees of freedom on each entity, aka tag size in moab */ 10 PetscBool icreatedinstance; /* true if DM created moab instance internally, will destroy instance in DMDestroy */ 11 moab::ParallelComm *pcomm; 12 moab::Interface *mbiface; 13 moab::Tag ltog_tag; /* moab supports "global id" tags, which are usually local to global numbering */ 14 moab::Range range; 15 } DM_Moab; 16 17 typedef struct { 18 moab::Interface *mbiface; 19 moab::ParallelComm *pcomm; 20 moab::Range tag_range; /* entities to which this tag applies */ 21 moab::Tag tag; 22 moab::Tag ltog_tag; 23 PetscInt tag_size; 24 PetscBool new_tag; 25 PetscBool serial; 26 27 } Vec_MOAB; 28 29 #undef __FUNCT__ 30 #define __FUNCT__ "DMCreateGlobalVector_Moab" 31 PetscErrorCode DMCreateGlobalVector_Moab(DM dm,Vec *gvec) 32 { 33 PetscErrorCode ierr; 34 DM_Moab *dmmoab = (DM_Moab*)dm->data; 35 36 PetscFunctionBegin; 37 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 38 PetscValidPointer(gvec,2); 39 PetscInt block_size = ((DM_Moab*)dm->data)->bs; 40 moab::Tag tag = 0; 41 ierr = DMMoabCreateVector(dm,tag,block_size,dmmoab->range,PETSC_FALSE,PETSC_TRUE,gvec);CHKERRQ(ierr); 42 PetscFunctionReturn(0); 43 } 44 45 46 #undef __FUNCT__ 47 #define __FUNCT__ "DMCreateLocalVector_Moab" 48 PetscErrorCode DMCreateLocalVector_Moab(DM dm,Vec *gvec) 49 { 50 PetscErrorCode ierr; 51 DM_Moab *dmmoab = (DM_Moab*)dm->data; 52 53 PetscFunctionBegin; 54 PetscInt bs = 1; 55 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 56 PetscValidPointer(gvec,2); 57 moab::Tag tag = 0; 58 ierr = DMMoabCreateVector(dm,tag,bs,dmmoab->range,PETSC_TRUE,PETSC_TRUE,gvec);CHKERRQ(ierr); 59 PetscFunctionReturn(0); 60 } 61 62 #undef __FUNCT__ 63 #define __FUNCT__ "DMDestroy_Moab" 64 PetscErrorCode DMDestroy_Moab(DM dm) 65 { 66 PetscErrorCode ierr; 67 68 PetscFunctionBegin; 69 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 70 if (((DM_Moab*)dm->data)->icreatedinstance) { 71 delete ((DM_Moab*)dm->data)->mbiface; 72 ((DM_Moab*)dm->data)->mbiface = NULL; 73 ((DM_Moab*)dm->data)->pcomm = NULL; 74 ((DM_Moab*)dm->data)->range.~Range(); 75 } 76 ierr = PetscFree(dm->data);CHKERRQ(ierr); 77 PetscFunctionReturn(0); 78 } 79 80 #undef __FUNCT__ 81 #define __FUNCT__ "DMCreate_Moab" 82 PETSC_EXTERN PetscErrorCode DMCreate_Moab(DM dm) 83 { 84 DM_Moab *moab; 85 PetscErrorCode ierr; 86 87 PetscFunctionBegin; 88 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 89 ierr = PetscNewLog(dm,DM_Moab,&moab);CHKERRQ(ierr); 90 dm->data = moab; 91 new (moab) DM_Moab(); 92 93 dm->ops->createglobalvector = DMCreateGlobalVector_Moab; 94 dm->ops->createlocalvector = DMCreateLocalVector_Moab; 95 dm->ops->destroy = DMDestroy_Moab; 96 PetscFunctionReturn(0); 97 } 98 99 #undef __FUNCT__ 100 #define __FUNCT__ "DMMoabCreate" 101 /*@ 102 DMMoabCreate - Creates a DMMoab object, which encapsulates a moab instance 103 104 Collective on MPI_Comm 105 106 Input Parameter: 107 . comm - The communicator for the DMMoab object 108 109 Output Parameter: 110 . moab - The DMMoab object 111 112 Level: beginner 113 114 .keywords: DMMoab, create 115 @*/ 116 PetscErrorCode DMMoabCreate(MPI_Comm comm, DM *moab) 117 { 118 PetscErrorCode ierr; 119 120 PetscFunctionBegin; 121 PetscValidPointer(moab,2); 122 ierr = DMCreate(comm, moab);CHKERRQ(ierr); 123 ierr = DMSetType(*moab, DMMOAB);CHKERRQ(ierr); 124 PetscFunctionReturn(0); 125 } 126 127 #undef __FUNCT__ 128 #define __FUNCT__ "DMMoabCreateMoab" 129 /*@ 130 DMMoabCreate - Creates a DMMoab object, optionally from an instance and other data 131 132 Collective on MPI_Comm 133 134 Input Parameter: 135 . comm - The communicator for the DMMoab object 136 . moab - (ptr to) the MOAB Instance; if passed in NULL, MOAB instance is created inside PETSc, and destroyed 137 along with the DMMoab 138 . pcomm - (ptr to) a ParallelComm; if NULL, creates one internally for the whole communicator 139 . ltog_tag - A tag to use to retrieve global id for an entity; if 0, will use GLOBAL_ID_TAG_NAME/tag 140 . range - If non-NULL, contains range of entities to which DOFs will be assigned 141 142 Output Parameter: 143 . moab - The DMMoab object 144 145 Level: beginner 146 147 .keywords: DMMoab, create 148 @*/ 149 PetscErrorCode DMMoabCreateMoab(MPI_Comm comm, moab::Interface *mbiface, moab::ParallelComm *pcomm, moab::Tag ltog_tag, moab::Range *range, DM *moab) 150 { 151 PetscErrorCode ierr; 152 DM_Moab *dmmoab; 153 154 PetscFunctionBegin; 155 PetscValidPointer(moab,2); 156 ierr = DMMoabCreate(comm, moab);CHKERRQ(ierr); 157 dmmoab = (DM_Moab*)(*moab)->data; 158 159 if (!mbiface) { 160 mbiface = new moab::Core(); 161 dmmoab->icreatedinstance = PETSC_TRUE; 162 } 163 else 164 dmmoab->icreatedinstance = PETSC_FALSE; 165 166 if (!pcomm) { 167 PetscInt rank, nprocs; 168 MPI_Comm_rank(comm, &rank); 169 MPI_Comm_size(comm, &nprocs); 170 pcomm = new moab::ParallelComm(mbiface, comm); 171 } 172 173 // do the initialization of the DM 174 dmmoab->bs = 0; 175 dmmoab->pcomm = pcomm; 176 dmmoab->mbiface = mbiface; 177 dmmoab->ltog_tag = ltog_tag; 178 179 ierr = DMMoabSetInterface(*moab, mbiface);CHKERRQ(ierr); 180 if (!pcomm) pcomm = new moab::ParallelComm(mbiface, comm); 181 ierr = DMMoabSetParallelComm(*moab, pcomm);CHKERRQ(ierr); 182 if (!ltog_tag) { 183 moab::ErrorCode merr = mbiface->tag_get_handle(GLOBAL_ID_TAG_NAME, ltog_tag);MBERRNM(merr); 184 } 185 if (ltog_tag) { 186 ierr = DMMoabSetLocalToGlobalTag(*moab, ltog_tag);CHKERRQ(ierr); 187 } 188 if (range) { 189 ierr = DMMoabSetRange(*moab, *range);CHKERRQ(ierr); 190 } 191 PetscFunctionReturn(0); 192 } 193 194 #undef __FUNCT__ 195 #define __FUNCT__ "DMMoabSetParallelComm" 196 /*@ 197 DMMoabSetParallelComm - Set the ParallelComm used with this DMMoab 198 199 Collective on MPI_Comm 200 201 Input Parameter: 202 . dm - The DMMoab object being set 203 . pcomm - The ParallelComm being set on the DMMoab 204 205 Level: beginner 206 207 .keywords: DMMoab, create 208 @*/ 209 PetscErrorCode DMMoabSetParallelComm(DM dm,moab::ParallelComm *pcomm) 210 { 211 PetscFunctionBegin; 212 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 213 ((DM_Moab*)dm->data)->pcomm = pcomm; 214 ((DM_Moab*)dm->data)->mbiface = pcomm->get_moab(); 215 PetscFunctionReturn(0); 216 } 217 218 219 #undef __FUNCT__ 220 #define __FUNCT__ "DMMoabGetParallelComm" 221 /*@ 222 DMMoabGetParallelComm - Get the ParallelComm used with this DMMoab 223 224 Collective on MPI_Comm 225 226 Input Parameter: 227 . dm - The DMMoab object being set 228 229 Output Parameter: 230 . pcomm - The ParallelComm for the DMMoab 231 232 Level: beginner 233 234 .keywords: DMMoab, create 235 @*/ 236 PetscErrorCode DMMoabGetParallelComm(DM dm,moab::ParallelComm **pcomm) 237 { 238 PetscFunctionBegin; 239 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 240 *pcomm = ((DM_Moab*)dm->data)->pcomm; 241 PetscFunctionReturn(0); 242 } 243 244 245 #undef __FUNCT__ 246 #define __FUNCT__ "DMMoabSetInterface" 247 /*@ 248 DMMoabSetInterface - Set the MOAB instance used with this DMMoab 249 250 Collective on MPI_Comm 251 252 Input Parameter: 253 . dm - The DMMoab object being set 254 . mbiface - The MOAB instance being set on this DMMoab 255 256 Level: beginner 257 258 .keywords: DMMoab, create 259 @*/ 260 PetscErrorCode DMMoabSetInterface(DM dm,moab::Interface *mbiface) 261 { 262 PetscFunctionBegin; 263 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 264 ((DM_Moab*)dm->data)->pcomm = NULL; 265 ((DM_Moab*)dm->data)->mbiface = mbiface; 266 PetscFunctionReturn(0); 267 } 268 269 270 #undef __FUNCT__ 271 #define __FUNCT__ "DMMoabGetInterface" 272 /*@ 273 DMMoabGetInterface - Get the MOAB instance used with this DMMoab 274 275 Collective on MPI_Comm 276 277 Input Parameter: 278 . dm - The DMMoab object being set 279 280 Output Parameter: 281 . mbiface - The MOAB instance set on this DMMoab 282 283 Level: beginner 284 285 .keywords: DMMoab, create 286 @*/ 287 PetscErrorCode DMMoabGetInterface(DM dm,moab::Interface **mbiface) 288 { 289 PetscErrorCode ierr; 290 static PetscBool cite = PETSC_FALSE; 291 PetscErrorCode ierr; 292 293 PetscFunctionBegin; 294 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 295 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); 296 *mbiface = ((DM_Moab*)dm->data)->mbiface; 297 PetscFunctionReturn(0); 298 } 299 300 301 #undef __FUNCT__ 302 #define __FUNCT__ "DMMoabSetRange" 303 /*@ 304 DMMoabSetRange - Set the entities having DOFs on this DMMoab 305 306 Collective on MPI_Comm 307 308 Input Parameter: 309 . dm - The DMMoab object being set 310 . range - The entities treated by this DMMoab 311 312 Level: beginner 313 314 .keywords: DMMoab, create 315 @*/ 316 PetscErrorCode DMMoabSetRange(DM dm,moab::Range range) 317 { 318 PetscFunctionBegin; 319 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 320 ((DM_Moab*)dm->data)->range = range; 321 PetscFunctionReturn(0); 322 } 323 324 325 #undef __FUNCT__ 326 #define __FUNCT__ "DMMoabGetRange" 327 /*@ 328 DMMoabGetRange - Get the entities having DOFs on this DMMoab 329 330 Collective on MPI_Comm 331 332 Input Parameter: 333 . dm - The DMMoab object being set 334 335 Output Parameter: 336 . range - The entities treated by this DMMoab 337 338 Level: beginner 339 340 .keywords: DMMoab, create 341 @*/ 342 PetscErrorCode DMMoabGetRange(DM dm,moab::Range *range) 343 { 344 PetscFunctionBegin; 345 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 346 *range = ((DM_Moab*)dm->data)->range; 347 PetscFunctionReturn(0); 348 } 349 350 #undef __FUNCT__ 351 #define __FUNCT__ "DMMoabSetLocalToGlobalTag" 352 /*@ 353 DMMoabSetLocalToGlobalTag - Set the tag used for local to global numbering 354 355 Collective on MPI_Comm 356 357 Input Parameter: 358 . dm - The DMMoab object being set 359 . ltogtag - The MOAB tag used for local to global ids 360 361 Level: beginner 362 363 .keywords: DMMoab, create 364 @*/ 365 PetscErrorCode DMMoabSetLocalToGlobalTag(DM dm,moab::Tag ltogtag) 366 { 367 PetscFunctionBegin; 368 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 369 ((DM_Moab*)dm->data)->ltog_tag = ltogtag; 370 PetscFunctionReturn(0); 371 } 372 373 374 #undef __FUNCT__ 375 #define __FUNCT__ "DMMoabGetLocalToGlobalTag" 376 /*@ 377 DMMoabGetLocalToGlobalTag - Get the tag used for local to global numbering 378 379 Collective on MPI_Comm 380 381 Input Parameter: 382 . dm - The DMMoab object being set 383 384 Output Parameter: 385 . ltogtag - The MOAB tag used for local to global ids 386 387 Level: beginner 388 389 .keywords: DMMoab, create 390 @*/ 391 PetscErrorCode DMMoabGetLocalToGlobalTag(DM dm,moab::Tag *ltog_tag) 392 { 393 PetscFunctionBegin; 394 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 395 *ltog_tag = ((DM_Moab*)dm->data)->ltog_tag; 396 PetscFunctionReturn(0); 397 } 398 399 400 #undef __FUNCT__ 401 #define __FUNCT__ "DMMoabSetBlockSize" 402 /*@ 403 DMMoabSetBlockSize - Set the block size used with this DMMoab 404 405 Collective on MPI_Comm 406 407 Input Parameter: 408 . dm - The DMMoab object being set 409 . bs - The block size used with this DMMoab 410 411 Level: beginner 412 413 .keywords: DMMoab, create 414 @*/ 415 PetscErrorCode DMMoabSetBlockSize(DM dm,PetscInt bs) 416 { 417 PetscFunctionBegin; 418 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 419 ((DM_Moab*)dm->data)->bs = bs; 420 PetscFunctionReturn(0); 421 } 422 423 424 #undef __FUNCT__ 425 #define __FUNCT__ "DMMoabGetBlockSize" 426 /*@ 427 DMMoabGetBlockSize - Get the block size used with this DMMoab 428 429 Collective on MPI_Comm 430 431 Input Parameter: 432 . dm - The DMMoab object being set 433 434 Output Parameter: 435 . bs - The block size used with this DMMoab 436 437 Level: beginner 438 439 .keywords: DMMoab, create 440 @*/ 441 PetscErrorCode DMMoabGetBlockSize(DM dm,PetscInt *bs) 442 { 443 PetscFunctionBegin; 444 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 445 *bs = ((DM_Moab*)dm->data)->bs; 446 PetscFunctionReturn(0); 447 } 448 449 450 // declare for use later but before they're defined 451 PetscErrorCode DMMoab_VecUserDestroy(void *user); 452 PetscErrorCode DMMoab_VecDuplicate(Vec x,Vec *y); 453 PetscErrorCode DMMoab_CreateTagName(const moab::ParallelComm *pcomm,std::string& tag_name); 454 PetscErrorCode DMMoab_CreateVector(moab::Interface *iface,moab::ParallelComm *pcomm,moab::Tag tag,PetscInt tag_size,moab::Tag ltog_tag,moab::Range range,PetscBool serial, PetscBool destroy_tag,Vec *vec); 455 456 #undef __FUNCT__ 457 #define __FUNCT__ "DMMoabCreateVector" 458 /*@ 459 DMMoabCreateVector - Create a Vec from either an existing tag, or a specified tag size, and a range of entities 460 461 Collective on MPI_Comm 462 463 Input Parameter: 464 . dm - The DMMoab object being set 465 . tag - If non-zero, block size will be taken from the tag size 466 . tag_size - If tag was zero, this parameter specifies the block size; unique tag name will be generated automatically 467 . range - If non-empty, Vec corresponds to these entities, otherwise to the entities set on the DMMoab 468 . serial - If true, this is a serial Vec, otherwise a parallel one 469 . destroy_tag - If true, MOAB tag is destroyed with Vec, otherwise it is left on MOAB 470 471 Output Parameter: 472 . vec - The created vector 473 474 Level: beginner 475 476 .keywords: DMMoab, create 477 @*/ 478 PetscErrorCode DMMoabCreateVector(DM dm,moab::Tag tag,PetscInt tag_size,moab::Range range,PetscBool serial, PetscBool destroy_tag,Vec *vec) 479 { 480 PetscErrorCode ierr; 481 482 PetscFunctionBegin; 483 484 DM_Moab *dmmoab = (DM_Moab*)dm->data; 485 moab::ParallelComm *pcomm = dmmoab->pcomm; 486 moab::Interface *mbiface = dmmoab->mbiface; 487 moab::Tag ltog_tag = dmmoab->ltog_tag; 488 489 if (!tag && !tag_size) { 490 PetscFunctionReturn(PETSC_ERR_ARG_WRONG); 491 } 492 else { 493 ierr = DMMoab_CreateVector(mbiface,pcomm,tag,tag_size,ltog_tag,range,serial,destroy_tag,vec);CHKERRQ(ierr); 494 } 495 PetscFunctionReturn(0); 496 } 497 498 499 #undef __FUNCT__ 500 #define __FUNCT__ "DMMoab_CreateVector" 501 PetscErrorCode DMMoab_CreateVector(moab::Interface *mbiface,moab::ParallelComm *pcomm,moab::Tag tag,PetscInt tag_size,moab::Tag ltog_tag,moab::Range range,PetscBool serial, PetscBool destroy_tag,Vec *vec) 502 { 503 PetscErrorCode ierr; 504 moab::ErrorCode merr; 505 506 PetscFunctionBegin; 507 508 if (!tag) { 509 std::string tag_name; 510 ierr = DMMoab_CreateTagName(pcomm,tag_name);CHKERRQ(ierr); 511 512 // Create the default value for the tag (all zeros): 513 std::vector<PetscScalar> default_value(tag_size, 0.0); 514 515 // Create the tag: 516 merr = mbiface->tag_get_handle(tag_name.c_str(),tag_size,moab::MB_TYPE_DOUBLE,tag, 517 moab::MB_TAG_DENSE | moab::MB_TAG_CREAT,default_value.data());MBERRNM(merr); 518 } 519 else { 520 521 // Make sure the tag data is of type "double": 522 moab::DataType tag_type; 523 merr = mbiface->tag_get_data_type(tag, tag_type);MBERRNM(merr); 524 if(tag_type != moab::MB_TYPE_DOUBLE) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Tag data type must be MB_TYPE_DOUBLE"); 525 } 526 527 // Create the MOAB internal data object 528 Vec_MOAB *vmoab; 529 ierr = PetscMalloc(sizeof(Vec_MOAB),&vmoab);CHKERRQ(ierr); 530 new (vmoab) Vec_MOAB(); 531 vmoab->tag = tag; 532 vmoab->ltog_tag = ltog_tag; 533 vmoab->mbiface = mbiface; 534 vmoab->pcomm = pcomm; 535 vmoab->tag_range = range; 536 vmoab->new_tag = destroy_tag; 537 vmoab->serial = serial; 538 merr = mbiface->tag_get_length(tag,vmoab->tag_size);MBERR("tag_get_size", merr); 539 540 // Call tag_iterate. This will cause MOAB to allocate memory for the 541 // tag data if it hasn't already happened: 542 int count; 543 void *void_ptr; 544 merr = mbiface->tag_iterate(tag,range.begin(),range.end(),count,void_ptr);MBERRNM(merr); 545 546 // Check to make sure the tag data is in a single sequence: 547 if ((unsigned)count != range.size()) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Can only create MOAB Vector for single sequence"); 548 PetscScalar *data_ptr = (PetscScalar*)void_ptr; 549 550 // Create the PETSc Vector: 551 if(!serial) { 552 // This is an MPI Vector: 553 ierr = VecCreateMPIWithArray(vmoab->pcomm->comm(),vmoab->tag_size,vmoab->tag_size*range.size(), 554 PETSC_DECIDE,data_ptr,vec);CHKERRQ(ierr); 555 556 // Vector created, manually set local to global mapping: 557 ISLocalToGlobalMapping ltog; 558 PetscInt *gindices = new PetscInt[range.size()]; 559 PetscInt count = 0; 560 moab::Range::iterator iter; 561 for(iter = range.begin(); iter != range.end(); iter++) { 562 int dof; 563 merr = mbiface->tag_get_data(ltog_tag,&(*iter),1,&dof);MBERRNM(merr); 564 gindices[count] = dof; 565 count++; 566 } 567 568 ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF,range.size(),gindices, 569 PETSC_COPY_VALUES,<og);CHKERRQ(ierr); 570 ierr = VecSetLocalToGlobalMappingBlock(*vec,ltog);CHKERRQ(ierr); 571 572 // Clean up: 573 ierr = ISLocalToGlobalMappingDestroy(<og);CHKERRQ(ierr); 574 delete [] gindices; 575 } else { 576 // This is a serial vector: 577 ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,vmoab->tag_size,vmoab->tag_size*range.size(),data_ptr,vec);CHKERRQ(ierr); 578 } 579 580 581 PetscContainer moabdata; 582 ierr = PetscContainerCreate(PETSC_COMM_SELF,&moabdata);CHKERRQ(ierr); 583 ierr = PetscContainerSetPointer(moabdata,vmoab);CHKERRQ(ierr); 584 ierr = PetscContainerSetUserDestroy(moabdata,DMMoab_VecUserDestroy);CHKERRQ(ierr); 585 ierr = PetscObjectCompose((PetscObject)*vec,"MOABData",(PetscObject)moabdata);CHKERRQ(ierr); 586 (*vec)->ops->duplicate = DMMoab_VecDuplicate; 587 588 ierr = PetscContainerDestroy(&moabdata);CHKERRQ(ierr); 589 PetscFunctionReturn(0); 590 } 591 592 #undef __FUNCT__ 593 #define __FUNCT__ "DMMoabGetVecTag" 594 /*@ 595 DMMoabGetVecTag - Get the MOAB tag associated with this Vec 596 597 Collective on MPI_Comm 598 599 Input Parameter: 600 . vec - Vec being queried 601 602 Output Parameter: 603 . tag - Tag associated with this Vec 604 605 Level: beginner 606 607 .keywords: DMMoab, create 608 @*/ 609 PetscErrorCode DMMoabGetVecTag(Vec vec,moab::Tag *tag) 610 { 611 PetscContainer moabdata; 612 Vec_MOAB *vmoab; 613 PetscErrorCode ierr; 614 615 PetscFunctionBegin; 616 617 // Get the MOAB private data: 618 ierr = PetscObjectQuery((PetscObject)vec,"MOABData", (PetscObject*) &moabdata);CHKERRQ(ierr); 619 ierr = PetscContainerGetPointer(moabdata, (void**) &vmoab);CHKERRQ(ierr); 620 621 *tag = vmoab->tag; 622 623 PetscFunctionReturn(0); 624 } 625 626 627 #undef __FUNCT__ 628 #define __FUNCT__ "DMMoabGetVecRange" 629 /*@ 630 DMMoabGetVecRange - Get the MOAB entities associated with this Vec 631 632 Collective on MPI_Comm 633 634 Input Parameter: 635 . vec - Vec being queried 636 637 Output Parameter: 638 . range - Entities associated with this Vec 639 640 Level: beginner 641 642 .keywords: DMMoab, create 643 @*/ 644 PetscErrorCode DMMoabGetVecRange(Vec vec,moab::Range *range) 645 { 646 PetscContainer moabdata; 647 Vec_MOAB *vmoab; 648 PetscErrorCode ierr; 649 650 PetscFunctionBegin; 651 652 // Get the MOAB private data: 653 ierr = PetscObjectQuery((PetscObject)vec,"MOABData", (PetscObject*) &moabdata);CHKERRQ(ierr); 654 ierr = PetscContainerGetPointer(moabdata, (void**) &vmoab);CHKERRQ(ierr); 655 656 *range = vmoab->tag_range; 657 658 PetscFunctionReturn(0); 659 } 660 661 662 #undef __FUNCT__ 663 #define __FUNCT__ "DMMoab_VecDuplicate" 664 PetscErrorCode DMMoab_VecDuplicate(Vec x,Vec *y) 665 { 666 PetscErrorCode ierr; 667 PetscFunctionBegin; 668 PetscValidHeaderSpecific(x,VEC_CLASSID,1); 669 PetscValidPointer(y,2); 670 671 // Get the Vec_MOAB struct for the original vector: 672 PetscContainer moabdata; 673 Vec_MOAB *vmoab; 674 ierr = PetscObjectQuery((PetscObject)x,"MOABData", (PetscObject*) &moabdata);CHKERRQ(ierr); 675 ierr = PetscContainerGetPointer(moabdata, (void**)&vmoab);CHKERRQ(ierr); 676 677 ierr = DMMoab_CreateVector(vmoab->mbiface,vmoab->pcomm,0,vmoab->tag_size,vmoab->ltog_tag,vmoab->tag_range,vmoab->serial,PETSC_TRUE,y);CHKERRQ(ierr); 678 PetscFunctionReturn(0); 679 } 680 681 682 #undef __FUNCT__ 683 #define __FUNCT__ "DMMoab_CreateTagName" 684 /* DMMoab_CreateTagName 685 * 686 * Creates a unique tag name that will be shared across processes. If 687 * pcomm is NULL, then this is a serial vector. A unique tag name 688 * will be returned in tag_name in either case. 689 * 690 * The tag names have the format _PETSC_VEC_N where N is some integer. 691 */ 692 PetscErrorCode DMMoab_CreateTagName(const moab::ParallelComm *pcomm,std::string& tag_name) 693 { 694 moab::ErrorCode mberr; 695 PetscErrorCode ierr; 696 697 PetscFunctionBegin; 698 const std::string PVEC_PREFIX = "_PETSC_VEC_"; 699 const PetscInt PVEC_PREFIX_SIZE = PVEC_PREFIX.size(); 700 701 // Check to see if there are any PETSc vectors defined: 702 const moab::Interface *mbiface = pcomm->get_moab(); 703 std::vector<moab::Tag> tags; 704 PetscInt n = 0; 705 mberr = mbiface->tag_get_tags(tags);MBERRNM(mberr); 706 for(unsigned i = 0; i < tags.size(); i++) { 707 std::string s; 708 mberr = mbiface->tag_get_name(tags[i],s);MBERRNM(mberr); 709 if(s.find(PVEC_PREFIX) != std::string::npos){ 710 // This tag represents a PETSc vector. Find the vector number: 711 PetscInt m; 712 std::istringstream(s.substr(PVEC_PREFIX_SIZE)) >> m; 713 if(m >= n) n = m+1; 714 } 715 } 716 717 // Make sure that n is consistent across all processes: 718 PetscInt global_n; 719 MPI_Comm comm = PETSC_COMM_SELF; 720 if(pcomm) comm = pcomm->comm(); 721 ierr = MPI_Allreduce(&n,&global_n,1,MPI_INT,MPI_MAX,comm);CHKERRQ(ierr); 722 723 // Set the answer and return: 724 std::ostringstream ss; 725 ss << PVEC_PREFIX << global_n; 726 tag_name = ss.str(); 727 PetscFunctionReturn(0); 728 } 729 730 731 #undef __FUNCT__ 732 #define __FUNCT__ "DMMoab_VecUserDestroy" 733 PetscErrorCode DMMoab_VecUserDestroy(void *user) 734 { 735 Vec_MOAB *vmoab; 736 PetscErrorCode ierr; 737 moab::ErrorCode merr; 738 739 PetscFunctionBegin; 740 vmoab = (Vec_MOAB*)user; 741 vmoab->tag_range.~Range(); 742 if(vmoab->new_tag) { 743 // Tag created via a call to VecDuplicate, delete the underlying tag in MOAB... 744 merr = vmoab->mbiface->tag_delete(vmoab->tag);MBERRNM(merr); 745 } 746 747 ierr = PetscFree(vmoab);CHKERRQ(ierr); 748 PetscFunctionReturn(0); 749 } 750 751