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