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