xref: /petsc/src/dm/impls/da/dagetarray.c (revision fdc842d1a43d22858d8041cc45d2f5b4ad073a0b)
147c6ae99SBarry Smith 
2af0996ceSBarry Smith #include <petsc/private/dmdaimpl.h>    /*I   "petscdmda.h"   I*/
347c6ae99SBarry Smith 
447c6ae99SBarry Smith /*@C
5aa219208SBarry Smith    DMDAVecGetArray - Returns a multiple dimension array that shares data with
647c6ae99SBarry Smith       the underlying vector and is indexed using the global dimensions.
747c6ae99SBarry Smith 
8d083f849SBarry Smith    Logically collective on da
947c6ae99SBarry Smith 
1047c6ae99SBarry Smith    Input Parameter:
1147c6ae99SBarry Smith +  da - the distributed array
127e57d48aSBarry Smith -  vec - the vector, either a vector the same size as one obtained with DMCreateGlobalVector() or DMCreateLocalVector()
1347c6ae99SBarry Smith 
1447c6ae99SBarry Smith    Output Parameter:
1547c6ae99SBarry Smith .  array - the array
1647c6ae99SBarry Smith 
1747c6ae99SBarry Smith    Notes:
18aa219208SBarry Smith     Call DMDAVecRestoreArray() once you have finished accessing the vector entries.
1947c6ae99SBarry Smith 
2047c6ae99SBarry Smith     In C, the indexing is "backwards" from what expects: array[k][j][i] NOT array[i][j][k]!
2147c6ae99SBarry Smith 
227e57d48aSBarry Smith     If vec is a local vector (obtained with DMCreateLocalVector() etc) then the ghost point locations are accessible. If it is
237e57d48aSBarry Smith     a global vector then the ghost points are not accessible. Of course with the local vector you will have had to do the
2447c6ae99SBarry Smith 
257e57d48aSBarry Smith     appropriate DMGlobalToLocalBegin() and DMGlobalToLocalEnd() to have correct values in the ghost locations.
2647c6ae99SBarry Smith 
2795452b02SPatrick Sanan   Fortran Notes:
2895452b02SPatrick Sanan     From Fortran use DMDAVecGetArrayF90() and pass for the array type PetscScalar,pointer :: array(:,...,:) of the appropriate
29aa219208SBarry Smith        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
30aa219208SBarry Smith        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
31bef27881SBarry Smith        array(0:dof-1,xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1) where the values are obtained from
32af0996ceSBarry Smith        DMDAGetCorners() for a global array or DMDAGetGhostCorners() for a local array. Include petsc/finclude/petscdmda.h90 to access this routine.
3347c6ae99SBarry Smith 
34596f5af7SJed Brown   Due to bugs in the compiler DMDAVecGetArrayF90() does not work with gfortran versions before 4.5
3547c6ae99SBarry Smith 
3647c6ae99SBarry Smith   Level: intermediate
3747c6ae99SBarry Smith 
38aa219208SBarry Smith .seealso: DMDAGetGhostCorners(), DMDAGetCorners(), VecGetArray(), VecRestoreArray(), DMDAVecRestoreArray(), DMDAVecRestoreArrayDOF()
39*fdc842d1SBarry Smith           DMDAVecGetArrayDOF(), DMDAVecGetArrayWrite(), DMDAVecRestoreArrayWrite(), DMDAVecGetArrayRead(), DMDAVecRestoreArrayRead()
4047c6ae99SBarry Smith @*/
417087cfbeSBarry Smith PetscErrorCode  DMDAVecGetArray(DM da,Vec vec,void *array)
4247c6ae99SBarry Smith {
4347c6ae99SBarry Smith   PetscErrorCode ierr;
4447c6ae99SBarry Smith   PetscInt       xs,ys,zs,xm,ym,zm,gxs,gys,gzs,gxm,gym,gzm,N,dim,dof;
4547c6ae99SBarry Smith 
4647c6ae99SBarry Smith   PetscFunctionBegin;
47a9a02de4SBarry Smith   PetscValidHeaderSpecificType(da, DM_CLASSID, 1,DMDA);
486db82c94SMatthew G Knepley   PetscValidHeaderSpecific(vec, VEC_CLASSID, 2);
496db82c94SMatthew G Knepley   PetscValidPointer(array, 3);
50aa1993deSMatthew G Knepley   if (da->defaultSection) {
51aa1993deSMatthew G Knepley     ierr = VecGetArray(vec,(PetscScalar**)array);CHKERRQ(ierr);
52aa1993deSMatthew G Knepley     PetscFunctionReturn(0);
53aa1993deSMatthew G Knepley   }
54aa219208SBarry Smith   ierr = DMDAGetCorners(da,&xs,&ys,&zs,&xm,&ym,&zm);CHKERRQ(ierr);
55aa219208SBarry Smith   ierr = DMDAGetGhostCorners(da,&gxs,&gys,&gzs,&gxm,&gym,&gzm);CHKERRQ(ierr);
561321219cSEthan Coon   ierr = DMDAGetInfo(da,&dim,0,0,0,0,0,0,&dof,0,0,0,0,0);CHKERRQ(ierr);
5747c6ae99SBarry Smith 
5847c6ae99SBarry Smith   /* Handle case where user passes in global vector as opposed to local */
5947c6ae99SBarry Smith   ierr = VecGetLocalSize(vec,&N);CHKERRQ(ierr);
6047c6ae99SBarry Smith   if (N == xm*ym*zm*dof) {
6147c6ae99SBarry Smith     gxm = xm;
6247c6ae99SBarry Smith     gym = ym;
6347c6ae99SBarry Smith     gzm = zm;
6447c6ae99SBarry Smith     gxs = xs;
6547c6ae99SBarry Smith     gys = ys;
6647c6ae99SBarry Smith     gzs = zs;
6730729d88SBarry Smith   } 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);
6847c6ae99SBarry Smith 
6947c6ae99SBarry Smith   if (dim == 1) {
7047c6ae99SBarry Smith     ierr = VecGetArray1d(vec,gxm*dof,gxs*dof,(PetscScalar**)array);CHKERRQ(ierr);
7147c6ae99SBarry Smith   } else if (dim == 2) {
7247c6ae99SBarry Smith     ierr = VecGetArray2d(vec,gym,gxm*dof,gys,gxs*dof,(PetscScalar***)array);CHKERRQ(ierr);
7347c6ae99SBarry Smith   } else if (dim == 3) {
7447c6ae99SBarry Smith     ierr = VecGetArray3d(vec,gzm,gym,gxm*dof,gzs,gys,gxs*dof,(PetscScalar****)array);CHKERRQ(ierr);
7530729d88SBarry Smith   } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"DMDA dimension not 1, 2, or 3, it is %D\n",dim);
7647c6ae99SBarry Smith   PetscFunctionReturn(0);
7747c6ae99SBarry Smith }
7847c6ae99SBarry Smith 
7947c6ae99SBarry Smith /*@
80aa219208SBarry Smith    DMDAVecRestoreArray - Restores a multiple dimension array obtained with DMDAVecGetArray()
8147c6ae99SBarry Smith 
82d083f849SBarry Smith    Logically collective on da
8347c6ae99SBarry Smith 
8447c6ae99SBarry Smith    Input Parameter:
8547c6ae99SBarry Smith +  da - the distributed array
8647c6ae99SBarry Smith .  vec - the vector, either a vector the same size as one obtained with
87564755cdSBarry Smith          DMCreateGlobalVector() or DMCreateLocalVector()
88e5c84f05SJed Brown -  array - the array, non-NULL pointer is zeroed
8947c6ae99SBarry Smith 
9047c6ae99SBarry Smith   Level: intermediate
9147c6ae99SBarry Smith 
9295452b02SPatrick Sanan   Fortran Notes:
93*fdc842d1SBarry Smith     From Fortran use DMDAVecRestoreArayF90()
9447c6ae99SBarry Smith 
95*fdc842d1SBarry Smith .seealso: DMDAGetGhostCorners(), DMDAGetCorners(), VecGetArray(), VecRestoreArray(), DMDAVecGetArray(),
96*fdc842d1SBarry Smith           DMDAVecGetArrayWrite(), DMDAVecRestoreArrayWrite(), DMDAVecGetArrayRead(), DMDAVecRestoreArrayRead()
9747c6ae99SBarry Smith @*/
987087cfbeSBarry Smith PetscErrorCode  DMDAVecRestoreArray(DM da,Vec vec,void *array)
9947c6ae99SBarry Smith {
10047c6ae99SBarry Smith   PetscErrorCode ierr;
10147c6ae99SBarry Smith   PetscInt       xs,ys,zs,xm,ym,zm,gxs,gys,gzs,gxm,gym,gzm,N,dim,dof;
10247c6ae99SBarry Smith 
10347c6ae99SBarry Smith   PetscFunctionBegin;
104a9a02de4SBarry Smith   PetscValidHeaderSpecificType(da, DM_CLASSID, 1,DMDA);
1056db82c94SMatthew G Knepley   PetscValidHeaderSpecific(vec, VEC_CLASSID, 2);
1066db82c94SMatthew G Knepley   PetscValidPointer(array, 3);
107aa1993deSMatthew G Knepley   if (da->defaultSection) {
108aa1993deSMatthew G Knepley     ierr = VecRestoreArray(vec,(PetscScalar**)array);CHKERRQ(ierr);
109aa1993deSMatthew G Knepley     PetscFunctionReturn(0);
110aa1993deSMatthew G Knepley   }
111aa219208SBarry Smith   ierr = DMDAGetCorners(da,&xs,&ys,&zs,&xm,&ym,&zm);CHKERRQ(ierr);
112aa219208SBarry Smith   ierr = DMDAGetGhostCorners(da,&gxs,&gys,&gzs,&gxm,&gym,&gzm);CHKERRQ(ierr);
1131321219cSEthan Coon   ierr = DMDAGetInfo(da,&dim,0,0,0,0,0,0,&dof,0,0,0,0,0);CHKERRQ(ierr);
11447c6ae99SBarry Smith 
11547c6ae99SBarry Smith   /* Handle case where user passes in global vector as opposed to local */
11647c6ae99SBarry Smith   ierr = VecGetLocalSize(vec,&N);CHKERRQ(ierr);
11747c6ae99SBarry Smith   if (N == xm*ym*zm*dof) {
11847c6ae99SBarry Smith     gxm = xm;
11947c6ae99SBarry Smith     gym = ym;
12047c6ae99SBarry Smith     gzm = zm;
12147c6ae99SBarry Smith     gxs = xs;
12247c6ae99SBarry Smith     gys = ys;
12347c6ae99SBarry Smith     gzs = zs;
12430729d88SBarry Smith   } 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);
12547c6ae99SBarry Smith 
12647c6ae99SBarry Smith   if (dim == 1) {
12747c6ae99SBarry Smith     ierr = VecRestoreArray1d(vec,gxm*dof,gxs*dof,(PetscScalar**)array);CHKERRQ(ierr);
12847c6ae99SBarry Smith   } else if (dim == 2) {
12947c6ae99SBarry Smith     ierr = VecRestoreArray2d(vec,gym,gxm*dof,gys,gxs*dof,(PetscScalar***)array);CHKERRQ(ierr);
13047c6ae99SBarry Smith   } else if (dim == 3) {
13147c6ae99SBarry Smith     ierr = VecRestoreArray3d(vec,gzm,gym,gxm*dof,gzs,gys,gxs*dof,(PetscScalar****)array);CHKERRQ(ierr);
13230729d88SBarry Smith   } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"DMDA dimension not 1, 2, or 3, it is %D\n",dim);
13347c6ae99SBarry Smith   PetscFunctionReturn(0);
13447c6ae99SBarry Smith }
13547c6ae99SBarry Smith 
13647c6ae99SBarry Smith /*@C
137*fdc842d1SBarry Smith    DMDAVecGetArrayWrite - Returns a multiple dimension array that shares data with
138*fdc842d1SBarry Smith       the underlying vector and is indexed using the global dimensions.
139*fdc842d1SBarry Smith 
140*fdc842d1SBarry Smith    Logically collective on Vec
141*fdc842d1SBarry Smith 
142*fdc842d1SBarry Smith    Input Parameter:
143*fdc842d1SBarry Smith +  da - the distributed array
144*fdc842d1SBarry Smith -  vec - the vector, either a vector the same size as one obtained with DMCreateGlobalVector() or DMCreateLocalVector()
145*fdc842d1SBarry Smith 
146*fdc842d1SBarry Smith    Output Parameter:
147*fdc842d1SBarry Smith .  array - the array
148*fdc842d1SBarry Smith 
149*fdc842d1SBarry Smith    Notes:
150*fdc842d1SBarry Smith     Call DMDAVecRestoreArray() once you have finished accessing the vector entries.
151*fdc842d1SBarry Smith 
152*fdc842d1SBarry Smith     In C, the indexing is "backwards" from what expects: array[k][j][i] NOT array[i][j][k]!
153*fdc842d1SBarry Smith 
154*fdc842d1SBarry Smith     If vec is a local vector (obtained with DMCreateLocalVector() etc) then the ghost point locations are accessible. If it is
155*fdc842d1SBarry Smith     a global vector then the ghost points are not accessible. Of course with the local vector you will have had to do the
156*fdc842d1SBarry Smith 
157*fdc842d1SBarry Smith     appropriate DMGlobalToLocalBegin() and DMGlobalToLocalEnd() to have correct values in the ghost locations.
158*fdc842d1SBarry Smith 
159*fdc842d1SBarry Smith   Fortran Notes:
160*fdc842d1SBarry Smith     From Fortran use DMDAVecGetArrayF90() and pass for the array type PetscScalar,pointer :: array(:,...,:) of the appropriate
161*fdc842d1SBarry Smith        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
162*fdc842d1SBarry Smith        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
163*fdc842d1SBarry Smith        array(0:dof-1,xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1) where the values are obtained from
164*fdc842d1SBarry Smith        DMDAGetCorners() for a global array or DMDAGetGhostCorners() for a local array. Include petsc/finclude/petscdmda.h90 to access this routine.
165*fdc842d1SBarry Smith 
166*fdc842d1SBarry Smith   Due to bugs in the compiler DMDAVecGetArrayF90() does not work with gfortran versions before 4.5
167*fdc842d1SBarry Smith 
168*fdc842d1SBarry Smith   Level: intermediate
169*fdc842d1SBarry Smith 
170*fdc842d1SBarry Smith   Developer Notes: This has code duplication with DMDAVecGetArray() and DMDAVecGetArrayRead()
171*fdc842d1SBarry Smith 
172*fdc842d1SBarry Smith .seealso: DMDAGetGhostCorners(), DMDAGetCorners(), VecGetArray(), VecRestoreArray(), DMDAVecRestoreArrayWrite(), DMDAVecRestoreArrayDOF()
173*fdc842d1SBarry Smith           DMDAVecGetArrayDOF(), DMDAVecGetArray(), DMDAVecRestoreArray(), DMDAVecGetArrayRead(), DMDAVecRestoreArrayRead()
174*fdc842d1SBarry Smith @*/
175*fdc842d1SBarry Smith PetscErrorCode  DMDAVecGetArrayWrite(DM da,Vec vec,void *array)
176*fdc842d1SBarry Smith {
177*fdc842d1SBarry Smith   PetscErrorCode ierr;
178*fdc842d1SBarry Smith   PetscInt       xs,ys,zs,xm,ym,zm,gxs,gys,gzs,gxm,gym,gzm,N,dim,dof;
179*fdc842d1SBarry Smith 
180*fdc842d1SBarry Smith   PetscFunctionBegin;
181*fdc842d1SBarry Smith   PetscValidHeaderSpecificType(da, DM_CLASSID, 1,DMDA);
182*fdc842d1SBarry Smith   PetscValidHeaderSpecific(vec, VEC_CLASSID, 2);
183*fdc842d1SBarry Smith   PetscValidPointer(array, 3);
184*fdc842d1SBarry Smith   if (da->defaultSection) {
185*fdc842d1SBarry Smith     ierr = VecGetArrayWrite(vec,(PetscScalar**)array);CHKERRQ(ierr);
186*fdc842d1SBarry Smith     PetscFunctionReturn(0);
187*fdc842d1SBarry Smith   }
188*fdc842d1SBarry Smith   ierr = DMDAGetCorners(da,&xs,&ys,&zs,&xm,&ym,&zm);CHKERRQ(ierr);
189*fdc842d1SBarry Smith   ierr = DMDAGetGhostCorners(da,&gxs,&gys,&gzs,&gxm,&gym,&gzm);CHKERRQ(ierr);
190*fdc842d1SBarry Smith   ierr = DMDAGetInfo(da,&dim,0,0,0,0,0,0,&dof,0,0,0,0,0);CHKERRQ(ierr);
191*fdc842d1SBarry Smith 
192*fdc842d1SBarry Smith   /* Handle case where user passes in global vector as opposed to local */
193*fdc842d1SBarry Smith   ierr = VecGetLocalSize(vec,&N);CHKERRQ(ierr);
194*fdc842d1SBarry Smith   if (N == xm*ym*zm*dof) {
195*fdc842d1SBarry Smith     gxm = xm;
196*fdc842d1SBarry Smith     gym = ym;
197*fdc842d1SBarry Smith     gzm = zm;
198*fdc842d1SBarry Smith     gxs = xs;
199*fdc842d1SBarry Smith     gys = ys;
200*fdc842d1SBarry Smith     gzs = zs;
201*fdc842d1SBarry Smith   } 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);
202*fdc842d1SBarry Smith 
203*fdc842d1SBarry Smith   if (dim == 1) {
204*fdc842d1SBarry Smith     ierr = VecGetArray1dWrite(vec,gxm*dof,gxs*dof,(PetscScalar**)array);CHKERRQ(ierr);
205*fdc842d1SBarry Smith   } else if (dim == 2) {
206*fdc842d1SBarry Smith     ierr = VecGetArray2dWrite(vec,gym,gxm*dof,gys,gxs*dof,(PetscScalar***)array);CHKERRQ(ierr);
207*fdc842d1SBarry Smith   } else if (dim == 3) {
208*fdc842d1SBarry Smith     ierr = VecGetArray3dWrite(vec,gzm,gym,gxm*dof,gzs,gys,gxs*dof,(PetscScalar****)array);CHKERRQ(ierr);
209*fdc842d1SBarry Smith   } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"DMDA dimension not 1, 2, or 3, it is %D\n",dim);
210*fdc842d1SBarry Smith   PetscFunctionReturn(0);
211*fdc842d1SBarry Smith }
212*fdc842d1SBarry Smith 
213*fdc842d1SBarry Smith /*@
214*fdc842d1SBarry Smith    DMDAVecRestoreArrayWrite - Restores a multiple dimension array obtained with DMDAVecGetArrayWrite()
215*fdc842d1SBarry Smith 
216*fdc842d1SBarry Smith    Logically collective on Vec
217*fdc842d1SBarry Smith 
218*fdc842d1SBarry Smith    Input Parameter:
219*fdc842d1SBarry Smith +  da - the distributed array
220*fdc842d1SBarry Smith .  vec - the vector, either a vector the same size as one obtained with
221*fdc842d1SBarry Smith          DMCreateGlobalVector() or DMCreateLocalVector()
222*fdc842d1SBarry Smith -  array - the array, non-NULL pointer is zeroed
223*fdc842d1SBarry Smith 
224*fdc842d1SBarry Smith   Level: intermediate
225*fdc842d1SBarry Smith 
226*fdc842d1SBarry Smith   Fortran Notes:
227*fdc842d1SBarry Smith     From Fortran use DMDAVecRestoreArayF90()
228*fdc842d1SBarry Smith 
229*fdc842d1SBarry Smith .seealso: DMDAGetGhostCorners(), DMDAGetCorners(), VecGetArray(), VecRestoreArray(), DMDAVecGetArrayWrite(),
230*fdc842d1SBarry Smith           DMDAVecGetArray(), DMDAVecRestoreArray(), DMDAVecGetArrayRead(), DMDAVecRestoreArrayRead()
231*fdc842d1SBarry Smith @*/
232*fdc842d1SBarry Smith PetscErrorCode  DMDAVecRestoreArrayWrite(DM da,Vec vec,void *array)
233*fdc842d1SBarry Smith {
234*fdc842d1SBarry Smith   PetscErrorCode ierr;
235*fdc842d1SBarry Smith   PetscInt       xs,ys,zs,xm,ym,zm,gxs,gys,gzs,gxm,gym,gzm,N,dim,dof;
236*fdc842d1SBarry Smith 
237*fdc842d1SBarry Smith   PetscFunctionBegin;
238*fdc842d1SBarry Smith   PetscValidHeaderSpecificType(da, DM_CLASSID, 1,DMDA);
239*fdc842d1SBarry Smith   PetscValidHeaderSpecific(vec, VEC_CLASSID, 2);
240*fdc842d1SBarry Smith   PetscValidPointer(array, 3);
241*fdc842d1SBarry Smith   if (da->defaultSection) {
242*fdc842d1SBarry Smith     ierr = VecRestoreArray(vec,(PetscScalar**)array);CHKERRQ(ierr);
243*fdc842d1SBarry Smith     PetscFunctionReturn(0);
244*fdc842d1SBarry Smith   }
245*fdc842d1SBarry Smith   ierr = DMDAGetCorners(da,&xs,&ys,&zs,&xm,&ym,&zm);CHKERRQ(ierr);
246*fdc842d1SBarry Smith   ierr = DMDAGetGhostCorners(da,&gxs,&gys,&gzs,&gxm,&gym,&gzm);CHKERRQ(ierr);
247*fdc842d1SBarry Smith   ierr = DMDAGetInfo(da,&dim,0,0,0,0,0,0,&dof,0,0,0,0,0);CHKERRQ(ierr);
248*fdc842d1SBarry Smith 
249*fdc842d1SBarry Smith   /* Handle case where user passes in global vector as opposed to local */
250*fdc842d1SBarry Smith   ierr = VecGetLocalSize(vec,&N);CHKERRQ(ierr);
251*fdc842d1SBarry Smith   if (N == xm*ym*zm*dof) {
252*fdc842d1SBarry Smith     gxm = xm;
253*fdc842d1SBarry Smith     gym = ym;
254*fdc842d1SBarry Smith     gzm = zm;
255*fdc842d1SBarry Smith     gxs = xs;
256*fdc842d1SBarry Smith     gys = ys;
257*fdc842d1SBarry Smith     gzs = zs;
258*fdc842d1SBarry Smith   } 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);
259*fdc842d1SBarry Smith 
260*fdc842d1SBarry Smith   if (dim == 1) {
261*fdc842d1SBarry Smith     ierr = VecRestoreArray1dWrite(vec,gxm*dof,gxs*dof,(PetscScalar**)array);CHKERRQ(ierr);
262*fdc842d1SBarry Smith   } else if (dim == 2) {
263*fdc842d1SBarry Smith     ierr = VecRestoreArray2dWrite(vec,gym,gxm*dof,gys,gxs*dof,(PetscScalar***)array);CHKERRQ(ierr);
264*fdc842d1SBarry Smith   } else if (dim == 3) {
265*fdc842d1SBarry Smith     ierr = VecRestoreArray3dWrite(vec,gzm,gym,gxm*dof,gzs,gys,gxs*dof,(PetscScalar****)array);CHKERRQ(ierr);
266*fdc842d1SBarry Smith   } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"DMDA dimension not 1, 2, or 3, it is %D\n",dim);
267*fdc842d1SBarry Smith   PetscFunctionReturn(0);
268*fdc842d1SBarry Smith }
269*fdc842d1SBarry Smith 
270*fdc842d1SBarry Smith /*@C
271aa219208SBarry Smith    DMDAVecGetArrayDOF - Returns a multiple dimension array that shares data with
27247c6ae99SBarry Smith       the underlying vector and is indexed using the global dimensions.
27347c6ae99SBarry Smith 
2742ddbf755SMatthew G. Knepley    Logically collective
27547c6ae99SBarry Smith 
27647c6ae99SBarry Smith    Input Parameter:
27747c6ae99SBarry Smith +  da - the distributed array
27847c6ae99SBarry Smith -  vec - the vector, either a vector the same size as one obtained with
279564755cdSBarry Smith          DMCreateGlobalVector() or DMCreateLocalVector()
28047c6ae99SBarry Smith 
28147c6ae99SBarry Smith    Output Parameter:
28247c6ae99SBarry Smith .  array - the array
28347c6ae99SBarry Smith 
28447c6ae99SBarry Smith    Notes:
285aa219208SBarry Smith     Call DMDAVecRestoreArrayDOF() once you have finished accessing the vector entries.
28647c6ae99SBarry Smith 
28747c6ae99SBarry Smith     In C, the indexing is "backwards" from what expects: array[k][j][i][DOF] NOT array[i][j][k][DOF]!
28847c6ae99SBarry Smith 
2891b82215eSBarry Smith     In Fortran 90 you do not need a version of DMDAVecRestoreArrayDOF() just use  DMDAVecRestoreArrayF90() and declare your array with one higher dimension,
2901b82215eSBarry Smith     see src/dm/examples/tutorials/ex11f90.F
2911b82215eSBarry Smith 
29247c6ae99SBarry Smith   Level: intermediate
29347c6ae99SBarry Smith 
294*fdc842d1SBarry Smith .seealso: DMDAGetGhostCorners(), DMDAGetCorners(), VecGetArray(), VecRestoreArray(), DMDAVecRestoreArray(), DMDAVecGetArray(), DMDAVecRestoreArrayDOF(),
295*fdc842d1SBarry Smith           DMDAVecGetArrayWrite(), DMDAVecRestoreArrayWrite(), DMDAVecGetArrayRead(), DMDAVecRestoreArrayRead()
29647c6ae99SBarry Smith @*/
2977087cfbeSBarry Smith PetscErrorCode  DMDAVecGetArrayDOF(DM da,Vec vec,void *array)
29847c6ae99SBarry Smith {
29947c6ae99SBarry Smith   PetscErrorCode ierr;
30047c6ae99SBarry Smith   PetscInt       xs,ys,zs,xm,ym,zm,gxs,gys,gzs,gxm,gym,gzm,N,dim,dof;
30147c6ae99SBarry Smith 
30247c6ae99SBarry Smith   PetscFunctionBegin;
303aa219208SBarry Smith   ierr = DMDAGetCorners(da,&xs,&ys,&zs,&xm,&ym,&zm);CHKERRQ(ierr);
304aa219208SBarry Smith   ierr = DMDAGetGhostCorners(da,&gxs,&gys,&gzs,&gxm,&gym,&gzm);CHKERRQ(ierr);
3051321219cSEthan Coon   ierr = DMDAGetInfo(da,&dim,0,0,0,0,0,0,&dof,0,0,0,0,0);CHKERRQ(ierr);
30647c6ae99SBarry Smith 
30747c6ae99SBarry Smith   /* Handle case where user passes in global vector as opposed to local */
30847c6ae99SBarry Smith   ierr = VecGetLocalSize(vec,&N);CHKERRQ(ierr);
30947c6ae99SBarry Smith   if (N == xm*ym*zm*dof) {
31047c6ae99SBarry Smith     gxm = xm;
31147c6ae99SBarry Smith     gym = ym;
31247c6ae99SBarry Smith     gzm = zm;
31347c6ae99SBarry Smith     gxs = xs;
31447c6ae99SBarry Smith     gys = ys;
31547c6ae99SBarry Smith     gzs = zs;
31630729d88SBarry Smith   } 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);
31747c6ae99SBarry Smith 
31847c6ae99SBarry Smith   if (dim == 1) {
31947c6ae99SBarry Smith     ierr = VecGetArray2d(vec,gxm,dof,gxs,0,(PetscScalar***)array);CHKERRQ(ierr);
32047c6ae99SBarry Smith   } else if (dim == 2) {
32147c6ae99SBarry Smith     ierr = VecGetArray3d(vec,gym,gxm,dof,gys,gxs,0,(PetscScalar****)array);CHKERRQ(ierr);
32247c6ae99SBarry Smith   } else if (dim == 3) {
32347c6ae99SBarry Smith     ierr = VecGetArray4d(vec,gzm,gym,gxm,dof,gzs,gys,gxs,0,(PetscScalar*****)array);CHKERRQ(ierr);
32430729d88SBarry Smith   } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"DMDA dimension not 1, 2, or 3, it is %D\n",dim);
32547c6ae99SBarry Smith   PetscFunctionReturn(0);
32647c6ae99SBarry Smith }
32747c6ae99SBarry Smith 
32847c6ae99SBarry Smith /*@
329aa219208SBarry Smith    DMDAVecRestoreArrayDOF - Restores a multiple dimension array obtained with DMDAVecGetArrayDOF()
33047c6ae99SBarry Smith 
3312ddbf755SMatthew G. Knepley    Logically collective
33247c6ae99SBarry Smith 
33347c6ae99SBarry Smith    Input Parameter:
33447c6ae99SBarry Smith +  da - the distributed array
33547c6ae99SBarry Smith .  vec - the vector, either a vector the same size as one obtained with
336564755cdSBarry Smith          DMCreateGlobalVector() or DMCreateLocalVector()
33747c6ae99SBarry Smith -  array - the array
33847c6ae99SBarry Smith 
33947c6ae99SBarry Smith   Level: intermediate
34047c6ae99SBarry Smith 
341*fdc842d1SBarry Smith .seealso: DMDAGetGhostCorners(), DMDAGetCorners(), VecGetArray(), VecRestoreArray(), DMDAVecGetArray(), DMDAVecGetArrayDOF(), DMDAVecRestoreArrayDOF(),
342*fdc842d1SBarry Smith           DMDAVecGetArrayWrite(), DMDAVecRestoreArrayWrite(), DMDAVecGetArrayRead(), DMDAVecRestoreArrayRead()
34347c6ae99SBarry Smith @*/
3447087cfbeSBarry Smith PetscErrorCode  DMDAVecRestoreArrayDOF(DM da,Vec vec,void *array)
34547c6ae99SBarry Smith {
34647c6ae99SBarry Smith   PetscErrorCode ierr;
34747c6ae99SBarry Smith   PetscInt       xs,ys,zs,xm,ym,zm,gxs,gys,gzs,gxm,gym,gzm,N,dim,dof;
34847c6ae99SBarry Smith 
34947c6ae99SBarry Smith   PetscFunctionBegin;
350aa219208SBarry Smith   ierr = DMDAGetCorners(da,&xs,&ys,&zs,&xm,&ym,&zm);CHKERRQ(ierr);
351aa219208SBarry Smith   ierr = DMDAGetGhostCorners(da,&gxs,&gys,&gzs,&gxm,&gym,&gzm);CHKERRQ(ierr);
3521321219cSEthan Coon   ierr = DMDAGetInfo(da,&dim,0,0,0,0,0,0,&dof,0,0,0,0,0);CHKERRQ(ierr);
35347c6ae99SBarry Smith 
35447c6ae99SBarry Smith   /* Handle case where user passes in global vector as opposed to local */
35547c6ae99SBarry Smith   ierr = VecGetLocalSize(vec,&N);CHKERRQ(ierr);
35647c6ae99SBarry Smith   if (N == xm*ym*zm*dof) {
35747c6ae99SBarry Smith     gxm = xm;
35847c6ae99SBarry Smith     gym = ym;
35947c6ae99SBarry Smith     gzm = zm;
36047c6ae99SBarry Smith     gxs = xs;
36147c6ae99SBarry Smith     gys = ys;
36247c6ae99SBarry Smith     gzs = zs;
36347c6ae99SBarry Smith   }
36447c6ae99SBarry Smith 
36547c6ae99SBarry Smith   if (dim == 1) {
36647c6ae99SBarry Smith     ierr = VecRestoreArray2d(vec,gxm,dof,gxs,0,(PetscScalar***)array);CHKERRQ(ierr);
36747c6ae99SBarry Smith   } else if (dim == 2) {
36847c6ae99SBarry Smith     ierr = VecRestoreArray3d(vec,gym,gxm,dof,gys,gxs,0,(PetscScalar****)array);CHKERRQ(ierr);
36947c6ae99SBarry Smith   } else if (dim == 3) {
37047c6ae99SBarry Smith     ierr = VecRestoreArray4d(vec,gzm,gym,gxm,dof,gzs,gys,gxs,0,(PetscScalar*****)array);CHKERRQ(ierr);
37130729d88SBarry Smith   } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"DMDA dimension not 1, 2, or 3, it is %D\n",dim);
37247c6ae99SBarry Smith   PetscFunctionReturn(0);
37347c6ae99SBarry Smith }
37447c6ae99SBarry Smith 
3755edff71fSBarry Smith /*@C
3765edff71fSBarry Smith    DMDAVecGetArrayRead - Returns a multiple dimension array that shares data with
3775edff71fSBarry Smith       the underlying vector and is indexed using the global dimensions.
3785edff71fSBarry Smith 
3792ddbf755SMatthew G. Knepley    Not collective
3805edff71fSBarry Smith 
3815edff71fSBarry Smith    Input Parameter:
3825edff71fSBarry Smith +  da - the distributed array
3835edff71fSBarry Smith -  vec - the vector, either a vector the same size as one obtained with DMCreateGlobalVector() or DMCreateLocalVector()
3845edff71fSBarry Smith 
3855edff71fSBarry Smith    Output Parameter:
3865edff71fSBarry Smith .  array - the array
3875edff71fSBarry Smith 
3885edff71fSBarry Smith    Notes:
3895edff71fSBarry Smith     Call DMDAVecRestoreArrayRead() once you have finished accessing the vector entries.
3905edff71fSBarry Smith 
3915edff71fSBarry Smith     In C, the indexing is "backwards" from what expects: array[k][j][i] NOT array[i][j][k]!
3925edff71fSBarry Smith 
3935edff71fSBarry Smith     If vec is a local vector (obtained with DMCreateLocalVector() etc) then the ghost point locations are accessible. If it is
3945edff71fSBarry Smith     a global vector then the ghost points are not accessible. Of course with the local vector you will have had to do the
3955edff71fSBarry Smith 
3965edff71fSBarry Smith     appropriate DMGlobalToLocalBegin() and DMGlobalToLocalEnd() to have correct values in the ghost locations.
3975edff71fSBarry Smith 
39895452b02SPatrick Sanan   Fortran Notes:
39995452b02SPatrick Sanan     From Fortran use DMDAVecGetArrayReadF90() and pass for the array type PetscScalar,pointer :: array(:,...,:) of the appropriate
4005edff71fSBarry Smith        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
4015edff71fSBarry Smith        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
4025edff71fSBarry Smith        array(0:dof-1,xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1) where the values are obtained from
403af0996ceSBarry Smith        DMDAGetCorners() for a global array or DMDAGetGhostCorners() for a local array. Include petsc/finclude/petscdmda.h90 to access this routine.
4045edff71fSBarry Smith 
4054ebdaf59SBarry Smith   Due to bugs in the compiler DMDAVecGetArrayReadF90() does not work with gfortran versions before 4.5
4065edff71fSBarry Smith 
4075edff71fSBarry Smith   Level: intermediate
4085edff71fSBarry Smith 
409*fdc842d1SBarry Smith .seealso: DMDAGetGhostCorners(), DMDAGetCorners(), VecGetArray(), VecRestoreArray(), DMDAVecRestoreArrayRead(), DMDAVecRestoreArrayDOF()
410*fdc842d1SBarry Smith           DMDAVecGetArrayDOF(), DMDAVecGetArray(), DMDAVecRestoreArray(), DMDAVecGetArrayRead(), DMDAVecRestoreArrayRead()
4115edff71fSBarry Smith @*/
4125edff71fSBarry Smith PetscErrorCode  DMDAVecGetArrayRead(DM da,Vec vec,void *array)
4135edff71fSBarry Smith {
4145edff71fSBarry Smith   PetscErrorCode ierr;
4155edff71fSBarry Smith   PetscInt       xs,ys,zs,xm,ym,zm,gxs,gys,gzs,gxm,gym,gzm,N,dim,dof;
4165edff71fSBarry Smith 
4175edff71fSBarry Smith   PetscFunctionBegin;
418a9a02de4SBarry Smith   PetscValidHeaderSpecificType(da, DM_CLASSID, 1,DMDA);
4195edff71fSBarry Smith   PetscValidHeaderSpecific(vec, VEC_CLASSID, 2);
4205edff71fSBarry Smith   PetscValidPointer(array, 3);
4215edff71fSBarry Smith   if (da->defaultSection) {
4225edff71fSBarry Smith     ierr = VecGetArrayRead(vec,(const PetscScalar**)array);CHKERRQ(ierr);
4235edff71fSBarry Smith     PetscFunctionReturn(0);
4245edff71fSBarry Smith   }
4255edff71fSBarry Smith   ierr = DMDAGetCorners(da,&xs,&ys,&zs,&xm,&ym,&zm);CHKERRQ(ierr);
4265edff71fSBarry Smith   ierr = DMDAGetGhostCorners(da,&gxs,&gys,&gzs,&gxm,&gym,&gzm);CHKERRQ(ierr);
4275edff71fSBarry Smith   ierr = DMDAGetInfo(da,&dim,0,0,0,0,0,0,&dof,0,0,0,0,0);CHKERRQ(ierr);
4285edff71fSBarry Smith 
4295edff71fSBarry Smith   /* Handle case where user passes in global vector as opposed to local */
4305edff71fSBarry Smith   ierr = VecGetLocalSize(vec,&N);CHKERRQ(ierr);
4315edff71fSBarry Smith   if (N == xm*ym*zm*dof) {
4325edff71fSBarry Smith     gxm = xm;
4335edff71fSBarry Smith     gym = ym;
4345edff71fSBarry Smith     gzm = zm;
4355edff71fSBarry Smith     gxs = xs;
4365edff71fSBarry Smith     gys = ys;
4375edff71fSBarry Smith     gzs = zs;
4385edff71fSBarry Smith   } 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);
4395edff71fSBarry Smith 
4405edff71fSBarry Smith   if (dim == 1) {
4415edff71fSBarry Smith     ierr = VecGetArray1dRead(vec,gxm*dof,gxs*dof,(PetscScalar**)array);CHKERRQ(ierr);
4425edff71fSBarry Smith   } else if (dim == 2) {
4435edff71fSBarry Smith     ierr = VecGetArray2dRead(vec,gym,gxm*dof,gys,gxs*dof,(PetscScalar***)array);CHKERRQ(ierr);
4445edff71fSBarry Smith   } else if (dim == 3) {
4455edff71fSBarry Smith     ierr = VecGetArray3dRead(vec,gzm,gym,gxm*dof,gzs,gys,gxs*dof,(PetscScalar****)array);CHKERRQ(ierr);
4465edff71fSBarry Smith   } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"DMDA dimension not 1, 2, or 3, it is %D\n",dim);
4475edff71fSBarry Smith   PetscFunctionReturn(0);
4485edff71fSBarry Smith }
4495edff71fSBarry Smith 
4505edff71fSBarry Smith /*@
4515edff71fSBarry Smith    DMDAVecRestoreArrayRead - Restores a multiple dimension array obtained with DMDAVecGetArrayRead()
4525edff71fSBarry Smith 
4532ddbf755SMatthew G. Knepley    Not collective
4545edff71fSBarry Smith 
4555edff71fSBarry Smith    Input Parameter:
4565edff71fSBarry Smith +  da - the distributed array
4575edff71fSBarry Smith .  vec - the vector, either a vector the same size as one obtained with
4585edff71fSBarry Smith          DMCreateGlobalVector() or DMCreateLocalVector()
4595edff71fSBarry Smith -  array - the array, non-NULL pointer is zeroed
4605edff71fSBarry Smith 
4615edff71fSBarry Smith   Level: intermediate
4625edff71fSBarry Smith 
46395452b02SPatrick Sanan   Fortran Notes:
46495452b02SPatrick Sanan     From Fortran use DMDAVecRestoreArrayReadF90()
4655edff71fSBarry Smith 
466*fdc842d1SBarry Smith .seealso: DMDAGetGhostCorners(), DMDAGetCorners(), VecGetArray(), VecRestoreArray(), DMDAVecGetArrayRead(),
467*fdc842d1SBarry Smith           DMDAVecGetArray(), DMDAVecRestoreArray(), DMDAVecGetArrayWrite(), DMDAVecRestoreArrayWrite()
4685edff71fSBarry Smith @*/
4695edff71fSBarry Smith PetscErrorCode  DMDAVecRestoreArrayRead(DM da,Vec vec,void *array)
4705edff71fSBarry Smith {
4715edff71fSBarry Smith   PetscErrorCode ierr;
4725edff71fSBarry Smith   PetscInt       xs,ys,zs,xm,ym,zm,gxs,gys,gzs,gxm,gym,gzm,N,dim,dof;
4735edff71fSBarry Smith 
4745edff71fSBarry Smith   PetscFunctionBegin;
475a9a02de4SBarry Smith   PetscValidHeaderSpecificType(da, DM_CLASSID, 1,DMDA);
4765edff71fSBarry Smith   PetscValidHeaderSpecific(vec, VEC_CLASSID, 2);
4775edff71fSBarry Smith   PetscValidPointer(array, 3);
4785edff71fSBarry Smith   if (da->defaultSection) {
4795edff71fSBarry Smith     ierr = VecRestoreArrayRead(vec,(const PetscScalar**)array);CHKERRQ(ierr);
4805edff71fSBarry Smith     PetscFunctionReturn(0);
4815edff71fSBarry Smith   }
4825edff71fSBarry Smith   ierr = DMDAGetCorners(da,&xs,&ys,&zs,&xm,&ym,&zm);CHKERRQ(ierr);
4835edff71fSBarry Smith   ierr = DMDAGetGhostCorners(da,&gxs,&gys,&gzs,&gxm,&gym,&gzm);CHKERRQ(ierr);
4845edff71fSBarry Smith   ierr = DMDAGetInfo(da,&dim,0,0,0,0,0,0,&dof,0,0,0,0,0);CHKERRQ(ierr);
4855edff71fSBarry Smith 
4865edff71fSBarry Smith   /* Handle case where user passes in global vector as opposed to local */
4875edff71fSBarry Smith   ierr = VecGetLocalSize(vec,&N);CHKERRQ(ierr);
4885edff71fSBarry Smith   if (N == xm*ym*zm*dof) {
4895edff71fSBarry Smith     gxm = xm;
4905edff71fSBarry Smith     gym = ym;
4915edff71fSBarry Smith     gzm = zm;
4925edff71fSBarry Smith     gxs = xs;
4935edff71fSBarry Smith     gys = ys;
4945edff71fSBarry Smith     gzs = zs;
4955edff71fSBarry Smith   } 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);
4965edff71fSBarry Smith 
4975edff71fSBarry Smith   if (dim == 1) {
4985edff71fSBarry Smith     ierr = VecRestoreArray1dRead(vec,gxm*dof,gxs*dof,(PetscScalar**)array);CHKERRQ(ierr);
4995edff71fSBarry Smith   } else if (dim == 2) {
5005edff71fSBarry Smith     ierr = VecRestoreArray2dRead(vec,gym,gxm*dof,gys,gxs*dof,(PetscScalar***)array);CHKERRQ(ierr);
5015edff71fSBarry Smith   } else if (dim == 3) {
5025edff71fSBarry Smith     ierr = VecRestoreArray3dRead(vec,gzm,gym,gxm*dof,gzs,gys,gxs*dof,(PetscScalar****)array);CHKERRQ(ierr);
5035edff71fSBarry Smith   } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"DMDA dimension not 1, 2, or 3, it is %D\n",dim);
5045edff71fSBarry Smith   PetscFunctionReturn(0);
5055edff71fSBarry Smith }
5065edff71fSBarry Smith 
5075edff71fSBarry Smith /*@C
5085edff71fSBarry Smith    DMDAVecGetArrayDOFRead - Returns a multiple dimension array that shares data with
5095edff71fSBarry Smith       the underlying vector and is indexed using the global dimensions.
5105edff71fSBarry Smith 
5115edff71fSBarry Smith    Not Collective
5125edff71fSBarry Smith 
5135edff71fSBarry Smith    Input Parameter:
5145edff71fSBarry Smith +  da - the distributed array
5155edff71fSBarry Smith -  vec - the vector, either a vector the same size as one obtained with
5165edff71fSBarry Smith          DMCreateGlobalVector() or DMCreateLocalVector()
5175edff71fSBarry Smith 
5185edff71fSBarry Smith    Output Parameter:
5195edff71fSBarry Smith .  array - the array
5205edff71fSBarry Smith 
5215edff71fSBarry Smith    Notes:
5225edff71fSBarry Smith     Call DMDAVecRestoreArrayDOFRead() once you have finished accessing the vector entries.
5235edff71fSBarry Smith 
5245edff71fSBarry Smith     In C, the indexing is "backwards" from what expects: array[k][j][i][DOF] NOT array[i][j][k][DOF]!
5255edff71fSBarry Smith 
5264ebdaf59SBarry Smith     In Fortran 90 you do not need a version of DMDAVecRestoreArrayDOF() just use  DMDAVecRestoreArrayReadF90() and declare your array with one higher dimension,
5275edff71fSBarry Smith     see src/dm/examples/tutorials/ex11f90.F
5285edff71fSBarry Smith 
5295edff71fSBarry Smith   Level: intermediate
5305edff71fSBarry Smith 
531*fdc842d1SBarry Smith .seealso: DMDAGetGhostCorners(), DMDAGetCorners(), VecGetArray(), VecRestoreArray(), DMDAVecRestoreArray(), DMDAVecGetArray(), DMDAVecRestoreArrayDOF(),
532*fdc842d1SBarry Smith           DMDAVecGetArrayWrite(), DMDAVecRestoreArrayWrite(), DMDAVecGetArrayRead(), DMDAVecRestoreArrayRead()
5335edff71fSBarry Smith @*/
5345edff71fSBarry Smith PetscErrorCode  DMDAVecGetArrayDOFRead(DM da,Vec vec,void *array)
5355edff71fSBarry Smith {
5365edff71fSBarry Smith   PetscErrorCode ierr;
5375edff71fSBarry Smith   PetscInt       xs,ys,zs,xm,ym,zm,gxs,gys,gzs,gxm,gym,gzm,N,dim,dof;
5385edff71fSBarry Smith 
5395edff71fSBarry Smith   PetscFunctionBegin;
5405edff71fSBarry Smith   ierr = DMDAGetCorners(da,&xs,&ys,&zs,&xm,&ym,&zm);CHKERRQ(ierr);
5415edff71fSBarry Smith   ierr = DMDAGetGhostCorners(da,&gxs,&gys,&gzs,&gxm,&gym,&gzm);CHKERRQ(ierr);
5425edff71fSBarry Smith   ierr = DMDAGetInfo(da,&dim,0,0,0,0,0,0,&dof,0,0,0,0,0);CHKERRQ(ierr);
5435edff71fSBarry Smith 
5445edff71fSBarry Smith   /* Handle case where user passes in global vector as opposed to local */
5455edff71fSBarry Smith   ierr = VecGetLocalSize(vec,&N);CHKERRQ(ierr);
5465edff71fSBarry Smith   if (N == xm*ym*zm*dof) {
5475edff71fSBarry Smith     gxm = xm;
5485edff71fSBarry Smith     gym = ym;
5495edff71fSBarry Smith     gzm = zm;
5505edff71fSBarry Smith     gxs = xs;
5515edff71fSBarry Smith     gys = ys;
5525edff71fSBarry Smith     gzs = zs;
5535edff71fSBarry Smith   } 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);
5545edff71fSBarry Smith 
5555edff71fSBarry Smith   if (dim == 1) {
5565edff71fSBarry Smith     ierr = VecGetArray2dRead(vec,gxm,dof,gxs,0,(PetscScalar***)array);CHKERRQ(ierr);
5575edff71fSBarry Smith   } else if (dim == 2) {
5585edff71fSBarry Smith     ierr = VecGetArray3dRead(vec,gym,gxm,dof,gys,gxs,0,(PetscScalar****)array);CHKERRQ(ierr);
5595edff71fSBarry Smith   } else if (dim == 3) {
5605edff71fSBarry Smith     ierr = VecGetArray4dRead(vec,gzm,gym,gxm,dof,gzs,gys,gxs,0,(PetscScalar*****)array);CHKERRQ(ierr);
5615edff71fSBarry Smith   } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"DMDA dimension not 1, 2, or 3, it is %D\n",dim);
5625edff71fSBarry Smith   PetscFunctionReturn(0);
5635edff71fSBarry Smith }
5645edff71fSBarry Smith 
5655edff71fSBarry Smith /*@
5665edff71fSBarry Smith    DMDAVecRestoreArrayDOFRead - Restores a multiple dimension array obtained with DMDAVecGetArrayDOFRead()
5675edff71fSBarry Smith 
5685edff71fSBarry Smith    Not Collective
5695edff71fSBarry Smith 
5705edff71fSBarry Smith    Input Parameter:
5715edff71fSBarry Smith +  da - the distributed array
5725edff71fSBarry Smith .  vec - the vector, either a vector the same size as one obtained with
5735edff71fSBarry Smith          DMCreateGlobalVector() or DMCreateLocalVector()
5745edff71fSBarry Smith -  array - the array
5755edff71fSBarry Smith 
5765edff71fSBarry Smith   Level: intermediate
5775edff71fSBarry Smith 
578*fdc842d1SBarry Smith .seealso: DMDAGetGhostCorners(), DMDAGetCorners(), VecGetArray(), VecRestoreArray(), DMDAVecGetArray(), DMDAVecGetArrayDOF(), DMDAVecRestoreArrayDOF(),
579*fdc842d1SBarry Smith           DMDAVecGetArrayWrite(), DMDAVecRestoreArrayWrite(), DMDAVecGetArrayRead(), DMDAVecRestoreArrayRead()
5805edff71fSBarry Smith @*/
5815edff71fSBarry Smith PetscErrorCode  DMDAVecRestoreArrayDOFRead(DM da,Vec vec,void *array)
5825edff71fSBarry Smith {
5835edff71fSBarry Smith   PetscErrorCode ierr;
5845edff71fSBarry Smith   PetscInt       xs,ys,zs,xm,ym,zm,gxs,gys,gzs,gxm,gym,gzm,N,dim,dof;
5855edff71fSBarry Smith 
5865edff71fSBarry Smith   PetscFunctionBegin;
5875edff71fSBarry Smith   ierr = DMDAGetCorners(da,&xs,&ys,&zs,&xm,&ym,&zm);CHKERRQ(ierr);
5885edff71fSBarry Smith   ierr = DMDAGetGhostCorners(da,&gxs,&gys,&gzs,&gxm,&gym,&gzm);CHKERRQ(ierr);
5895edff71fSBarry Smith   ierr = DMDAGetInfo(da,&dim,0,0,0,0,0,0,&dof,0,0,0,0,0);CHKERRQ(ierr);
5905edff71fSBarry Smith 
5915edff71fSBarry Smith   /* Handle case where user passes in global vector as opposed to local */
5925edff71fSBarry Smith   ierr = VecGetLocalSize(vec,&N);CHKERRQ(ierr);
5935edff71fSBarry Smith   if (N == xm*ym*zm*dof) {
5945edff71fSBarry Smith     gxm = xm;
5955edff71fSBarry Smith     gym = ym;
5965edff71fSBarry Smith     gzm = zm;
5975edff71fSBarry Smith     gxs = xs;
5985edff71fSBarry Smith     gys = ys;
5995edff71fSBarry Smith     gzs = zs;
6005edff71fSBarry Smith   }
6015edff71fSBarry Smith 
6025edff71fSBarry Smith   if (dim == 1) {
6035edff71fSBarry Smith     ierr = VecRestoreArray2dRead(vec,gxm,dof,gxs,0,(PetscScalar***)array);CHKERRQ(ierr);
6045edff71fSBarry Smith   } else if (dim == 2) {
6055edff71fSBarry Smith     ierr = VecRestoreArray3dRead(vec,gym,gxm,dof,gys,gxs,0,(PetscScalar****)array);CHKERRQ(ierr);
6065edff71fSBarry Smith   } else if (dim == 3) {
6075edff71fSBarry Smith     ierr = VecRestoreArray4dRead(vec,gzm,gym,gxm,dof,gzs,gys,gxs,0,(PetscScalar*****)array);CHKERRQ(ierr);
6085edff71fSBarry Smith   } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"DMDA dimension not 1, 2, or 3, it is %D\n",dim);
6095edff71fSBarry Smith   PetscFunctionReturn(0);
6105edff71fSBarry Smith }
6115edff71fSBarry Smith 
61247c6ae99SBarry Smith 
61347c6ae99SBarry Smith 
61447c6ae99SBarry Smith 
61547c6ae99SBarry Smith 
61647c6ae99SBarry Smith 
61747c6ae99SBarry Smith 
61847c6ae99SBarry Smith 
61947c6ae99SBarry Smith 
62047c6ae99SBarry Smith 
62147c6ae99SBarry Smith 
62247c6ae99SBarry Smith 
62347c6ae99SBarry Smith 
624