1 #include <petsc-private/dmmbimpl.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 // declare for use later but before they're defined 8 static PetscErrorCode DMMoab_VecUserDestroy(void *user); 9 static PetscErrorCode DMMoab_VecDuplicate(Vec x,Vec *y); 10 static PetscErrorCode DMMoab_VecCreateTagName_Private(moab::ParallelComm *pcomm,char** tag_name); 11 12 #undef __FUNCT__ 13 #define __FUNCT__ "DMMoab_CreateVector_Private" 14 PetscErrorCode DMMoab_CreateVector_Private(DM dm,moab::Tag tag,moab::Range* userrange,PetscBool is_global_vec,PetscBool destroy_tag,Vec *vec) 15 { 16 PetscErrorCode ierr; 17 moab::ErrorCode merr; 18 PetscBool is_newtag; 19 moab::Range *range; 20 PetscInt count,lnative_vec,gnative_vec; 21 std::string ttname; 22 PetscScalar *data_ptr; 23 ISLocalToGlobalMapping ltogb; 24 25 Vec_MOAB *vmoab; 26 DM_Moab *dmmoab = (DM_Moab*)dm->data; 27 moab::ParallelComm *pcomm = dmmoab->pcomm; 28 moab::Interface *mbiface = dmmoab->mbiface; 29 30 PetscFunctionBegin; 31 if(!userrange) range = dmmoab->vowned; 32 else range = userrange; 33 if(!range) SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONG, "Input range cannot be empty or call DMSetUp first."); 34 35 /* If the tag data is in a single sequence, use PETSc native vector since tag_iterate isn't useful anymore */ 36 lnative_vec=(range->psize()-1); 37 38 // lnative_vec=1; /* NOTE: Testing PETSc vector: will force to create native vector all the time */ 39 ierr = MPI_Allreduce(&lnative_vec, &gnative_vec, 1, MPI_INT, MPI_MAX, pcomm->comm());CHKERRQ(ierr); 40 41 /* Create the MOAB internal data object */ 42 ierr = PetscNew(Vec_MOAB,&vmoab);CHKERRQ(ierr); 43 vmoab->is_native_vec=(gnative_vec>0?PETSC_TRUE:PETSC_FALSE); 44 45 if (!vmoab->is_native_vec) { 46 merr = mbiface->tag_get_name(tag, ttname); 47 if (!ttname.length() && merr !=moab::MB_SUCCESS) { 48 /* get the new name for the anonymous MOABVec -> the tag_name will be destroyed along with Tag */ 49 char *tag_name = PETSC_NULL; 50 ierr = DMMoab_VecCreateTagName_Private(pcomm,&tag_name);CHKERRQ(ierr); 51 is_newtag = PETSC_TRUE; 52 53 /* Create the default value for the tag (all zeros) */ 54 std::vector<PetscScalar> default_value(dmmoab->nfields, 0.0); 55 56 /* Create the tag */ 57 merr = mbiface->tag_get_handle(tag_name,dmmoab->nfields,moab::MB_TYPE_DOUBLE,tag, 58 moab::MB_TAG_DENSE|moab::MB_TAG_CREAT,default_value.data());MBERRNM(merr); 59 ierr = PetscFree(tag_name);CHKERRQ(ierr); 60 } 61 else { 62 /* Make sure the tag data is of type "double" */ 63 moab::DataType tag_type; 64 merr = mbiface->tag_get_data_type(tag, tag_type);MBERRNM(merr); 65 if(tag_type != moab::MB_TYPE_DOUBLE) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Tag data type must be MB_TYPE_DOUBLE"); 66 is_newtag = destroy_tag; 67 } 68 69 vmoab->tag = tag; 70 vmoab->new_tag = is_newtag; 71 } 72 vmoab->mbiface = mbiface; 73 vmoab->pcomm = pcomm; 74 vmoab->is_global_vec = is_global_vec; 75 vmoab->tag_size=dmmoab->bs; 76 77 if (vmoab->is_native_vec) { 78 79 /* Create the PETSc Vector directly and attach our functions accordingly */ 80 if (!is_global_vec) { 81 /* This is an MPI Vector with ghosted padding */ 82 ierr = VecCreateGhostBlock(pcomm->comm(),dmmoab->bs,dmmoab->nfields*dmmoab->nloc, 83 dmmoab->nfields*dmmoab->n,dmmoab->nghost,&dmmoab->gsindices[dmmoab->nloc],vec);CHKERRQ(ierr); 84 } 85 else { 86 /* This is an MPI/SEQ Vector */ 87 ierr = VecCreate(pcomm->comm(),vec);CHKERRQ(ierr); 88 ierr = VecSetSizes(*vec,dmmoab->nfields*dmmoab->nloc,PETSC_DECIDE);CHKERRQ(ierr); 89 ierr = VecSetBlockSize(*vec,dmmoab->bs);CHKERRQ(ierr); 90 ierr = VecSetType(*vec, VECMPI);CHKERRQ(ierr); 91 } 92 } 93 else { 94 /* Call tag_iterate. This will cause MOAB to allocate memory for the 95 tag data if it hasn't already happened */ 96 merr = mbiface->tag_iterate(tag,range->begin(),range->end(),count,(void*&)data_ptr);MBERRNM(merr); 97 98 /* set the reference for vector range */ 99 vmoab->tag_range = new moab::Range(*range); 100 merr = mbiface->tag_get_length(tag,dmmoab->nfields);MBERRNM(merr); 101 102 /* Create the PETSc Vector 103 Query MOAB mesh to check if there are any ghosted entities 104 -> if we do, create a ghosted vector to map correctly to the same layout 105 -> else, create a non-ghosted parallel vector */ 106 if (!is_global_vec) { 107 /* This is an MPI Vector with ghosted padding */ 108 ierr = VecCreateGhostBlockWithArray(pcomm->comm(),dmmoab->bs,dmmoab->nfields*dmmoab->nloc, 109 dmmoab->nfields*dmmoab->n,dmmoab->nghost,&dmmoab->gsindices[dmmoab->nloc],data_ptr,vec);CHKERRQ(ierr); 110 } 111 else { 112 /* This is an MPI Vector without ghosted padding */ 113 ierr = VecCreateMPIWithArray(pcomm->comm(),dmmoab->bs,dmmoab->nfields*range->size(), 114 PETSC_DECIDE,data_ptr,vec);CHKERRQ(ierr); 115 } 116 } 117 ierr = VecSetFromOptions(*vec);CHKERRQ(ierr); 118 119 PetscContainer moabdata; 120 ierr = PetscContainerCreate(PETSC_COMM_WORLD,&moabdata);CHKERRQ(ierr); 121 ierr = PetscContainerSetPointer(moabdata,vmoab);CHKERRQ(ierr); 122 ierr = PetscContainerSetUserDestroy(moabdata,DMMoab_VecUserDestroy);CHKERRQ(ierr); 123 ierr = PetscObjectCompose((PetscObject)*vec,"MOABData",(PetscObject)moabdata);CHKERRQ(ierr); 124 (*vec)->ops->duplicate = DMMoab_VecDuplicate; 125 ierr = PetscContainerDestroy(&moabdata);CHKERRQ(ierr); 126 127 /* Vector created, manually set local to global mapping */ 128 ierr = VecSetLocalToGlobalMapping(*vec,dmmoab->ltog_map);CHKERRQ(ierr); 129 ierr = ISLocalToGlobalMappingBlock(dmmoab->ltog_map,dmmoab->bs,<ogb); 130 ierr = VecSetLocalToGlobalMappingBlock(*vec,ltogb);CHKERRQ(ierr); 131 ierr = ISLocalToGlobalMappingDestroy(<ogb);CHKERRQ(ierr); 132 133 /* set the DM reference to the vector */ 134 ierr = VecSetDM(*vec, dm);CHKERRQ(ierr); 135 PetscFunctionReturn(0); 136 } 137 138 139 #undef __FUNCT__ 140 #define __FUNCT__ "DMMoabCreateVector" 141 /*@ 142 DMMoabCreateVector - Create a Vec from either an existing tag, or a specified tag size, and a range of entities 143 144 Collective on MPI_Comm 145 146 Input Parameter: 147 . dm - The DMMoab object being set 148 . tag - If non-zero, block size will be taken from the tag size 149 . range - If non-empty, Vec corresponds to these entities, otherwise to the entities set on the DMMoab 150 . is_global_vec - If true, this is a local representation of the Vec (including ghosts in parallel), otherwise a truly parallel one 151 . destroy_tag - If true, MOAB tag is destroyed with Vec, otherwise it is left on MOAB 152 153 Output Parameter: 154 . vec - The created vector 155 156 Level: beginner 157 158 .keywords: DMMoab, create 159 @*/ 160 PetscErrorCode DMMoabCreateVector(DM dm,moab::Tag tag,moab::Range* range,PetscBool is_global_vec,PetscBool destroy_tag,Vec *vec) 161 { 162 PetscErrorCode ierr; 163 164 PetscFunctionBegin; 165 if(!tag && (!range || range->empty())) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Both tag and range cannot be null."); 166 167 ierr = DMMoab_CreateVector_Private(dm,tag,range,is_global_vec,destroy_tag,vec);CHKERRQ(ierr); 168 PetscFunctionReturn(0); 169 } 170 171 172 #undef __FUNCT__ 173 #define __FUNCT__ "DMCreateGlobalVector_Moab" 174 PetscErrorCode DMCreateGlobalVector_Moab(DM dm,Vec *gvec) 175 { 176 PetscErrorCode ierr; 177 DM_Moab *dmmoab = (DM_Moab*)dm->data; 178 179 PetscFunctionBegin; 180 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 181 PetscValidPointer(gvec,2); 182 ierr = DMMoab_CreateVector_Private(dm,PETSC_NULL,dmmoab->vowned,PETSC_TRUE,PETSC_TRUE,gvec);CHKERRQ(ierr); 183 PetscFunctionReturn(0); 184 } 185 186 187 #undef __FUNCT__ 188 #define __FUNCT__ "DMCreateLocalVector_Moab" 189 PetscErrorCode DMCreateLocalVector_Moab(DM dm,Vec *lvec) 190 { 191 PetscErrorCode ierr; 192 DM_Moab *dmmoab = (DM_Moab*)dm->data; 193 194 PetscFunctionBegin; 195 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 196 PetscValidPointer(lvec,2); 197 ierr = DMMoab_CreateVector_Private(dm,PETSC_NULL,dmmoab->vlocal,PETSC_FALSE,PETSC_TRUE,lvec);CHKERRQ(ierr); 198 PetscFunctionReturn(0); 199 } 200 201 202 #undef __FUNCT__ 203 #define __FUNCT__ "DMMoabGetVecTag" 204 /*@ 205 DMMoabGetVecTag - Get the MOAB tag associated with this Vec 206 207 Input Parameter: 208 . vec - Vec being queried 209 210 Output Parameter: 211 . tag - Tag associated with this Vec 212 213 Level: beginner 214 215 .keywords: DMMoab, create 216 @*/ 217 PetscErrorCode DMMoabGetVecTag(Vec vec,moab::Tag *tag) 218 { 219 PetscContainer moabdata; 220 Vec_MOAB *vmoab; 221 PetscErrorCode ierr; 222 223 PetscFunctionBegin; 224 PetscValidPointer(tag,2); 225 226 /* Get the MOAB private data */ 227 ierr = PetscObjectQuery((PetscObject)vec,"MOABData", (PetscObject*) &moabdata);CHKERRQ(ierr); 228 ierr = PetscContainerGetPointer(moabdata, (void**) &vmoab);CHKERRQ(ierr); 229 230 *tag = vmoab->tag; 231 PetscFunctionReturn(0); 232 } 233 234 235 #undef __FUNCT__ 236 #define __FUNCT__ "DMMoabGetVecRange" 237 /*@ 238 DMMoabGetVecRange - Get the MOAB entities associated with this Vec 239 240 Input Parameter: 241 . vec - Vec being queried 242 243 Output Parameter: 244 . range - Entities associated with this Vec 245 246 Level: beginner 247 248 .keywords: DMMoab, create 249 @*/ 250 PetscErrorCode DMMoabGetVecRange(Vec vec,moab::Range *range) 251 { 252 PetscContainer moabdata; 253 Vec_MOAB *vmoab; 254 PetscErrorCode ierr; 255 256 PetscFunctionBegin; 257 PetscValidPointer(range,2); 258 259 /* Get the MOAB private data handle */ 260 ierr = PetscObjectQuery((PetscObject)vec,"MOABData", (PetscObject*) &moabdata);CHKERRQ(ierr); 261 ierr = PetscContainerGetPointer(moabdata, (void**) &vmoab);CHKERRQ(ierr); 262 263 *range = *vmoab->tag_range; 264 PetscFunctionReturn(0); 265 } 266 267 268 #undef __FUNCT__ 269 #define __FUNCT__ "DMMoab_VecDuplicate" 270 PetscErrorCode DMMoab_VecDuplicate(Vec x,Vec *y) 271 { 272 PetscErrorCode ierr; 273 DM dm; 274 PetscContainer moabdata; 275 Vec_MOAB *vmoab; 276 277 PetscFunctionBegin; 278 PetscValidHeaderSpecific(x,VEC_CLASSID,1); 279 PetscValidPointer(y,2); 280 281 /* Get the Vec_MOAB struct for the original vector */ 282 ierr = PetscObjectQuery((PetscObject)x,"MOABData", (PetscObject*) &moabdata);CHKERRQ(ierr); 283 ierr = PetscContainerGetPointer(moabdata, (void**)&vmoab);CHKERRQ(ierr); 284 285 ierr = VecGetDM(x, &dm);CHKERRQ(ierr); 286 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 287 288 ierr = DMMoab_CreateVector_Private(dm,PETSC_NULL,vmoab->tag_range,vmoab->is_global_vec,PETSC_TRUE,y);CHKERRQ(ierr); 289 ierr = VecSetDM(*y, dm);CHKERRQ(ierr); 290 PetscFunctionReturn(0); 291 } 292 293 294 #undef __FUNCT__ 295 #define __FUNCT__ "DMMoab_VecCreateTagName_Private" 296 /* DMMoab_VecCreateTagName_Private 297 * 298 * Creates a unique tag name that will be shared across processes. If 299 * pcomm is NULL, then this is a serial vector. A unique tag name 300 * will be returned in tag_name in either case. 301 * 302 * The tag names have the format _PETSC_VEC_N where N is some integer. 303 * 304 * NOTE: The tag_name is allocated in this routine; The user needs to free 305 * the character array. 306 */ 307 PetscErrorCode DMMoab_VecCreateTagName_Private(moab::ParallelComm *pcomm,char** tag_name) 308 { 309 moab::ErrorCode mberr; 310 PetscErrorCode ierr; 311 PetscInt n,global_n; 312 moab::Tag indexTag; 313 314 PetscFunctionBegin; 315 const char* PVEC_PREFIX = "__PETSC_VEC_"; 316 ierr = PetscMalloc(PETSC_MAX_PATH_LEN, tag_name);CHKERRQ(ierr); 317 318 /* Check to see if there are any PETSc vectors defined */ 319 moab::Interface *mbiface = pcomm->get_moab(); 320 moab::EntityHandle rootset = mbiface->get_root_set(); 321 322 /* Create a tag in MOAB mesh to index and keep track of number of Petsc vec tags */ 323 mberr = mbiface->tag_get_handle("__PETSC_VECS__",1,moab::MB_TYPE_INTEGER,indexTag, 324 moab::MB_TAG_SPARSE | moab::MB_TAG_CREAT,0);MBERRNM(mberr); 325 mberr = mbiface->tag_get_data(indexTag, &rootset, 1, &n); 326 if (mberr == moab::MB_TAG_NOT_FOUND) n=0; /* this is the first temporary vector */ 327 else MBERRNM(mberr); 328 329 /* increment the new value of n */ 330 ++n; 331 332 /* Make sure that n is consistent across all processes */ 333 ierr = MPI_Allreduce(&n,&global_n,1,MPI_INT,MPI_MAX,pcomm->comm());CHKERRQ(ierr); 334 335 /* Set the new name accordingly and return */ 336 ierr = PetscSNPrintf(*tag_name, PETSC_MAX_PATH_LEN-1, "%s_%D", PVEC_PREFIX, global_n);CHKERRQ(ierr); 337 mberr = mbiface->tag_set_data(indexTag, &rootset, 1, (const void*)&global_n);MBERRNM(mberr); 338 PetscFunctionReturn(0); 339 } 340 341 342 #undef __FUNCT__ 343 #define __FUNCT__ "DMMoab_VecUserDestroy" 344 PetscErrorCode DMMoab_VecUserDestroy(void *user) 345 { 346 Vec_MOAB *vmoab=(Vec_MOAB*)user; 347 PetscErrorCode ierr; 348 moab::ErrorCode merr; 349 350 PetscFunctionBegin; 351 if(vmoab->new_tag && vmoab->tag) { 352 /* Tag was created via a call to VecDuplicate, delete the underlying tag in MOAB */ 353 merr = vmoab->mbiface->tag_delete(vmoab->tag);MBERRNM(merr); 354 } 355 delete vmoab->tag_range; 356 vmoab->tag = PETSC_NULL; 357 vmoab->mbiface = PETSC_NULL; 358 vmoab->pcomm = PETSC_NULL; 359 ierr = PetscFree(vmoab);CHKERRQ(ierr); 360 PetscFunctionReturn(0); 361 } 362 363 364 #undef __FUNCT__ 365 #define __FUNCT__ "DMMoabVecGetArray" 366 /*@ 367 DMMoabVecGetArray - Returns the writable direct access array to the local representation of MOAB tag data for the underlying vector using locally owned+ghosted range of entities 368 369 Collective on MPI_Comm 370 371 Input Parameter: 372 . dm - The DMMoab object being set 373 . vec - The Vector whose underlying data is requested 374 375 Output Parameter: 376 . array - The local data array 377 378 Level: intermediate 379 380 .keywords: MOAB, distributed array 381 382 .seealso: DMMoabVecRestoreArray(), DMMoabVecGetArrayRead(), DMMoabVecRestoreArrayRead() 383 @*/ 384 PetscErrorCode DMMoabVecGetArray(DM dm,Vec vec,void* array) 385 { 386 DM_Moab *dmmoab; 387 moab::ErrorCode merr; 388 PetscErrorCode ierr; 389 PetscInt count; 390 moab::Tag vtag; 391 PetscScalar **varray; 392 393 PetscFunctionBegin; 394 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 395 PetscValidHeaderSpecific(vec,VEC_CLASSID,2); 396 PetscValidPointer(array,3); 397 dmmoab=(DM_Moab*)dm->data; 398 399 /* Get the MOAB private data */ 400 ierr = DMMoabGetVecTag(vec,&vtag);CHKERRQ(ierr); 401 402 /* Get the real scalar array handle */ 403 varray = reinterpret_cast<PetscScalar**>(array); 404 405 /* exchange the data into ghost cells first */ 406 merr = dmmoab->pcomm->exchange_tags(vtag,*dmmoab->vlocal);MBERRNM(merr); 407 408 /* Get the array data for local entities */ 409 merr = dmmoab->mbiface->tag_iterate(vtag,dmmoab->vlocal->begin(),dmmoab->vlocal->end(),count,reinterpret_cast<void*&>(*varray),true);MBERRNM(merr); 410 if (count!=(PetscInt)dmmoab->vlocal->size()) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Mismatch between local vertices and tag partition for Vec. %D != %D.",count,dmmoab->vlocal->size()); 411 412 PetscFunctionReturn(0); 413 } 414 415 416 #undef __FUNCT__ 417 #define __FUNCT__ "DMMoabVecRestoreArray" 418 /*@ 419 DMMoabVecRestoreArray - Restores the writable direct access array obtained via DMMoabVecGetArray 420 421 Collective on MPI_Comm 422 423 Input Parameter: 424 + dm - The DMMoab object being set 425 . vec - The Vector whose underlying data is requested 426 - array - The local data array 427 428 Level: intermediate 429 430 .keywords: MOAB, distributed array 431 432 .seealso: DMMoabVecGetArray(), DMMoabVecGetArrayRead(), DMMoabVecRestoreArrayRead() 433 @*/ 434 PetscErrorCode DMMoabVecRestoreArray(DM dm,Vec v,void* array) 435 { 436 DM_Moab *moab; 437 moab::ErrorCode merr; 438 PetscErrorCode ierr; 439 moab::Tag vtag; 440 PetscScalar **varray; 441 442 PetscFunctionBegin; 443 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 444 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 445 PetscValidPointer(array,3); 446 moab=(DM_Moab*)dm->data; 447 448 /* Get the MOAB private data */ 449 ierr = DMMoabGetVecTag(v,&vtag);CHKERRQ(ierr); 450 451 /* Get the real scalar array handle */ 452 varray = reinterpret_cast<PetscScalar**>(array); 453 merr = moab->mbiface->tag_set_data(vtag,*moab->vlocal,reinterpret_cast<void*&>(*varray));MBERRNM(merr); 454 455 /* reduce the tags correctly -> should probably let the user choose how to reduce in the future 456 For all FEM residual based assembly calculations, MPI_SUM should serve well */ 457 merr = moab->pcomm->reduce_tags(vtag,MPI_SUM,*moab->vlocal);MBERRNM(merr); 458 PetscFunctionReturn(0); 459 } 460 461 #undef __FUNCT__ 462 #define __FUNCT__ "DMMoabVecGetArrayRead" 463 /*@ 464 DMMoabVecGetArrayRead - Returns the read-only direct access array to the local representation of MOAB tag data for the underlying vector using locally owned+ghosted range of entities 465 466 Collective on MPI_Comm 467 468 Input Parameter: 469 + dm - The DMMoab object being set 470 . vec - The Vector whose underlying data is requested 471 472 Output Parameter: 473 . array - The local data array 474 475 Level: intermediate 476 477 .keywords: MOAB, distributed array 478 479 .seealso: DMMoabVecRestoreArrayRead(), DMMoabVecGetArray(), DMMoabVecRestoreArray() 480 @*/ 481 PetscErrorCode DMMoabVecGetArrayRead(DM dm,Vec vec,void* array) 482 { 483 DM_Moab *moab; 484 moab::ErrorCode merr; 485 PetscErrorCode ierr; 486 PetscInt count; 487 moab::Tag vtag; 488 PetscScalar **varray; 489 490 PetscFunctionBegin; 491 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 492 PetscValidHeaderSpecific(vec,VEC_CLASSID,2); 493 moab=(DM_Moab*)dm->data; 494 495 /* Get the MOAB private data */ 496 ierr = DMMoabGetVecTag(vec,&vtag);CHKERRQ(ierr); 497 498 /* Get the real scalar array handle */ 499 varray = reinterpret_cast<PetscScalar**>(array); 500 501 /* exchange the data into ghost cells first */ 502 merr = moab->pcomm->exchange_tags(vtag,*moab->vlocal);MBERRNM(merr); 503 504 /* Get the array data for local entities */ 505 merr = moab->mbiface->tag_iterate(vtag,moab->vlocal->begin(),moab->vlocal->end(),count,reinterpret_cast<void*&>(*varray),true);MBERRNM(merr); 506 if (count!=(PetscInt)moab->vlocal->size()) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Mismatch between local vertices and tag partition for Vec. %D != %D.",count,moab->vlocal->size()); 507 508 PetscFunctionReturn(0); 509 } 510 511 512 #undef __FUNCT__ 513 #define __FUNCT__ "DMMoabVecRestoreArrayRead" 514 /*@ 515 DMMoabVecRestoreArray - Restores the read-only direct access array obtained via DMMoabVecGetArray 516 517 Collective on MPI_Comm 518 519 Input Parameter: 520 + dm - The DMMoab object being set 521 . vec - The Vector whose underlying data is requested 522 - array - The local data array 523 524 Level: intermediate 525 526 .keywords: MOAB, distributed array 527 528 .seealso: DMMoabVecGetArrayRead(), DMMoabVecGetArray(), DMMoabVecRestoreArray() 529 @*/ 530 PetscErrorCode DMMoabVecRestoreArrayRead(DM dm,Vec v,void* array) 531 { 532 PetscFunctionBegin; 533 /* Nothing to do -> do not free the array memory obtained from tag_iterate */ 534 PetscFunctionReturn(0); 535 } 536 537 538 #undef __FUNCT__ 539 #define __FUNCT__ "DMGlobalToLocalBegin_Moab" 540 PetscErrorCode DMGlobalToLocalBegin_Moab(DM dm,Vec g,InsertMode mode,Vec l) 541 { 542 PetscErrorCode ierr; 543 DM_Moab *dmmoab = (DM_Moab*)dm->data; 544 545 PetscFunctionBegin; 546 ierr = VecScatterBegin(dmmoab->ltog_sendrecv,g,l,mode,SCATTER_FORWARD);CHKERRQ(ierr); 547 PetscFunctionReturn(0); 548 } 549 550 551 #undef __FUNCT__ 552 #define __FUNCT__ "DMGlobalToLocalEnd_Moab" 553 PetscErrorCode DMGlobalToLocalEnd_Moab(DM dm,Vec g,InsertMode mode,Vec l) 554 { 555 PetscErrorCode ierr; 556 DM_Moab *dmmoab = (DM_Moab*)dm->data; 557 558 PetscFunctionBegin; 559 ierr = VecScatterEnd(dmmoab->ltog_sendrecv,g,l,mode,SCATTER_FORWARD);CHKERRQ(ierr); 560 PetscFunctionReturn(0); 561 } 562 563 564 #undef __FUNCT__ 565 #define __FUNCT__ "DMLocalToGlobalBegin_Moab" 566 PetscErrorCode DMLocalToGlobalBegin_Moab(DM dm,Vec l,InsertMode mode,Vec g) 567 { 568 PetscErrorCode ierr; 569 DM_Moab *dmmoab = (DM_Moab*)dm->data; 570 571 PetscFunctionBegin; 572 ierr = VecScatterBegin(dmmoab->ltog_sendrecv,l,g,mode,SCATTER_REVERSE);CHKERRQ(ierr); 573 PetscFunctionReturn(0); 574 } 575 576 577 #undef __FUNCT__ 578 #define __FUNCT__ "DMLocalToGlobalEnd_Moab" 579 PetscErrorCode DMLocalToGlobalEnd_Moab(DM dm,Vec l,InsertMode mode,Vec g) 580 { 581 PetscErrorCode ierr; 582 DM_Moab *dmmoab = (DM_Moab*)dm->data; 583 584 PetscFunctionBegin; 585 ierr = VecScatterEnd(dmmoab->ltog_sendrecv,l,g,mode,SCATTER_REVERSE);CHKERRQ(ierr); 586 PetscFunctionReturn(0); 587 } 588 589 590