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