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,icount,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 if (rank) range->print(); 80 /* Check to make sure the tag data is in a single sequence */ 81 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()); 82 83 /* Create the PETSc Vector 84 Query MOAB mesh to check if there are any ghosted entities 85 -> if we do, create a ghosted vector to map correctly to the same layout 86 -> else, create a non-ghosted parallel vector */ 87 if (!is_global_vec && (size>1)) { 88 /* This is an MPI Vector with ghosted padding */ 89 ierr = VecCreateGhostBlockWithArray(vmoab->pcomm->comm(),vmoab->tag_size,vmoab->tag_size*dmmoab->nloc, 90 vmoab->tag_size*dmmoab->n,dmmoab->nghost,&dmmoab->gsindices[dmmoab->nloc],data_ptr,vec);CHKERRQ(ierr); 91 } 92 else if (size>1) { 93 /* This is an MPI Vector without ghosted padding */ 94 ierr = VecCreateMPIWithArray(vmoab->pcomm->comm(),vmoab->tag_size,vmoab->tag_size*range->size(), 95 PETSC_DECIDE,data_ptr,vec);CHKERRQ(ierr); 96 } 97 else { 98 /* This is a sequential vector - valid only for the single processor case since MOAB tags are always partitioned 99 and we cannot define a Vec using the Tag array with size>1 will be of full length */ 100 ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,vmoab->tag_size,vmoab->tag_size*dmmoab->n,data_ptr,vec);CHKERRQ(ierr); 101 } 102 103 PetscContainer moabdata; 104 ierr = PetscContainerCreate(PETSC_COMM_SELF,&moabdata);CHKERRQ(ierr); 105 ierr = PetscContainerSetPointer(moabdata,vmoab);CHKERRQ(ierr); 106 ierr = PetscContainerSetUserDestroy(moabdata,DMMoab_VecUserDestroy);CHKERRQ(ierr); 107 ierr = PetscObjectCompose((PetscObject)*vec,"MOABData",(PetscObject)moabdata);CHKERRQ(ierr); 108 (*vec)->ops->duplicate = DMMoab_VecDuplicate; 109 ierr = PetscContainerDestroy(&moabdata);CHKERRQ(ierr); 110 111 if (!dmmoab->ltog_map) { 112 /* Vector created, manually set local to global mapping */ 113 ierr = PetscMalloc(range->size()*sizeof(PetscInt)*vmoab->tag_size, &gindices);CHKERRQ(ierr); 114 moab::Range::iterator iter; 115 for(iter = range->begin(),count=0; iter != range->end(); iter++,count+=vmoab->tag_size) { 116 merr = mbiface->tag_get_data(ltog_tag,&(*iter),1,&dof);MBERRNM(merr); 117 for(i=0; i<vmoab->tag_size; ++i) 118 gindices[count+i] = (dof)*vmoab->tag_size+i; 119 } 120 121 ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF,range->size(),gindices, 122 PETSC_COPY_VALUES,&dmmoab->ltog_map);CHKERRQ(ierr); 123 124 ierr = VecSetLocalToGlobalMappingBlock(*vec,dmmoab->ltog_map);CHKERRQ(ierr); 125 126 /* Clean up */ 127 ierr = PetscFree(gindices);CHKERRQ(ierr); 128 } 129 else { 130 ierr = VecSetLocalToGlobalMappingBlock(*vec,dmmoab->ltog_map);CHKERRQ(ierr); 131 } 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 . tag_size - If tag was zero, this parameter specifies the block size; unique tag name will be generated automatically 150 . range - If non-empty, Vec corresponds to these entities, otherwise to the entities set on the DMMoab 151 . is_global_vec - If true, this is a local representation of the Vec (including ghosts in parallel), otherwise a truly parallel one 152 . destroy_tag - If true, MOAB tag is destroyed with Vec, otherwise it is left on MOAB 153 154 Output Parameter: 155 . vec - The created vector 156 157 Level: beginner 158 159 .keywords: DMMoab, create 160 @*/ 161 PetscErrorCode DMMoabCreateVector(DM dm,moab::Tag tag,PetscInt tag_size,moab::Range* range,PetscBool is_global_vec,PetscBool destroy_tag,Vec *vec) 162 { 163 PetscErrorCode ierr; 164 165 PetscFunctionBegin; 166 if(!tag && !tag_size) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Both tag_size and tag cannot be null."); 167 168 ierr = DMMoab_CreateVector_Private(dm,tag,tag_size,range,is_global_vec,destroy_tag,vec);CHKERRQ(ierr); 169 PetscFunctionReturn(0); 170 } 171 172 173 #undef __FUNCT__ 174 #define __FUNCT__ "DMCreateGlobalVector_Moab" 175 PetscErrorCode DMCreateGlobalVector_Moab(DM dm,Vec *gvec) 176 { 177 PetscErrorCode ierr; 178 DM_Moab *dmmoab = (DM_Moab*)dm->data; 179 180 PetscFunctionBegin; 181 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 182 PetscValidPointer(gvec,2); 183 ierr = DMMoab_CreateVector_Private(dm,PETSC_NULL,dmmoab->bs,dmmoab->vowned,PETSC_TRUE,PETSC_TRUE,gvec);CHKERRQ(ierr); 184 PetscFunctionReturn(0); 185 } 186 187 188 #undef __FUNCT__ 189 #define __FUNCT__ "DMCreateLocalVector_Moab" 190 PetscErrorCode DMCreateLocalVector_Moab(DM dm,Vec *lvec) 191 { 192 PetscErrorCode ierr; 193 DM_Moab *dmmoab = (DM_Moab*)dm->data; 194 195 PetscFunctionBegin; 196 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 197 PetscValidPointer(lvec,2); 198 ierr = DMMoab_CreateVector_Private(dm,PETSC_NULL,dmmoab->bs,dmmoab->vlocal,PETSC_FALSE,PETSC_TRUE,lvec);CHKERRQ(ierr); 199 PetscFunctionReturn(0); 200 } 201 202 203 #undef __FUNCT__ 204 #define __FUNCT__ "DMMoabGetVecTag" 205 /*@ 206 DMMoabGetVecTag - Get the MOAB tag associated with this Vec 207 208 Input Parameter: 209 . vec - Vec being queried 210 211 Output Parameter: 212 . tag - Tag associated with this Vec 213 214 Level: beginner 215 216 .keywords: DMMoab, create 217 @*/ 218 PetscErrorCode DMMoabGetVecTag(Vec vec,moab::Tag *tag) 219 { 220 PetscContainer moabdata; 221 Vec_MOAB *vmoab; 222 PetscErrorCode ierr; 223 224 PetscFunctionBegin; 225 PetscValidPointer(tag,2); 226 227 /* Get the MOAB private data */ 228 ierr = PetscObjectQuery((PetscObject)vec,"MOABData", (PetscObject*) &moabdata);CHKERRQ(ierr); 229 ierr = PetscContainerGetPointer(moabdata, (void**) &vmoab);CHKERRQ(ierr); 230 231 *tag = vmoab->tag; 232 PetscFunctionReturn(0); 233 } 234 235 236 #undef __FUNCT__ 237 #define __FUNCT__ "DMMoabGetVecRange" 238 /*@ 239 DMMoabGetVecRange - Get the MOAB entities associated with this Vec 240 241 Input Parameter: 242 . vec - Vec being queried 243 244 Output Parameter: 245 . range - Entities associated with this Vec 246 247 Level: beginner 248 249 .keywords: DMMoab, create 250 @*/ 251 PetscErrorCode DMMoabGetVecRange(Vec vec,moab::Range *range) 252 { 253 PetscContainer moabdata; 254 Vec_MOAB *vmoab; 255 PetscErrorCode ierr; 256 257 PetscFunctionBegin; 258 PetscValidPointer(range,2); 259 260 /* Get the MOAB private data handle */ 261 ierr = PetscObjectQuery((PetscObject)vec,"MOABData", (PetscObject*) &moabdata);CHKERRQ(ierr); 262 ierr = PetscContainerGetPointer(moabdata, (void**) &vmoab);CHKERRQ(ierr); 263 264 *range = *vmoab->tag_range; 265 PetscFunctionReturn(0); 266 } 267 268 269 #undef __FUNCT__ 270 #define __FUNCT__ "DMMoab_VecDuplicate" 271 PetscErrorCode DMMoab_VecDuplicate(Vec x,Vec *y) 272 { 273 PetscErrorCode ierr; 274 DM dm; 275 PetscContainer moabdata; 276 Vec_MOAB *vmoab; 277 278 PetscFunctionBegin; 279 PetscValidHeaderSpecific(x,VEC_CLASSID,1); 280 PetscValidPointer(y,2); 281 282 /* Get the Vec_MOAB struct for the original vector */ 283 ierr = PetscObjectQuery((PetscObject)x,"MOABData", (PetscObject*) &moabdata);CHKERRQ(ierr); 284 ierr = PetscContainerGetPointer(moabdata, (void**)&vmoab);CHKERRQ(ierr); 285 286 ierr = VecGetDM(x, &dm);CHKERRQ(ierr); 287 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 288 289 ierr = DMMoab_CreateVector_Private(dm,PETSC_NULL,vmoab->tag_size,vmoab->tag_range,vmoab->is_global_vec,PETSC_TRUE,y);CHKERRQ(ierr); 290 ierr = VecSetDM(*y, dm);CHKERRQ(ierr); 291 PetscFunctionReturn(0); 292 } 293 294 295 #undef __FUNCT__ 296 #define __FUNCT__ "DMMoab_VecCreateTagName_Private" 297 /* DMMoab_VecCreateTagName_Private 298 * 299 * Creates a unique tag name that will be shared across processes. If 300 * pcomm is NULL, then this is a serial vector. A unique tag name 301 * will be returned in tag_name in either case. 302 * 303 * The tag names have the format _PETSC_VEC_N where N is some integer. 304 * 305 * NOTE: The tag_name is allocated in this routine; The user needs to free 306 * the character array. 307 */ 308 PetscErrorCode DMMoab_VecCreateTagName_Private(moab::ParallelComm *pcomm,char** tag_name) 309 { 310 moab::ErrorCode mberr; 311 PetscErrorCode ierr; 312 PetscInt n,global_n; 313 moab::Tag indexTag; 314 315 PetscFunctionBegin; 316 const char* PVEC_PREFIX = "__PETSC_VEC_"; 317 ierr = PetscMalloc(PETSC_MAX_PATH_LEN, tag_name);CHKERRQ(ierr); 318 319 /* Check to see if there are any PETSc vectors defined */ 320 moab::Interface *mbiface = pcomm->get_moab(); 321 moab::EntityHandle rootset = mbiface->get_root_set(); 322 323 /* Create a tag in MOAB mesh to index and keep track of number of Petsc vec tags */ 324 mberr = mbiface->tag_get_handle("__PETSC_VECS__",1,moab::MB_TYPE_INTEGER,indexTag, 325 moab::MB_TAG_SPARSE | moab::MB_TAG_CREAT,0);MBERRNM(mberr); 326 mberr = mbiface->tag_get_data(indexTag, &rootset, 1, &n); 327 if (mberr == moab::MB_TAG_NOT_FOUND) n=0; /* this is the first temporary vector */ 328 else MBERRNM(mberr); 329 330 /* increment the new value of n */ 331 ++n; 332 333 /* Make sure that n is consistent across all processes */ 334 ierr = MPI_Allreduce(&n,&global_n,1,MPI_INT,MPI_MAX,pcomm->comm());CHKERRQ(ierr); 335 336 /* Set the new name accordingly and return */ 337 ierr = PetscSNPrintf(*tag_name, PETSC_MAX_PATH_LEN-1, "%s_%D", PVEC_PREFIX, global_n);CHKERRQ(ierr); 338 mberr = mbiface->tag_set_data(indexTag, &rootset, 1, (const void*)&global_n);MBERRNM(mberr); 339 PetscFunctionReturn(0); 340 } 341 342 343 #undef __FUNCT__ 344 #define __FUNCT__ "DMMoab_VecUserDestroy" 345 PetscErrorCode DMMoab_VecUserDestroy(void *user) 346 { 347 Vec_MOAB *vmoab=(Vec_MOAB*)user; 348 PetscErrorCode ierr; 349 moab::ErrorCode merr; 350 351 PetscFunctionBegin; 352 if(vmoab->new_tag && vmoab->tag) { 353 /* Tag was created via a call to VecDuplicate, delete the underlying tag in MOAB */ 354 merr = vmoab->mbiface->tag_delete(vmoab->tag);MBERRNM(merr); 355 } 356 delete vmoab->tag_range; 357 vmoab->tag = PETSC_NULL; 358 vmoab->mbiface = PETSC_NULL; 359 vmoab->pcomm = PETSC_NULL; 360 ierr = PetscFree(vmoab);CHKERRQ(ierr); 361 PetscFunctionReturn(0); 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 *moab; 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 moab=(DM_Moab*)dm->data; 397 398 /* Get the MOAB private data */ 399 ierr = DMMoabGetVecTag(vec,&vtag);CHKERRQ(ierr); 400 401 /* Get the real scalar array handle */ 402 varray = reinterpret_cast<PetscScalar**>(array); 403 404 /* Get the array data for local entities */ 405 merr = moab->mbiface->tag_iterate(vtag,moab->vlocal->begin(),moab->vlocal->end(),count,reinterpret_cast<void*&>(*varray),true);MBERRNM(merr); 406 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()); 407 408 merr = moab->pcomm->exchange_tags(vtag,*moab->vlocal);MBERRNM(merr); 409 PetscFunctionReturn(0); 410 } 411 412 413 #undef __FUNCT__ 414 #define __FUNCT__ "DMMoabVecRestoreArray" 415 /*@ 416 DMMoabVecRestoreArray - Restores the writable direct access array obtained via DMMoabVecGetArray 417 418 Collective on MPI_Comm 419 420 Input Parameter: 421 + dm - The DMMoab object being set 422 . vec - The Vector whose underlying data is requested 423 - array - The local data array 424 425 Level: intermediate 426 427 .keywords: MOAB, distributed array 428 429 .seealso: DMMoabVecGetArray(), DMMoabVecGetArrayRead(), DMMoabVecRestoreArrayRead() 430 @*/ 431 PetscErrorCode DMMoabVecRestoreArray(DM dm,Vec v,void* array) 432 { 433 DM_Moab *moab; 434 moab::ErrorCode merr; 435 PetscErrorCode ierr; 436 moab::Tag vtag; 437 438 PetscFunctionBegin; 439 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 440 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 441 moab=(DM_Moab*)dm->data; 442 443 /* Get the MOAB private data */ 444 ierr = DMMoabGetVecTag(v,&vtag);CHKERRQ(ierr); 445 446 /* reduce the tags correctly -> should probably let the user choose how to reduce in the future 447 For all FEM residual based assembly calculations, MPI_SUM should serve well 448 */ 449 merr = moab->pcomm->reduce_tags(vtag,MPI_SUM,*moab->vghost);MBERRNM(merr); 450 PetscFunctionReturn(0); 451 } 452 453 #undef __FUNCT__ 454 #define __FUNCT__ "DMMoabVecGetArrayRead" 455 /*@ 456 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 457 458 Collective on MPI_Comm 459 460 Input Parameter: 461 + dm - The DMMoab object being set 462 . vec - The Vector whose underlying data is requested 463 464 Output Parameter: 465 . array - The local data array 466 467 Level: intermediate 468 469 .keywords: MOAB, distributed array 470 471 .seealso: DMMoabVecRestoreArrayRead(), DMMoabVecGetArray(), DMMoabVecRestoreArray() 472 @*/ 473 PetscErrorCode DMMoabVecGetArrayRead(DM dm,Vec vec,void* array) 474 { 475 DM_Moab *moab; 476 moab::ErrorCode merr; 477 PetscErrorCode ierr; 478 PetscInt count; 479 moab::Tag vtag; 480 PetscScalar **varray; 481 482 PetscFunctionBegin; 483 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 484 PetscValidHeaderSpecific(vec,VEC_CLASSID,2); 485 moab=(DM_Moab*)dm->data; 486 487 /* Get the MOAB private data */ 488 ierr = DMMoabGetVecTag(vec,&vtag);CHKERRQ(ierr); 489 490 /* Get the real scalar array handle */ 491 varray = reinterpret_cast<PetscScalar**>(array); 492 493 /* Get the array data for local entities */ 494 merr = moab->mbiface->tag_iterate(vtag,moab->vlocal->begin(),moab->vlocal->end(),count,reinterpret_cast<void*&>(*varray),true);MBERRNM(merr); 495 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()); 496 497 merr = moab->pcomm->exchange_tags(vtag,*moab->vlocal);MBERRNM(merr); 498 PetscFunctionReturn(0); 499 } 500 501 502 #undef __FUNCT__ 503 #define __FUNCT__ "DMMoabVecRestoreArrayRead" 504 /*@ 505 DMMoabVecRestoreArray - Restores the read-only direct access array obtained via DMMoabVecGetArray 506 507 Collective on MPI_Comm 508 509 Input Parameter: 510 + dm - The DMMoab object being set 511 . vec - The Vector whose underlying data is requested 512 - array - The local data array 513 514 Level: intermediate 515 516 .keywords: MOAB, distributed array 517 518 .seealso: DMMoabVecGetArrayRead(), DMMoabVecGetArray(), DMMoabVecRestoreArray() 519 @*/ 520 PetscErrorCode DMMoabVecRestoreArrayRead(DM dm,Vec v,void* array) 521 { 522 PetscFunctionBegin; 523 /* Nothing to do -> do not free the array memory obtained from tag_iterate */ 524 PetscFunctionReturn(0); 525 } 526 527 528 #undef __FUNCT__ 529 #define __FUNCT__ "DMGlobalToLocalBegin_Moab" 530 PetscErrorCode DMGlobalToLocalBegin_Moab(DM dm,Vec g,InsertMode mode,Vec l) 531 { 532 PetscErrorCode ierr; 533 DM_Moab *dmmoab = (DM_Moab*)dm->data; 534 535 PetscFunctionBegin; 536 ierr = VecScatterBegin(dmmoab->ltog_sendrecv,g,l,mode,SCATTER_FORWARD);CHKERRQ(ierr); 537 PetscFunctionReturn(0); 538 } 539 540 541 #undef __FUNCT__ 542 #define __FUNCT__ "DMGlobalToLocalEnd_Moab" 543 PetscErrorCode DMGlobalToLocalEnd_Moab(DM dm,Vec g,InsertMode mode,Vec l) 544 { 545 PetscErrorCode ierr; 546 DM_Moab *dmmoab = (DM_Moab*)dm->data; 547 548 PetscFunctionBegin; 549 ierr = VecScatterEnd(dmmoab->ltog_sendrecv,g,l,mode,SCATTER_FORWARD);CHKERRQ(ierr); 550 PetscFunctionReturn(0); 551 } 552 553 554 #undef __FUNCT__ 555 #define __FUNCT__ "DMLocalToGlobalBegin_Moab" 556 PetscErrorCode DMLocalToGlobalBegin_Moab(DM dm,Vec l,InsertMode mode,Vec g) 557 { 558 PetscErrorCode ierr; 559 DM_Moab *dmmoab = (DM_Moab*)dm->data; 560 561 PetscFunctionBegin; 562 ierr = VecScatterBegin(dmmoab->ltog_sendrecv,l,g,mode,SCATTER_REVERSE);CHKERRQ(ierr); 563 PetscFunctionReturn(0); 564 } 565 566 567 #undef __FUNCT__ 568 #define __FUNCT__ "DMLocalToGlobalEnd_Moab" 569 PetscErrorCode DMLocalToGlobalEnd_Moab(DM dm,Vec l,InsertMode mode,Vec g) 570 { 571 PetscErrorCode ierr; 572 DM_Moab *dmmoab = (DM_Moab*)dm->data; 573 574 PetscFunctionBegin; 575 ierr = VecScatterEnd(dmmoab->ltog_sendrecv,l,g,mode,SCATTER_REVERSE);CHKERRQ(ierr); 576 PetscFunctionReturn(0); 577 } 578 579 580