xref: /petsc/src/dm/impls/da/dagetarray.c (revision 1bb6d2a8d27998275780769967d0e939765fcbef)
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()
39fdc842d1SBarry 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);
50aa219208SBarry Smith   ierr = DMDAGetCorners(da,&xs,&ys,&zs,&xm,&ym,&zm);CHKERRQ(ierr);
51aa219208SBarry Smith   ierr = DMDAGetGhostCorners(da,&gxs,&gys,&gzs,&gxm,&gym,&gzm);CHKERRQ(ierr);
521321219cSEthan Coon   ierr = DMDAGetInfo(da,&dim,0,0,0,0,0,0,&dof,0,0,0,0,0);CHKERRQ(ierr);
5347c6ae99SBarry Smith 
5447c6ae99SBarry Smith   /* Handle case where user passes in global vector as opposed to local */
5547c6ae99SBarry Smith   ierr = VecGetLocalSize(vec,&N);CHKERRQ(ierr);
5647c6ae99SBarry Smith   if (N == xm*ym*zm*dof) {
5747c6ae99SBarry Smith     gxm = xm;
5847c6ae99SBarry Smith     gym = ym;
5947c6ae99SBarry Smith     gzm = zm;
6047c6ae99SBarry Smith     gxs = xs;
6147c6ae99SBarry Smith     gys = ys;
6247c6ae99SBarry Smith     gzs = zs;
6330729d88SBarry 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);
6447c6ae99SBarry Smith 
6547c6ae99SBarry Smith   if (dim == 1) {
6647c6ae99SBarry Smith     ierr = VecGetArray1d(vec,gxm*dof,gxs*dof,(PetscScalar**)array);CHKERRQ(ierr);
6747c6ae99SBarry Smith   } else if (dim == 2) {
6847c6ae99SBarry Smith     ierr = VecGetArray2d(vec,gym,gxm*dof,gys,gxs*dof,(PetscScalar***)array);CHKERRQ(ierr);
6947c6ae99SBarry Smith   } else if (dim == 3) {
7047c6ae99SBarry Smith     ierr = VecGetArray3d(vec,gzm,gym,gxm*dof,gzs,gys,gxs*dof,(PetscScalar****)array);CHKERRQ(ierr);
7130729d88SBarry Smith   } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"DMDA dimension not 1, 2, or 3, it is %D\n",dim);
7247c6ae99SBarry Smith   PetscFunctionReturn(0);
7347c6ae99SBarry Smith }
7447c6ae99SBarry Smith 
7547c6ae99SBarry Smith /*@
76aa219208SBarry Smith    DMDAVecRestoreArray - Restores a multiple dimension array obtained with DMDAVecGetArray()
7747c6ae99SBarry Smith 
78d083f849SBarry Smith    Logically collective on da
7947c6ae99SBarry Smith 
8047c6ae99SBarry Smith    Input Parameter:
8147c6ae99SBarry Smith +  da - the distributed array
8247c6ae99SBarry Smith .  vec - the vector, either a vector the same size as one obtained with
83564755cdSBarry Smith          DMCreateGlobalVector() or DMCreateLocalVector()
84e5c84f05SJed Brown -  array - the array, non-NULL pointer is zeroed
8547c6ae99SBarry Smith 
8647c6ae99SBarry Smith   Level: intermediate
8747c6ae99SBarry Smith 
8895452b02SPatrick Sanan   Fortran Notes:
89fdc842d1SBarry Smith     From Fortran use DMDAVecRestoreArayF90()
9047c6ae99SBarry Smith 
91fdc842d1SBarry Smith .seealso: DMDAGetGhostCorners(), DMDAGetCorners(), VecGetArray(), VecRestoreArray(), DMDAVecGetArray(),
92fdc842d1SBarry Smith           DMDAVecGetArrayWrite(), DMDAVecRestoreArrayWrite(), DMDAVecGetArrayRead(), DMDAVecRestoreArrayRead()
9347c6ae99SBarry Smith @*/
947087cfbeSBarry Smith PetscErrorCode  DMDAVecRestoreArray(DM da,Vec vec,void *array)
9547c6ae99SBarry Smith {
9647c6ae99SBarry Smith   PetscErrorCode ierr;
9747c6ae99SBarry Smith   PetscInt       xs,ys,zs,xm,ym,zm,gxs,gys,gzs,gxm,gym,gzm,N,dim,dof;
9847c6ae99SBarry Smith 
9947c6ae99SBarry Smith   PetscFunctionBegin;
100a9a02de4SBarry Smith   PetscValidHeaderSpecificType(da, DM_CLASSID, 1,DMDA);
1016db82c94SMatthew G Knepley   PetscValidHeaderSpecific(vec, VEC_CLASSID, 2);
1026db82c94SMatthew G Knepley   PetscValidPointer(array, 3);
103aa219208SBarry Smith   ierr = DMDAGetCorners(da,&xs,&ys,&zs,&xm,&ym,&zm);CHKERRQ(ierr);
104aa219208SBarry Smith   ierr = DMDAGetGhostCorners(da,&gxs,&gys,&gzs,&gxm,&gym,&gzm);CHKERRQ(ierr);
1051321219cSEthan Coon   ierr = DMDAGetInfo(da,&dim,0,0,0,0,0,0,&dof,0,0,0,0,0);CHKERRQ(ierr);
10647c6ae99SBarry Smith 
10747c6ae99SBarry Smith   /* Handle case where user passes in global vector as opposed to local */
10847c6ae99SBarry Smith   ierr = VecGetLocalSize(vec,&N);CHKERRQ(ierr);
10947c6ae99SBarry Smith   if (N == xm*ym*zm*dof) {
11047c6ae99SBarry Smith     gxm = xm;
11147c6ae99SBarry Smith     gym = ym;
11247c6ae99SBarry Smith     gzm = zm;
11347c6ae99SBarry Smith     gxs = xs;
11447c6ae99SBarry Smith     gys = ys;
11547c6ae99SBarry Smith     gzs = zs;
11630729d88SBarry 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);
11747c6ae99SBarry Smith 
11847c6ae99SBarry Smith   if (dim == 1) {
11947c6ae99SBarry Smith     ierr = VecRestoreArray1d(vec,gxm*dof,gxs*dof,(PetscScalar**)array);CHKERRQ(ierr);
12047c6ae99SBarry Smith   } else if (dim == 2) {
12147c6ae99SBarry Smith     ierr = VecRestoreArray2d(vec,gym,gxm*dof,gys,gxs*dof,(PetscScalar***)array);CHKERRQ(ierr);
12247c6ae99SBarry Smith   } else if (dim == 3) {
12347c6ae99SBarry Smith     ierr = VecRestoreArray3d(vec,gzm,gym,gxm*dof,gzs,gys,gxs*dof,(PetscScalar****)array);CHKERRQ(ierr);
12430729d88SBarry Smith   } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"DMDA dimension not 1, 2, or 3, it is %D\n",dim);
12547c6ae99SBarry Smith   PetscFunctionReturn(0);
12647c6ae99SBarry Smith }
12747c6ae99SBarry Smith 
12847c6ae99SBarry Smith /*@C
129fdc842d1SBarry Smith    DMDAVecGetArrayWrite - Returns a multiple dimension array that shares data with
130fdc842d1SBarry Smith       the underlying vector and is indexed using the global dimensions.
131fdc842d1SBarry Smith 
132fdc842d1SBarry Smith    Logically collective on Vec
133fdc842d1SBarry Smith 
134fdc842d1SBarry Smith    Input Parameter:
135fdc842d1SBarry Smith +  da - the distributed array
136fdc842d1SBarry Smith -  vec - the vector, either a vector the same size as one obtained with DMCreateGlobalVector() or DMCreateLocalVector()
137fdc842d1SBarry Smith 
138fdc842d1SBarry Smith    Output Parameter:
139fdc842d1SBarry Smith .  array - the array
140fdc842d1SBarry Smith 
141fdc842d1SBarry Smith    Notes:
142fdc842d1SBarry Smith     Call DMDAVecRestoreArray() once you have finished accessing the vector entries.
143fdc842d1SBarry Smith 
144fdc842d1SBarry Smith     In C, the indexing is "backwards" from what expects: array[k][j][i] NOT array[i][j][k]!
145fdc842d1SBarry Smith 
146fdc842d1SBarry Smith     If vec is a local vector (obtained with DMCreateLocalVector() etc) then the ghost point locations are accessible. If it is
147fdc842d1SBarry Smith     a global vector then the ghost points are not accessible. Of course with the local vector you will have had to do the
148fdc842d1SBarry Smith 
149fdc842d1SBarry Smith     appropriate DMGlobalToLocalBegin() and DMGlobalToLocalEnd() to have correct values in the ghost locations.
150fdc842d1SBarry Smith 
151fdc842d1SBarry Smith   Fortran Notes:
152fdc842d1SBarry Smith     From Fortran use DMDAVecGetArrayF90() and pass for the array type PetscScalar,pointer :: array(:,...,:) of the appropriate
153fdc842d1SBarry 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
154fdc842d1SBarry 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
155fdc842d1SBarry Smith        array(0:dof-1,xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1) where the values are obtained from
156fdc842d1SBarry Smith        DMDAGetCorners() for a global array or DMDAGetGhostCorners() for a local array. Include petsc/finclude/petscdmda.h90 to access this routine.
157fdc842d1SBarry Smith 
158fdc842d1SBarry Smith   Due to bugs in the compiler DMDAVecGetArrayF90() does not work with gfortran versions before 4.5
159fdc842d1SBarry Smith 
160fdc842d1SBarry Smith   Level: intermediate
161fdc842d1SBarry Smith 
162fdc842d1SBarry Smith   Developer Notes: This has code duplication with DMDAVecGetArray() and DMDAVecGetArrayRead()
163fdc842d1SBarry Smith 
164fdc842d1SBarry Smith .seealso: DMDAGetGhostCorners(), DMDAGetCorners(), VecGetArray(), VecRestoreArray(), DMDAVecRestoreArrayWrite(), DMDAVecRestoreArrayDOF()
165fdc842d1SBarry Smith           DMDAVecGetArrayDOF(), DMDAVecGetArray(), DMDAVecRestoreArray(), DMDAVecGetArrayRead(), DMDAVecRestoreArrayRead()
166fdc842d1SBarry Smith @*/
167fdc842d1SBarry Smith PetscErrorCode  DMDAVecGetArrayWrite(DM da,Vec vec,void *array)
168fdc842d1SBarry Smith {
169fdc842d1SBarry Smith   PetscErrorCode ierr;
170fdc842d1SBarry Smith   PetscInt       xs,ys,zs,xm,ym,zm,gxs,gys,gzs,gxm,gym,gzm,N,dim,dof;
171fdc842d1SBarry Smith 
172fdc842d1SBarry Smith   PetscFunctionBegin;
173fdc842d1SBarry Smith   PetscValidHeaderSpecificType(da, DM_CLASSID, 1,DMDA);
174fdc842d1SBarry Smith   PetscValidHeaderSpecific(vec, VEC_CLASSID, 2);
175fdc842d1SBarry Smith   PetscValidPointer(array, 3);
176*1bb6d2a8SBarry Smith   if (da->localSection) {
177fdc842d1SBarry Smith     ierr = VecGetArrayWrite(vec,(PetscScalar**)array);CHKERRQ(ierr);
178fdc842d1SBarry Smith     PetscFunctionReturn(0);
179fdc842d1SBarry Smith   }
180fdc842d1SBarry Smith   ierr = DMDAGetCorners(da,&xs,&ys,&zs,&xm,&ym,&zm);CHKERRQ(ierr);
181fdc842d1SBarry Smith   ierr = DMDAGetGhostCorners(da,&gxs,&gys,&gzs,&gxm,&gym,&gzm);CHKERRQ(ierr);
182fdc842d1SBarry Smith   ierr = DMDAGetInfo(da,&dim,0,0,0,0,0,0,&dof,0,0,0,0,0);CHKERRQ(ierr);
183fdc842d1SBarry Smith 
184fdc842d1SBarry Smith   /* Handle case where user passes in global vector as opposed to local */
185fdc842d1SBarry Smith   ierr = VecGetLocalSize(vec,&N);CHKERRQ(ierr);
186fdc842d1SBarry Smith   if (N == xm*ym*zm*dof) {
187fdc842d1SBarry Smith     gxm = xm;
188fdc842d1SBarry Smith     gym = ym;
189fdc842d1SBarry Smith     gzm = zm;
190fdc842d1SBarry Smith     gxs = xs;
191fdc842d1SBarry Smith     gys = ys;
192fdc842d1SBarry Smith     gzs = zs;
193fdc842d1SBarry 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);
194fdc842d1SBarry Smith 
195fdc842d1SBarry Smith   if (dim == 1) {
196fdc842d1SBarry Smith     ierr = VecGetArray1dWrite(vec,gxm*dof,gxs*dof,(PetscScalar**)array);CHKERRQ(ierr);
197fdc842d1SBarry Smith   } else if (dim == 2) {
198fdc842d1SBarry Smith     ierr = VecGetArray2dWrite(vec,gym,gxm*dof,gys,gxs*dof,(PetscScalar***)array);CHKERRQ(ierr);
199fdc842d1SBarry Smith   } else if (dim == 3) {
200fdc842d1SBarry Smith     ierr = VecGetArray3dWrite(vec,gzm,gym,gxm*dof,gzs,gys,gxs*dof,(PetscScalar****)array);CHKERRQ(ierr);
201fdc842d1SBarry Smith   } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"DMDA dimension not 1, 2, or 3, it is %D\n",dim);
202fdc842d1SBarry Smith   PetscFunctionReturn(0);
203fdc842d1SBarry Smith }
204fdc842d1SBarry Smith 
205fdc842d1SBarry Smith /*@
206fdc842d1SBarry Smith    DMDAVecRestoreArrayWrite - Restores a multiple dimension array obtained with DMDAVecGetArrayWrite()
207fdc842d1SBarry Smith 
208fdc842d1SBarry Smith    Logically collective on Vec
209fdc842d1SBarry Smith 
210fdc842d1SBarry Smith    Input Parameter:
211fdc842d1SBarry Smith +  da - the distributed array
212fdc842d1SBarry Smith .  vec - the vector, either a vector the same size as one obtained with
213fdc842d1SBarry Smith          DMCreateGlobalVector() or DMCreateLocalVector()
214fdc842d1SBarry Smith -  array - the array, non-NULL pointer is zeroed
215fdc842d1SBarry Smith 
216fdc842d1SBarry Smith   Level: intermediate
217fdc842d1SBarry Smith 
218fdc842d1SBarry Smith   Fortran Notes:
219fdc842d1SBarry Smith     From Fortran use DMDAVecRestoreArayF90()
220fdc842d1SBarry Smith 
221fdc842d1SBarry Smith .seealso: DMDAGetGhostCorners(), DMDAGetCorners(), VecGetArray(), VecRestoreArray(), DMDAVecGetArrayWrite(),
222fdc842d1SBarry Smith           DMDAVecGetArray(), DMDAVecRestoreArray(), DMDAVecGetArrayRead(), DMDAVecRestoreArrayRead()
223fdc842d1SBarry Smith @*/
224fdc842d1SBarry Smith PetscErrorCode  DMDAVecRestoreArrayWrite(DM da,Vec vec,void *array)
225fdc842d1SBarry Smith {
226fdc842d1SBarry Smith   PetscErrorCode ierr;
227fdc842d1SBarry Smith   PetscInt       xs,ys,zs,xm,ym,zm,gxs,gys,gzs,gxm,gym,gzm,N,dim,dof;
228fdc842d1SBarry Smith 
229fdc842d1SBarry Smith   PetscFunctionBegin;
230fdc842d1SBarry Smith   PetscValidHeaderSpecificType(da, DM_CLASSID, 1,DMDA);
231fdc842d1SBarry Smith   PetscValidHeaderSpecific(vec, VEC_CLASSID, 2);
232fdc842d1SBarry Smith   PetscValidPointer(array, 3);
233*1bb6d2a8SBarry Smith   if (da->localSection) {
234fdc842d1SBarry Smith     ierr = VecRestoreArray(vec,(PetscScalar**)array);CHKERRQ(ierr);
235fdc842d1SBarry Smith     PetscFunctionReturn(0);
236fdc842d1SBarry Smith   }
237fdc842d1SBarry Smith   ierr = DMDAGetCorners(da,&xs,&ys,&zs,&xm,&ym,&zm);CHKERRQ(ierr);
238fdc842d1SBarry Smith   ierr = DMDAGetGhostCorners(da,&gxs,&gys,&gzs,&gxm,&gym,&gzm);CHKERRQ(ierr);
239fdc842d1SBarry Smith   ierr = DMDAGetInfo(da,&dim,0,0,0,0,0,0,&dof,0,0,0,0,0);CHKERRQ(ierr);
240fdc842d1SBarry Smith 
241fdc842d1SBarry Smith   /* Handle case where user passes in global vector as opposed to local */
242fdc842d1SBarry Smith   ierr = VecGetLocalSize(vec,&N);CHKERRQ(ierr);
243fdc842d1SBarry Smith   if (N == xm*ym*zm*dof) {
244fdc842d1SBarry Smith     gxm = xm;
245fdc842d1SBarry Smith     gym = ym;
246fdc842d1SBarry Smith     gzm = zm;
247fdc842d1SBarry Smith     gxs = xs;
248fdc842d1SBarry Smith     gys = ys;
249fdc842d1SBarry Smith     gzs = zs;
250fdc842d1SBarry 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);
251fdc842d1SBarry Smith 
252fdc842d1SBarry Smith   if (dim == 1) {
253fdc842d1SBarry Smith     ierr = VecRestoreArray1dWrite(vec,gxm*dof,gxs*dof,(PetscScalar**)array);CHKERRQ(ierr);
254fdc842d1SBarry Smith   } else if (dim == 2) {
255fdc842d1SBarry Smith     ierr = VecRestoreArray2dWrite(vec,gym,gxm*dof,gys,gxs*dof,(PetscScalar***)array);CHKERRQ(ierr);
256fdc842d1SBarry Smith   } else if (dim == 3) {
257fdc842d1SBarry Smith     ierr = VecRestoreArray3dWrite(vec,gzm,gym,gxm*dof,gzs,gys,gxs*dof,(PetscScalar****)array);CHKERRQ(ierr);
258fdc842d1SBarry Smith   } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"DMDA dimension not 1, 2, or 3, it is %D\n",dim);
259fdc842d1SBarry Smith   PetscFunctionReturn(0);
260fdc842d1SBarry Smith }
261fdc842d1SBarry Smith 
262fdc842d1SBarry Smith /*@C
263aa219208SBarry Smith    DMDAVecGetArrayDOF - Returns a multiple dimension array that shares data with
26447c6ae99SBarry Smith       the underlying vector and is indexed using the global dimensions.
26547c6ae99SBarry Smith 
2662ddbf755SMatthew G. Knepley    Logically collective
26747c6ae99SBarry Smith 
26847c6ae99SBarry Smith    Input Parameter:
26947c6ae99SBarry Smith +  da - the distributed array
27047c6ae99SBarry Smith -  vec - the vector, either a vector the same size as one obtained with
271564755cdSBarry Smith          DMCreateGlobalVector() or DMCreateLocalVector()
27247c6ae99SBarry Smith 
27347c6ae99SBarry Smith    Output Parameter:
27447c6ae99SBarry Smith .  array - the array
27547c6ae99SBarry Smith 
27647c6ae99SBarry Smith    Notes:
277aa219208SBarry Smith     Call DMDAVecRestoreArrayDOF() once you have finished accessing the vector entries.
27847c6ae99SBarry Smith 
27947c6ae99SBarry Smith     In C, the indexing is "backwards" from what expects: array[k][j][i][DOF] NOT array[i][j][k][DOF]!
28047c6ae99SBarry Smith 
2811b82215eSBarry Smith     In Fortran 90 you do not need a version of DMDAVecRestoreArrayDOF() just use  DMDAVecRestoreArrayF90() and declare your array with one higher dimension,
2821b82215eSBarry Smith     see src/dm/examples/tutorials/ex11f90.F
2831b82215eSBarry Smith 
28447c6ae99SBarry Smith   Level: intermediate
28547c6ae99SBarry Smith 
286fdc842d1SBarry Smith .seealso: DMDAGetGhostCorners(), DMDAGetCorners(), VecGetArray(), VecRestoreArray(), DMDAVecRestoreArray(), DMDAVecGetArray(), DMDAVecRestoreArrayDOF(),
287fdc842d1SBarry Smith           DMDAVecGetArrayWrite(), DMDAVecRestoreArrayWrite(), DMDAVecGetArrayRead(), DMDAVecRestoreArrayRead()
28847c6ae99SBarry Smith @*/
2897087cfbeSBarry Smith PetscErrorCode  DMDAVecGetArrayDOF(DM da,Vec vec,void *array)
29047c6ae99SBarry Smith {
29147c6ae99SBarry Smith   PetscErrorCode ierr;
29247c6ae99SBarry Smith   PetscInt       xs,ys,zs,xm,ym,zm,gxs,gys,gzs,gxm,gym,gzm,N,dim,dof;
29347c6ae99SBarry Smith 
29447c6ae99SBarry Smith   PetscFunctionBegin;
295aa219208SBarry Smith   ierr = DMDAGetCorners(da,&xs,&ys,&zs,&xm,&ym,&zm);CHKERRQ(ierr);
296aa219208SBarry Smith   ierr = DMDAGetGhostCorners(da,&gxs,&gys,&gzs,&gxm,&gym,&gzm);CHKERRQ(ierr);
2971321219cSEthan Coon   ierr = DMDAGetInfo(da,&dim,0,0,0,0,0,0,&dof,0,0,0,0,0);CHKERRQ(ierr);
29847c6ae99SBarry Smith 
29947c6ae99SBarry Smith   /* Handle case where user passes in global vector as opposed to local */
30047c6ae99SBarry Smith   ierr = VecGetLocalSize(vec,&N);CHKERRQ(ierr);
30147c6ae99SBarry Smith   if (N == xm*ym*zm*dof) {
30247c6ae99SBarry Smith     gxm = xm;
30347c6ae99SBarry Smith     gym = ym;
30447c6ae99SBarry Smith     gzm = zm;
30547c6ae99SBarry Smith     gxs = xs;
30647c6ae99SBarry Smith     gys = ys;
30747c6ae99SBarry Smith     gzs = zs;
30830729d88SBarry 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);
30947c6ae99SBarry Smith 
31047c6ae99SBarry Smith   if (dim == 1) {
31147c6ae99SBarry Smith     ierr = VecGetArray2d(vec,gxm,dof,gxs,0,(PetscScalar***)array);CHKERRQ(ierr);
31247c6ae99SBarry Smith   } else if (dim == 2) {
31347c6ae99SBarry Smith     ierr = VecGetArray3d(vec,gym,gxm,dof,gys,gxs,0,(PetscScalar****)array);CHKERRQ(ierr);
31447c6ae99SBarry Smith   } else if (dim == 3) {
31547c6ae99SBarry Smith     ierr = VecGetArray4d(vec,gzm,gym,gxm,dof,gzs,gys,gxs,0,(PetscScalar*****)array);CHKERRQ(ierr);
31630729d88SBarry Smith   } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"DMDA dimension not 1, 2, or 3, it is %D\n",dim);
31747c6ae99SBarry Smith   PetscFunctionReturn(0);
31847c6ae99SBarry Smith }
31947c6ae99SBarry Smith 
32047c6ae99SBarry Smith /*@
321aa219208SBarry Smith    DMDAVecRestoreArrayDOF - Restores a multiple dimension array obtained with DMDAVecGetArrayDOF()
32247c6ae99SBarry Smith 
3232ddbf755SMatthew G. Knepley    Logically collective
32447c6ae99SBarry Smith 
32547c6ae99SBarry Smith    Input Parameter:
32647c6ae99SBarry Smith +  da - the distributed array
32747c6ae99SBarry Smith .  vec - the vector, either a vector the same size as one obtained with
328564755cdSBarry Smith          DMCreateGlobalVector() or DMCreateLocalVector()
32947c6ae99SBarry Smith -  array - the array
33047c6ae99SBarry Smith 
33147c6ae99SBarry Smith   Level: intermediate
33247c6ae99SBarry Smith 
333fdc842d1SBarry Smith .seealso: DMDAGetGhostCorners(), DMDAGetCorners(), VecGetArray(), VecRestoreArray(), DMDAVecGetArray(), DMDAVecGetArrayDOF(), DMDAVecRestoreArrayDOF(),
334fdc842d1SBarry Smith           DMDAVecGetArrayWrite(), DMDAVecRestoreArrayWrite(), DMDAVecGetArrayRead(), DMDAVecRestoreArrayRead()
33547c6ae99SBarry Smith @*/
3367087cfbeSBarry Smith PetscErrorCode  DMDAVecRestoreArrayDOF(DM da,Vec vec,void *array)
33747c6ae99SBarry Smith {
33847c6ae99SBarry Smith   PetscErrorCode ierr;
33947c6ae99SBarry Smith   PetscInt       xs,ys,zs,xm,ym,zm,gxs,gys,gzs,gxm,gym,gzm,N,dim,dof;
34047c6ae99SBarry Smith 
34147c6ae99SBarry Smith   PetscFunctionBegin;
342aa219208SBarry Smith   ierr = DMDAGetCorners(da,&xs,&ys,&zs,&xm,&ym,&zm);CHKERRQ(ierr);
343aa219208SBarry Smith   ierr = DMDAGetGhostCorners(da,&gxs,&gys,&gzs,&gxm,&gym,&gzm);CHKERRQ(ierr);
3441321219cSEthan Coon   ierr = DMDAGetInfo(da,&dim,0,0,0,0,0,0,&dof,0,0,0,0,0);CHKERRQ(ierr);
34547c6ae99SBarry Smith 
34647c6ae99SBarry Smith   /* Handle case where user passes in global vector as opposed to local */
34747c6ae99SBarry Smith   ierr = VecGetLocalSize(vec,&N);CHKERRQ(ierr);
34847c6ae99SBarry Smith   if (N == xm*ym*zm*dof) {
34947c6ae99SBarry Smith     gxm = xm;
35047c6ae99SBarry Smith     gym = ym;
35147c6ae99SBarry Smith     gzm = zm;
35247c6ae99SBarry Smith     gxs = xs;
35347c6ae99SBarry Smith     gys = ys;
35447c6ae99SBarry Smith     gzs = zs;
35547c6ae99SBarry Smith   }
35647c6ae99SBarry Smith 
35747c6ae99SBarry Smith   if (dim == 1) {
35847c6ae99SBarry Smith     ierr = VecRestoreArray2d(vec,gxm,dof,gxs,0,(PetscScalar***)array);CHKERRQ(ierr);
35947c6ae99SBarry Smith   } else if (dim == 2) {
36047c6ae99SBarry Smith     ierr = VecRestoreArray3d(vec,gym,gxm,dof,gys,gxs,0,(PetscScalar****)array);CHKERRQ(ierr);
36147c6ae99SBarry Smith   } else if (dim == 3) {
36247c6ae99SBarry Smith     ierr = VecRestoreArray4d(vec,gzm,gym,gxm,dof,gzs,gys,gxs,0,(PetscScalar*****)array);CHKERRQ(ierr);
36330729d88SBarry Smith   } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"DMDA dimension not 1, 2, or 3, it is %D\n",dim);
36447c6ae99SBarry Smith   PetscFunctionReturn(0);
36547c6ae99SBarry Smith }
36647c6ae99SBarry Smith 
3675edff71fSBarry Smith /*@C
3685edff71fSBarry Smith    DMDAVecGetArrayRead - Returns a multiple dimension array that shares data with
3695edff71fSBarry Smith       the underlying vector and is indexed using the global dimensions.
3705edff71fSBarry Smith 
3712ddbf755SMatthew G. Knepley    Not collective
3725edff71fSBarry Smith 
3735edff71fSBarry Smith    Input Parameter:
3745edff71fSBarry Smith +  da - the distributed array
3755edff71fSBarry Smith -  vec - the vector, either a vector the same size as one obtained with DMCreateGlobalVector() or DMCreateLocalVector()
3765edff71fSBarry Smith 
3775edff71fSBarry Smith    Output Parameter:
3785edff71fSBarry Smith .  array - the array
3795edff71fSBarry Smith 
3805edff71fSBarry Smith    Notes:
3815edff71fSBarry Smith     Call DMDAVecRestoreArrayRead() once you have finished accessing the vector entries.
3825edff71fSBarry Smith 
3835edff71fSBarry Smith     In C, the indexing is "backwards" from what expects: array[k][j][i] NOT array[i][j][k]!
3845edff71fSBarry Smith 
3855edff71fSBarry Smith     If vec is a local vector (obtained with DMCreateLocalVector() etc) then the ghost point locations are accessible. If it is
3865edff71fSBarry Smith     a global vector then the ghost points are not accessible. Of course with the local vector you will have had to do the
3875edff71fSBarry Smith 
3885edff71fSBarry Smith     appropriate DMGlobalToLocalBegin() and DMGlobalToLocalEnd() to have correct values in the ghost locations.
3895edff71fSBarry Smith 
39095452b02SPatrick Sanan   Fortran Notes:
39195452b02SPatrick Sanan     From Fortran use DMDAVecGetArrayReadF90() and pass for the array type PetscScalar,pointer :: array(:,...,:) of the appropriate
3925edff71fSBarry 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
3935edff71fSBarry 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
3945edff71fSBarry Smith        array(0:dof-1,xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1) where the values are obtained from
395af0996ceSBarry Smith        DMDAGetCorners() for a global array or DMDAGetGhostCorners() for a local array. Include petsc/finclude/petscdmda.h90 to access this routine.
3965edff71fSBarry Smith 
3974ebdaf59SBarry Smith   Due to bugs in the compiler DMDAVecGetArrayReadF90() does not work with gfortran versions before 4.5
3985edff71fSBarry Smith 
3995edff71fSBarry Smith   Level: intermediate
4005edff71fSBarry Smith 
401fdc842d1SBarry Smith .seealso: DMDAGetGhostCorners(), DMDAGetCorners(), VecGetArray(), VecRestoreArray(), DMDAVecRestoreArrayRead(), DMDAVecRestoreArrayDOF()
402fdc842d1SBarry Smith           DMDAVecGetArrayDOF(), DMDAVecGetArray(), DMDAVecRestoreArray(), DMDAVecGetArrayRead(), DMDAVecRestoreArrayRead()
4035edff71fSBarry Smith @*/
4045edff71fSBarry Smith PetscErrorCode  DMDAVecGetArrayRead(DM da,Vec vec,void *array)
4055edff71fSBarry Smith {
4065edff71fSBarry Smith   PetscErrorCode ierr;
4075edff71fSBarry Smith   PetscInt       xs,ys,zs,xm,ym,zm,gxs,gys,gzs,gxm,gym,gzm,N,dim,dof;
4085edff71fSBarry Smith 
4095edff71fSBarry Smith   PetscFunctionBegin;
410a9a02de4SBarry Smith   PetscValidHeaderSpecificType(da, DM_CLASSID, 1,DMDA);
4115edff71fSBarry Smith   PetscValidHeaderSpecific(vec, VEC_CLASSID, 2);
4125edff71fSBarry Smith   PetscValidPointer(array, 3);
4135edff71fSBarry Smith   ierr = DMDAGetCorners(da,&xs,&ys,&zs,&xm,&ym,&zm);CHKERRQ(ierr);
4145edff71fSBarry Smith   ierr = DMDAGetGhostCorners(da,&gxs,&gys,&gzs,&gxm,&gym,&gzm);CHKERRQ(ierr);
4155edff71fSBarry Smith   ierr = DMDAGetInfo(da,&dim,0,0,0,0,0,0,&dof,0,0,0,0,0);CHKERRQ(ierr);
4165edff71fSBarry Smith 
4175edff71fSBarry Smith   /* Handle case where user passes in global vector as opposed to local */
4185edff71fSBarry Smith   ierr = VecGetLocalSize(vec,&N);CHKERRQ(ierr);
4195edff71fSBarry Smith   if (N == xm*ym*zm*dof) {
4205edff71fSBarry Smith     gxm = xm;
4215edff71fSBarry Smith     gym = ym;
4225edff71fSBarry Smith     gzm = zm;
4235edff71fSBarry Smith     gxs = xs;
4245edff71fSBarry Smith     gys = ys;
4255edff71fSBarry Smith     gzs = zs;
4265edff71fSBarry 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);
4275edff71fSBarry Smith 
4285edff71fSBarry Smith   if (dim == 1) {
4295edff71fSBarry Smith     ierr = VecGetArray1dRead(vec,gxm*dof,gxs*dof,(PetscScalar**)array);CHKERRQ(ierr);
4305edff71fSBarry Smith   } else if (dim == 2) {
4315edff71fSBarry Smith     ierr = VecGetArray2dRead(vec,gym,gxm*dof,gys,gxs*dof,(PetscScalar***)array);CHKERRQ(ierr);
4325edff71fSBarry Smith   } else if (dim == 3) {
4335edff71fSBarry Smith     ierr = VecGetArray3dRead(vec,gzm,gym,gxm*dof,gzs,gys,gxs*dof,(PetscScalar****)array);CHKERRQ(ierr);
4345edff71fSBarry Smith   } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"DMDA dimension not 1, 2, or 3, it is %D\n",dim);
4355edff71fSBarry Smith   PetscFunctionReturn(0);
4365edff71fSBarry Smith }
4375edff71fSBarry Smith 
4385edff71fSBarry Smith /*@
4395edff71fSBarry Smith    DMDAVecRestoreArrayRead - Restores a multiple dimension array obtained with DMDAVecGetArrayRead()
4405edff71fSBarry Smith 
4412ddbf755SMatthew G. Knepley    Not collective
4425edff71fSBarry Smith 
4435edff71fSBarry Smith    Input Parameter:
4445edff71fSBarry Smith +  da - the distributed array
4455edff71fSBarry Smith .  vec - the vector, either a vector the same size as one obtained with
4465edff71fSBarry Smith          DMCreateGlobalVector() or DMCreateLocalVector()
4475edff71fSBarry Smith -  array - the array, non-NULL pointer is zeroed
4485edff71fSBarry Smith 
4495edff71fSBarry Smith   Level: intermediate
4505edff71fSBarry Smith 
45195452b02SPatrick Sanan   Fortran Notes:
45295452b02SPatrick Sanan     From Fortran use DMDAVecRestoreArrayReadF90()
4535edff71fSBarry Smith 
454fdc842d1SBarry Smith .seealso: DMDAGetGhostCorners(), DMDAGetCorners(), VecGetArray(), VecRestoreArray(), DMDAVecGetArrayRead(),
455fdc842d1SBarry Smith           DMDAVecGetArray(), DMDAVecRestoreArray(), DMDAVecGetArrayWrite(), DMDAVecRestoreArrayWrite()
4565edff71fSBarry Smith @*/
4575edff71fSBarry Smith PetscErrorCode  DMDAVecRestoreArrayRead(DM da,Vec vec,void *array)
4585edff71fSBarry Smith {
4595edff71fSBarry Smith   PetscErrorCode ierr;
4605edff71fSBarry Smith   PetscInt       xs,ys,zs,xm,ym,zm,gxs,gys,gzs,gxm,gym,gzm,N,dim,dof;
4615edff71fSBarry Smith 
4625edff71fSBarry Smith   PetscFunctionBegin;
463a9a02de4SBarry Smith   PetscValidHeaderSpecificType(da, DM_CLASSID, 1,DMDA);
4645edff71fSBarry Smith   PetscValidHeaderSpecific(vec, VEC_CLASSID, 2);
4655edff71fSBarry Smith   PetscValidPointer(array, 3);
4665edff71fSBarry Smith   ierr = DMDAGetCorners(da,&xs,&ys,&zs,&xm,&ym,&zm);CHKERRQ(ierr);
4675edff71fSBarry Smith   ierr = DMDAGetGhostCorners(da,&gxs,&gys,&gzs,&gxm,&gym,&gzm);CHKERRQ(ierr);
4685edff71fSBarry Smith   ierr = DMDAGetInfo(da,&dim,0,0,0,0,0,0,&dof,0,0,0,0,0);CHKERRQ(ierr);
4695edff71fSBarry Smith 
4705edff71fSBarry Smith   /* Handle case where user passes in global vector as opposed to local */
4715edff71fSBarry Smith   ierr = VecGetLocalSize(vec,&N);CHKERRQ(ierr);
4725edff71fSBarry Smith   if (N == xm*ym*zm*dof) {
4735edff71fSBarry Smith     gxm = xm;
4745edff71fSBarry Smith     gym = ym;
4755edff71fSBarry Smith     gzm = zm;
4765edff71fSBarry Smith     gxs = xs;
4775edff71fSBarry Smith     gys = ys;
4785edff71fSBarry Smith     gzs = zs;
4795edff71fSBarry 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);
4805edff71fSBarry Smith 
4815edff71fSBarry Smith   if (dim == 1) {
4825edff71fSBarry Smith     ierr = VecRestoreArray1dRead(vec,gxm*dof,gxs*dof,(PetscScalar**)array);CHKERRQ(ierr);
4835edff71fSBarry Smith   } else if (dim == 2) {
4845edff71fSBarry Smith     ierr = VecRestoreArray2dRead(vec,gym,gxm*dof,gys,gxs*dof,(PetscScalar***)array);CHKERRQ(ierr);
4855edff71fSBarry Smith   } else if (dim == 3) {
4865edff71fSBarry Smith     ierr = VecRestoreArray3dRead(vec,gzm,gym,gxm*dof,gzs,gys,gxs*dof,(PetscScalar****)array);CHKERRQ(ierr);
4875edff71fSBarry Smith   } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"DMDA dimension not 1, 2, or 3, it is %D\n",dim);
4885edff71fSBarry Smith   PetscFunctionReturn(0);
4895edff71fSBarry Smith }
4905edff71fSBarry Smith 
4915edff71fSBarry Smith /*@C
4925edff71fSBarry Smith    DMDAVecGetArrayDOFRead - Returns a multiple dimension array that shares data with
4935edff71fSBarry Smith       the underlying vector and is indexed using the global dimensions.
4945edff71fSBarry Smith 
4955edff71fSBarry Smith    Not Collective
4965edff71fSBarry Smith 
4975edff71fSBarry Smith    Input Parameter:
4985edff71fSBarry Smith +  da - the distributed array
4995edff71fSBarry Smith -  vec - the vector, either a vector the same size as one obtained with
5005edff71fSBarry Smith          DMCreateGlobalVector() or DMCreateLocalVector()
5015edff71fSBarry Smith 
5025edff71fSBarry Smith    Output Parameter:
5035edff71fSBarry Smith .  array - the array
5045edff71fSBarry Smith 
5055edff71fSBarry Smith    Notes:
5065edff71fSBarry Smith     Call DMDAVecRestoreArrayDOFRead() once you have finished accessing the vector entries.
5075edff71fSBarry Smith 
5085edff71fSBarry Smith     In C, the indexing is "backwards" from what expects: array[k][j][i][DOF] NOT array[i][j][k][DOF]!
5095edff71fSBarry Smith 
5104ebdaf59SBarry Smith     In Fortran 90 you do not need a version of DMDAVecRestoreArrayDOF() just use  DMDAVecRestoreArrayReadF90() and declare your array with one higher dimension,
5115edff71fSBarry Smith     see src/dm/examples/tutorials/ex11f90.F
5125edff71fSBarry Smith 
5135edff71fSBarry Smith   Level: intermediate
5145edff71fSBarry Smith 
515fdc842d1SBarry Smith .seealso: DMDAGetGhostCorners(), DMDAGetCorners(), VecGetArray(), VecRestoreArray(), DMDAVecRestoreArray(), DMDAVecGetArray(), DMDAVecRestoreArrayDOF(),
516fdc842d1SBarry Smith           DMDAVecGetArrayWrite(), DMDAVecRestoreArrayWrite(), DMDAVecGetArrayRead(), DMDAVecRestoreArrayRead()
5175edff71fSBarry Smith @*/
5185edff71fSBarry Smith PetscErrorCode  DMDAVecGetArrayDOFRead(DM da,Vec vec,void *array)
5195edff71fSBarry Smith {
5205edff71fSBarry Smith   PetscErrorCode ierr;
5215edff71fSBarry Smith   PetscInt       xs,ys,zs,xm,ym,zm,gxs,gys,gzs,gxm,gym,gzm,N,dim,dof;
5225edff71fSBarry Smith 
5235edff71fSBarry Smith   PetscFunctionBegin;
5245edff71fSBarry Smith   ierr = DMDAGetCorners(da,&xs,&ys,&zs,&xm,&ym,&zm);CHKERRQ(ierr);
5255edff71fSBarry Smith   ierr = DMDAGetGhostCorners(da,&gxs,&gys,&gzs,&gxm,&gym,&gzm);CHKERRQ(ierr);
5265edff71fSBarry Smith   ierr = DMDAGetInfo(da,&dim,0,0,0,0,0,0,&dof,0,0,0,0,0);CHKERRQ(ierr);
5275edff71fSBarry Smith 
5285edff71fSBarry Smith   /* Handle case where user passes in global vector as opposed to local */
5295edff71fSBarry Smith   ierr = VecGetLocalSize(vec,&N);CHKERRQ(ierr);
5305edff71fSBarry Smith   if (N == xm*ym*zm*dof) {
5315edff71fSBarry Smith     gxm = xm;
5325edff71fSBarry Smith     gym = ym;
5335edff71fSBarry Smith     gzm = zm;
5345edff71fSBarry Smith     gxs = xs;
5355edff71fSBarry Smith     gys = ys;
5365edff71fSBarry Smith     gzs = zs;
5375edff71fSBarry 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);
5385edff71fSBarry Smith 
5395edff71fSBarry Smith   if (dim == 1) {
5405edff71fSBarry Smith     ierr = VecGetArray2dRead(vec,gxm,dof,gxs,0,(PetscScalar***)array);CHKERRQ(ierr);
5415edff71fSBarry Smith   } else if (dim == 2) {
5425edff71fSBarry Smith     ierr = VecGetArray3dRead(vec,gym,gxm,dof,gys,gxs,0,(PetscScalar****)array);CHKERRQ(ierr);
5435edff71fSBarry Smith   } else if (dim == 3) {
5445edff71fSBarry Smith     ierr = VecGetArray4dRead(vec,gzm,gym,gxm,dof,gzs,gys,gxs,0,(PetscScalar*****)array);CHKERRQ(ierr);
5455edff71fSBarry Smith   } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"DMDA dimension not 1, 2, or 3, it is %D\n",dim);
5465edff71fSBarry Smith   PetscFunctionReturn(0);
5475edff71fSBarry Smith }
5485edff71fSBarry Smith 
5495edff71fSBarry Smith /*@
5505edff71fSBarry Smith    DMDAVecRestoreArrayDOFRead - Restores a multiple dimension array obtained with DMDAVecGetArrayDOFRead()
5515edff71fSBarry Smith 
5525edff71fSBarry Smith    Not Collective
5535edff71fSBarry Smith 
5545edff71fSBarry Smith    Input Parameter:
5555edff71fSBarry Smith +  da - the distributed array
5565edff71fSBarry Smith .  vec - the vector, either a vector the same size as one obtained with
5575edff71fSBarry Smith          DMCreateGlobalVector() or DMCreateLocalVector()
5585edff71fSBarry Smith -  array - the array
5595edff71fSBarry Smith 
5605edff71fSBarry Smith   Level: intermediate
5615edff71fSBarry Smith 
562fdc842d1SBarry Smith .seealso: DMDAGetGhostCorners(), DMDAGetCorners(), VecGetArray(), VecRestoreArray(), DMDAVecGetArray(), DMDAVecGetArrayDOF(), DMDAVecRestoreArrayDOF(),
563fdc842d1SBarry Smith           DMDAVecGetArrayWrite(), DMDAVecRestoreArrayWrite(), DMDAVecGetArrayRead(), DMDAVecRestoreArrayRead()
5645edff71fSBarry Smith @*/
5655edff71fSBarry Smith PetscErrorCode  DMDAVecRestoreArrayDOFRead(DM da,Vec vec,void *array)
5665edff71fSBarry Smith {
5675edff71fSBarry Smith   PetscErrorCode ierr;
5685edff71fSBarry Smith   PetscInt       xs,ys,zs,xm,ym,zm,gxs,gys,gzs,gxm,gym,gzm,N,dim,dof;
5695edff71fSBarry Smith 
5705edff71fSBarry Smith   PetscFunctionBegin;
5715edff71fSBarry Smith   ierr = DMDAGetCorners(da,&xs,&ys,&zs,&xm,&ym,&zm);CHKERRQ(ierr);
5725edff71fSBarry Smith   ierr = DMDAGetGhostCorners(da,&gxs,&gys,&gzs,&gxm,&gym,&gzm);CHKERRQ(ierr);
5735edff71fSBarry Smith   ierr = DMDAGetInfo(da,&dim,0,0,0,0,0,0,&dof,0,0,0,0,0);CHKERRQ(ierr);
5745edff71fSBarry Smith 
5755edff71fSBarry Smith   /* Handle case where user passes in global vector as opposed to local */
5765edff71fSBarry Smith   ierr = VecGetLocalSize(vec,&N);CHKERRQ(ierr);
5775edff71fSBarry Smith   if (N == xm*ym*zm*dof) {
5785edff71fSBarry Smith     gxm = xm;
5795edff71fSBarry Smith     gym = ym;
5805edff71fSBarry Smith     gzm = zm;
5815edff71fSBarry Smith     gxs = xs;
5825edff71fSBarry Smith     gys = ys;
5835edff71fSBarry Smith     gzs = zs;
5845edff71fSBarry Smith   }
5855edff71fSBarry Smith 
5865edff71fSBarry Smith   if (dim == 1) {
5875edff71fSBarry Smith     ierr = VecRestoreArray2dRead(vec,gxm,dof,gxs,0,(PetscScalar***)array);CHKERRQ(ierr);
5885edff71fSBarry Smith   } else if (dim == 2) {
5895edff71fSBarry Smith     ierr = VecRestoreArray3dRead(vec,gym,gxm,dof,gys,gxs,0,(PetscScalar****)array);CHKERRQ(ierr);
5905edff71fSBarry Smith   } else if (dim == 3) {
5915edff71fSBarry Smith     ierr = VecRestoreArray4dRead(vec,gzm,gym,gxm,dof,gzs,gys,gxs,0,(PetscScalar*****)array);CHKERRQ(ierr);
5925edff71fSBarry Smith   } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"DMDA dimension not 1, 2, or 3, it is %D\n",dim);
5935edff71fSBarry Smith   PetscFunctionReturn(0);
5945edff71fSBarry Smith }
5955edff71fSBarry Smith 
59647c6ae99SBarry Smith 
59747c6ae99SBarry Smith 
59847c6ae99SBarry Smith 
59947c6ae99SBarry Smith 
60047c6ae99SBarry Smith 
60147c6ae99SBarry Smith 
60247c6ae99SBarry Smith 
60347c6ae99SBarry Smith 
60447c6ae99SBarry Smith 
60547c6ae99SBarry Smith 
60647c6ae99SBarry Smith 
60747c6ae99SBarry Smith 
608