Actual source code: dagetarray.c

petsc-master 2015-01-31
Report Typos and Errors
  2: #include <petsc-private/dmdaimpl.h>    /*I   "petscdmda.h"   I*/

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

 10:    Collective on Vec

 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()

 16:    Output Parameter:
 17: .  array - the array

 19:    Notes:
 20:     Call DMDAVecRestoreArray() once you have finished accessing the vector entries.

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

 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

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

 29:   Fortran Notes: From Fortran use DMDAVecGetArrayF90() and pass for the array type PetscScalar,pointer :: array(:,...,:) of the appropriate
 30:        dimension. For a DMDA created with a dof of 1 use the dimension of the DMDA, for a DMDA created with a dof greater than 1 use one more than the
 31:        dimension of the DMDA. The order of the indices is array(xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1) (when dof is 1) otherwise
 32:        array(0:dof-1,xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1) where the values are obtained from
 33:        DMDAGetCorners() for a global array or DMDAGetGhostCorners() for a local array. Include petsc-finclude/petscdmda.h90 to access this routine.

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

 37:   Level: intermediate

 39: .keywords: distributed array, get, corners, nodes, local indices, coordinates

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

 53:   if (da->defaultSection) {
 54:     VecGetArray(vec,(PetscScalar**)array);
 55:     return(0);
 56:   }
 57:   DMDAGetCorners(da,&xs,&ys,&zs,&xm,&ym,&zm);
 58:   DMDAGetGhostCorners(da,&gxs,&gys,&gzs,&gxm,&gym,&gzm);
 59:   DMDAGetInfo(da,&dim,0,0,0,0,0,0,&dof,0,0,0,0,0);

 61:   /* Handle case where user passes in global vector as opposed to local */
 62:   VecGetLocalSize(vec,&N);
 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);

 72:   if (dim == 1) {
 73:     VecGetArray1d(vec,gxm*dof,gxs*dof,(PetscScalar**)array);
 74:   } else if (dim == 2) {
 75:     VecGetArray2d(vec,gym,gxm*dof,gys,gxs*dof,(PetscScalar***)array);
 76:   } else if (dim == 3) {
 77:     VecGetArray3d(vec,gzm,gym,gxm*dof,gzs,gys,gxs*dof,(PetscScalar****)array);
 78:   } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"DMDA dimension not 1, 2, or 3, it is %D\n",dim);
 79:   return(0);
 80: }

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

 87:    Collective on Vec

 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

 95:   Level: intermediate

 97:   Fortran Notes: From Fortran use DMDAVecRestoreArrayF90()

 99: .keywords: distributed array, get, corners, nodes, local indices, coordinates

101: .seealso: DMDAGetGhostCorners(), DMDAGetCorners(), VecGetArray(), VecRestoreArray(), DMDAVecGetArray()
102: @*/
103: PetscErrorCode  DMDAVecRestoreArray(DM da,Vec vec,void *array)
104: {
106:   PetscInt       xs,ys,zs,xm,ym,zm,gxs,gys,gzs,gxm,gym,gzm,N,dim,dof;

112:   if (da->defaultSection) {
113:     VecRestoreArray(vec,(PetscScalar**)array);
114:     return(0);
115:   }
116:   DMDAGetCorners(da,&xs,&ys,&zs,&xm,&ym,&zm);
117:   DMDAGetGhostCorners(da,&gxs,&gys,&gzs,&gxm,&gym,&gzm);
118:   DMDAGetInfo(da,&dim,0,0,0,0,0,0,&dof,0,0,0,0,0);

120:   /* Handle case where user passes in global vector as opposed to local */
121:   VecGetLocalSize(vec,&N);
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);

131:   if (dim == 1) {
132:     VecRestoreArray1d(vec,gxm*dof,gxs*dof,(PetscScalar**)array);
133:   } else if (dim == 2) {
134:     VecRestoreArray2d(vec,gym,gxm*dof,gys,gxs*dof,(PetscScalar***)array);
135:   } else if (dim == 3) {
136:     VecRestoreArray3d(vec,gzm,gym,gxm*dof,gzs,gys,gxs*dof,(PetscScalar****)array);
137:   } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"DMDA dimension not 1, 2, or 3, it is %D\n",dim);
138:   return(0);
139: }

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

147:    Not Collective

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()

154:    Output Parameter:
155: .  array - the array

157:    Notes:
158:     Call DMDAVecRestoreArrayDOF() once you have finished accessing the vector entries.

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

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

165:   Level: intermediate

167: .keywords: distributed array, get, corners, nodes, local indices, coordinates

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

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

181:   /* Handle case where user passes in global vector as opposed to local */
182:   VecGetLocalSize(vec,&N);
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);

192:   if (dim == 1) {
193:     VecGetArray2d(vec,gxm,dof,gxs,0,(PetscScalar***)array);
194:   } else if (dim == 2) {
195:     VecGetArray3d(vec,gym,gxm,dof,gys,gxs,0,(PetscScalar****)array);
196:   } else if (dim == 3) {
197:     VecGetArray4d(vec,gzm,gym,gxm,dof,gzs,gys,gxs,0,(PetscScalar*****)array);
198:   } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"DMDA dimension not 1, 2, or 3, it is %D\n",dim);
199:   return(0);
200: }

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

207:    Not Collective

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

215:   Level: intermediate

217: .keywords: distributed array, get, corners, nodes, local indices, coordinates

219: .seealso: DMDAGetGhostCorners(), DMDAGetCorners(), VecGetArray(), VecRestoreArray(), DMDAVecGetArray(), DMDAVecGetArrayDOF(), DMDAVecRestoreArrayDOF()
220: @*/
221: PetscErrorCode  DMDAVecRestoreArrayDOF(DM da,Vec vec,void *array)
222: {
224:   PetscInt       xs,ys,zs,xm,ym,zm,gxs,gys,gzs,gxm,gym,gzm,N,dim,dof;

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

231:   /* Handle case where user passes in global vector as opposed to local */
232:   VecGetLocalSize(vec,&N);
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:   }

242:   if (dim == 1) {
243:     VecRestoreArray2d(vec,gxm,dof,gxs,0,(PetscScalar***)array);
244:   } else if (dim == 2) {
245:     VecRestoreArray3d(vec,gym,gxm,dof,gys,gxs,0,(PetscScalar****)array);
246:   } else if (dim == 3) {
247:     VecRestoreArray4d(vec,gzm,gym,gxm,dof,gzs,gys,gxs,0,(PetscScalar*****)array);
248:   } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"DMDA dimension not 1, 2, or 3, it is %D\n",dim);
249:   return(0);
250: }