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