1 2 #include <petsc/private/dmdaimpl.h> /*I "petscdmda.h" I*/ 3 4 #undef __FUNCT__ 5 #define __FUNCT__ "DMDAVecGetArray" 6 /*@C 7 DMDAVecGetArray - Returns a multiple dimension array that shares data with 8 the underlying vector and is indexed using the global dimensions. 9 10 Logically collective on Vec 11 12 Input Parameter: 13 + da - the distributed array 14 - vec - the vector, either a vector the same size as one obtained with DMCreateGlobalVector() or DMCreateLocalVector() 15 16 Output Parameter: 17 . array - the array 18 19 Notes: 20 Call DMDAVecRestoreArray() once you have finished accessing the vector entries. 21 22 In C, the indexing is "backwards" from what expects: array[k][j][i] NOT array[i][j][k]! 23 24 If vec is a local vector (obtained with DMCreateLocalVector() etc) then the ghost point locations are accessible. If it is 25 a global vector then the ghost points are not accessible. Of course with the local vector you will have had to do the 26 27 appropriate DMGlobalToLocalBegin() and DMGlobalToLocalEnd() to have correct values in the ghost locations. 28 29 Fortran Notes: From Fortran use DMDAVecGetArrayF90() and pass for the array type PetscScalar,pointer :: array(:,...,:) of the appropriate 30 dimension. For a DMDA created with a dof of 1 use the dimension of the DMDA, for a DMDA created with a dof greater than 1 use one more than the 31 dimension of the DMDA. The order of the indices is array(xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1) (when dof is 1) otherwise 32 array(0:dof-1,xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1) where the values are obtained from 33 DMDAGetCorners() for a global array or DMDAGetGhostCorners() for a local array. Include petsc/finclude/petscdmda.h90 to access this routine. 34 35 Due to bugs in the compiler DMDAVecGetArrayF90() does not work with gfortran versions before 4.5 36 37 Level: intermediate 38 39 .keywords: distributed array, get, corners, nodes, local indices, coordinates 40 41 .seealso: DMDAGetGhostCorners(), DMDAGetCorners(), VecGetArray(), VecRestoreArray(), DMDAVecRestoreArray(), DMDAVecRestoreArrayDOF() 42 DMDAVecGetArrayDOF() 43 @*/ 44 PetscErrorCode DMDAVecGetArray(DM da,Vec vec,void *array) 45 { 46 PetscErrorCode ierr; 47 PetscInt xs,ys,zs,xm,ym,zm,gxs,gys,gzs,gxm,gym,gzm,N,dim,dof; 48 49 PetscFunctionBegin; 50 PetscValidHeaderSpecific(da, DM_CLASSID, 1); 51 PetscValidHeaderSpecific(vec, VEC_CLASSID, 2); 52 PetscValidPointer(array, 3); 53 if (da->defaultSection) { 54 ierr = VecGetArray(vec,(PetscScalar**)array);CHKERRQ(ierr); 55 PetscFunctionReturn(0); 56 } 57 ierr = DMDAGetCorners(da,&xs,&ys,&zs,&xm,&ym,&zm);CHKERRQ(ierr); 58 ierr = DMDAGetGhostCorners(da,&gxs,&gys,&gzs,&gxm,&gym,&gzm);CHKERRQ(ierr); 59 ierr = DMDAGetInfo(da,&dim,0,0,0,0,0,0,&dof,0,0,0,0,0);CHKERRQ(ierr); 60 61 /* Handle case where user passes in global vector as opposed to local */ 62 ierr = VecGetLocalSize(vec,&N);CHKERRQ(ierr); 63 if (N == xm*ym*zm*dof) { 64 gxm = xm; 65 gym = ym; 66 gzm = zm; 67 gxs = xs; 68 gys = ys; 69 gzs = zs; 70 } else if (N != gxm*gym*gzm*dof) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Vector local size %D is not compatible with DMDA local sizes %D %D\n",N,xm*ym*zm*dof,gxm*gym*gzm*dof); 71 72 if (dim == 1) { 73 ierr = VecGetArray1d(vec,gxm*dof,gxs*dof,(PetscScalar**)array);CHKERRQ(ierr); 74 } else if (dim == 2) { 75 ierr = VecGetArray2d(vec,gym,gxm*dof,gys,gxs*dof,(PetscScalar***)array);CHKERRQ(ierr); 76 } else if (dim == 3) { 77 ierr = VecGetArray3d(vec,gzm,gym,gxm*dof,gzs,gys,gxs*dof,(PetscScalar****)array);CHKERRQ(ierr); 78 } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"DMDA dimension not 1, 2, or 3, it is %D\n",dim); 79 PetscFunctionReturn(0); 80 } 81 82 #undef __FUNCT__ 83 #define __FUNCT__ "DMDAVecRestoreArray" 84 /*@ 85 DMDAVecRestoreArray - Restores a multiple dimension array obtained with DMDAVecGetArray() 86 87 Logically collective on Vec 88 89 Input Parameter: 90 + da - the distributed array 91 . vec - the vector, either a vector the same size as one obtained with 92 DMCreateGlobalVector() or DMCreateLocalVector() 93 - array - the array, non-NULL pointer is zeroed 94 95 Level: intermediate 96 97 Fortran Notes: From Fortran use DMDAVecRestoreArrayF90() 98 99 .keywords: distributed array, get, corners, nodes, local indices, coordinates 100 101 .seealso: DMDAGetGhostCorners(), DMDAGetCorners(), VecGetArray(), VecRestoreArray(), DMDAVecGetArray() 102 @*/ 103 PetscErrorCode DMDAVecRestoreArray(DM da,Vec vec,void *array) 104 { 105 PetscErrorCode ierr; 106 PetscInt xs,ys,zs,xm,ym,zm,gxs,gys,gzs,gxm,gym,gzm,N,dim,dof; 107 108 PetscFunctionBegin; 109 PetscValidHeaderSpecific(da, DM_CLASSID, 1); 110 PetscValidHeaderSpecific(vec, VEC_CLASSID, 2); 111 PetscValidPointer(array, 3); 112 if (da->defaultSection) { 113 ierr = VecRestoreArray(vec,(PetscScalar**)array);CHKERRQ(ierr); 114 PetscFunctionReturn(0); 115 } 116 ierr = DMDAGetCorners(da,&xs,&ys,&zs,&xm,&ym,&zm);CHKERRQ(ierr); 117 ierr = DMDAGetGhostCorners(da,&gxs,&gys,&gzs,&gxm,&gym,&gzm);CHKERRQ(ierr); 118 ierr = DMDAGetInfo(da,&dim,0,0,0,0,0,0,&dof,0,0,0,0,0);CHKERRQ(ierr); 119 120 /* Handle case where user passes in global vector as opposed to local */ 121 ierr = VecGetLocalSize(vec,&N);CHKERRQ(ierr); 122 if (N == xm*ym*zm*dof) { 123 gxm = xm; 124 gym = ym; 125 gzm = zm; 126 gxs = xs; 127 gys = ys; 128 gzs = zs; 129 } else if (N != gxm*gym*gzm*dof) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Vector local size %D is not compatible with DMDA local sizes %D %D\n",N,xm*ym*zm*dof,gxm*gym*gzm*dof); 130 131 if (dim == 1) { 132 ierr = VecRestoreArray1d(vec,gxm*dof,gxs*dof,(PetscScalar**)array);CHKERRQ(ierr); 133 } else if (dim == 2) { 134 ierr = VecRestoreArray2d(vec,gym,gxm*dof,gys,gxs*dof,(PetscScalar***)array);CHKERRQ(ierr); 135 } else if (dim == 3) { 136 ierr = VecRestoreArray3d(vec,gzm,gym,gxm*dof,gzs,gys,gxs*dof,(PetscScalar****)array);CHKERRQ(ierr); 137 } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"DMDA dimension not 1, 2, or 3, it is %D\n",dim); 138 PetscFunctionReturn(0); 139 } 140 141 #undef __FUNCT__ 142 #define __FUNCT__ "DMDAVecGetArrayDOF" 143 /*@C 144 DMDAVecGetArrayDOF - Returns a multiple dimension array that shares data with 145 the underlying vector and is indexed using the global dimensions. 146 147 Logically collective 148 149 Input Parameter: 150 + da - the distributed array 151 - vec - the vector, either a vector the same size as one obtained with 152 DMCreateGlobalVector() or DMCreateLocalVector() 153 154 Output Parameter: 155 . array - the array 156 157 Notes: 158 Call DMDAVecRestoreArrayDOF() once you have finished accessing the vector entries. 159 160 In C, the indexing is "backwards" from what expects: array[k][j][i][DOF] NOT array[i][j][k][DOF]! 161 162 In Fortran 90 you do not need a version of DMDAVecRestoreArrayDOF() just use DMDAVecRestoreArrayF90() and declare your array with one higher dimension, 163 see src/dm/examples/tutorials/ex11f90.F 164 165 Level: intermediate 166 167 .keywords: distributed array, get, corners, nodes, local indices, coordinates 168 169 .seealso: DMDAGetGhostCorners(), DMDAGetCorners(), VecGetArray(), VecRestoreArray(), DMDAVecRestoreArray(), DMDAVecGetArray(), DMDAVecRestoreArrayDOF() 170 @*/ 171 PetscErrorCode DMDAVecGetArrayDOF(DM da,Vec vec,void *array) 172 { 173 PetscErrorCode ierr; 174 PetscInt xs,ys,zs,xm,ym,zm,gxs,gys,gzs,gxm,gym,gzm,N,dim,dof; 175 176 PetscFunctionBegin; 177 ierr = DMDAGetCorners(da,&xs,&ys,&zs,&xm,&ym,&zm);CHKERRQ(ierr); 178 ierr = DMDAGetGhostCorners(da,&gxs,&gys,&gzs,&gxm,&gym,&gzm);CHKERRQ(ierr); 179 ierr = DMDAGetInfo(da,&dim,0,0,0,0,0,0,&dof,0,0,0,0,0);CHKERRQ(ierr); 180 181 /* Handle case where user passes in global vector as opposed to local */ 182 ierr = VecGetLocalSize(vec,&N);CHKERRQ(ierr); 183 if (N == xm*ym*zm*dof) { 184 gxm = xm; 185 gym = ym; 186 gzm = zm; 187 gxs = xs; 188 gys = ys; 189 gzs = zs; 190 } else if (N != gxm*gym*gzm*dof) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Vector local size %D is not compatible with DMDA local sizes %D %D\n",N,xm*ym*zm*dof,gxm*gym*gzm*dof); 191 192 if (dim == 1) { 193 ierr = VecGetArray2d(vec,gxm,dof,gxs,0,(PetscScalar***)array);CHKERRQ(ierr); 194 } else if (dim == 2) { 195 ierr = VecGetArray3d(vec,gym,gxm,dof,gys,gxs,0,(PetscScalar****)array);CHKERRQ(ierr); 196 } else if (dim == 3) { 197 ierr = VecGetArray4d(vec,gzm,gym,gxm,dof,gzs,gys,gxs,0,(PetscScalar*****)array);CHKERRQ(ierr); 198 } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"DMDA dimension not 1, 2, or 3, it is %D\n",dim); 199 PetscFunctionReturn(0); 200 } 201 202 #undef __FUNCT__ 203 #define __FUNCT__ "DMDAVecRestoreArrayDOF" 204 /*@ 205 DMDAVecRestoreArrayDOF - Restores a multiple dimension array obtained with DMDAVecGetArrayDOF() 206 207 Logically collective 208 209 Input Parameter: 210 + da - the distributed array 211 . vec - the vector, either a vector the same size as one obtained with 212 DMCreateGlobalVector() or DMCreateLocalVector() 213 - array - the array 214 215 Level: intermediate 216 217 .keywords: distributed array, get, corners, nodes, local indices, coordinates 218 219 .seealso: DMDAGetGhostCorners(), DMDAGetCorners(), VecGetArray(), VecRestoreArray(), DMDAVecGetArray(), DMDAVecGetArrayDOF(), DMDAVecRestoreArrayDOF() 220 @*/ 221 PetscErrorCode DMDAVecRestoreArrayDOF(DM da,Vec vec,void *array) 222 { 223 PetscErrorCode ierr; 224 PetscInt xs,ys,zs,xm,ym,zm,gxs,gys,gzs,gxm,gym,gzm,N,dim,dof; 225 226 PetscFunctionBegin; 227 ierr = DMDAGetCorners(da,&xs,&ys,&zs,&xm,&ym,&zm);CHKERRQ(ierr); 228 ierr = DMDAGetGhostCorners(da,&gxs,&gys,&gzs,&gxm,&gym,&gzm);CHKERRQ(ierr); 229 ierr = DMDAGetInfo(da,&dim,0,0,0,0,0,0,&dof,0,0,0,0,0);CHKERRQ(ierr); 230 231 /* Handle case where user passes in global vector as opposed to local */ 232 ierr = VecGetLocalSize(vec,&N);CHKERRQ(ierr); 233 if (N == xm*ym*zm*dof) { 234 gxm = xm; 235 gym = ym; 236 gzm = zm; 237 gxs = xs; 238 gys = ys; 239 gzs = zs; 240 } 241 242 if (dim == 1) { 243 ierr = VecRestoreArray2d(vec,gxm,dof,gxs,0,(PetscScalar***)array);CHKERRQ(ierr); 244 } else if (dim == 2) { 245 ierr = VecRestoreArray3d(vec,gym,gxm,dof,gys,gxs,0,(PetscScalar****)array);CHKERRQ(ierr); 246 } else if (dim == 3) { 247 ierr = VecRestoreArray4d(vec,gzm,gym,gxm,dof,gzs,gys,gxs,0,(PetscScalar*****)array);CHKERRQ(ierr); 248 } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"DMDA dimension not 1, 2, or 3, it is %D\n",dim); 249 PetscFunctionReturn(0); 250 } 251 252 #undef __FUNCT__ 253 #define __FUNCT__ "DMDAVecGetArrayRead" 254 /*@C 255 DMDAVecGetArrayRead - Returns a multiple dimension array that shares data with 256 the underlying vector and is indexed using the global dimensions. 257 258 Not collective 259 260 Input Parameter: 261 + da - the distributed array 262 - vec - the vector, either a vector the same size as one obtained with DMCreateGlobalVector() or DMCreateLocalVector() 263 264 Output Parameter: 265 . array - the array 266 267 Notes: 268 Call DMDAVecRestoreArrayRead() once you have finished accessing the vector entries. 269 270 In C, the indexing is "backwards" from what expects: array[k][j][i] NOT array[i][j][k]! 271 272 If vec is a local vector (obtained with DMCreateLocalVector() etc) then the ghost point locations are accessible. If it is 273 a global vector then the ghost points are not accessible. Of course with the local vector you will have had to do the 274 275 appropriate DMGlobalToLocalBegin() and DMGlobalToLocalEnd() to have correct values in the ghost locations. 276 277 Fortran Notes: From Fortran use DMDAVecGetArrayReadF90() and pass for the array type PetscScalar,pointer :: array(:,...,:) of the appropriate 278 dimension. For a DMDA created with a dof of 1 use the dimension of the DMDA, for a DMDA created with a dof greater than 1 use one more than the 279 dimension of the DMDA. The order of the indices is array(xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1) (when dof is 1) otherwise 280 array(0:dof-1,xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1) where the values are obtained from 281 DMDAGetCorners() for a global array or DMDAGetGhostCorners() for a local array. Include petsc/finclude/petscdmda.h90 to access this routine. 282 283 Due to bugs in the compiler DMDAVecGetArrayReadF90() does not work with gfortran versions before 4.5 284 285 Level: intermediate 286 287 .keywords: distributed array, get, corners, nodes, local indices, coordinates 288 289 .seealso: DMDAGetGhostCorners(), DMDAGetCorners(), VecGetArray(), VecRestoreArray(), DMDAVecRestoreArray(), DMDAVecRestoreArrayDOF() 290 DMDAVecGetArrayDOF() 291 @*/ 292 PetscErrorCode DMDAVecGetArrayRead(DM da,Vec vec,void *array) 293 { 294 PetscErrorCode ierr; 295 PetscInt xs,ys,zs,xm,ym,zm,gxs,gys,gzs,gxm,gym,gzm,N,dim,dof; 296 297 PetscFunctionBegin; 298 PetscValidHeaderSpecific(da, DM_CLASSID, 1); 299 PetscValidHeaderSpecific(vec, VEC_CLASSID, 2); 300 PetscValidPointer(array, 3); 301 if (da->defaultSection) { 302 ierr = VecGetArrayRead(vec,(const PetscScalar**)array);CHKERRQ(ierr); 303 PetscFunctionReturn(0); 304 } 305 ierr = DMDAGetCorners(da,&xs,&ys,&zs,&xm,&ym,&zm);CHKERRQ(ierr); 306 ierr = DMDAGetGhostCorners(da,&gxs,&gys,&gzs,&gxm,&gym,&gzm);CHKERRQ(ierr); 307 ierr = DMDAGetInfo(da,&dim,0,0,0,0,0,0,&dof,0,0,0,0,0);CHKERRQ(ierr); 308 309 /* Handle case where user passes in global vector as opposed to local */ 310 ierr = VecGetLocalSize(vec,&N);CHKERRQ(ierr); 311 if (N == xm*ym*zm*dof) { 312 gxm = xm; 313 gym = ym; 314 gzm = zm; 315 gxs = xs; 316 gys = ys; 317 gzs = zs; 318 } else if (N != gxm*gym*gzm*dof) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Vector local size %D is not compatible with DMDA local sizes %D %D\n",N,xm*ym*zm*dof,gxm*gym*gzm*dof); 319 320 if (dim == 1) { 321 ierr = VecGetArray1dRead(vec,gxm*dof,gxs*dof,(PetscScalar**)array);CHKERRQ(ierr); 322 } else if (dim == 2) { 323 ierr = VecGetArray2dRead(vec,gym,gxm*dof,gys,gxs*dof,(PetscScalar***)array);CHKERRQ(ierr); 324 } else if (dim == 3) { 325 ierr = VecGetArray3dRead(vec,gzm,gym,gxm*dof,gzs,gys,gxs*dof,(PetscScalar****)array);CHKERRQ(ierr); 326 } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"DMDA dimension not 1, 2, or 3, it is %D\n",dim); 327 PetscFunctionReturn(0); 328 } 329 330 #undef __FUNCT__ 331 #define __FUNCT__ "DMDAVecRestoreArrayRead" 332 /*@ 333 DMDAVecRestoreArrayRead - Restores a multiple dimension array obtained with DMDAVecGetArrayRead() 334 335 Not collective 336 337 Input Parameter: 338 + da - the distributed array 339 . vec - the vector, either a vector the same size as one obtained with 340 DMCreateGlobalVector() or DMCreateLocalVector() 341 - array - the array, non-NULL pointer is zeroed 342 343 Level: intermediate 344 345 Fortran Notes: From Fortran use DMDAVecRestoreArrayReadF90() 346 347 .keywords: distributed array, get, corners, nodes, local indices, coordinates 348 349 .seealso: DMDAGetGhostCorners(), DMDAGetCorners(), VecGetArray(), VecRestoreArray(), DMDAVecGetArray() 350 @*/ 351 PetscErrorCode DMDAVecRestoreArrayRead(DM da,Vec vec,void *array) 352 { 353 PetscErrorCode ierr; 354 PetscInt xs,ys,zs,xm,ym,zm,gxs,gys,gzs,gxm,gym,gzm,N,dim,dof; 355 356 PetscFunctionBegin; 357 PetscValidHeaderSpecific(da, DM_CLASSID, 1); 358 PetscValidHeaderSpecific(vec, VEC_CLASSID, 2); 359 PetscValidPointer(array, 3); 360 if (da->defaultSection) { 361 ierr = VecRestoreArrayRead(vec,(const PetscScalar**)array);CHKERRQ(ierr); 362 PetscFunctionReturn(0); 363 } 364 ierr = DMDAGetCorners(da,&xs,&ys,&zs,&xm,&ym,&zm);CHKERRQ(ierr); 365 ierr = DMDAGetGhostCorners(da,&gxs,&gys,&gzs,&gxm,&gym,&gzm);CHKERRQ(ierr); 366 ierr = DMDAGetInfo(da,&dim,0,0,0,0,0,0,&dof,0,0,0,0,0);CHKERRQ(ierr); 367 368 /* Handle case where user passes in global vector as opposed to local */ 369 ierr = VecGetLocalSize(vec,&N);CHKERRQ(ierr); 370 if (N == xm*ym*zm*dof) { 371 gxm = xm; 372 gym = ym; 373 gzm = zm; 374 gxs = xs; 375 gys = ys; 376 gzs = zs; 377 } else if (N != gxm*gym*gzm*dof) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Vector local size %D is not compatible with DMDA local sizes %D %D\n",N,xm*ym*zm*dof,gxm*gym*gzm*dof); 378 379 if (dim == 1) { 380 ierr = VecRestoreArray1dRead(vec,gxm*dof,gxs*dof,(PetscScalar**)array);CHKERRQ(ierr); 381 } else if (dim == 2) { 382 ierr = VecRestoreArray2dRead(vec,gym,gxm*dof,gys,gxs*dof,(PetscScalar***)array);CHKERRQ(ierr); 383 } else if (dim == 3) { 384 ierr = VecRestoreArray3dRead(vec,gzm,gym,gxm*dof,gzs,gys,gxs*dof,(PetscScalar****)array);CHKERRQ(ierr); 385 } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"DMDA dimension not 1, 2, or 3, it is %D\n",dim); 386 PetscFunctionReturn(0); 387 } 388 389 #undef __FUNCT__ 390 #define __FUNCT__ "DMDAVecGetArrayDOFRead" 391 /*@C 392 DMDAVecGetArrayDOFRead - Returns a multiple dimension array that shares data with 393 the underlying vector and is indexed using the global dimensions. 394 395 Not Collective 396 397 Input Parameter: 398 + da - the distributed array 399 - vec - the vector, either a vector the same size as one obtained with 400 DMCreateGlobalVector() or DMCreateLocalVector() 401 402 Output Parameter: 403 . array - the array 404 405 Notes: 406 Call DMDAVecRestoreArrayDOFRead() once you have finished accessing the vector entries. 407 408 In C, the indexing is "backwards" from what expects: array[k][j][i][DOF] NOT array[i][j][k][DOF]! 409 410 In Fortran 90 you do not need a version of DMDAVecRestoreArrayDOF() just use DMDAVecRestoreArrayReadF90() and declare your array with one higher dimension, 411 see src/dm/examples/tutorials/ex11f90.F 412 413 Level: intermediate 414 415 .keywords: distributed array, get, corners, nodes, local indices, coordinates 416 417 .seealso: DMDAGetGhostCorners(), DMDAGetCorners(), VecGetArray(), VecRestoreArray(), DMDAVecRestoreArray(), DMDAVecGetArray(), DMDAVecRestoreArrayDOF() 418 @*/ 419 PetscErrorCode DMDAVecGetArrayDOFRead(DM da,Vec vec,void *array) 420 { 421 PetscErrorCode ierr; 422 PetscInt xs,ys,zs,xm,ym,zm,gxs,gys,gzs,gxm,gym,gzm,N,dim,dof; 423 424 PetscFunctionBegin; 425 ierr = DMDAGetCorners(da,&xs,&ys,&zs,&xm,&ym,&zm);CHKERRQ(ierr); 426 ierr = DMDAGetGhostCorners(da,&gxs,&gys,&gzs,&gxm,&gym,&gzm);CHKERRQ(ierr); 427 ierr = DMDAGetInfo(da,&dim,0,0,0,0,0,0,&dof,0,0,0,0,0);CHKERRQ(ierr); 428 429 /* Handle case where user passes in global vector as opposed to local */ 430 ierr = VecGetLocalSize(vec,&N);CHKERRQ(ierr); 431 if (N == xm*ym*zm*dof) { 432 gxm = xm; 433 gym = ym; 434 gzm = zm; 435 gxs = xs; 436 gys = ys; 437 gzs = zs; 438 } else if (N != gxm*gym*gzm*dof) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Vector local size %D is not compatible with DMDA local sizes %D %D\n",N,xm*ym*zm*dof,gxm*gym*gzm*dof); 439 440 if (dim == 1) { 441 ierr = VecGetArray2dRead(vec,gxm,dof,gxs,0,(PetscScalar***)array);CHKERRQ(ierr); 442 } else if (dim == 2) { 443 ierr = VecGetArray3dRead(vec,gym,gxm,dof,gys,gxs,0,(PetscScalar****)array);CHKERRQ(ierr); 444 } else if (dim == 3) { 445 ierr = VecGetArray4dRead(vec,gzm,gym,gxm,dof,gzs,gys,gxs,0,(PetscScalar*****)array);CHKERRQ(ierr); 446 } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"DMDA dimension not 1, 2, or 3, it is %D\n",dim); 447 PetscFunctionReturn(0); 448 } 449 450 #undef __FUNCT__ 451 #define __FUNCT__ "DMDAVecRestoreArrayDOFRead" 452 /*@ 453 DMDAVecRestoreArrayDOFRead - Restores a multiple dimension array obtained with DMDAVecGetArrayDOFRead() 454 455 Not Collective 456 457 Input Parameter: 458 + da - the distributed array 459 . vec - the vector, either a vector the same size as one obtained with 460 DMCreateGlobalVector() or DMCreateLocalVector() 461 - array - the array 462 463 Level: intermediate 464 465 .keywords: distributed array, get, corners, nodes, local indices, coordinates 466 467 .seealso: DMDAGetGhostCorners(), DMDAGetCorners(), VecGetArray(), VecRestoreArray(), DMDAVecGetArray(), DMDAVecGetArrayDOF(), DMDAVecRestoreArrayDOF() 468 @*/ 469 PetscErrorCode DMDAVecRestoreArrayDOFRead(DM da,Vec vec,void *array) 470 { 471 PetscErrorCode ierr; 472 PetscInt xs,ys,zs,xm,ym,zm,gxs,gys,gzs,gxm,gym,gzm,N,dim,dof; 473 474 PetscFunctionBegin; 475 ierr = DMDAGetCorners(da,&xs,&ys,&zs,&xm,&ym,&zm);CHKERRQ(ierr); 476 ierr = DMDAGetGhostCorners(da,&gxs,&gys,&gzs,&gxm,&gym,&gzm);CHKERRQ(ierr); 477 ierr = DMDAGetInfo(da,&dim,0,0,0,0,0,0,&dof,0,0,0,0,0);CHKERRQ(ierr); 478 479 /* Handle case where user passes in global vector as opposed to local */ 480 ierr = VecGetLocalSize(vec,&N);CHKERRQ(ierr); 481 if (N == xm*ym*zm*dof) { 482 gxm = xm; 483 gym = ym; 484 gzm = zm; 485 gxs = xs; 486 gys = ys; 487 gzs = zs; 488 } 489 490 if (dim == 1) { 491 ierr = VecRestoreArray2dRead(vec,gxm,dof,gxs,0,(PetscScalar***)array);CHKERRQ(ierr); 492 } else if (dim == 2) { 493 ierr = VecRestoreArray3dRead(vec,gym,gxm,dof,gys,gxs,0,(PetscScalar****)array);CHKERRQ(ierr); 494 } else if (dim == 3) { 495 ierr = VecRestoreArray4dRead(vec,gzm,gym,gxm,dof,gzs,gys,gxs,0,(PetscScalar*****)array);CHKERRQ(ierr); 496 } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"DMDA dimension not 1, 2, or 3, it is %D\n",dim); 497 PetscFunctionReturn(0); 498 } 499 500 501 502 503 504 505 506 507 508 509 510 511 512