xref: /petsc/src/dm/impls/da/dagetarray.c (revision f66eea085cceefc5191b4b3d61f096e7c3d8e689)
1 
2 #include <petsc-private/dmdaimpl.h>    /*I   "petscdmda.h"   I*/
3 
4 #undef __FUNCT__
5 #define __FUNCT__ "DMDAVecGetArray"
6 /*@C
7    DMDAVecGetArray - Returns a multiple dimension array that shares data with
8       the underlying vector and is indexed using the global dimensions.
9 
10    Collective on Vec
11 
12    Input Parameter:
13 +  da - the distributed array
14 -  vec - the vector, either a vector the same size as one obtained with DMCreateGlobalVector() or DMCreateLocalVector()
15 
16    Output Parameter:
17 .  array - the array
18 
19    Notes:
20     Call DMDAVecRestoreArray() once you have finished accessing the vector entries.
21 
22     In C, the indexing is "backwards" from what expects: array[k][j][i] NOT array[i][j][k]!
23 
24     If vec is a local vector (obtained with DMCreateLocalVector() etc) then the ghost point locations are accessible. If it is
25     a global vector then the ghost points are not accessible. Of course with the local vector you will have had to do the
26 
27     appropriate DMGlobalToLocalBegin() and DMGlobalToLocalEnd() to have correct values in the ghost locations.
28 
29   Fortran Notes: From Fortran use DMDAVecGetArrayF90() and pass for the array type PetscScalar,pointer :: array(:,...,:) of the appropriate
30        dimension. For a DMDA created with a dof of 1 use the dimension of the DMDA, for a DMDA created with a dof greater than 1 use one more than the
31        dimension of the DMDA. The order of the indices is array(xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1) (when dof is 1) otherwise
32        array(0:dof-1,xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1) where the values are obtained from
33        DMDAGetCorners() for a global array or DMDAGetGhostCorners() for a local array. Include finclude/petscdmda.h90 to access this routine.
34 
35   Due to bugs in the compiler DMDAVecGetArrayF90() does not work with gfortran versions before 4.5
36 
37   Level: intermediate
38 
39 .keywords: distributed array, get, corners, nodes, local indices, coordinates
40 
41 .seealso: DMDAGetGhostCorners(), DMDAGetCorners(), VecGetArray(), VecRestoreArray(), DMDAVecRestoreArray(), DMDAVecRestoreArrayDOF()
42           DMDAVecGetArrayDOF()
43 @*/
44 PetscErrorCode  DMDAVecGetArray(DM da,Vec vec,void *array)
45 {
46   PetscErrorCode ierr;
47   PetscInt       xs,ys,zs,xm,ym,zm,gxs,gys,gzs,gxm,gym,gzm,N,dim,dof;
48 
49   PetscFunctionBegin;
50   PetscValidHeaderSpecific(da, DM_CLASSID, 1);
51   PetscValidHeaderSpecific(vec, VEC_CLASSID, 2);
52   PetscValidPointer(array, 3);
53   if (da->defaultSection) {
54     ierr = VecGetArray(vec,(PetscScalar**)array);CHKERRQ(ierr);
55     PetscFunctionReturn(0);
56   }
57   ierr = DMDAGetCorners(da,&xs,&ys,&zs,&xm,&ym,&zm);CHKERRQ(ierr);
58   ierr = DMDAGetGhostCorners(da,&gxs,&gys,&gzs,&gxm,&gym,&gzm);CHKERRQ(ierr);
59   ierr = DMDAGetInfo(da,&dim,0,0,0,0,0,0,&dof,0,0,0,0,0);CHKERRQ(ierr);
60 
61   /* Handle case where user passes in global vector as opposed to local */
62   ierr = VecGetLocalSize(vec,&N);CHKERRQ(ierr);
63   if (N == xm*ym*zm*dof) {
64     gxm = xm;
65     gym = ym;
66     gzm = zm;
67     gxs = xs;
68     gys = ys;
69     gzs = zs;
70   } else if (N != gxm*gym*gzm*dof) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Vector local size %D is not compatible with DMDA local sizes %D %D\n",N,xm*ym*zm*dof,gxm*gym*gzm*dof);
71 
72   if (dim == 1) {
73     ierr = VecGetArray1d(vec,gxm*dof,gxs*dof,(PetscScalar**)array);CHKERRQ(ierr);
74   } else if (dim == 2) {
75     ierr = VecGetArray2d(vec,gym,gxm*dof,gys,gxs*dof,(PetscScalar***)array);CHKERRQ(ierr);
76   } else if (dim == 3) {
77     ierr = VecGetArray3d(vec,gzm,gym,gxm*dof,gzs,gys,gxs*dof,(PetscScalar****)array);CHKERRQ(ierr);
78   } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"DMDA dimension not 1, 2, or 3, it is %D\n",dim);
79   PetscFunctionReturn(0);
80 }
81 
82 #undef __FUNCT__
83 #define __FUNCT__ "DMDAVecRestoreArray"
84 /*@
85    DMDAVecRestoreArray - Restores a multiple dimension array obtained with DMDAVecGetArray()
86 
87    Collective on Vec
88 
89    Input Parameter:
90 +  da - the distributed array
91 .  vec - the vector, either a vector the same size as one obtained with
92          DMCreateGlobalVector() or DMCreateLocalVector()
93 -  array - the array, non-NULL pointer is zeroed
94 
95   Level: intermediate
96 
97   Fortran Notes: From Fortran use DMDAVecRestoreArrayF90()
98 
99 .keywords: distributed array, get, corners, nodes, local indices, coordinates
100 
101 .seealso: DMDAGetGhostCorners(), DMDAGetCorners(), VecGetArray(), VecRestoreArray(), DMDAVecGetArray()
102 @*/
103 PetscErrorCode  DMDAVecRestoreArray(DM da,Vec vec,void *array)
104 {
105   PetscErrorCode ierr;
106   PetscInt       xs,ys,zs,xm,ym,zm,gxs,gys,gzs,gxm,gym,gzm,N,dim,dof;
107 
108   PetscFunctionBegin;
109   PetscValidHeaderSpecific(da, DM_CLASSID, 1);
110   PetscValidHeaderSpecific(vec, VEC_CLASSID, 2);
111   PetscValidPointer(array, 3);
112   if (da->defaultSection) {
113     ierr = VecRestoreArray(vec,(PetscScalar**)array);CHKERRQ(ierr);
114     PetscFunctionReturn(0);
115   }
116   ierr = DMDAGetCorners(da,&xs,&ys,&zs,&xm,&ym,&zm);CHKERRQ(ierr);
117   ierr = DMDAGetGhostCorners(da,&gxs,&gys,&gzs,&gxm,&gym,&gzm);CHKERRQ(ierr);
118   ierr = DMDAGetInfo(da,&dim,0,0,0,0,0,0,&dof,0,0,0,0,0);CHKERRQ(ierr);
119 
120   /* Handle case where user passes in global vector as opposed to local */
121   ierr = VecGetLocalSize(vec,&N);CHKERRQ(ierr);
122   if (N == xm*ym*zm*dof) {
123     gxm = xm;
124     gym = ym;
125     gzm = zm;
126     gxs = xs;
127     gys = ys;
128     gzs = zs;
129   } else if (N != gxm*gym*gzm*dof) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Vector local size %D is not compatible with DMDA local sizes %D %D\n",N,xm*ym*zm*dof,gxm*gym*gzm*dof);
130 
131   if (dim == 1) {
132     ierr = VecRestoreArray1d(vec,gxm*dof,gxs*dof,(PetscScalar**)array);CHKERRQ(ierr);
133   } else if (dim == 2) {
134     ierr = VecRestoreArray2d(vec,gym,gxm*dof,gys,gxs*dof,(PetscScalar***)array);CHKERRQ(ierr);
135   } else if (dim == 3) {
136     ierr = VecRestoreArray3d(vec,gzm,gym,gxm*dof,gzs,gys,gxs*dof,(PetscScalar****)array);CHKERRQ(ierr);
137   } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"DMDA dimension not 1, 2, or 3, it is %D\n",dim);
138   PetscFunctionReturn(0);
139 }
140 
141 #undef __FUNCT__
142 #define __FUNCT__ "DMDAVecGetArrayDOF"
143 /*@C
144    DMDAVecGetArrayDOF - Returns a multiple dimension array that shares data with
145       the underlying vector and is indexed using the global dimensions.
146 
147    Not Collective
148 
149    Input Parameter:
150 +  da - the distributed array
151 -  vec - the vector, either a vector the same size as one obtained with
152          DMCreateGlobalVector() or DMCreateLocalVector()
153 
154    Output Parameter:
155 .  array - the array
156 
157    Notes:
158     Call DMDAVecRestoreArrayDOF() once you have finished accessing the vector entries.
159 
160     In C, the indexing is "backwards" from what expects: array[k][j][i][DOF] NOT array[i][j][k][DOF]!
161 
162     In Fortran 90 you do not need a version of DMDAVecRestoreArrayDOF() just use  DMDAVecRestoreArrayF90() and declare your array with one higher dimension,
163     see src/dm/examples/tutorials/ex11f90.F
164 
165   Level: intermediate
166 
167 .keywords: distributed array, get, corners, nodes, local indices, coordinates
168 
169 .seealso: DMDAGetGhostCorners(), DMDAGetCorners(), VecGetArray(), VecRestoreArray(), DMDAVecRestoreArray(), DMDAVecGetArray(), DMDAVecRestoreArrayDOF()
170 @*/
171 PetscErrorCode  DMDAVecGetArrayDOF(DM da,Vec vec,void *array)
172 {
173   PetscErrorCode ierr;
174   PetscInt       xs,ys,zs,xm,ym,zm,gxs,gys,gzs,gxm,gym,gzm,N,dim,dof;
175 
176   PetscFunctionBegin;
177   ierr = DMDAGetCorners(da,&xs,&ys,&zs,&xm,&ym,&zm);CHKERRQ(ierr);
178   ierr = DMDAGetGhostCorners(da,&gxs,&gys,&gzs,&gxm,&gym,&gzm);CHKERRQ(ierr);
179   ierr = DMDAGetInfo(da,&dim,0,0,0,0,0,0,&dof,0,0,0,0,0);CHKERRQ(ierr);
180 
181   /* Handle case where user passes in global vector as opposed to local */
182   ierr = VecGetLocalSize(vec,&N);CHKERRQ(ierr);
183   if (N == xm*ym*zm*dof) {
184     gxm = xm;
185     gym = ym;
186     gzm = zm;
187     gxs = xs;
188     gys = ys;
189     gzs = zs;
190   } else if (N != gxm*gym*gzm*dof) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Vector local size %D is not compatible with DMDA local sizes %D %D\n",N,xm*ym*zm*dof,gxm*gym*gzm*dof);
191 
192   if (dim == 1) {
193     ierr = VecGetArray2d(vec,gxm,dof,gxs,0,(PetscScalar***)array);CHKERRQ(ierr);
194   } else if (dim == 2) {
195     ierr = VecGetArray3d(vec,gym,gxm,dof,gys,gxs,0,(PetscScalar****)array);CHKERRQ(ierr);
196   } else if (dim == 3) {
197     ierr = VecGetArray4d(vec,gzm,gym,gxm,dof,gzs,gys,gxs,0,(PetscScalar*****)array);CHKERRQ(ierr);
198   } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"DMDA dimension not 1, 2, or 3, it is %D\n",dim);
199   PetscFunctionReturn(0);
200 }
201 
202 #undef __FUNCT__
203 #define __FUNCT__ "DMDAVecRestoreArrayDOF"
204 /*@
205    DMDAVecRestoreArrayDOF - Restores a multiple dimension array obtained with DMDAVecGetArrayDOF()
206 
207    Not Collective
208 
209    Input Parameter:
210 +  da - the distributed array
211 .  vec - the vector, either a vector the same size as one obtained with
212          DMCreateGlobalVector() or DMCreateLocalVector()
213 -  array - the array
214 
215   Level: intermediate
216 
217 .keywords: distributed array, get, corners, nodes, local indices, coordinates
218 
219 .seealso: DMDAGetGhostCorners(), DMDAGetCorners(), VecGetArray(), VecRestoreArray(), DMDAVecGetArray(), DMDAVecGetArrayDOF(), DMDAVecRestoreArrayDOF()
220 @*/
221 PetscErrorCode  DMDAVecRestoreArrayDOF(DM da,Vec vec,void *array)
222 {
223   PetscErrorCode ierr;
224   PetscInt       xs,ys,zs,xm,ym,zm,gxs,gys,gzs,gxm,gym,gzm,N,dim,dof;
225 
226   PetscFunctionBegin;
227   ierr = DMDAGetCorners(da,&xs,&ys,&zs,&xm,&ym,&zm);CHKERRQ(ierr);
228   ierr = DMDAGetGhostCorners(da,&gxs,&gys,&gzs,&gxm,&gym,&gzm);CHKERRQ(ierr);
229   ierr = DMDAGetInfo(da,&dim,0,0,0,0,0,0,&dof,0,0,0,0,0);CHKERRQ(ierr);
230 
231   /* Handle case where user passes in global vector as opposed to local */
232   ierr = VecGetLocalSize(vec,&N);CHKERRQ(ierr);
233   if (N == xm*ym*zm*dof) {
234     gxm = xm;
235     gym = ym;
236     gzm = zm;
237     gxs = xs;
238     gys = ys;
239     gzs = zs;
240   }
241 
242   if (dim == 1) {
243     ierr = VecRestoreArray2d(vec,gxm,dof,gxs,0,(PetscScalar***)array);CHKERRQ(ierr);
244   } else if (dim == 2) {
245     ierr = VecRestoreArray3d(vec,gym,gxm,dof,gys,gxs,0,(PetscScalar****)array);CHKERRQ(ierr);
246   } else if (dim == 3) {
247     ierr = VecRestoreArray4d(vec,gzm,gym,gxm,dof,gzs,gys,gxs,0,(PetscScalar*****)array);CHKERRQ(ierr);
248   } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"DMDA dimension not 1, 2, or 3, it is %D\n",dim);
249   PetscFunctionReturn(0);
250 }
251 
252 
253 
254 
255 
256 
257 
258 
259 
260 
261 
262 
263 
264