xref: /petsc/src/dm/impls/da/dagetarray.c (revision 53c0d4ae618d507ffd9793a3bdcbc009f3c9f497)
147c6ae99SBarry Smith 
2af0996ceSBarry Smith #include <petsc/private/dmdaimpl.h> /*I   "petscdmda.h"   I*/
347c6ae99SBarry Smith 
40f99b6f4SBarry Smith /*MC
50f99b6f4SBarry Smith     DMDAVecGetArrayF90 - check Fortran Notes at `DMDAVecGetArray()`
60f99b6f4SBarry Smith M*/
70f99b6f4SBarry Smith 
847c6ae99SBarry Smith /*@C
9aa219208SBarry Smith    DMDAVecGetArray - Returns a multiple dimension array that shares data with
1047c6ae99SBarry Smith       the underlying vector and is indexed using the global dimensions.
1147c6ae99SBarry Smith 
12d083f849SBarry Smith    Logically collective on da
1347c6ae99SBarry Smith 
14d8d19677SJose E. Roman    Input Parameters:
1547c6ae99SBarry Smith +  da - the distributed array
16dce8aebaSBarry Smith -  vec - the vector, either a vector the same size as one obtained with `DMCreateGlobalVector()` or `DMCreateLocalVector()`
1747c6ae99SBarry Smith 
1847c6ae99SBarry Smith    Output Parameter:
1947c6ae99SBarry Smith .  array - the array
2047c6ae99SBarry Smith 
21dce8aebaSBarry Smith   Level: intermediate
22dce8aebaSBarry Smith 
2347c6ae99SBarry Smith    Notes:
24dce8aebaSBarry Smith     Call `DMDAVecRestoreArray()` once you have finished accessing the vector entries.
2547c6ae99SBarry Smith 
2647c6ae99SBarry Smith     In C, the indexing is "backwards" from what expects: array[k][j][i] NOT array[i][j][k]!
2747c6ae99SBarry Smith 
287e57d48aSBarry Smith     If vec is a local vector (obtained with DMCreateLocalVector() etc) then the ghost point locations are accessible. If it is
297e57d48aSBarry Smith     a global vector then the ghost points are not accessible. Of course with the local vector you will have had to do the
3047c6ae99SBarry Smith 
31dce8aebaSBarry Smith     appropriate `DMGlobalToLocalBegin()` and `DMGlobalToLocalEnd()` to have correct values in the ghost locations.
3247c6ae99SBarry Smith 
3395452b02SPatrick Sanan   Fortran Notes:
340f99b6f4SBarry Smith   Use `DMDAVecGetArrayF90()` and pass for the array type `PetscScalar`,pointer :: array(:,...,:) of the appropriate
35dce8aebaSBarry 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
360f99b6f4SBarry Smith   dimension of the `DMDA`.
3747c6ae99SBarry Smith 
380f99b6f4SBarry Smith   The order of the indices is array(xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1) (when dof is 1) otherwise
390f99b6f4SBarry Smith   array(0:dof-1,xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1) where the values are obtained from
400f99b6f4SBarry Smith   `DMDAGetCorners()` for a global array or `DMDAGetGhostCorners()` for a local array.
4147c6ae99SBarry Smith 
42dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecRestoreArray()`, `DMDAVecRestoreArrayDOF()`
43db781477SPatrick Sanan           `DMDAVecGetArrayDOF()`, `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()`,
44db781477SPatrick Sanan           `DMStagVecGetArray()`
4547c6ae99SBarry Smith @*/
46d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAVecGetArray(DM da, Vec vec, void *array)
47d71ae5a4SJacob Faibussowitsch {
4847c6ae99SBarry Smith   PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof;
4947c6ae99SBarry Smith 
5047c6ae99SBarry Smith   PetscFunctionBegin;
51a9a02de4SBarry Smith   PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA);
526db82c94SMatthew G Knepley   PetscValidHeaderSpecific(vec, VEC_CLASSID, 2);
536db82c94SMatthew G Knepley   PetscValidPointer(array, 3);
549566063dSJacob Faibussowitsch   PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm));
559566063dSJacob Faibussowitsch   PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm));
569566063dSJacob Faibussowitsch   PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL));
5747c6ae99SBarry Smith 
5847c6ae99SBarry Smith   /* Handle case where user passes in global vector as opposed to local */
599566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(vec, &N));
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;
6763a3b9bcSJacob Faibussowitsch   } else PetscCheck(N == gxm * gym * gzm * dof, PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Vector local size %" PetscInt_FMT " is not compatible with DMDA local sizes %" PetscInt_FMT " %" PetscInt_FMT, N, xm * ym * zm * dof, gxm * gym * gzm * dof);
6847c6ae99SBarry Smith 
6947c6ae99SBarry Smith   if (dim == 1) {
709566063dSJacob Faibussowitsch     PetscCall(VecGetArray1d(vec, gxm * dof, gxs * dof, (PetscScalar **)array));
7147c6ae99SBarry Smith   } else if (dim == 2) {
729566063dSJacob Faibussowitsch     PetscCall(VecGetArray2d(vec, gym, gxm * dof, gys, gxs * dof, (PetscScalar ***)array));
7347c6ae99SBarry Smith   } else if (dim == 3) {
749566063dSJacob Faibussowitsch     PetscCall(VecGetArray3d(vec, gzm, gym, gxm * dof, gzs, gys, gxs * dof, (PetscScalar ****)array));
7563a3b9bcSJacob Faibussowitsch   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim);
763ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7747c6ae99SBarry Smith }
7847c6ae99SBarry Smith 
790f99b6f4SBarry Smith /*MC
800f99b6f4SBarry Smith     DMDAVecRestoreArrayF90 - check Fortran Notes at `DMDAVecRestoreArray()`
81*53c0d4aeSBarry Smith 
82*53c0d4aeSBarry Smith     Level: intermediate
830f99b6f4SBarry Smith M*/
840f99b6f4SBarry Smith 
8547c6ae99SBarry Smith /*@
86dce8aebaSBarry Smith    DMDAVecRestoreArray - Restores a multiple dimension array obtained with `DMDAVecGetArray()`
8747c6ae99SBarry Smith 
88d083f849SBarry Smith    Logically collective on da
8947c6ae99SBarry Smith 
90d8d19677SJose E. Roman    Input Parameters:
9147c6ae99SBarry Smith +  da - the distributed array
9247c6ae99SBarry Smith .  vec - the vector, either a vector the same size as one obtained with
930f99b6f4SBarry Smith          `DMCreateGlobalVector()` or `DMCreateLocalVector()`
94e5c84f05SJed Brown -  array - the array, non-NULL pointer is zeroed
9547c6ae99SBarry Smith 
9647c6ae99SBarry Smith   Level: intermediate
9747c6ae99SBarry Smith 
98dce8aebaSBarry Smith   Fortran Note:
99dce8aebaSBarry Smith   From Fortran use `DMDAVecRestoreArayF90()`
10047c6ae99SBarry Smith 
1010f99b6f4SBarry Smith .seealso: `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `DMDAVecRestoreArayF90()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecGetArray()`,
102db781477SPatrick Sanan           `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()`,
103db781477SPatrick Sanan           `DMDStagVecRestoreArray()`
10447c6ae99SBarry Smith @*/
105d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAVecRestoreArray(DM da, Vec vec, void *array)
106d71ae5a4SJacob Faibussowitsch {
10747c6ae99SBarry Smith   PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof;
10847c6ae99SBarry Smith 
10947c6ae99SBarry Smith   PetscFunctionBegin;
110a9a02de4SBarry Smith   PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA);
1116db82c94SMatthew G Knepley   PetscValidHeaderSpecific(vec, VEC_CLASSID, 2);
1126db82c94SMatthew G Knepley   PetscValidPointer(array, 3);
1139566063dSJacob Faibussowitsch   PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm));
1149566063dSJacob Faibussowitsch   PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm));
1159566063dSJacob Faibussowitsch   PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL));
11647c6ae99SBarry Smith 
11747c6ae99SBarry Smith   /* Handle case where user passes in global vector as opposed to local */
1189566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(vec, &N));
11947c6ae99SBarry Smith   if (N == xm * ym * zm * dof) {
12047c6ae99SBarry Smith     gxm = xm;
12147c6ae99SBarry Smith     gym = ym;
12247c6ae99SBarry Smith     gzm = zm;
12347c6ae99SBarry Smith     gxs = xs;
12447c6ae99SBarry Smith     gys = ys;
12547c6ae99SBarry Smith     gzs = zs;
12663a3b9bcSJacob Faibussowitsch   } else PetscCheck(N == gxm * gym * gzm * dof, PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Vector local size %" PetscInt_FMT " is not compatible with DMDA local sizes %" PetscInt_FMT " %" PetscInt_FMT, N, xm * ym * zm * dof, gxm * gym * gzm * dof);
12747c6ae99SBarry Smith 
12847c6ae99SBarry Smith   if (dim == 1) {
1299566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray1d(vec, gxm * dof, gxs * dof, (PetscScalar **)array));
13047c6ae99SBarry Smith   } else if (dim == 2) {
1319566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray2d(vec, gym, gxm * dof, gys, gxs * dof, (PetscScalar ***)array));
13247c6ae99SBarry Smith   } else if (dim == 3) {
1339566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray3d(vec, gzm, gym, gxm * dof, gzs, gys, gxs * dof, (PetscScalar ****)array));
13463a3b9bcSJacob Faibussowitsch   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim);
1353ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
13647c6ae99SBarry Smith }
13747c6ae99SBarry Smith 
1380f99b6f4SBarry Smith /*MC
1390f99b6f4SBarry Smith     DMDAVecGetArrayWriteF90 - check Fortran Notes at `DMDAVecGetArrayWrite()`
140*53c0d4aeSBarry Smith 
141*53c0d4aeSBarry Smith     Level: intermediate
1420f99b6f4SBarry Smith M*/
1430f99b6f4SBarry Smith 
14447c6ae99SBarry Smith /*@C
145fdc842d1SBarry Smith    DMDAVecGetArrayWrite - Returns a multiple dimension array that shares data with
146fdc842d1SBarry Smith       the underlying vector and is indexed using the global dimensions.
147fdc842d1SBarry Smith 
148fdc842d1SBarry Smith    Logically collective on Vec
149fdc842d1SBarry Smith 
150d8d19677SJose E. Roman    Input Parameters:
151fdc842d1SBarry Smith +  da - the distributed array
152dce8aebaSBarry Smith -  vec - the vector, either a vector the same size as one obtained with `DMCreateGlobalVector()` or `DMCreateLocalVector()`
153fdc842d1SBarry Smith 
154fdc842d1SBarry Smith    Output Parameter:
155fdc842d1SBarry Smith .  array - the array
156fdc842d1SBarry Smith 
157dce8aebaSBarry Smith   Level: intermediate
158dce8aebaSBarry Smith 
159fdc842d1SBarry Smith    Notes:
160dce8aebaSBarry Smith     Call `DMDAVecRestoreArray()` once you have finished accessing the vector entries.
161fdc842d1SBarry Smith 
162fdc842d1SBarry Smith     In C, the indexing is "backwards" from what expects: array[k][j][i] NOT array[i][j][k]!
163fdc842d1SBarry Smith 
164dce8aebaSBarry Smith     If vec is a local vector (obtained with `DMCreateLocalVector()` etc) then the ghost point locations are accessible. If it is
165fdc842d1SBarry Smith     a global vector then the ghost points are not accessible. Of course with the local vector you will have had to do the
166dce8aebaSBarry Smith     appropriate `DMGlobalToLocalBegin()` and `DMGlobalToLocalEnd()` to have correct values in the ghost locations.
167fdc842d1SBarry Smith 
168fdc842d1SBarry Smith    Fortran Notes:
1690f99b6f4SBarry Smith    From Fortran use `DMDAVecGetArrayWriteF90()` and pass for the array type PetscScalar,pointer :: array(:,...,:) of the appropriate
170dce8aebaSBarry 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
1710f99b6f4SBarry Smith    dimension of the `DMDA`.
172fdc842d1SBarry Smith 
1730f99b6f4SBarry Smith    The order of the indices is array(xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1) (when dof is 1) otherwise
1740f99b6f4SBarry Smith    array(0:dof-1,xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1) where the values are obtained from
1750f99b6f4SBarry Smith    `DMDAGetCorners()` for a global array or `DMDAGetGhostCorners()` for a local array.
176fdc842d1SBarry Smith 
177dce8aebaSBarry Smith   Developer Note:
178dce8aebaSBarry Smith   This has code duplication with `DMDAVecGetArray()` and `DMDAVecGetArrayRead()`
179fdc842d1SBarry Smith 
180dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecRestoreArrayWrite()`, `DMDAVecRestoreArrayDOF()`
181db781477SPatrick Sanan           `DMDAVecGetArrayDOF()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()`
182fdc842d1SBarry Smith @*/
183d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAVecGetArrayWrite(DM da, Vec vec, void *array)
184d71ae5a4SJacob Faibussowitsch {
185fdc842d1SBarry Smith   PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof;
186fdc842d1SBarry Smith 
187fdc842d1SBarry Smith   PetscFunctionBegin;
188fdc842d1SBarry Smith   PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA);
189fdc842d1SBarry Smith   PetscValidHeaderSpecific(vec, VEC_CLASSID, 2);
190fdc842d1SBarry Smith   PetscValidPointer(array, 3);
1911bb6d2a8SBarry Smith   if (da->localSection) {
1929566063dSJacob Faibussowitsch     PetscCall(VecGetArrayWrite(vec, (PetscScalar **)array));
1933ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
194fdc842d1SBarry Smith   }
1959566063dSJacob Faibussowitsch   PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm));
1969566063dSJacob Faibussowitsch   PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm));
1979566063dSJacob Faibussowitsch   PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL));
198fdc842d1SBarry Smith 
199fdc842d1SBarry Smith   /* Handle case where user passes in global vector as opposed to local */
2009566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(vec, &N));
201fdc842d1SBarry Smith   if (N == xm * ym * zm * dof) {
202fdc842d1SBarry Smith     gxm = xm;
203fdc842d1SBarry Smith     gym = ym;
204fdc842d1SBarry Smith     gzm = zm;
205fdc842d1SBarry Smith     gxs = xs;
206fdc842d1SBarry Smith     gys = ys;
207fdc842d1SBarry Smith     gzs = zs;
20863a3b9bcSJacob Faibussowitsch   } else PetscCheck(N == gxm * gym * gzm * dof, PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Vector local size %" PetscInt_FMT " is not compatible with DMDA local sizes %" PetscInt_FMT " %" PetscInt_FMT, N, xm * ym * zm * dof, gxm * gym * gzm * dof);
209fdc842d1SBarry Smith 
210fdc842d1SBarry Smith   if (dim == 1) {
2119566063dSJacob Faibussowitsch     PetscCall(VecGetArray1dWrite(vec, gxm * dof, gxs * dof, (PetscScalar **)array));
212fdc842d1SBarry Smith   } else if (dim == 2) {
2139566063dSJacob Faibussowitsch     PetscCall(VecGetArray2dWrite(vec, gym, gxm * dof, gys, gxs * dof, (PetscScalar ***)array));
214fdc842d1SBarry Smith   } else if (dim == 3) {
2159566063dSJacob Faibussowitsch     PetscCall(VecGetArray3dWrite(vec, gzm, gym, gxm * dof, gzs, gys, gxs * dof, (PetscScalar ****)array));
21663a3b9bcSJacob Faibussowitsch   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim);
2173ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
218fdc842d1SBarry Smith }
219fdc842d1SBarry Smith 
2200f99b6f4SBarry Smith /*MC
2210f99b6f4SBarry Smith     DMDAVecRestoreArrayWriteF90 - check Fortran Notes at `DMDAVecRestoreArrayWrite()`
222*53c0d4aeSBarry Smith 
223*53c0d4aeSBarry Smith     Level: intermediate
2240f99b6f4SBarry Smith M*/
2250f99b6f4SBarry Smith 
226fdc842d1SBarry Smith /*@
227dce8aebaSBarry Smith    DMDAVecRestoreArrayWrite - Restores a multiple dimension array obtained with `DMDAVecGetArrayWrite()`
228fdc842d1SBarry Smith 
229dce8aebaSBarry Smith    Logically collective on vec
230fdc842d1SBarry Smith 
231d8d19677SJose E. Roman    Input Parameters:
232fdc842d1SBarry Smith +  da - the distributed array
233fdc842d1SBarry Smith .  vec - the vector, either a vector the same size as one obtained with
234dce8aebaSBarry Smith          `DMCreateGlobalVector()` or `DMCreateLocalVector()`
235fdc842d1SBarry Smith -  array - the array, non-NULL pointer is zeroed
236fdc842d1SBarry Smith 
237fdc842d1SBarry Smith   Level: intermediate
238fdc842d1SBarry Smith 
239dce8aebaSBarry Smith   Fortran Note:
2400f99b6f4SBarry Smith   Use `DMDAVecRestoreArayWriteF90()`
241fdc842d1SBarry Smith 
242dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecGetArrayWrite()`,
243db781477SPatrick Sanan           `DMDAVecGetArray()`, `DMDAVecRestoreArray()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()`
244fdc842d1SBarry Smith @*/
245d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAVecRestoreArrayWrite(DM da, Vec vec, void *array)
246d71ae5a4SJacob Faibussowitsch {
247fdc842d1SBarry Smith   PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof;
248fdc842d1SBarry Smith 
249fdc842d1SBarry Smith   PetscFunctionBegin;
250fdc842d1SBarry Smith   PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA);
251fdc842d1SBarry Smith   PetscValidHeaderSpecific(vec, VEC_CLASSID, 2);
252fdc842d1SBarry Smith   PetscValidPointer(array, 3);
2531bb6d2a8SBarry Smith   if (da->localSection) {
2549566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(vec, (PetscScalar **)array));
2553ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
256fdc842d1SBarry Smith   }
2579566063dSJacob Faibussowitsch   PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm));
2589566063dSJacob Faibussowitsch   PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm));
2599566063dSJacob Faibussowitsch   PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL));
260fdc842d1SBarry Smith 
261fdc842d1SBarry Smith   /* Handle case where user passes in global vector as opposed to local */
2629566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(vec, &N));
263fdc842d1SBarry Smith   if (N == xm * ym * zm * dof) {
264fdc842d1SBarry Smith     gxm = xm;
265fdc842d1SBarry Smith     gym = ym;
266fdc842d1SBarry Smith     gzm = zm;
267fdc842d1SBarry Smith     gxs = xs;
268fdc842d1SBarry Smith     gys = ys;
269fdc842d1SBarry Smith     gzs = zs;
27063a3b9bcSJacob Faibussowitsch   } else PetscCheck(N == gxm * gym * gzm * dof, PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Vector local size %" PetscInt_FMT " is not compatible with DMDA local sizes %" PetscInt_FMT " %" PetscInt_FMT, N, xm * ym * zm * dof, gxm * gym * gzm * dof);
271fdc842d1SBarry Smith 
272fdc842d1SBarry Smith   if (dim == 1) {
2739566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray1dWrite(vec, gxm * dof, gxs * dof, (PetscScalar **)array));
274fdc842d1SBarry Smith   } else if (dim == 2) {
2759566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray2dWrite(vec, gym, gxm * dof, gys, gxs * dof, (PetscScalar ***)array));
276fdc842d1SBarry Smith   } else if (dim == 3) {
2779566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray3dWrite(vec, gzm, gym, gxm * dof, gzs, gys, gxs * dof, (PetscScalar ****)array));
27863a3b9bcSJacob Faibussowitsch   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim);
2793ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
280fdc842d1SBarry Smith }
281fdc842d1SBarry Smith 
282fdc842d1SBarry Smith /*@C
283aa219208SBarry Smith    DMDAVecGetArrayDOF - Returns a multiple dimension array that shares data with
28447c6ae99SBarry Smith       the underlying vector and is indexed using the global dimensions.
28547c6ae99SBarry Smith 
2862ddbf755SMatthew G. Knepley    Logically collective
28747c6ae99SBarry Smith 
288d8d19677SJose E. Roman    Input Parameters:
28947c6ae99SBarry Smith +  da - the distributed array
29047c6ae99SBarry Smith -  vec - the vector, either a vector the same size as one obtained with
291dce8aebaSBarry Smith          `DMCreateGlobalVector()` or `DMCreateLocalVector()`
29247c6ae99SBarry Smith 
29347c6ae99SBarry Smith    Output Parameter:
29447c6ae99SBarry Smith .  array - the array
29547c6ae99SBarry Smith 
296dce8aebaSBarry Smith   Level: intermediate
297dce8aebaSBarry Smith 
29847c6ae99SBarry Smith    Notes:
299dce8aebaSBarry Smith     Call `DMDAVecRestoreArrayDOF()` once you have finished accessing the vector entries.
30047c6ae99SBarry Smith 
30147c6ae99SBarry Smith     In C, the indexing is "backwards" from what expects: array[k][j][i][DOF] NOT array[i][j][k][DOF]!
30247c6ae99SBarry Smith 
3030f99b6f4SBarry Smith    Fortran Notes:
3040f99b6f4SBarry Smith     Use `DMDAVecGetArrayF90()` and pass for the array type PetscScalar,pointer :: array(:,...,:) of the appropriate
3050f99b6f4SBarry 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
3060f99b6f4SBarry Smith    dimension of the `DMDA`.
3070f99b6f4SBarry Smith 
3080f99b6f4SBarry Smith    The order of the indices is array(xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1) (when dof is 1) otherwise
3090f99b6f4SBarry Smith    array(0:dof-1,xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1) where the values are obtained from
3100f99b6f4SBarry Smith    `DMDAGetCorners()` for a global array or `DMDAGetGhostCorners()` for a local array.
3111b82215eSBarry Smith 
312dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecRestoreArray()`, `DMDAVecGetArray()`, `DMDAVecRestoreArrayDOF()`,
3134ab966ffSPatrick Sanan           `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()`, `DMDAVecGetArrayDOFRead()`
31447c6ae99SBarry Smith @*/
315d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAVecGetArrayDOF(DM da, Vec vec, void *array)
316d71ae5a4SJacob Faibussowitsch {
31747c6ae99SBarry Smith   PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof;
31847c6ae99SBarry Smith 
31947c6ae99SBarry Smith   PetscFunctionBegin;
3209566063dSJacob Faibussowitsch   PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm));
3219566063dSJacob Faibussowitsch   PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm));
3229566063dSJacob Faibussowitsch   PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL));
32347c6ae99SBarry Smith 
32447c6ae99SBarry Smith   /* Handle case where user passes in global vector as opposed to local */
3259566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(vec, &N));
32647c6ae99SBarry Smith   if (N == xm * ym * zm * dof) {
32747c6ae99SBarry Smith     gxm = xm;
32847c6ae99SBarry Smith     gym = ym;
32947c6ae99SBarry Smith     gzm = zm;
33047c6ae99SBarry Smith     gxs = xs;
33147c6ae99SBarry Smith     gys = ys;
33247c6ae99SBarry Smith     gzs = zs;
33363a3b9bcSJacob Faibussowitsch   } else PetscCheck(N == gxm * gym * gzm * dof, PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Vector local size %" PetscInt_FMT " is not compatible with DMDA local sizes %" PetscInt_FMT " %" PetscInt_FMT, N, xm * ym * zm * dof, gxm * gym * gzm * dof);
33447c6ae99SBarry Smith 
33547c6ae99SBarry Smith   if (dim == 1) {
3369566063dSJacob Faibussowitsch     PetscCall(VecGetArray2d(vec, gxm, dof, gxs, 0, (PetscScalar ***)array));
33747c6ae99SBarry Smith   } else if (dim == 2) {
3389566063dSJacob Faibussowitsch     PetscCall(VecGetArray3d(vec, gym, gxm, dof, gys, gxs, 0, (PetscScalar ****)array));
33947c6ae99SBarry Smith   } else if (dim == 3) {
3409566063dSJacob Faibussowitsch     PetscCall(VecGetArray4d(vec, gzm, gym, gxm, dof, gzs, gys, gxs, 0, (PetscScalar *****)array));
34163a3b9bcSJacob Faibussowitsch   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim);
3423ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
34347c6ae99SBarry Smith }
34447c6ae99SBarry Smith 
34547c6ae99SBarry Smith /*@
346dce8aebaSBarry Smith    DMDAVecRestoreArrayDOF - Restores a multiple dimension array obtained with `DMDAVecGetArrayDOF()`
34747c6ae99SBarry Smith 
3482ddbf755SMatthew G. Knepley    Logically collective
34947c6ae99SBarry Smith 
350d8d19677SJose E. Roman    Input Parameters:
35147c6ae99SBarry Smith +  da - the distributed array
35247c6ae99SBarry Smith .  vec - the vector, either a vector the same size as one obtained with
353dce8aebaSBarry Smith          `DMCreateGlobalVector()` or `DMCreateLocalVector()`
35447c6ae99SBarry Smith -  array - the array
35547c6ae99SBarry Smith 
35647c6ae99SBarry Smith   Level: intermediate
35747c6ae99SBarry Smith 
3580f99b6f4SBarry Smith   Fortran Note:
3590f99b6f4SBarry Smith   Use `DMDAVecRestoreArayF90()`
3600f99b6f4SBarry Smith 
361dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecGetArray()`, `DMDAVecGetArrayDOF()`, `DMDAVecRestoreArrayDOF()`,
3624ab966ffSPatrick Sanan           `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()`
36347c6ae99SBarry Smith @*/
364d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAVecRestoreArrayDOF(DM da, Vec vec, void *array)
365d71ae5a4SJacob Faibussowitsch {
36647c6ae99SBarry Smith   PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof;
36747c6ae99SBarry Smith 
36847c6ae99SBarry Smith   PetscFunctionBegin;
3699566063dSJacob Faibussowitsch   PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm));
3709566063dSJacob Faibussowitsch   PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm));
3719566063dSJacob Faibussowitsch   PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL));
37247c6ae99SBarry Smith 
37347c6ae99SBarry Smith   /* Handle case where user passes in global vector as opposed to local */
3749566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(vec, &N));
37547c6ae99SBarry Smith   if (N == xm * ym * zm * dof) {
37647c6ae99SBarry Smith     gxm = xm;
37747c6ae99SBarry Smith     gym = ym;
37847c6ae99SBarry Smith     gzm = zm;
37947c6ae99SBarry Smith     gxs = xs;
38047c6ae99SBarry Smith     gys = ys;
38147c6ae99SBarry Smith     gzs = zs;
38247c6ae99SBarry Smith   }
38347c6ae99SBarry Smith 
38447c6ae99SBarry Smith   if (dim == 1) {
3859566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray2d(vec, gxm, dof, gxs, 0, (PetscScalar ***)array));
38647c6ae99SBarry Smith   } else if (dim == 2) {
3879566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray3d(vec, gym, gxm, dof, gys, gxs, 0, (PetscScalar ****)array));
38847c6ae99SBarry Smith   } else if (dim == 3) {
3899566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray4d(vec, gzm, gym, gxm, dof, gzs, gys, gxs, 0, (PetscScalar *****)array));
39063a3b9bcSJacob Faibussowitsch   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim);
3913ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
39247c6ae99SBarry Smith }
39347c6ae99SBarry Smith 
3940f99b6f4SBarry Smith /*MC
3950f99b6f4SBarry Smith     DMDAVecGetArrayReadF90 - check Fortran Notes at `DMDAVecGetArrayRead()`
396*53c0d4aeSBarry Smith 
397*53c0d4aeSBarry Smith     Level: intermediate
3980f99b6f4SBarry Smith M*/
3990f99b6f4SBarry Smith 
4005edff71fSBarry Smith /*@C
4015edff71fSBarry Smith    DMDAVecGetArrayRead - Returns a multiple dimension array that shares data with
4025edff71fSBarry Smith       the underlying vector and is indexed using the global dimensions.
4035edff71fSBarry Smith 
4042ddbf755SMatthew G. Knepley    Not collective
4055edff71fSBarry Smith 
406d8d19677SJose E. Roman    Input Parameters:
4075edff71fSBarry Smith +  da - the distributed array
408dce8aebaSBarry Smith -  vec - the vector, either a vector the same size as one obtained with `DMCreateGlobalVector()` or `DMCreateLocalVector()`
4095edff71fSBarry Smith 
4105edff71fSBarry Smith    Output Parameter:
4115edff71fSBarry Smith .  array - the array
4125edff71fSBarry Smith 
413dce8aebaSBarry Smith   Level: intermediate
414dce8aebaSBarry Smith 
4155edff71fSBarry Smith    Notes:
416dce8aebaSBarry Smith     Call `DMDAVecRestoreArrayRead()` once you have finished accessing the vector entries.
4175edff71fSBarry Smith 
4185edff71fSBarry Smith     In C, the indexing is "backwards" from what expects: array[k][j][i] NOT array[i][j][k]!
4195edff71fSBarry Smith 
420dce8aebaSBarry Smith     If vec is a local vector (obtained with `DMCreateLocalVector()` etc) then the ghost point locations are accessible. If it is
4215edff71fSBarry Smith     a global vector then the ghost points are not accessible. Of course with the local vector you will have had to do the
422dce8aebaSBarry Smith     appropriate `DMGlobalToLocalBegin()` and `DMGlobalToLocalEnd()` to have correct values in the ghost locations.
4235edff71fSBarry Smith 
42495452b02SPatrick Sanan   Fortran Notes:
4250f99b6f4SBarry Smith   Use `DMDAVecGetArrayReadF90()` and pass for the array type `PetscScalar`,pointer :: array(:,...,:) of the appropriate
426dce8aebaSBarry 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
4270f99b6f4SBarry Smith   dimension of the `DMDA`.
4280f99b6f4SBarry Smith 
4290f99b6f4SBarry Smith   The order of the indices is array(xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1) (when dof is 1) otherwise
4305edff71fSBarry Smith   array(0:dof-1,xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1) where the values are obtained from
4310f99b6f4SBarry Smith   `DMDAGetCorners()` for a global array or `DMDAGetGhostCorners()` for a local array.
4325edff71fSBarry Smith 
4330f99b6f4SBarry Smith .seealso: `DM`, `DMDA`, `DMDAVecGetArrayReadF90()`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecRestoreArrayRead()`, `DMDAVecRestoreArrayDOF()`
434db781477SPatrick Sanan           `DMDAVecGetArrayDOF()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()`,
435db781477SPatrick Sanan           `DMStagVecGetArrayRead()`
4365edff71fSBarry Smith @*/
437d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAVecGetArrayRead(DM da, Vec vec, void *array)
438d71ae5a4SJacob Faibussowitsch {
4395edff71fSBarry Smith   PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof;
4405edff71fSBarry Smith 
4415edff71fSBarry Smith   PetscFunctionBegin;
442a9a02de4SBarry Smith   PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA);
4435edff71fSBarry Smith   PetscValidHeaderSpecific(vec, VEC_CLASSID, 2);
4445edff71fSBarry Smith   PetscValidPointer(array, 3);
4459566063dSJacob Faibussowitsch   PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm));
4469566063dSJacob Faibussowitsch   PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm));
4479566063dSJacob Faibussowitsch   PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL));
4485edff71fSBarry Smith 
4495edff71fSBarry Smith   /* Handle case where user passes in global vector as opposed to local */
4509566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(vec, &N));
4515edff71fSBarry Smith   if (N == xm * ym * zm * dof) {
4525edff71fSBarry Smith     gxm = xm;
4535edff71fSBarry Smith     gym = ym;
4545edff71fSBarry Smith     gzm = zm;
4555edff71fSBarry Smith     gxs = xs;
4565edff71fSBarry Smith     gys = ys;
4575edff71fSBarry Smith     gzs = zs;
45863a3b9bcSJacob Faibussowitsch   } else PetscCheck(N == gxm * gym * gzm * dof, PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Vector local size %" PetscInt_FMT " is not compatible with DMDA local sizes %" PetscInt_FMT " %" PetscInt_FMT, N, xm * ym * zm * dof, gxm * gym * gzm * dof);
4595edff71fSBarry Smith 
4605edff71fSBarry Smith   if (dim == 1) {
4619566063dSJacob Faibussowitsch     PetscCall(VecGetArray1dRead(vec, gxm * dof, gxs * dof, (PetscScalar **)array));
4625edff71fSBarry Smith   } else if (dim == 2) {
4639566063dSJacob Faibussowitsch     PetscCall(VecGetArray2dRead(vec, gym, gxm * dof, gys, gxs * dof, (PetscScalar ***)array));
4645edff71fSBarry Smith   } else if (dim == 3) {
4659566063dSJacob Faibussowitsch     PetscCall(VecGetArray3dRead(vec, gzm, gym, gxm * dof, gzs, gys, gxs * dof, (PetscScalar ****)array));
46663a3b9bcSJacob Faibussowitsch   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim);
4673ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4685edff71fSBarry Smith }
4695edff71fSBarry Smith 
4700f99b6f4SBarry Smith /*MC
4710f99b6f4SBarry Smith     DMDAVecRestoreArrayReadF90 - check Fortran Notes at `DMDAVecRestoreArrayRead()`
472*53c0d4aeSBarry Smith 
473*53c0d4aeSBarry Smith     Level: intermediate
4740f99b6f4SBarry Smith M*/
4750f99b6f4SBarry Smith 
4765edff71fSBarry Smith /*@
477dce8aebaSBarry Smith    DMDAVecRestoreArrayRead - Restores a multiple dimension array obtained with `DMDAVecGetArrayRead()`
4785edff71fSBarry Smith 
4792ddbf755SMatthew G. Knepley    Not collective
4805edff71fSBarry Smith 
481d8d19677SJose E. Roman    Input Parameters:
4825edff71fSBarry Smith +  da - the distributed array
4835edff71fSBarry Smith .  vec - the vector, either a vector the same size as one obtained with
484dce8aebaSBarry Smith          `DMCreateGlobalVector()` or `DMCreateLocalVector()`
4855edff71fSBarry Smith -  array - the array, non-NULL pointer is zeroed
4865edff71fSBarry Smith 
4875edff71fSBarry Smith   Level: intermediate
4885edff71fSBarry Smith 
489dce8aebaSBarry Smith   Fortran Note:
4900f99b6f4SBarry Smith   Use `DMDAVecRestoreArrayReadF90()`
4915edff71fSBarry Smith 
4920f99b6f4SBarry Smith .seealso: `DM`, `DMDA`, `DMDAVecRestoreArrayReadF90()`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecGetArrayRead()`,
493db781477SPatrick Sanan           `DMDAVecGetArray()`, `DMDAVecRestoreArray()`, `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`,
494db781477SPatrick Sanan           `DMStagVecRestoreArrayRead()`
4955edff71fSBarry Smith @*/
496d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAVecRestoreArrayRead(DM da, Vec vec, void *array)
497d71ae5a4SJacob Faibussowitsch {
4985edff71fSBarry Smith   PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof;
4995edff71fSBarry Smith 
5005edff71fSBarry Smith   PetscFunctionBegin;
501a9a02de4SBarry Smith   PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA);
5025edff71fSBarry Smith   PetscValidHeaderSpecific(vec, VEC_CLASSID, 2);
5035edff71fSBarry Smith   PetscValidPointer(array, 3);
5049566063dSJacob Faibussowitsch   PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm));
5059566063dSJacob Faibussowitsch   PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm));
5069566063dSJacob Faibussowitsch   PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL));
5075edff71fSBarry Smith 
5085edff71fSBarry Smith   /* Handle case where user passes in global vector as opposed to local */
5099566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(vec, &N));
5105edff71fSBarry Smith   if (N == xm * ym * zm * dof) {
5115edff71fSBarry Smith     gxm = xm;
5125edff71fSBarry Smith     gym = ym;
5135edff71fSBarry Smith     gzm = zm;
5145edff71fSBarry Smith     gxs = xs;
5155edff71fSBarry Smith     gys = ys;
5165edff71fSBarry Smith     gzs = zs;
51763a3b9bcSJacob Faibussowitsch   } else PetscCheck(N == gxm * gym * gzm * dof, PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Vector local size %" PetscInt_FMT " is not compatible with DMDA local sizes %" PetscInt_FMT " %" PetscInt_FMT, N, xm * ym * zm * dof, gxm * gym * gzm * dof);
5185edff71fSBarry Smith 
5195edff71fSBarry Smith   if (dim == 1) {
5209566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray1dRead(vec, gxm * dof, gxs * dof, (PetscScalar **)array));
5215edff71fSBarry Smith   } else if (dim == 2) {
5229566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray2dRead(vec, gym, gxm * dof, gys, gxs * dof, (PetscScalar ***)array));
5235edff71fSBarry Smith   } else if (dim == 3) {
5249566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray3dRead(vec, gzm, gym, gxm * dof, gzs, gys, gxs * dof, (PetscScalar ****)array));
52563a3b9bcSJacob Faibussowitsch   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim);
5263ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5275edff71fSBarry Smith }
5285edff71fSBarry Smith 
5295edff71fSBarry Smith /*@C
5305edff71fSBarry Smith    DMDAVecGetArrayDOFRead - Returns a multiple dimension array that shares data with
5315edff71fSBarry Smith       the underlying vector and is indexed using the global dimensions.
5325edff71fSBarry Smith 
5335edff71fSBarry Smith    Not Collective
5345edff71fSBarry Smith 
535d8d19677SJose E. Roman    Input Parameters:
5365edff71fSBarry Smith +  da - the distributed array
5375edff71fSBarry Smith -  vec - the vector, either a vector the same size as one obtained with
538dce8aebaSBarry Smith          `DMCreateGlobalVector()` or `DMCreateLocalVector()`
5395edff71fSBarry Smith 
5405edff71fSBarry Smith    Output Parameter:
5415edff71fSBarry Smith .  array - the array
5425edff71fSBarry Smith 
543dce8aebaSBarry Smith   Level: intermediate
544dce8aebaSBarry Smith 
5455edff71fSBarry Smith    Notes:
546dce8aebaSBarry Smith    Call `DMDAVecRestoreArrayDOFRead()` once you have finished accessing the vector entries.
5475edff71fSBarry Smith 
5485edff71fSBarry Smith    In C, the indexing is "backwards" from what expects: array[k][j][i][DOF] NOT array[i][j][k][DOF]!
5495edff71fSBarry Smith 
550dce8aebaSBarry Smith    Fortran Note:
5510f99b6f4SBarry Smith    Use  `DMDAVecGetArrayReadF90()` and pass for the array type PetscScalar,pointer :: array(:,...,:) of the appropriate
5520f99b6f4SBarry 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
5530f99b6f4SBarry Smith    dimension of the `DMDA`.
5540f99b6f4SBarry Smith 
5550f99b6f4SBarry Smith    The order of the indices is array(xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1) (when dof is 1) otherwise
5560f99b6f4SBarry Smith    array(0:dof-1,xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1) where the values are obtained from
5570f99b6f4SBarry Smith    `DMDAGetCorners()` for a global array or `DMDAGetGhostCorners()` for a local array.
5585edff71fSBarry Smith 
559dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecRestoreArray()`, `DMDAVecGetArray()`, `DMDAVecGetArrayDOF()`,
5604ab966ffSPatrick Sanan           `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()`
5615edff71fSBarry Smith @*/
562d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAVecGetArrayDOFRead(DM da, Vec vec, void *array)
563d71ae5a4SJacob Faibussowitsch {
5645edff71fSBarry Smith   PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof;
5655edff71fSBarry Smith 
5665edff71fSBarry Smith   PetscFunctionBegin;
5679566063dSJacob Faibussowitsch   PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm));
5689566063dSJacob Faibussowitsch   PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm));
5699566063dSJacob Faibussowitsch   PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL));
5705edff71fSBarry Smith 
5715edff71fSBarry Smith   /* Handle case where user passes in global vector as opposed to local */
5729566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(vec, &N));
5735edff71fSBarry Smith   if (N == xm * ym * zm * dof) {
5745edff71fSBarry Smith     gxm = xm;
5755edff71fSBarry Smith     gym = ym;
5765edff71fSBarry Smith     gzm = zm;
5775edff71fSBarry Smith     gxs = xs;
5785edff71fSBarry Smith     gys = ys;
5795edff71fSBarry Smith     gzs = zs;
58063a3b9bcSJacob Faibussowitsch   } else PetscCheck(N == gxm * gym * gzm * dof, PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Vector local size %" PetscInt_FMT " is not compatible with DMDA local sizes %" PetscInt_FMT " %" PetscInt_FMT, N, xm * ym * zm * dof, gxm * gym * gzm * dof);
5815edff71fSBarry Smith 
5825edff71fSBarry Smith   if (dim == 1) {
5839566063dSJacob Faibussowitsch     PetscCall(VecGetArray2dRead(vec, gxm, dof, gxs, 0, (PetscScalar ***)array));
5845edff71fSBarry Smith   } else if (dim == 2) {
5859566063dSJacob Faibussowitsch     PetscCall(VecGetArray3dRead(vec, gym, gxm, dof, gys, gxs, 0, (PetscScalar ****)array));
5865edff71fSBarry Smith   } else if (dim == 3) {
5879566063dSJacob Faibussowitsch     PetscCall(VecGetArray4dRead(vec, gzm, gym, gxm, dof, gzs, gys, gxs, 0, (PetscScalar *****)array));
58863a3b9bcSJacob Faibussowitsch   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim);
5893ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5905edff71fSBarry Smith }
5915edff71fSBarry Smith 
5925edff71fSBarry Smith /*@
593dce8aebaSBarry Smith    DMDAVecRestoreArrayDOFRead - Restores a multiple dimension array obtained with `DMDAVecGetArrayDOFRead()`
5945edff71fSBarry Smith 
5955edff71fSBarry Smith    Not Collective
5965edff71fSBarry Smith 
597d8d19677SJose E. Roman    Input Parameters:
5985edff71fSBarry Smith +  da - the distributed array
5995edff71fSBarry Smith .  vec - the vector, either a vector the same size as one obtained with
600dce8aebaSBarry Smith          `DMCreateGlobalVector()` or `DMCreateLocalVector()`
6015edff71fSBarry Smith -  array - the array
6025edff71fSBarry Smith 
6035edff71fSBarry Smith   Level: intermediate
6045edff71fSBarry Smith 
6050f99b6f4SBarry Smith   Fortran Note:
6060f99b6f4SBarry Smith   Use `DMDAVecRestoreArrayReadF90()`
6070f99b6f4SBarry Smith 
608dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecGetArray()`, `DMDAVecGetArrayDOF()`, `DMDAVecRestoreArrayDOF()`,
6094ab966ffSPatrick Sanan           `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()`
6105edff71fSBarry Smith @*/
611d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAVecRestoreArrayDOFRead(DM da, Vec vec, void *array)
612d71ae5a4SJacob Faibussowitsch {
6135edff71fSBarry Smith   PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof;
6145edff71fSBarry Smith 
6155edff71fSBarry Smith   PetscFunctionBegin;
6169566063dSJacob Faibussowitsch   PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm));
6179566063dSJacob Faibussowitsch   PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm));
6189566063dSJacob Faibussowitsch   PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL));
6195edff71fSBarry Smith 
6205edff71fSBarry Smith   /* Handle case where user passes in global vector as opposed to local */
6219566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(vec, &N));
6225edff71fSBarry Smith   if (N == xm * ym * zm * dof) {
6235edff71fSBarry Smith     gxm = xm;
6245edff71fSBarry Smith     gym = ym;
6255edff71fSBarry Smith     gzm = zm;
6265edff71fSBarry Smith     gxs = xs;
6275edff71fSBarry Smith     gys = ys;
6285edff71fSBarry Smith     gzs = zs;
6295edff71fSBarry Smith   }
6305edff71fSBarry Smith 
6315edff71fSBarry Smith   if (dim == 1) {
6329566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray2dRead(vec, gxm, dof, gxs, 0, (PetscScalar ***)array));
6335edff71fSBarry Smith   } else if (dim == 2) {
6349566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray3dRead(vec, gym, gxm, dof, gys, gxs, 0, (PetscScalar ****)array));
6355edff71fSBarry Smith   } else if (dim == 3) {
6369566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray4dRead(vec, gzm, gym, gxm, dof, gzs, gys, gxs, 0, (PetscScalar *****)array));
63763a3b9bcSJacob Faibussowitsch   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim);
6383ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6395edff71fSBarry Smith }
6405edff71fSBarry Smith 
6411e5d2365SBarry Smith /*@C
6421e5d2365SBarry Smith    DMDAVecGetArrayDOFWrite - Returns a multiple dimension array that shares data with
6431e5d2365SBarry Smith       the underlying vector and is indexed using the global dimensions.
6441e5d2365SBarry Smith 
6451e5d2365SBarry Smith    Not Collective
6461e5d2365SBarry Smith 
647d8d19677SJose E. Roman    Input Parameters:
6481e5d2365SBarry Smith +  da - the distributed array
6491e5d2365SBarry Smith -  vec - the vector, either a vector the same size as one obtained with
650dce8aebaSBarry Smith          `DMCreateGlobalVector()` or `DMCreateLocalVector()`
6511e5d2365SBarry Smith 
6521e5d2365SBarry Smith    Output Parameter:
6531e5d2365SBarry Smith .  array - the array
6541e5d2365SBarry Smith 
6550f99b6f4SBarry Smith    Level: intermediate
6560f99b6f4SBarry Smith 
6571e5d2365SBarry Smith    Notes:
658dce8aebaSBarry Smith     Call `DMDAVecRestoreArrayDOFWrite()` once you have finished accessing the vector entries.
6591e5d2365SBarry Smith 
6601e5d2365SBarry Smith     In C, the indexing is "backwards" from what expects: array[k][j][i][DOF] NOT array[i][j][k][DOF]!
6611e5d2365SBarry Smith 
6620f99b6f4SBarry Smith    Fortran Note:
6630f99b6f4SBarry Smith    Use  `DMDAVecGetArrayWriteF90()` and pass for the array type PetscScalar,pointer :: array(:,...,:) of the appropriate
6640f99b6f4SBarry 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
6650f99b6f4SBarry Smith    dimension of the `DMDA`.
6661e5d2365SBarry Smith 
6670f99b6f4SBarry Smith    The order of the indices is array(xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1) (when dof is 1) otherwise
6680f99b6f4SBarry Smith    array(0:dof-1,xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1) where the values are obtained from
6690f99b6f4SBarry Smith    `DMDAGetCorners()` for a global array or `DMDAGetGhostCorners()` for a local array.
6701e5d2365SBarry Smith 
6710f99b6f4SBarry Smith .seealso: `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `DMDAVecRestoreArrayWriteF90()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecRestoreArray()`, `DMDAVecGetArray()`, `DMDAVecGetArrayDOF()`,
6724ab966ffSPatrick Sanan           `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`, `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`
6731e5d2365SBarry Smith @*/
674d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAVecGetArrayDOFWrite(DM da, Vec vec, void *array)
675d71ae5a4SJacob Faibussowitsch {
6761e5d2365SBarry Smith   PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof;
6771e5d2365SBarry Smith 
6781e5d2365SBarry Smith   PetscFunctionBegin;
6799566063dSJacob Faibussowitsch   PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm));
6809566063dSJacob Faibussowitsch   PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm));
6819566063dSJacob Faibussowitsch   PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL));
6821e5d2365SBarry Smith 
6831e5d2365SBarry Smith   /* Handle case where user passes in global vector as opposed to local */
6849566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(vec, &N));
6851e5d2365SBarry Smith   if (N == xm * ym * zm * dof) {
6861e5d2365SBarry Smith     gxm = xm;
6871e5d2365SBarry Smith     gym = ym;
6881e5d2365SBarry Smith     gzm = zm;
6891e5d2365SBarry Smith     gxs = xs;
6901e5d2365SBarry Smith     gys = ys;
6911e5d2365SBarry Smith     gzs = zs;
69263a3b9bcSJacob Faibussowitsch   } else PetscCheck(N == gxm * gym * gzm * dof, PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Vector local size %" PetscInt_FMT " is not compatible with DMDA local sizes %" PetscInt_FMT " %" PetscInt_FMT, N, xm * ym * zm * dof, gxm * gym * gzm * dof);
6931e5d2365SBarry Smith 
6941e5d2365SBarry Smith   if (dim == 1) {
6959566063dSJacob Faibussowitsch     PetscCall(VecGetArray2dWrite(vec, gxm, dof, gxs, 0, (PetscScalar ***)array));
6961e5d2365SBarry Smith   } else if (dim == 2) {
6979566063dSJacob Faibussowitsch     PetscCall(VecGetArray3dWrite(vec, gym, gxm, dof, gys, gxs, 0, (PetscScalar ****)array));
6981e5d2365SBarry Smith   } else if (dim == 3) {
6999566063dSJacob Faibussowitsch     PetscCall(VecGetArray4dWrite(vec, gzm, gym, gxm, dof, gzs, gys, gxs, 0, (PetscScalar *****)array));
70063a3b9bcSJacob Faibussowitsch   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim);
7013ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7021e5d2365SBarry Smith }
7031e5d2365SBarry Smith 
7041e5d2365SBarry Smith /*@
705dce8aebaSBarry Smith    DMDAVecRestoreArrayDOFWrite - Restores a multiple dimension array obtained with `DMDAVecGetArrayDOFWrite()`
7061e5d2365SBarry Smith 
7071e5d2365SBarry Smith    Not Collective
7081e5d2365SBarry Smith 
709d8d19677SJose E. Roman    Input Parameters:
7101e5d2365SBarry Smith +  da - the distributed array
7111e5d2365SBarry Smith .  vec - the vector, either a vector the same size as one obtained with
712dce8aebaSBarry Smith          `DMCreateGlobalVector()` or `DMCreateLocalVector()`
7131e5d2365SBarry Smith -  array - the array
7141e5d2365SBarry Smith 
7151e5d2365SBarry Smith   Level: intermediate
7161e5d2365SBarry Smith 
7170f99b6f4SBarry Smith   Fortran Note:
7180f99b6f4SBarry Smith   Use `DMDAVecRestoreArrayWriteF90()`
7190f99b6f4SBarry Smith 
720dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecGetArray()`, `DMDAVecGetArrayDOF()`, `DMDAVecRestoreArrayDOF()`,
7214ab966ffSPatrick Sanan           `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`, `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`
7221e5d2365SBarry Smith @*/
723d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAVecRestoreArrayDOFWrite(DM da, Vec vec, void *array)
724d71ae5a4SJacob Faibussowitsch {
7251e5d2365SBarry Smith   PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof;
7261e5d2365SBarry Smith 
7271e5d2365SBarry Smith   PetscFunctionBegin;
7289566063dSJacob Faibussowitsch   PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm));
7299566063dSJacob Faibussowitsch   PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm));
7309566063dSJacob Faibussowitsch   PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL));
7311e5d2365SBarry Smith 
7321e5d2365SBarry Smith   /* Handle case where user passes in global vector as opposed to local */
7339566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(vec, &N));
7341e5d2365SBarry Smith   if (N == xm * ym * zm * dof) {
7351e5d2365SBarry Smith     gxm = xm;
7361e5d2365SBarry Smith     gym = ym;
7371e5d2365SBarry Smith     gzm = zm;
7381e5d2365SBarry Smith     gxs = xs;
7391e5d2365SBarry Smith     gys = ys;
7401e5d2365SBarry Smith     gzs = zs;
7411e5d2365SBarry Smith   }
7421e5d2365SBarry Smith 
7431e5d2365SBarry Smith   if (dim == 1) {
7449566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray2dWrite(vec, gxm, dof, gxs, 0, (PetscScalar ***)array));
7451e5d2365SBarry Smith   } else if (dim == 2) {
7469566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray3dWrite(vec, gym, gxm, dof, gys, gxs, 0, (PetscScalar ****)array));
7471e5d2365SBarry Smith   } else if (dim == 3) {
7489566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray4dWrite(vec, gzm, gym, gxm, dof, gzs, gys, gxs, 0, (PetscScalar *****)array));
74963a3b9bcSJacob Faibussowitsch   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim);
7503ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7511e5d2365SBarry Smith }
752