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 PetscFunctionBegin; 290 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 291 *mbiface = ((DM_Moab*)dm->data)->mbiface; 292 PetscFunctionReturn(0); 293 } 294 295 296 #undef __FUNCT__ 297 #define __FUNCT__ "DMMoabSetRange" 298 /*@ 299 DMMoabSetRange - Set the entities having DOFs on this DMMoab 300 301 Collective on MPI_Comm 302 303 Input Parameter: 304 . dm - The DMMoab object being set 305 . range - The entities treated by this DMMoab 306 307 Level: beginner 308 309 .keywords: DMMoab, create 310 @*/ 311 PetscErrorCode DMMoabSetRange(DM dm,moab::Range range) 312 { 313 PetscFunctionBegin; 314 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 315 ((DM_Moab*)dm->data)->range = range; 316 PetscFunctionReturn(0); 317 } 318 319 320 #undef __FUNCT__ 321 #define __FUNCT__ "DMMoabGetRange" 322 /*@ 323 DMMoabGetRange - Get the entities having DOFs on this DMMoab 324 325 Collective on MPI_Comm 326 327 Input Parameter: 328 . dm - The DMMoab object being set 329 330 Output Parameter: 331 . range - The entities treated by this DMMoab 332 333 Level: beginner 334 335 .keywords: DMMoab, create 336 @*/ 337 PetscErrorCode DMMoabGetRange(DM dm,moab::Range *range) 338 { 339 PetscFunctionBegin; 340 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 341 *range = ((DM_Moab*)dm->data)->range; 342 PetscFunctionReturn(0); 343 } 344 345 #undef __FUNCT__ 346 #define __FUNCT__ "DMMoabSetLocalToGlobalTag" 347 /*@ 348 DMMoabSetLocalToGlobalTag - Set the tag used for local to global numbering 349 350 Collective on MPI_Comm 351 352 Input Parameter: 353 . dm - The DMMoab object being set 354 . ltogtag - The MOAB tag used for local to global ids 355 356 Level: beginner 357 358 .keywords: DMMoab, create 359 @*/ 360 PetscErrorCode DMMoabSetLocalToGlobalTag(DM dm,moab::Tag ltogtag) 361 { 362 PetscFunctionBegin; 363 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 364 ((DM_Moab*)dm->data)->ltog_tag = ltogtag; 365 PetscFunctionReturn(0); 366 } 367 368 369 #undef __FUNCT__ 370 #define __FUNCT__ "DMMoabGetLocalToGlobalTag" 371 /*@ 372 DMMoabGetLocalToGlobalTag - Get the tag used for local to global numbering 373 374 Collective on MPI_Comm 375 376 Input Parameter: 377 . dm - The DMMoab object being set 378 379 Output Parameter: 380 . ltogtag - The MOAB tag used for local to global ids 381 382 Level: beginner 383 384 .keywords: DMMoab, create 385 @*/ 386 PetscErrorCode DMMoabGetLocalToGlobalTag(DM dm,moab::Tag *ltog_tag) 387 { 388 PetscFunctionBegin; 389 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 390 *ltog_tag = ((DM_Moab*)dm->data)->ltog_tag; 391 PetscFunctionReturn(0); 392 } 393 394 395 #undef __FUNCT__ 396 #define __FUNCT__ "DMMoabSetBlockSize" 397 /*@ 398 DMMoabSetBlockSize - Set the block size used with this DMMoab 399 400 Collective on MPI_Comm 401 402 Input Parameter: 403 . dm - The DMMoab object being set 404 . bs - The block size used with this DMMoab 405 406 Level: beginner 407 408 .keywords: DMMoab, create 409 @*/ 410 PetscErrorCode DMMoabSetBlockSize(DM dm,PetscInt bs) 411 { 412 PetscFunctionBegin; 413 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 414 ((DM_Moab*)dm->data)->bs = bs; 415 PetscFunctionReturn(0); 416 } 417 418 419 #undef __FUNCT__ 420 #define __FUNCT__ "DMMoabGetBlockSize" 421 /*@ 422 DMMoabGetBlockSize - Get the block size used with this DMMoab 423 424 Collective on MPI_Comm 425 426 Input Parameter: 427 . dm - The DMMoab object being set 428 429 Output Parameter: 430 . bs - The block size used with this DMMoab 431 432 Level: beginner 433 434 .keywords: DMMoab, create 435 @*/ 436 PetscErrorCode DMMoabGetBlockSize(DM dm,PetscInt *bs) 437 { 438 PetscFunctionBegin; 439 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 440 *bs = ((DM_Moab*)dm->data)->bs; 441 PetscFunctionReturn(0); 442 } 443 444 445 // declare for use later but before they're defined 446 PetscErrorCode DMMoab_VecUserDestroy(void *user); 447 PetscErrorCode DMMoab_VecDuplicate(Vec x,Vec *y); 448 PetscErrorCode DMMoab_CreateTagName(const moab::ParallelComm *pcomm,std::string& tag_name); 449 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); 450 451 #undef __FUNCT__ 452 #define __FUNCT__ "DMMoabCreateVector" 453 /*@ 454 DMMoabCreateVector - Create a Vec from either an existing tag, or a specified tag size, and a range of entities 455 456 Collective on MPI_Comm 457 458 Input Parameter: 459 . dm - The DMMoab object being set 460 . tag - If non-zero, block size will be taken from the tag size 461 . tag_size - If tag was zero, this parameter specifies the block size; unique tag name will be generated automatically 462 . range - If non-empty, Vec corresponds to these entities, otherwise to the entities set on the DMMoab 463 . serial - If true, this is a serial Vec, otherwise a parallel one 464 . destroy_tag - If true, MOAB tag is destroyed with Vec, otherwise it is left on MOAB 465 466 Output Parameter: 467 . vec - The created vector 468 469 Level: beginner 470 471 .keywords: DMMoab, create 472 @*/ 473 PetscErrorCode DMMoabCreateVector(DM dm,moab::Tag tag,PetscInt tag_size,moab::Range range,PetscBool serial, PetscBool destroy_tag,Vec *vec) 474 { 475 PetscErrorCode ierr; 476 477 PetscFunctionBegin; 478 479 DM_Moab *dmmoab = (DM_Moab*)dm->data; 480 moab::ParallelComm *pcomm = dmmoab->pcomm; 481 moab::Interface *mbiface = dmmoab->mbiface; 482 moab::Tag ltog_tag = dmmoab->ltog_tag; 483 484 if (!tag && !tag_size) { 485 PetscFunctionReturn(PETSC_ERR_ARG_WRONG); 486 } 487 else { 488 ierr = DMMoab_CreateVector(mbiface,pcomm,tag,tag_size,ltog_tag,range,serial,destroy_tag,vec);CHKERRQ(ierr); 489 } 490 PetscFunctionReturn(0); 491 } 492 493 494 #undef __FUNCT__ 495 #define __FUNCT__ "DMMoab_CreateVector" 496 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) 497 { 498 PetscErrorCode ierr; 499 moab::ErrorCode merr; 500 501 PetscFunctionBegin; 502 503 if (!tag) { 504 std::string tag_name; 505 ierr = DMMoab_CreateTagName(pcomm,tag_name);CHKERRQ(ierr); 506 507 // Create the default value for the tag (all zeros): 508 std::vector<PetscScalar> default_value(tag_size, 0.0); 509 510 // Create the tag: 511 merr = mbiface->tag_get_handle(tag_name.c_str(),tag_size,moab::MB_TYPE_DOUBLE,tag, 512 moab::MB_TAG_DENSE | moab::MB_TAG_CREAT,default_value.data());MBERRNM(merr); 513 } 514 else { 515 516 // Make sure the tag data is of type "double": 517 moab::DataType tag_type; 518 merr = mbiface->tag_get_data_type(tag, tag_type);MBERRNM(merr); 519 if(tag_type != moab::MB_TYPE_DOUBLE) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Tag data type must be MB_TYPE_DOUBLE"); 520 } 521 522 // Create the MOAB internal data object 523 Vec_MOAB *vmoab; 524 ierr = PetscMalloc(sizeof(Vec_MOAB),&vmoab);CHKERRQ(ierr); 525 new (vmoab) Vec_MOAB(); 526 vmoab->tag = tag; 527 vmoab->ltog_tag = ltog_tag; 528 vmoab->mbiface = mbiface; 529 vmoab->pcomm = pcomm; 530 vmoab->tag_range = range; 531 vmoab->new_tag = destroy_tag; 532 vmoab->serial = serial; 533 merr = mbiface->tag_get_length(tag,vmoab->tag_size);MBERR("tag_get_size", merr); 534 535 // Call tag_iterate. This will cause MOAB to allocate memory for the 536 // tag data if it hasn't already happened: 537 int count; 538 void *void_ptr; 539 merr = mbiface->tag_iterate(tag,range.begin(),range.end(),count,void_ptr);MBERRNM(merr); 540 541 // Check to make sure the tag data is in a single sequence: 542 if ((unsigned)count != range.size()) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Can only create MOAB Vector for single sequence"); 543 PetscScalar *data_ptr = (PetscScalar*)void_ptr; 544 545 // Create the PETSc Vector: 546 if(!serial) { 547 // This is an MPI Vector: 548 ierr = VecCreateMPIWithArray(vmoab->pcomm->comm(),vmoab->tag_size,vmoab->tag_size*range.size(), 549 PETSC_DECIDE,data_ptr,vec);CHKERRQ(ierr); 550 551 // Vector created, manually set local to global mapping: 552 ISLocalToGlobalMapping ltog; 553 PetscInt *gindices = new PetscInt[range.size()]; 554 PetscInt count = 0; 555 moab::Range::iterator iter; 556 for(iter = range.begin(); iter != range.end(); iter++) { 557 int dof; 558 merr = mbiface->tag_get_data(ltog_tag,&(*iter),1,&dof);MBERRNM(merr); 559 gindices[count] = dof; 560 count++; 561 } 562 563 ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF,range.size(),gindices, 564 PETSC_COPY_VALUES,<og);CHKERRQ(ierr); 565 ierr = VecSetLocalToGlobalMappingBlock(*vec,ltog);CHKERRQ(ierr); 566 567 // Clean up: 568 ierr = ISLocalToGlobalMappingDestroy(<og);CHKERRQ(ierr); 569 delete [] gindices; 570 } else { 571 // This is a serial vector: 572 ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,vmoab->tag_size,vmoab->tag_size*range.size(),data_ptr,vec);CHKERRQ(ierr); 573 } 574 575 576 PetscContainer moabdata; 577 ierr = PetscContainerCreate(PETSC_COMM_SELF,&moabdata);CHKERRQ(ierr); 578 ierr = PetscContainerSetPointer(moabdata,vmoab);CHKERRQ(ierr); 579 ierr = PetscContainerSetUserDestroy(moabdata,DMMoab_VecUserDestroy);CHKERRQ(ierr); 580 ierr = PetscObjectCompose((PetscObject)*vec,"MOABData",(PetscObject)moabdata);CHKERRQ(ierr); 581 (*vec)->ops->duplicate = DMMoab_VecDuplicate; 582 583 ierr = PetscContainerDestroy(&moabdata);CHKERRQ(ierr); 584 PetscFunctionReturn(0); 585 } 586 587 #undef __FUNCT__ 588 #define __FUNCT__ "DMMoabGetVecTag" 589 /*@ 590 DMMoabGetVecTag - Get the MOAB tag associated with this Vec 591 592 Collective on MPI_Comm 593 594 Input Parameter: 595 . vec - Vec being queried 596 597 Output Parameter: 598 . tag - Tag associated with this Vec 599 600 Level: beginner 601 602 .keywords: DMMoab, create 603 @*/ 604 PetscErrorCode DMMoabGetVecTag(Vec vec,moab::Tag *tag) 605 { 606 PetscContainer moabdata; 607 Vec_MOAB *vmoab; 608 PetscErrorCode ierr; 609 610 PetscFunctionBegin; 611 612 // Get the MOAB private data: 613 ierr = PetscObjectQuery((PetscObject)vec,"MOABData", (PetscObject*) &moabdata);CHKERRQ(ierr); 614 ierr = PetscContainerGetPointer(moabdata, (void**) &vmoab);CHKERRQ(ierr); 615 616 *tag = vmoab->tag; 617 618 PetscFunctionReturn(0); 619 } 620 621 622 #undef __FUNCT__ 623 #define __FUNCT__ "DMMoabGetVecRange" 624 /*@ 625 DMMoabGetVecRange - Get the MOAB entities associated with this Vec 626 627 Collective on MPI_Comm 628 629 Input Parameter: 630 . vec - Vec being queried 631 632 Output Parameter: 633 . range - Entities associated with this Vec 634 635 Level: beginner 636 637 .keywords: DMMoab, create 638 @*/ 639 PetscErrorCode DMMoabGetVecRange(Vec vec,moab::Range *range) 640 { 641 PetscContainer moabdata; 642 Vec_MOAB *vmoab; 643 PetscErrorCode ierr; 644 645 PetscFunctionBegin; 646 647 // Get the MOAB private data: 648 ierr = PetscObjectQuery((PetscObject)vec,"MOABData", (PetscObject*) &moabdata);CHKERRQ(ierr); 649 ierr = PetscContainerGetPointer(moabdata, (void**) &vmoab);CHKERRQ(ierr); 650 651 *range = vmoab->tag_range; 652 653 PetscFunctionReturn(0); 654 } 655 656 657 #undef __FUNCT__ 658 #define __FUNCT__ "DMMoab_VecDuplicate" 659 PetscErrorCode DMMoab_VecDuplicate(Vec x,Vec *y) 660 { 661 PetscErrorCode ierr; 662 PetscFunctionBegin; 663 PetscValidHeaderSpecific(x,VEC_CLASSID,1); 664 PetscValidPointer(y,2); 665 666 // Get the Vec_MOAB struct for the original vector: 667 PetscContainer moabdata; 668 Vec_MOAB *vmoab; 669 ierr = PetscObjectQuery((PetscObject)x,"MOABData", (PetscObject*) &moabdata);CHKERRQ(ierr); 670 ierr = PetscContainerGetPointer(moabdata, (void**)&vmoab);CHKERRQ(ierr); 671 672 ierr = DMMoab_CreateVector(vmoab->mbiface,vmoab->pcomm,0,vmoab->tag_size,vmoab->ltog_tag,vmoab->tag_range,vmoab->serial,PETSC_TRUE,y);CHKERRQ(ierr); 673 PetscFunctionReturn(0); 674 } 675 676 677 #undef __FUNCT__ 678 #define __FUNCT__ "DMMoab_CreateTagName" 679 /* DMMoab_CreateTagName 680 * 681 * Creates a unique tag name that will be shared across processes. If 682 * pcomm is NULL, then this is a serial vector. A unique tag name 683 * will be returned in tag_name in either case. 684 * 685 * The tag names have the format _PETSC_VEC_N where N is some integer. 686 */ 687 PetscErrorCode DMMoab_CreateTagName(const moab::ParallelComm *pcomm,std::string& tag_name) 688 { 689 moab::ErrorCode mberr; 690 PetscErrorCode ierr; 691 692 PetscFunctionBegin; 693 const std::string PVEC_PREFIX = "_PETSC_VEC_"; 694 const PetscInt PVEC_PREFIX_SIZE = PVEC_PREFIX.size(); 695 696 // Check to see if there are any PETSc vectors defined: 697 const moab::Interface *mbiface = pcomm->get_moab(); 698 std::vector<moab::Tag> tags; 699 PetscInt n = 0; 700 mberr = mbiface->tag_get_tags(tags);MBERRNM(mberr); 701 for(unsigned i = 0; i < tags.size(); i++) { 702 std::string s; 703 mberr = mbiface->tag_get_name(tags[i],s);MBERRNM(mberr); 704 if(s.find(PVEC_PREFIX) != std::string::npos){ 705 // This tag represents a PETSc vector. Find the vector number: 706 PetscInt m; 707 std::istringstream(s.substr(PVEC_PREFIX_SIZE)) >> m; 708 if(m >= n) n = m+1; 709 } 710 } 711 712 // Make sure that n is consistent across all processes: 713 PetscInt global_n; 714 MPI_Comm comm = PETSC_COMM_SELF; 715 if(pcomm) comm = pcomm->comm(); 716 ierr = MPI_Allreduce(&n,&global_n,1,MPI_INT,MPI_MAX,comm);CHKERRQ(ierr); 717 718 // Set the answer and return: 719 std::ostringstream ss; 720 ss << PVEC_PREFIX << global_n; 721 tag_name = ss.str(); 722 PetscFunctionReturn(0); 723 } 724 725 726 #undef __FUNCT__ 727 #define __FUNCT__ "DMMoab_VecUserDestroy" 728 PetscErrorCode DMMoab_VecUserDestroy(void *user) 729 { 730 Vec_MOAB *vmoab; 731 PetscErrorCode ierr; 732 moab::ErrorCode merr; 733 734 PetscFunctionBegin; 735 vmoab = (Vec_MOAB*)user; 736 vmoab->tag_range.~Range(); 737 if(vmoab->new_tag) { 738 // Tag created via a call to VecDuplicate, delete the underlying tag in MOAB... 739 merr = vmoab->mbiface->tag_delete(vmoab->tag);MBERRNM(merr); 740 } 741 742 ierr = PetscFree(vmoab);CHKERRQ(ierr); 743 PetscFunctionReturn(0); 744 } 745 746