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