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,PetscInt tag_size,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 *gindices; 21 PetscInt i,count,dof; 22 PetscInt size,rank; 23 std::string ttname; 24 PetscScalar *data_ptr; 25 26 Vec_MOAB *vmoab; 27 DM_Moab *dmmoab = (DM_Moab*)dm->data; 28 moab::ParallelComm *pcomm = dmmoab->pcomm; 29 moab::Interface *mbiface = dmmoab->mbiface; 30 moab::Tag ltog_tag = dmmoab->ltog_tag; 31 32 PetscFunctionBegin; 33 if(!userrange) range = dmmoab->vowned; 34 else range = userrange; 35 if(!range) SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONG, "Input range cannot be empty or call DMSetUp first."); 36 37 merr = mbiface->tag_get_name(tag, ttname); 38 if (!ttname.length() && merr !=moab::MB_SUCCESS) { 39 /* get the new name for the anonymous MOABVec -> the tag_name will be destroyed along with Tag */ 40 char *tag_name = PETSC_NULL; 41 ierr = DMMoab_VecCreateTagName_Private(pcomm,&tag_name);CHKERRQ(ierr); 42 is_newtag = PETSC_TRUE; 43 44 /* Create the default value for the tag (all zeros) */ 45 std::vector<PetscScalar> default_value(tag_size, 0.0); 46 47 /* Create the tag */ 48 merr = mbiface->tag_get_handle(tag_name,tag_size,moab::MB_TYPE_DOUBLE,tag, 49 moab::MB_TAG_DENSE|moab::MB_TAG_CREAT,default_value.data());MBERRNM(merr); 50 ierr = PetscFree(tag_name);CHKERRQ(ierr); 51 } 52 else { 53 /* Make sure the tag data is of type "double" */ 54 moab::DataType tag_type; 55 merr = mbiface->tag_get_data_type(tag, tag_type);MBERRNM(merr); 56 if(tag_type != moab::MB_TYPE_DOUBLE) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Tag data type must be MB_TYPE_DOUBLE"); 57 is_newtag = destroy_tag; 58 } 59 60 /* Create the MOAB internal data object */ 61 ierr = PetscNew(Vec_MOAB,&vmoab);CHKERRQ(ierr); 62 vmoab->tag = tag; 63 vmoab->mbiface = mbiface; 64 vmoab->pcomm = pcomm; 65 vmoab->new_tag = is_newtag; 66 vmoab->is_global_vec = is_global_vec; 67 merr = mbiface->tag_get_length(tag,vmoab->tag_size);MBERR("tag_get_size", merr); 68 69 size = pcomm->size(); 70 rank = pcomm->rank(); 71 72 /* set the reference for vector range */ 73 vmoab->tag_range = new moab::Range(*range); 74 75 /* Call tag_iterate. This will cause MOAB to allocate memory for the 76 tag data if it hasn't already happened */ 77 merr = mbiface->tag_iterate(tag,range->begin(),range->end(),count,(void*&)data_ptr);MBERRNM(merr); 78 79 /* Check to make sure the tag data is in a single sequence */ 80 if ((unsigned)count != range->size()) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Can only create MOAB Vector for single sequence: %D != %D",count,range->size()); 81 82 /* Create the PETSc Vector 83 Query MOAB mesh to check if there are any ghosted entities 84 -> if we do, create a ghosted vector to map correctly to the same layout 85 -> else, create a non-ghosted parallel vector */ 86 if (!is_global_vec && (size>1)) { 87 /* This is an MPI Vector with ghosted padding */ 88 ierr = VecCreateGhostBlockWithArray(vmoab->pcomm->comm(),vmoab->tag_size,vmoab->tag_size*dmmoab->nloc, 89 vmoab->tag_size*dmmoab->n,dmmoab->nghost,&dmmoab->gsindices[dmmoab->nloc],data_ptr,vec);CHKERRQ(ierr); 90 } 91 else if (size>1) { 92 /* This is an MPI Vector without ghosted padding */ 93 ierr = VecCreateMPIWithArray(vmoab->pcomm->comm(),vmoab->tag_size,vmoab->tag_size*range->size(), 94 PETSC_DECIDE,data_ptr,vec);CHKERRQ(ierr); 95 } 96 else { 97 /* This is a sequential vector - valid only for the single processor case since MOAB tags are always partitioned 98 and we cannot define a Vec using the Tag array with size>1 will be of full length */ 99 ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,vmoab->tag_size,vmoab->tag_size*dmmoab->n,data_ptr,vec);CHKERRQ(ierr); 100 } 101 102 PetscContainer moabdata; 103 ierr = PetscContainerCreate(PETSC_COMM_SELF,&moabdata);CHKERRQ(ierr); 104 ierr = PetscContainerSetPointer(moabdata,vmoab);CHKERRQ(ierr); 105 ierr = PetscContainerSetUserDestroy(moabdata,DMMoab_VecUserDestroy);CHKERRQ(ierr); 106 ierr = PetscObjectCompose((PetscObject)*vec,"MOABData",(PetscObject)moabdata);CHKERRQ(ierr); 107 (*vec)->ops->duplicate = DMMoab_VecDuplicate; 108 ierr = PetscContainerDestroy(&moabdata);CHKERRQ(ierr); 109 110 if (!dmmoab->ltog_map) { 111 /* Vector created, manually set local to global mapping */ 112 ierr = PetscMalloc(range->size()*sizeof(PetscInt)*vmoab->tag_size, &gindices);CHKERRQ(ierr); 113 moab::Range::iterator iter; 114 for(iter = range->begin(),count=0; iter != range->end(); iter++,count+=vmoab->tag_size) { 115 merr = mbiface->tag_get_data(ltog_tag,&(*iter),1,&dof);MBERRNM(merr); 116 for(i=0; i<vmoab->tag_size; ++i) 117 gindices[count+i] = (dof)*vmoab->tag_size+i; 118 } 119 120 ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF,range->size(),gindices, 121 PETSC_COPY_VALUES,&dmmoab->ltog_map);CHKERRQ(ierr); 122 123 ierr = VecSetLocalToGlobalMappingBlock(*vec,dmmoab->ltog_map);CHKERRQ(ierr); 124 125 /* Clean up */ 126 ierr = PetscFree(gindices);CHKERRQ(ierr); 127 } 128 else { 129 ierr = VecSetLocalToGlobalMappingBlock(*vec,dmmoab->ltog_map);CHKERRQ(ierr); 130 } 131 132 /* set the DM reference to the vector */ 133 ierr = VecSetDM(*vec, dm);CHKERRQ(ierr); 134 PetscFunctionReturn(0); 135 } 136 137 138 #undef __FUNCT__ 139 #define __FUNCT__ "DMMoabCreateVector" 140 /*@ 141 DMMoabCreateVector - Create a Vec from either an existing tag, or a specified tag size, and a range of entities 142 143 Collective on MPI_Comm 144 145 Input Parameter: 146 . dm - The DMMoab object being set 147 . tag - If non-zero, block size will be taken from the tag size 148 . tag_size - If tag was zero, this parameter specifies the block size; unique tag name will be generated automatically 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,PetscInt tag_size,moab::Range* range,PetscBool is_global_vec,PetscBool destroy_tag,Vec *vec) 161 { 162 PetscErrorCode ierr; 163 164 PetscFunctionBegin; 165 if(!tag && !tag_size) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Both tag_size and tag cannot be null."); 166 167 ierr = DMMoab_CreateVector_Private(dm,tag,tag_size,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->bs,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->bs,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_size,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 #undef __FUNCT__ 364 #define __FUNCT__ "DMMoabVecGetArray" 365 /*@ 366 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 367 368 Collective on MPI_Comm 369 370 Input Parameter: 371 . dm - The DMMoab object being set 372 . vec - The Vector whose underlying data is requested 373 374 Output Parameter: 375 . array - The local data array 376 377 Level: intermediate 378 379 .keywords: MOAB, distributed array 380 381 .seealso: DMMoabVecRestoreArray(), DMMoabVecGetArrayRead(), DMMoabVecRestoreArrayRead() 382 @*/ 383 PetscErrorCode DMMoabVecGetArray(DM dm,Vec vec,void* array) 384 { 385 DM_Moab *moab; 386 moab::ErrorCode merr; 387 PetscErrorCode ierr; 388 PetscInt count; 389 moab::Tag vtag; 390 PetscScalar **varray; 391 392 PetscFunctionBegin; 393 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 394 PetscValidHeaderSpecific(vec,VEC_CLASSID,2); 395 moab=(DM_Moab*)dm->data; 396 397 /* Get the MOAB private data */ 398 ierr = DMMoabGetVecTag(vec,&vtag);CHKERRQ(ierr); 399 400 /* Get the real scalar array handle */ 401 varray = reinterpret_cast<PetscScalar**>(array); 402 403 /* Get the array data for local entities */ 404 merr = moab->mbiface->tag_iterate(vtag,moab->vlocal->begin(),moab->vlocal->end(),count,reinterpret_cast<void*&>(*varray),true);MBERRNM(merr); 405 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()); 406 407 merr = moab->pcomm->exchange_tags(vtag,*moab->vlocal);MBERRNM(merr); 408 PetscFunctionReturn(0); 409 } 410 411 412 #undef __FUNCT__ 413 #define __FUNCT__ "DMMoabVecRestoreArray" 414 /*@ 415 DMMoabVecRestoreArray - Restores the writable direct access array obtained via DMMoabVecGetArray 416 417 Collective on MPI_Comm 418 419 Input Parameter: 420 + dm - The DMMoab object being set 421 . vec - The Vector whose underlying data is requested 422 - array - The local data array 423 424 Level: intermediate 425 426 .keywords: MOAB, distributed array 427 428 .seealso: DMMoabVecGetArray(), DMMoabVecGetArrayRead(), DMMoabVecRestoreArrayRead() 429 @*/ 430 PetscErrorCode DMMoabVecRestoreArray(DM dm,Vec v,void* array) 431 { 432 DM_Moab *moab; 433 moab::ErrorCode merr; 434 PetscErrorCode ierr; 435 moab::Tag vtag; 436 437 PetscFunctionBegin; 438 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 439 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 440 moab=(DM_Moab*)dm->data; 441 442 /* Get the MOAB private data */ 443 ierr = DMMoabGetVecTag(v,&vtag);CHKERRQ(ierr); 444 445 /* reduce the tags correctly -> should probably let the user choose how to reduce in the future 446 For all FEM residual based assembly calculations, MPI_SUM should serve well 447 */ 448 merr = moab->pcomm->reduce_tags(vtag,MPI_SUM,*moab->vlocal);MBERRNM(merr); 449 PetscFunctionReturn(0); 450 } 451 452 #undef __FUNCT__ 453 #define __FUNCT__ "DMMoabVecGetArrayRead" 454 /*@ 455 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 456 457 Collective on MPI_Comm 458 459 Input Parameter: 460 + dm - The DMMoab object being set 461 . vec - The Vector whose underlying data is requested 462 463 Output Parameter: 464 . array - The local data array 465 466 Level: intermediate 467 468 .keywords: MOAB, distributed array 469 470 .seealso: DMMoabVecRestoreArrayRead(), DMMoabVecGetArray(), DMMoabVecRestoreArray() 471 @*/ 472 PetscErrorCode DMMoabVecGetArrayRead(DM dm,Vec vec,void* array) 473 { 474 DM_Moab *moab; 475 moab::ErrorCode merr; 476 PetscErrorCode ierr; 477 PetscInt count; 478 moab::Tag vtag; 479 PetscScalar **varray; 480 481 PetscFunctionBegin; 482 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 483 PetscValidHeaderSpecific(vec,VEC_CLASSID,2); 484 moab=(DM_Moab*)dm->data; 485 486 /* Get the MOAB private data */ 487 ierr = DMMoabGetVecTag(vec,&vtag);CHKERRQ(ierr); 488 489 /* Get the real scalar array handle */ 490 varray = reinterpret_cast<PetscScalar**>(array); 491 492 /* Get the array data for local entities */ 493 merr = moab->mbiface->tag_iterate(vtag,moab->vlocal->begin(),moab->vlocal->end(),count,reinterpret_cast<void*&>(*varray),true);MBERRNM(merr); 494 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()); 495 496 merr = moab->pcomm->exchange_tags(vtag,*moab->vlocal);MBERRNM(merr); 497 PetscFunctionReturn(0); 498 } 499 500 501 #undef __FUNCT__ 502 #define __FUNCT__ "DMMoabVecRestoreArrayRead" 503 /*@ 504 DMMoabVecRestoreArray - Restores the read-only direct access array obtained via DMMoabVecGetArray 505 506 Collective on MPI_Comm 507 508 Input Parameter: 509 + dm - The DMMoab object being set 510 . vec - The Vector whose underlying data is requested 511 - array - The local data array 512 513 Level: intermediate 514 515 .keywords: MOAB, distributed array 516 517 .seealso: DMMoabVecGetArrayRead(), DMMoabVecGetArray(), DMMoabVecRestoreArray() 518 @*/ 519 PetscErrorCode DMMoabVecRestoreArrayRead(DM dm,Vec v,void* array) 520 { 521 PetscFunctionBegin; 522 /* Nothing to do -> do not free the array memory obtained from tag_iterate */ 523 PetscFunctionReturn(0); 524 } 525 526 527 #undef __FUNCT__ 528 #define __FUNCT__ "DMGlobalToLocalBegin_Moab" 529 PetscErrorCode DMGlobalToLocalBegin_Moab(DM dm,Vec g,InsertMode mode,Vec l) 530 { 531 PetscErrorCode ierr; 532 DM_Moab *dmmoab = (DM_Moab*)dm->data; 533 534 PetscFunctionBegin; 535 ierr = VecScatterBegin(dmmoab->ltog_sendrecv,g,l,mode,SCATTER_FORWARD);CHKERRQ(ierr); 536 PetscFunctionReturn(0); 537 } 538 539 540 #undef __FUNCT__ 541 #define __FUNCT__ "DMGlobalToLocalEnd_Moab" 542 PetscErrorCode DMGlobalToLocalEnd_Moab(DM dm,Vec g,InsertMode mode,Vec l) 543 { 544 PetscErrorCode ierr; 545 DM_Moab *dmmoab = (DM_Moab*)dm->data; 546 547 PetscFunctionBegin; 548 ierr = VecScatterEnd(dmmoab->ltog_sendrecv,g,l,mode,SCATTER_FORWARD);CHKERRQ(ierr); 549 PetscFunctionReturn(0); 550 } 551 552 553 #undef __FUNCT__ 554 #define __FUNCT__ "DMLocalToGlobalBegin_Moab" 555 PetscErrorCode DMLocalToGlobalBegin_Moab(DM dm,Vec l,InsertMode mode,Vec g) 556 { 557 PetscErrorCode ierr; 558 DM_Moab *dmmoab = (DM_Moab*)dm->data; 559 560 PetscFunctionBegin; 561 ierr = VecScatterBegin(dmmoab->ltog_sendrecv,l,g,mode,SCATTER_REVERSE);CHKERRQ(ierr); 562 PetscFunctionReturn(0); 563 } 564 565 566 #undef __FUNCT__ 567 #define __FUNCT__ "DMLocalToGlobalEnd_Moab" 568 PetscErrorCode DMLocalToGlobalEnd_Moab(DM dm,Vec l,InsertMode mode,Vec g) 569 { 570 PetscErrorCode ierr; 571 DM_Moab *dmmoab = (DM_Moab*)dm->data; 572 573 PetscFunctionBegin; 574 ierr = VecScatterEnd(dmmoab->ltog_sendrecv,l,g,mode,SCATTER_REVERSE);CHKERRQ(ierr); 575 PetscFunctionReturn(0); 576 } 577 578 579