Actual source code: dagetarray.c

petsc-master 2019-10-17
Report Typos and Errors

  2:  #include <petsc/private/dmdaimpl.h>

  4: /*@C
  5:    DMDAVecGetArray - Returns a multiple dimension array that shares data with
  6:       the underlying vector and is indexed using the global dimensions.

  8:    Logically collective on da

 10:    Input Parameter:
 11: +  da - the distributed array
 12: -  vec - the vector, either a vector the same size as one obtained with DMCreateGlobalVector() or DMCreateLocalVector()

 14:    Output Parameter:
 15: .  array - the array

 17:    Notes:
 18:     Call DMDAVecRestoreArray() once you have finished accessing the vector entries.

 20:     In C, the indexing is "backwards" from what expects: array[k][j][i] NOT array[i][j][k]!

 22:     If vec is a local vector (obtained with DMCreateLocalVector() etc) then the ghost point locations are accessible. If it is
 23:     a global vector then the ghost points are not accessible. Of course with the local vector you will have had to do the

 25:     appropriate DMGlobalToLocalBegin() and DMGlobalToLocalEnd() to have correct values in the ghost locations.

 27:   Fortran Notes:
 28:     From Fortran use DMDAVecGetArrayF90() and pass for the array type PetscScalar,pointer :: array(:,...,:) of the appropriate
 29:        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
 30:        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
 31:        array(0:dof-1,xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1) where the values are obtained from
 32:        DMDAGetCorners() for a global array or DMDAGetGhostCorners() for a local array. Include petsc/finclude/petscdmda.h90 to access this routine.

 34:   Due to bugs in the compiler DMDAVecGetArrayF90() does not work with gfortran versions before 4.5

 36:   Level: intermediate

 38: .seealso: DMDAGetGhostCorners(), DMDAGetCorners(), VecGetArray(), VecRestoreArray(), DMDAVecRestoreArray(), DMDAVecRestoreArrayDOF()
 39:           DMDAVecGetArrayDOF(), DMDAVecGetArrayWrite(), DMDAVecRestoreArrayWrite(), DMDAVecGetArrayRead(), DMDAVecRestoreArrayRead(),
 40:           DMStagVecGetArray()
 41: @*/
 42: PetscErrorCode  DMDAVecGetArray(DM da,Vec vec,void *array)
 43: {
 45:   PetscInt       xs,ys,zs,xm,ym,zm,gxs,gys,gzs,gxm,gym,gzm,N,dim,dof;

 51:   DMDAGetCorners(da,&xs,&ys,&zs,&xm,&ym,&zm);
 52:   DMDAGetGhostCorners(da,&gxs,&gys,&gzs,&gxm,&gym,&gzm);
 53:   DMDAGetInfo(da,&dim,0,0,0,0,0,0,&dof,0,0,0,0,0);

 55:   /* Handle case where user passes in global vector as opposed to local */
 56:   VecGetLocalSize(vec,&N);
 57:   if (N == xm*ym*zm*dof) {
 58:     gxm = xm;
 59:     gym = ym;
 60:     gzm = zm;
 61:     gxs = xs;
 62:     gys = ys;
 63:     gzs = zs;
 64:   } 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);

 66:   if (dim == 1) {
 67:     VecGetArray1d(vec,gxm*dof,gxs*dof,(PetscScalar**)array);
 68:   } else if (dim == 2) {
 69:     VecGetArray2d(vec,gym,gxm*dof,gys,gxs*dof,(PetscScalar***)array);
 70:   } else if (dim == 3) {
 71:     VecGetArray3d(vec,gzm,gym,gxm*dof,gzs,gys,gxs*dof,(PetscScalar****)array);
 72:   } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"DMDA dimension not 1, 2, or 3, it is %D\n",dim);
 73:   return(0);
 74: }

 76: /*@
 77:    DMDAVecRestoreArray - Restores a multiple dimension array obtained with DMDAVecGetArray()

 79:    Logically collective on da

 81:    Input Parameter:
 82: +  da - the distributed array
 83: .  vec - the vector, either a vector the same size as one obtained with
 84:          DMCreateGlobalVector() or DMCreateLocalVector()
 85: -  array - the array, non-NULL pointer is zeroed

 87:   Level: intermediate

 89:   Fortran Notes:
 90:     From Fortran use DMDAVecRestoreArayF90()

 92: .seealso: DMDAGetGhostCorners(), DMDAGetCorners(), VecGetArray(), VecRestoreArray(), DMDAVecGetArray(),
 93:           DMDAVecGetArrayWrite(), DMDAVecRestoreArrayWrite(), DMDAVecGetArrayRead(), DMDAVecRestoreArrayRead(),
 94:           DMDStagVecRestoreArray()
 95: @*/
 96: PetscErrorCode  DMDAVecRestoreArray(DM da,Vec vec,void *array)
 97: {
 99:   PetscInt       xs,ys,zs,xm,ym,zm,gxs,gys,gzs,gxm,gym,gzm,N,dim,dof;

105:   DMDAGetCorners(da,&xs,&ys,&zs,&xm,&ym,&zm);
106:   DMDAGetGhostCorners(da,&gxs,&gys,&gzs,&gxm,&gym,&gzm);
107:   DMDAGetInfo(da,&dim,0,0,0,0,0,0,&dof,0,0,0,0,0);

109:   /* Handle case where user passes in global vector as opposed to local */
110:   VecGetLocalSize(vec,&N);
111:   if (N == xm*ym*zm*dof) {
112:     gxm = xm;
113:     gym = ym;
114:     gzm = zm;
115:     gxs = xs;
116:     gys = ys;
117:     gzs = zs;
118:   } 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);

120:   if (dim == 1) {
121:     VecRestoreArray1d(vec,gxm*dof,gxs*dof,(PetscScalar**)array);
122:   } else if (dim == 2) {
123:     VecRestoreArray2d(vec,gym,gxm*dof,gys,gxs*dof,(PetscScalar***)array);
124:   } else if (dim == 3) {
125:     VecRestoreArray3d(vec,gzm,gym,gxm*dof,gzs,gys,gxs*dof,(PetscScalar****)array);
126:   } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"DMDA dimension not 1, 2, or 3, it is %D\n",dim);
127:   return(0);
128: }

130: /*@C
131:    DMDAVecGetArrayWrite - Returns a multiple dimension array that shares data with
132:       the underlying vector and is indexed using the global dimensions.

134:    Logically collective on Vec

136:    Input Parameter:
137: +  da - the distributed array
138: -  vec - the vector, either a vector the same size as one obtained with DMCreateGlobalVector() or DMCreateLocalVector()

140:    Output Parameter:
141: .  array - the array

143:    Notes:
144:     Call DMDAVecRestoreArray() once you have finished accessing the vector entries.

146:     In C, the indexing is "backwards" from what expects: array[k][j][i] NOT array[i][j][k]!

148:     If vec is a local vector (obtained with DMCreateLocalVector() etc) then the ghost point locations are accessible. If it is
149:     a global vector then the ghost points are not accessible. Of course with the local vector you will have had to do the

151:     appropriate DMGlobalToLocalBegin() and DMGlobalToLocalEnd() to have correct values in the ghost locations.

153:   Fortran Notes:
154:     From Fortran use DMDAVecGetArrayF90() and pass for the array type PetscScalar,pointer :: array(:,...,:) of the appropriate
155:        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
156:        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
157:        array(0:dof-1,xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1) where the values are obtained from
158:        DMDAGetCorners() for a global array or DMDAGetGhostCorners() for a local array. Include petsc/finclude/petscdmda.h90 to access this routine.

160:   Due to bugs in the compiler DMDAVecGetArrayF90() does not work with gfortran versions before 4.5

162:   Level: intermediate

164:   Developer Notes: This has code duplication with DMDAVecGetArray() and DMDAVecGetArrayRead()

166: .seealso: DMDAGetGhostCorners(), DMDAGetCorners(), VecGetArray(), VecRestoreArray(), DMDAVecRestoreArrayWrite(), DMDAVecRestoreArrayDOF()
167:           DMDAVecGetArrayDOF(), DMDAVecGetArray(), DMDAVecRestoreArray(), DMDAVecGetArrayRead(), DMDAVecRestoreArrayRead()
168: @*/
169: PetscErrorCode  DMDAVecGetArrayWrite(DM da,Vec vec,void *array)
170: {
172:   PetscInt       xs,ys,zs,xm,ym,zm,gxs,gys,gzs,gxm,gym,gzm,N,dim,dof;

178:   if (da->localSection) {
179:     VecGetArrayWrite(vec,(PetscScalar**)array);
180:     return(0);
181:   }
182:   DMDAGetCorners(da,&xs,&ys,&zs,&xm,&ym,&zm);
183:   DMDAGetGhostCorners(da,&gxs,&gys,&gzs,&gxm,&gym,&gzm);
184:   DMDAGetInfo(da,&dim,0,0,0,0,0,0,&dof,0,0,0,0,0);

186:   /* Handle case where user passes in global vector as opposed to local */
187:   VecGetLocalSize(vec,&N);
188:   if (N == xm*ym*zm*dof) {
189:     gxm = xm;
190:     gym = ym;
191:     gzm = zm;
192:     gxs = xs;
193:     gys = ys;
194:     gzs = zs;
195:   } 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);

197:   if (dim == 1) {
198:     VecGetArray1dWrite(vec,gxm*dof,gxs*dof,(PetscScalar**)array);
199:   } else if (dim == 2) {
200:     VecGetArray2dWrite(vec,gym,gxm*dof,gys,gxs*dof,(PetscScalar***)array);
201:   } else if (dim == 3) {
202:     VecGetArray3dWrite(vec,gzm,gym,gxm*dof,gzs,gys,gxs*dof,(PetscScalar****)array);
203:   } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"DMDA dimension not 1, 2, or 3, it is %D\n",dim);
204:   return(0);
205: }

207: /*@
208:    DMDAVecRestoreArrayWrite - Restores a multiple dimension array obtained with DMDAVecGetArrayWrite()

210:    Logically collective on Vec

212:    Input Parameter:
213: +  da - the distributed array
214: .  vec - the vector, either a vector the same size as one obtained with
215:          DMCreateGlobalVector() or DMCreateLocalVector()
216: -  array - the array, non-NULL pointer is zeroed

218:   Level: intermediate

220:   Fortran Notes:
221:     From Fortran use DMDAVecRestoreArayF90()

223: .seealso: DMDAGetGhostCorners(), DMDAGetCorners(), VecGetArray(), VecRestoreArray(), DMDAVecGetArrayWrite(),
224:           DMDAVecGetArray(), DMDAVecRestoreArray(), DMDAVecGetArrayRead(), DMDAVecRestoreArrayRead()
225: @*/
226: PetscErrorCode  DMDAVecRestoreArrayWrite(DM da,Vec vec,void *array)
227: {
229:   PetscInt       xs,ys,zs,xm,ym,zm,gxs,gys,gzs,gxm,gym,gzm,N,dim,dof;

235:   if (da->localSection) {
236:     VecRestoreArray(vec,(PetscScalar**)array);
237:     return(0);
238:   }
239:   DMDAGetCorners(da,&xs,&ys,&zs,&xm,&ym,&zm);
240:   DMDAGetGhostCorners(da,&gxs,&gys,&gzs,&gxm,&gym,&gzm);
241:   DMDAGetInfo(da,&dim,0,0,0,0,0,0,&dof,0,0,0,0,0);

243:   /* Handle case where user passes in global vector as opposed to local */
244:   VecGetLocalSize(vec,&N);
245:   if (N == xm*ym*zm*dof) {
246:     gxm = xm;
247:     gym = ym;
248:     gzm = zm;
249:     gxs = xs;
250:     gys = ys;
251:     gzs = zs;
252:   } 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);

254:   if (dim == 1) {
255:     VecRestoreArray1dWrite(vec,gxm*dof,gxs*dof,(PetscScalar**)array);
256:   } else if (dim == 2) {
257:     VecRestoreArray2dWrite(vec,gym,gxm*dof,gys,gxs*dof,(PetscScalar***)array);
258:   } else if (dim == 3) {
259:     VecRestoreArray3dWrite(vec,gzm,gym,gxm*dof,gzs,gys,gxs*dof,(PetscScalar****)array);
260:   } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"DMDA dimension not 1, 2, or 3, it is %D\n",dim);
261:   return(0);
262: }

264: /*@C
265:    DMDAVecGetArrayDOF - Returns a multiple dimension array that shares data with
266:       the underlying vector and is indexed using the global dimensions.

268:    Logically collective

270:    Input Parameter:
271: +  da - the distributed array
272: -  vec - the vector, either a vector the same size as one obtained with
273:          DMCreateGlobalVector() or DMCreateLocalVector()

275:    Output Parameter:
276: .  array - the array

278:    Notes:
279:     Call DMDAVecRestoreArrayDOF() once you have finished accessing the vector entries.

281:     In C, the indexing is "backwards" from what expects: array[k][j][i][DOF] NOT array[i][j][k][DOF]!

283:     In Fortran 90 you do not need a version of DMDAVecRestoreArrayDOF() just use  DMDAVecRestoreArrayF90() and declare your array with one higher dimension,
284:     see src/dm/examples/tutorials/ex11f90.F

286:   Level: intermediate

288: .seealso: DMDAGetGhostCorners(), DMDAGetCorners(), VecGetArray(), VecRestoreArray(), DMDAVecRestoreArray(), DMDAVecGetArray(), DMDAVecRestoreArrayDOF(),
289:           DMDAVecGetArrayWrite(), DMDAVecRestoreArrayWrite(), DMDAVecGetArrayRead(), DMDAVecRestoreArrayRead(), DMStagVecGetArrayDOF()
290: @*/
291: PetscErrorCode  DMDAVecGetArrayDOF(DM da,Vec vec,void *array)
292: {
294:   PetscInt       xs,ys,zs,xm,ym,zm,gxs,gys,gzs,gxm,gym,gzm,N,dim,dof;

297:   DMDAGetCorners(da,&xs,&ys,&zs,&xm,&ym,&zm);
298:   DMDAGetGhostCorners(da,&gxs,&gys,&gzs,&gxm,&gym,&gzm);
299:   DMDAGetInfo(da,&dim,0,0,0,0,0,0,&dof,0,0,0,0,0);

301:   /* Handle case where user passes in global vector as opposed to local */
302:   VecGetLocalSize(vec,&N);
303:   if (N == xm*ym*zm*dof) {
304:     gxm = xm;
305:     gym = ym;
306:     gzm = zm;
307:     gxs = xs;
308:     gys = ys;
309:     gzs = zs;
310:   } 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);

312:   if (dim == 1) {
313:     VecGetArray2d(vec,gxm,dof,gxs,0,(PetscScalar***)array);
314:   } else if (dim == 2) {
315:     VecGetArray3d(vec,gym,gxm,dof,gys,gxs,0,(PetscScalar****)array);
316:   } else if (dim == 3) {
317:     VecGetArray4d(vec,gzm,gym,gxm,dof,gzs,gys,gxs,0,(PetscScalar*****)array);
318:   } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"DMDA dimension not 1, 2, or 3, it is %D\n",dim);
319:   return(0);
320: }

322: /*@
323:    DMDAVecRestoreArrayDOF - Restores a multiple dimension array obtained with DMDAVecGetArrayDOF()

325:    Logically collective

327:    Input Parameter:
328: +  da - the distributed array
329: .  vec - the vector, either a vector the same size as one obtained with
330:          DMCreateGlobalVector() or DMCreateLocalVector()
331: -  array - the array

333:   Level: intermediate

335: .seealso: DMDAGetGhostCorners(), DMDAGetCorners(), VecGetArray(), VecRestoreArray(), DMDAVecGetArray(), DMDAVecGetArrayDOF(), DMDAVecRestoreArrayDOF(),
336:           DMDAVecGetArrayWrite(), DMDAVecRestoreArrayWrite(), DMDAVecGetArrayRead(), DMDAVecRestoreArrayRead(), DMStagVecRestoreArrayDOF()
337: @*/
338: PetscErrorCode  DMDAVecRestoreArrayDOF(DM da,Vec vec,void *array)
339: {
341:   PetscInt       xs,ys,zs,xm,ym,zm,gxs,gys,gzs,gxm,gym,gzm,N,dim,dof;

344:   DMDAGetCorners(da,&xs,&ys,&zs,&xm,&ym,&zm);
345:   DMDAGetGhostCorners(da,&gxs,&gys,&gzs,&gxm,&gym,&gzm);
346:   DMDAGetInfo(da,&dim,0,0,0,0,0,0,&dof,0,0,0,0,0);

348:   /* Handle case where user passes in global vector as opposed to local */
349:   VecGetLocalSize(vec,&N);
350:   if (N == xm*ym*zm*dof) {
351:     gxm = xm;
352:     gym = ym;
353:     gzm = zm;
354:     gxs = xs;
355:     gys = ys;
356:     gzs = zs;
357:   }

359:   if (dim == 1) {
360:     VecRestoreArray2d(vec,gxm,dof,gxs,0,(PetscScalar***)array);
361:   } else if (dim == 2) {
362:     VecRestoreArray3d(vec,gym,gxm,dof,gys,gxs,0,(PetscScalar****)array);
363:   } else if (dim == 3) {
364:     VecRestoreArray4d(vec,gzm,gym,gxm,dof,gzs,gys,gxs,0,(PetscScalar*****)array);
365:   } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"DMDA dimension not 1, 2, or 3, it is %D\n",dim);
366:   return(0);
367: }

369: /*@C
370:    DMDAVecGetArrayRead - Returns a multiple dimension array that shares data with
371:       the underlying vector and is indexed using the global dimensions.

373:    Not collective

375:    Input Parameter:
376: +  da - the distributed array
377: -  vec - the vector, either a vector the same size as one obtained with DMCreateGlobalVector() or DMCreateLocalVector()

379:    Output Parameter:
380: .  array - the array

382:    Notes:
383:     Call DMDAVecRestoreArrayRead() once you have finished accessing the vector entries.

385:     In C, the indexing is "backwards" from what expects: array[k][j][i] NOT array[i][j][k]!

387:     If vec is a local vector (obtained with DMCreateLocalVector() etc) then the ghost point locations are accessible. If it is
388:     a global vector then the ghost points are not accessible. Of course with the local vector you will have had to do the

390:     appropriate DMGlobalToLocalBegin() and DMGlobalToLocalEnd() to have correct values in the ghost locations.

392:   Fortran Notes:
393:     From Fortran use DMDAVecGetArrayReadF90() and pass for the array type PetscScalar,pointer :: array(:,...,:) of the appropriate
394:        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
395:        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
396:        array(0:dof-1,xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1) where the values are obtained from
397:        DMDAGetCorners() for a global array or DMDAGetGhostCorners() for a local array. Include petsc/finclude/petscdmda.h90 to access this routine.

399:   Due to bugs in the compiler DMDAVecGetArrayReadF90() does not work with gfortran versions before 4.5

401:   Level: intermediate

403: .seealso: DMDAGetGhostCorners(), DMDAGetCorners(), VecGetArray(), VecRestoreArray(), DMDAVecRestoreArrayRead(), DMDAVecRestoreArrayDOF()
404:           DMDAVecGetArrayDOF(), DMDAVecGetArray(), DMDAVecRestoreArray(), DMDAVecGetArrayRead(), DMDAVecRestoreArrayRead(),
405:           DMStagVecGetArrayRead()
406: @*/
407: PetscErrorCode  DMDAVecGetArrayRead(DM da,Vec vec,void *array)
408: {
410:   PetscInt       xs,ys,zs,xm,ym,zm,gxs,gys,gzs,gxm,gym,gzm,N,dim,dof;

416:   DMDAGetCorners(da,&xs,&ys,&zs,&xm,&ym,&zm);
417:   DMDAGetGhostCorners(da,&gxs,&gys,&gzs,&gxm,&gym,&gzm);
418:   DMDAGetInfo(da,&dim,0,0,0,0,0,0,&dof,0,0,0,0,0);

420:   /* Handle case where user passes in global vector as opposed to local */
421:   VecGetLocalSize(vec,&N);
422:   if (N == xm*ym*zm*dof) {
423:     gxm = xm;
424:     gym = ym;
425:     gzm = zm;
426:     gxs = xs;
427:     gys = ys;
428:     gzs = zs;
429:   } 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);

431:   if (dim == 1) {
432:     VecGetArray1dRead(vec,gxm*dof,gxs*dof,(PetscScalar**)array);
433:   } else if (dim == 2) {
434:     VecGetArray2dRead(vec,gym,gxm*dof,gys,gxs*dof,(PetscScalar***)array);
435:   } else if (dim == 3) {
436:     VecGetArray3dRead(vec,gzm,gym,gxm*dof,gzs,gys,gxs*dof,(PetscScalar****)array);
437:   } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"DMDA dimension not 1, 2, or 3, it is %D\n",dim);
438:   return(0);
439: }

441: /*@
442:    DMDAVecRestoreArrayRead - Restores a multiple dimension array obtained with DMDAVecGetArrayRead()

444:    Not collective

446:    Input Parameter:
447: +  da - the distributed array
448: .  vec - the vector, either a vector the same size as one obtained with
449:          DMCreateGlobalVector() or DMCreateLocalVector()
450: -  array - the array, non-NULL pointer is zeroed

452:   Level: intermediate

454:   Fortran Notes:
455:     From Fortran use DMDAVecRestoreArrayReadF90()

457: .seealso: DMDAGetGhostCorners(), DMDAGetCorners(), VecGetArray(), VecRestoreArray(), DMDAVecGetArrayRead(),
458:           DMDAVecGetArray(), DMDAVecRestoreArray(), DMDAVecGetArrayWrite(), DMDAVecRestoreArrayWrite(),
459:           DMStagVecRestoreArrayRead()
460: @*/
461: PetscErrorCode  DMDAVecRestoreArrayRead(DM da,Vec vec,void *array)
462: {
464:   PetscInt       xs,ys,zs,xm,ym,zm,gxs,gys,gzs,gxm,gym,gzm,N,dim,dof;

470:   DMDAGetCorners(da,&xs,&ys,&zs,&xm,&ym,&zm);
471:   DMDAGetGhostCorners(da,&gxs,&gys,&gzs,&gxm,&gym,&gzm);
472:   DMDAGetInfo(da,&dim,0,0,0,0,0,0,&dof,0,0,0,0,0);

474:   /* Handle case where user passes in global vector as opposed to local */
475:   VecGetLocalSize(vec,&N);
476:   if (N == xm*ym*zm*dof) {
477:     gxm = xm;
478:     gym = ym;
479:     gzm = zm;
480:     gxs = xs;
481:     gys = ys;
482:     gzs = zs;
483:   } 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);

485:   if (dim == 1) {
486:     VecRestoreArray1dRead(vec,gxm*dof,gxs*dof,(PetscScalar**)array);
487:   } else if (dim == 2) {
488:     VecRestoreArray2dRead(vec,gym,gxm*dof,gys,gxs*dof,(PetscScalar***)array);
489:   } else if (dim == 3) {
490:     VecRestoreArray3dRead(vec,gzm,gym,gxm*dof,gzs,gys,gxs*dof,(PetscScalar****)array);
491:   } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"DMDA dimension not 1, 2, or 3, it is %D\n",dim);
492:   return(0);
493: }

495: /*@C
496:    DMDAVecGetArrayDOFRead - Returns a multiple dimension array that shares data with
497:       the underlying vector and is indexed using the global dimensions.

499:    Not Collective

501:    Input Parameter:
502: +  da - the distributed array
503: -  vec - the vector, either a vector the same size as one obtained with
504:          DMCreateGlobalVector() or DMCreateLocalVector()

506:    Output Parameter:
507: .  array - the array

509:    Notes:
510:     Call DMDAVecRestoreArrayDOFRead() once you have finished accessing the vector entries.

512:     In C, the indexing is "backwards" from what expects: array[k][j][i][DOF] NOT array[i][j][k][DOF]!

514:     In Fortran 90 you do not need a version of DMDAVecRestoreArrayDOF() just use  DMDAVecRestoreArrayReadF90() and declare your array with one higher dimension,
515:     see src/dm/examples/tutorials/ex11f90.F

517:   Level: intermediate

519: .seealso: DMDAGetGhostCorners(), DMDAGetCorners(), VecGetArray(), VecRestoreArray(), DMDAVecRestoreArray(), DMDAVecGetArray(), DMDAVecRestoreArrayDOF(),
520:           DMDAVecGetArrayWrite(), DMDAVecRestoreArrayWrite(), DMDAVecGetArrayRead(), DMDAVecRestoreArrayRead(), DMStagVecGetArrayDOFRead()
521: @*/
522: PetscErrorCode  DMDAVecGetArrayDOFRead(DM da,Vec vec,void *array)
523: {
525:   PetscInt       xs,ys,zs,xm,ym,zm,gxs,gys,gzs,gxm,gym,gzm,N,dim,dof;

528:   DMDAGetCorners(da,&xs,&ys,&zs,&xm,&ym,&zm);
529:   DMDAGetGhostCorners(da,&gxs,&gys,&gzs,&gxm,&gym,&gzm);
530:   DMDAGetInfo(da,&dim,0,0,0,0,0,0,&dof,0,0,0,0,0);

532:   /* Handle case where user passes in global vector as opposed to local */
533:   VecGetLocalSize(vec,&N);
534:   if (N == xm*ym*zm*dof) {
535:     gxm = xm;
536:     gym = ym;
537:     gzm = zm;
538:     gxs = xs;
539:     gys = ys;
540:     gzs = zs;
541:   } 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);

543:   if (dim == 1) {
544:     VecGetArray2dRead(vec,gxm,dof,gxs,0,(PetscScalar***)array);
545:   } else if (dim == 2) {
546:     VecGetArray3dRead(vec,gym,gxm,dof,gys,gxs,0,(PetscScalar****)array);
547:   } else if (dim == 3) {
548:     VecGetArray4dRead(vec,gzm,gym,gxm,dof,gzs,gys,gxs,0,(PetscScalar*****)array);
549:   } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"DMDA dimension not 1, 2, or 3, it is %D\n",dim);
550:   return(0);
551: }

553: /*@
554:    DMDAVecRestoreArrayDOFRead - Restores a multiple dimension array obtained with DMDAVecGetArrayDOFRead()

556:    Not Collective

558:    Input Parameter:
559: +  da - the distributed array
560: .  vec - the vector, either a vector the same size as one obtained with
561:          DMCreateGlobalVector() or DMCreateLocalVector()
562: -  array - the array

564:   Level: intermediate

566: .seealso: DMDAGetGhostCorners(), DMDAGetCorners(), VecGetArray(), VecRestoreArray(), DMDAVecGetArray(), DMDAVecGetArrayDOF(), DMDAVecRestoreArrayDOF(),
567:           DMDAVecGetArrayWrite(), DMDAVecRestoreArrayWrite(), DMDAVecGetArrayRead(), DMDAVecRestoreArrayRead(), DMStagVecRestoreArrayDOFRead()
568: @*/
569: PetscErrorCode  DMDAVecRestoreArrayDOFRead(DM da,Vec vec,void *array)
570: {
572:   PetscInt       xs,ys,zs,xm,ym,zm,gxs,gys,gzs,gxm,gym,gzm,N,dim,dof;

575:   DMDAGetCorners(da,&xs,&ys,&zs,&xm,&ym,&zm);
576:   DMDAGetGhostCorners(da,&gxs,&gys,&gzs,&gxm,&gym,&gzm);
577:   DMDAGetInfo(da,&dim,0,0,0,0,0,0,&dof,0,0,0,0,0);

579:   /* Handle case where user passes in global vector as opposed to local */
580:   VecGetLocalSize(vec,&N);
581:   if (N == xm*ym*zm*dof) {
582:     gxm = xm;
583:     gym = ym;
584:     gzm = zm;
585:     gxs = xs;
586:     gys = ys;
587:     gzs = zs;
588:   }

590:   if (dim == 1) {
591:     VecRestoreArray2dRead(vec,gxm,dof,gxs,0,(PetscScalar***)array);
592:   } else if (dim == 2) {
593:     VecRestoreArray3dRead(vec,gym,gxm,dof,gys,gxs,0,(PetscScalar****)array);
594:   } else if (dim == 3) {
595:     VecRestoreArray4dRead(vec,gzm,gym,gxm,dof,gzs,gys,gxs,0,(PetscScalar*****)array);
596:   } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"DMDA dimension not 1, 2, or 3, it is %D\n",dim);
597:   return(0);
598: }