xref: /petsc/src/dm/impls/da/dagetarray.c (revision 42747ad1c0f89c178fc384aacf6345db4954f4b1)
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()`
671b416bcSMatthew G. Knepley 
771b416bcSMatthew G. Knepley   Level: intermediate
80f99b6f4SBarry Smith M*/
90f99b6f4SBarry Smith 
1047c6ae99SBarry Smith /*@C
11aa219208SBarry Smith   DMDAVecGetArray - Returns a multiple dimension array that shares data with
1247c6ae99SBarry Smith   the underlying vector and is indexed using the global dimensions.
1347c6ae99SBarry Smith 
1420f4b53cSBarry Smith   Logically Collective
1547c6ae99SBarry Smith 
16d8d19677SJose E. Roman   Input Parameters:
1747c6ae99SBarry Smith + da  - the distributed array
180af9b551SBarry Smith - vec - a vector the same size as one obtained with `DMCreateGlobalVector()` or `DMCreateLocalVector()`
1947c6ae99SBarry Smith 
2047c6ae99SBarry Smith   Output Parameter:
2147c6ae99SBarry Smith . array - the array
2247c6ae99SBarry Smith 
23dce8aebaSBarry Smith   Level: intermediate
24dce8aebaSBarry Smith 
2547c6ae99SBarry Smith   Notes:
26dce8aebaSBarry Smith   Call `DMDAVecRestoreArray()` once you have finished accessing the vector entries.
2747c6ae99SBarry Smith 
2847c6ae99SBarry Smith   In C, the indexing is "backwards" from what expects: array[k][j][i] NOT array[i][j][k]!
2947c6ae99SBarry Smith 
300af9b551SBarry Smith   If `vec` is a local vector (obtained with DMCreateLocalVector() etc) then the ghost point locations are accessible. If it is
310af9b551SBarry Smith   a global vector then the ghost points are not accessible. Of course, with a local vector you will have had to do the
32dce8aebaSBarry Smith   appropriate `DMGlobalToLocalBegin()` and `DMGlobalToLocalEnd()` to have correct values in the ghost locations.
3347c6ae99SBarry Smith 
340af9b551SBarry Smith   The accessible indices are `array[zs:zs+zm-1][ys:ys+ym-1][xs:xs+xm-1]` where the values are obtained from
350af9b551SBarry Smith   `DMDAGetCorners()` for a global vector or `DMDAGetGhostCorners()` for a local vector.
360af9b551SBarry Smith 
3795452b02SPatrick Sanan   Fortran Notes:
380f99b6f4SBarry Smith   Use `DMDAVecGetArrayF90()` and pass for the array type `PetscScalar`,pointer :: array(:,...,:) of the appropriate
39dce8aebaSBarry 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
400f99b6f4SBarry Smith   dimension of the `DMDA`.
4147c6ae99SBarry Smith 
420af9b551SBarry 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
430af9b551SBarry Smith   `array(0:dof-1,xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1)` where the values are obtained from
440af9b551SBarry Smith   `DMDAGetCorners()` for a global vector or `DMDAGetGhostCorners()` for a local vector.
4547c6ae99SBarry Smith 
46dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecRestoreArray()`, `DMDAVecRestoreArrayDOF()`
47db781477SPatrick Sanan           `DMDAVecGetArrayDOF()`, `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()`,
48db781477SPatrick Sanan           `DMStagVecGetArray()`
4947c6ae99SBarry Smith @*/
50d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAVecGetArray(DM da, Vec vec, void *array)
51d71ae5a4SJacob Faibussowitsch {
5247c6ae99SBarry Smith   PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof;
5347c6ae99SBarry Smith 
5447c6ae99SBarry Smith   PetscFunctionBegin;
55a9a02de4SBarry Smith   PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA);
566db82c94SMatthew G Knepley   PetscValidHeaderSpecific(vec, VEC_CLASSID, 2);
574f572ea9SToby Isaac   PetscAssertPointer(array, 3);
589566063dSJacob Faibussowitsch   PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm));
599566063dSJacob Faibussowitsch   PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm));
609566063dSJacob Faibussowitsch   PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL));
6147c6ae99SBarry Smith 
6247c6ae99SBarry Smith   /* Handle case where user passes in global vector as opposed to local */
639566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(vec, &N));
6447c6ae99SBarry Smith   if (N == xm * ym * zm * dof) {
6547c6ae99SBarry Smith     gxm = xm;
6647c6ae99SBarry Smith     gym = ym;
6747c6ae99SBarry Smith     gzm = zm;
6847c6ae99SBarry Smith     gxs = xs;
6947c6ae99SBarry Smith     gys = ys;
7047c6ae99SBarry Smith     gzs = zs;
7163a3b9bcSJacob 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);
7247c6ae99SBarry Smith 
7347c6ae99SBarry Smith   if (dim == 1) {
749566063dSJacob Faibussowitsch     PetscCall(VecGetArray1d(vec, gxm * dof, gxs * dof, (PetscScalar **)array));
7547c6ae99SBarry Smith   } else if (dim == 2) {
769566063dSJacob Faibussowitsch     PetscCall(VecGetArray2d(vec, gym, gxm * dof, gys, gxs * dof, (PetscScalar ***)array));
7747c6ae99SBarry Smith   } else if (dim == 3) {
789566063dSJacob Faibussowitsch     PetscCall(VecGetArray3d(vec, gzm, gym, gxm * dof, gzs, gys, gxs * dof, (PetscScalar ****)array));
7963a3b9bcSJacob Faibussowitsch   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim);
803ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
8147c6ae99SBarry Smith }
8247c6ae99SBarry Smith 
830f99b6f4SBarry Smith /*MC
840f99b6f4SBarry Smith   DMDAVecRestoreArrayF90 - check Fortran Notes at `DMDAVecRestoreArray()`
8553c0d4aeSBarry Smith 
8653c0d4aeSBarry Smith   Level: intermediate
870f99b6f4SBarry Smith M*/
880f99b6f4SBarry Smith 
8947c6ae99SBarry Smith /*@
90dce8aebaSBarry Smith   DMDAVecRestoreArray - Restores a multiple dimension array obtained with `DMDAVecGetArray()`
9147c6ae99SBarry Smith 
9220f4b53cSBarry Smith   Logically Collective
9347c6ae99SBarry Smith 
94d8d19677SJose E. Roman   Input Parameters:
9547c6ae99SBarry Smith + da    - the distributed array
960af9b551SBarry Smith . vec   - a vector the same size as one obtained with `DMCreateGlobalVector()` or `DMCreateLocalVector()`
970af9b551SBarry Smith - array - the `array` pointer is zeroed
9847c6ae99SBarry Smith 
9947c6ae99SBarry Smith   Level: intermediate
10047c6ae99SBarry Smith 
10160225df5SJacob Faibussowitsch   Fortran Notes:
1020af9b551SBarry Smith   Use `DMDAVecRestoreArayF90()`
10347c6ae99SBarry Smith 
1040f99b6f4SBarry Smith .seealso: `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `DMDAVecRestoreArayF90()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecGetArray()`,
105db781477SPatrick Sanan           `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()`,
106db781477SPatrick Sanan           `DMDStagVecRestoreArray()`
10747c6ae99SBarry Smith @*/
108d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAVecRestoreArray(DM da, Vec vec, void *array)
109d71ae5a4SJacob Faibussowitsch {
11047c6ae99SBarry Smith   PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof;
11147c6ae99SBarry Smith 
11247c6ae99SBarry Smith   PetscFunctionBegin;
113a9a02de4SBarry Smith   PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA);
1146db82c94SMatthew G Knepley   PetscValidHeaderSpecific(vec, VEC_CLASSID, 2);
1154f572ea9SToby Isaac   PetscAssertPointer(array, 3);
1169566063dSJacob Faibussowitsch   PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm));
1179566063dSJacob Faibussowitsch   PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm));
1189566063dSJacob Faibussowitsch   PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL));
11947c6ae99SBarry Smith 
12047c6ae99SBarry Smith   /* Handle case where user passes in global vector as opposed to local */
1219566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(vec, &N));
12247c6ae99SBarry Smith   if (N == xm * ym * zm * dof) {
12347c6ae99SBarry Smith     gxm = xm;
12447c6ae99SBarry Smith     gym = ym;
12547c6ae99SBarry Smith     gzm = zm;
12647c6ae99SBarry Smith     gxs = xs;
12747c6ae99SBarry Smith     gys = ys;
12847c6ae99SBarry Smith     gzs = zs;
12963a3b9bcSJacob 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);
13047c6ae99SBarry Smith 
13147c6ae99SBarry Smith   if (dim == 1) {
1329566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray1d(vec, gxm * dof, gxs * dof, (PetscScalar **)array));
13347c6ae99SBarry Smith   } else if (dim == 2) {
1349566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray2d(vec, gym, gxm * dof, gys, gxs * dof, (PetscScalar ***)array));
13547c6ae99SBarry Smith   } else if (dim == 3) {
1369566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray3d(vec, gzm, gym, gxm * dof, gzs, gys, gxs * dof, (PetscScalar ****)array));
13763a3b9bcSJacob Faibussowitsch   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim);
1383ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
13947c6ae99SBarry Smith }
14047c6ae99SBarry Smith 
1410f99b6f4SBarry Smith /*MC
1420f99b6f4SBarry Smith   DMDAVecGetArrayWriteF90 - check Fortran Notes at `DMDAVecGetArrayWrite()`
14353c0d4aeSBarry Smith 
14453c0d4aeSBarry Smith   Level: intermediate
1450f99b6f4SBarry Smith M*/
1460f99b6f4SBarry Smith 
14747c6ae99SBarry Smith /*@C
148fdc842d1SBarry Smith   DMDAVecGetArrayWrite - Returns a multiple dimension array that shares data with
149fdc842d1SBarry Smith   the underlying vector and is indexed using the global dimensions.
150fdc842d1SBarry Smith 
15120f4b53cSBarry Smith   Logically Collective
152fdc842d1SBarry Smith 
153d8d19677SJose E. Roman   Input Parameters:
154fdc842d1SBarry Smith + da  - the distributed array
1550af9b551SBarry Smith - vec - a vector the same size as one obtained with `DMCreateGlobalVector()` or `DMCreateLocalVector()`
156fdc842d1SBarry Smith 
157fdc842d1SBarry Smith   Output Parameter:
158fdc842d1SBarry Smith . array - the array
159fdc842d1SBarry Smith 
160dce8aebaSBarry Smith   Level: intermediate
161dce8aebaSBarry Smith 
162fdc842d1SBarry Smith   Notes:
163dce8aebaSBarry Smith   Call `DMDAVecRestoreArray()` once you have finished accessing the vector entries.
164fdc842d1SBarry Smith 
165fdc842d1SBarry Smith   In C, the indexing is "backwards" from what expects: array[k][j][i] NOT array[i][j][k]!
166fdc842d1SBarry Smith 
1670af9b551SBarry Smith   if `vec` is a local vector (obtained with `DMCreateLocalVector()` etc) then the ghost point locations are accessible. If it is
168fdc842d1SBarry Smith   a global vector then the ghost points are not accessible. Of course with the local vector you will have had to do the
169dce8aebaSBarry Smith   appropriate `DMGlobalToLocalBegin()` and `DMGlobalToLocalEnd()` to have correct values in the ghost locations.
170fdc842d1SBarry Smith 
1710af9b551SBarry Smith   The accessible indices are `array[zs:zs+zm-1][ys:ys+ym-1][xs:xs+xm-1]` where the values are obtained from
1720af9b551SBarry Smith   `DMDAGetCorners()` for a global vector or `DMDAGetGhostCorners()` for a local vector.
1730af9b551SBarry Smith 
174fdc842d1SBarry Smith   Fortran Notes:
17560225df5SJacob Faibussowitsch 
1760f99b6f4SBarry Smith   From Fortran use `DMDAVecGetArrayWriteF90()` and pass for the array type PetscScalar,pointer :: array(:,...,:) of the appropriate
177dce8aebaSBarry 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
1780f99b6f4SBarry Smith   dimension of the `DMDA`.
179fdc842d1SBarry Smith 
1800af9b551SBarry 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
1810af9b551SBarry Smith   `array(0:dof-1,xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1)` where the values are obtained from
1820af9b551SBarry Smith   `DMDAGetCorners()` for a global vector or `DMDAGetGhostCorners()` for a local vector.
183fdc842d1SBarry Smith 
18460225df5SJacob Faibussowitsch   The order of the indices is array(xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1) (when dof is 1) otherwise
18560225df5SJacob Faibussowitsch   array(0:dof-1,xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1) where the values are obtained from
18660225df5SJacob Faibussowitsch   `DMDAGetCorners()` for a global array or `DMDAGetGhostCorners()` for a local array.
18760225df5SJacob Faibussowitsch 
18860225df5SJacob Faibussowitsch   Developer Notes:
189dce8aebaSBarry Smith   This has code duplication with `DMDAVecGetArray()` and `DMDAVecGetArrayRead()`
190fdc842d1SBarry Smith 
191dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecRestoreArrayWrite()`, `DMDAVecRestoreArrayDOF()`
192db781477SPatrick Sanan           `DMDAVecGetArrayDOF()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()`
193fdc842d1SBarry Smith @*/
194d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAVecGetArrayWrite(DM da, Vec vec, void *array)
195d71ae5a4SJacob Faibussowitsch {
196fdc842d1SBarry Smith   PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof;
197fdc842d1SBarry Smith 
198fdc842d1SBarry Smith   PetscFunctionBegin;
199fdc842d1SBarry Smith   PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA);
200fdc842d1SBarry Smith   PetscValidHeaderSpecific(vec, VEC_CLASSID, 2);
2014f572ea9SToby Isaac   PetscAssertPointer(array, 3);
2021bb6d2a8SBarry Smith   if (da->localSection) {
2039566063dSJacob Faibussowitsch     PetscCall(VecGetArrayWrite(vec, (PetscScalar **)array));
2043ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
205fdc842d1SBarry Smith   }
2069566063dSJacob Faibussowitsch   PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm));
2079566063dSJacob Faibussowitsch   PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm));
2089566063dSJacob Faibussowitsch   PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL));
209fdc842d1SBarry Smith 
210fdc842d1SBarry Smith   /* Handle case where user passes in global vector as opposed to local */
2119566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(vec, &N));
212fdc842d1SBarry Smith   if (N == xm * ym * zm * dof) {
213fdc842d1SBarry Smith     gxm = xm;
214fdc842d1SBarry Smith     gym = ym;
215fdc842d1SBarry Smith     gzm = zm;
216fdc842d1SBarry Smith     gxs = xs;
217fdc842d1SBarry Smith     gys = ys;
218fdc842d1SBarry Smith     gzs = zs;
21963a3b9bcSJacob 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);
220fdc842d1SBarry Smith 
221fdc842d1SBarry Smith   if (dim == 1) {
2229566063dSJacob Faibussowitsch     PetscCall(VecGetArray1dWrite(vec, gxm * dof, gxs * dof, (PetscScalar **)array));
223fdc842d1SBarry Smith   } else if (dim == 2) {
2249566063dSJacob Faibussowitsch     PetscCall(VecGetArray2dWrite(vec, gym, gxm * dof, gys, gxs * dof, (PetscScalar ***)array));
225fdc842d1SBarry Smith   } else if (dim == 3) {
2269566063dSJacob Faibussowitsch     PetscCall(VecGetArray3dWrite(vec, gzm, gym, gxm * dof, gzs, gys, gxs * dof, (PetscScalar ****)array));
22763a3b9bcSJacob Faibussowitsch   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim);
2283ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
229fdc842d1SBarry Smith }
230fdc842d1SBarry Smith 
2310f99b6f4SBarry Smith /*MC
2320f99b6f4SBarry Smith   DMDAVecRestoreArrayWriteF90 - check Fortran Notes at `DMDAVecRestoreArrayWrite()`
23353c0d4aeSBarry Smith 
23453c0d4aeSBarry Smith   Level: intermediate
2350f99b6f4SBarry Smith M*/
2360f99b6f4SBarry Smith 
237fdc842d1SBarry Smith /*@
238dce8aebaSBarry Smith   DMDAVecRestoreArrayWrite - Restores a multiple dimension array obtained with `DMDAVecGetArrayWrite()`
239fdc842d1SBarry Smith 
24020f4b53cSBarry Smith   Logically Collective
241fdc842d1SBarry Smith 
242d8d19677SJose E. Roman   Input Parameters:
243fdc842d1SBarry Smith + da    - the distributed array
2440af9b551SBarry Smith . vec   - a vector the same size as one obtained with `DMCreateGlobalVector()` or `DMCreateLocalVector()`
2450af9b551SBarry Smith - array - the `array` pointer is zeroed
246fdc842d1SBarry Smith 
247fdc842d1SBarry Smith   Level: intermediate
248fdc842d1SBarry Smith 
24960225df5SJacob Faibussowitsch   Fortran Notes:
2500f99b6f4SBarry Smith   Use `DMDAVecRestoreArayWriteF90()`
251fdc842d1SBarry Smith 
252dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecGetArrayWrite()`,
253db781477SPatrick Sanan           `DMDAVecGetArray()`, `DMDAVecRestoreArray()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()`
254fdc842d1SBarry Smith @*/
255d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAVecRestoreArrayWrite(DM da, Vec vec, void *array)
256d71ae5a4SJacob Faibussowitsch {
257fdc842d1SBarry Smith   PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof;
258fdc842d1SBarry Smith 
259fdc842d1SBarry Smith   PetscFunctionBegin;
260fdc842d1SBarry Smith   PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA);
261fdc842d1SBarry Smith   PetscValidHeaderSpecific(vec, VEC_CLASSID, 2);
2624f572ea9SToby Isaac   PetscAssertPointer(array, 3);
2631bb6d2a8SBarry Smith   if (da->localSection) {
2649566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(vec, (PetscScalar **)array));
2653ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
266fdc842d1SBarry Smith   }
2679566063dSJacob Faibussowitsch   PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm));
2689566063dSJacob Faibussowitsch   PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm));
2699566063dSJacob Faibussowitsch   PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL));
270fdc842d1SBarry Smith 
271fdc842d1SBarry Smith   /* Handle case where user passes in global vector as opposed to local */
2729566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(vec, &N));
273fdc842d1SBarry Smith   if (N == xm * ym * zm * dof) {
274fdc842d1SBarry Smith     gxm = xm;
275fdc842d1SBarry Smith     gym = ym;
276fdc842d1SBarry Smith     gzm = zm;
277fdc842d1SBarry Smith     gxs = xs;
278fdc842d1SBarry Smith     gys = ys;
279fdc842d1SBarry Smith     gzs = zs;
28063a3b9bcSJacob 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);
281fdc842d1SBarry Smith 
282fdc842d1SBarry Smith   if (dim == 1) {
2839566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray1dWrite(vec, gxm * dof, gxs * dof, (PetscScalar **)array));
284fdc842d1SBarry Smith   } else if (dim == 2) {
2859566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray2dWrite(vec, gym, gxm * dof, gys, gxs * dof, (PetscScalar ***)array));
286fdc842d1SBarry Smith   } else if (dim == 3) {
2879566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray3dWrite(vec, gzm, gym, gxm * dof, gzs, gys, gxs * dof, (PetscScalar ****)array));
28863a3b9bcSJacob Faibussowitsch   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim);
2893ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
290fdc842d1SBarry Smith }
291fdc842d1SBarry Smith 
292fdc842d1SBarry Smith /*@C
293aa219208SBarry Smith   DMDAVecGetArrayDOF - Returns a multiple dimension array that shares data with
29447c6ae99SBarry Smith   the underlying vector and is indexed using the global dimensions.
29547c6ae99SBarry Smith 
29620f4b53cSBarry Smith   Logically Collective
29747c6ae99SBarry Smith 
298d8d19677SJose E. Roman   Input Parameters:
29947c6ae99SBarry Smith + da  - the distributed array
3000af9b551SBarry Smith - vec - a vector the same size as one obtained with `DMCreateGlobalVector()` or `DMCreateLocalVector()`
30147c6ae99SBarry Smith 
30247c6ae99SBarry Smith   Output Parameter:
3030af9b551SBarry Smith . array - the `array` pointer is zeroed
30447c6ae99SBarry Smith 
305dce8aebaSBarry Smith   Level: intermediate
306dce8aebaSBarry Smith 
30747c6ae99SBarry Smith   Notes:
308dce8aebaSBarry Smith   Call `DMDAVecRestoreArrayDOF()` once you have finished accessing the vector entries.
30947c6ae99SBarry Smith 
3100af9b551SBarry Smith   In C, the indexing is "backwards" from what expects: array[k][j][i][DOF] NOT array[i][j][k][DOF]
3110af9b551SBarry Smith 
3120af9b551SBarry Smith   The accessible indices are `array[zs:zs+zm-1][ys:ys+ym-1][xs:xs+xm-1][0:ndof-1]` where the values are obtained from
3130af9b551SBarry Smith   `DMDAGetCorners()` for a global vector or `DMDAGetGhostCorners()` for a local vector.
31447c6ae99SBarry Smith 
3150f99b6f4SBarry Smith   Fortran Notes:
3160f99b6f4SBarry Smith   Use `DMDAVecGetArrayF90()` and pass for the array type PetscScalar,pointer :: array(:,...,:) of the appropriate
3170f99b6f4SBarry 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
3180f99b6f4SBarry Smith   dimension of the `DMDA`.
3190f99b6f4SBarry Smith 
3200af9b551SBarry Smith   The order of the indices is `array(xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1)` (when ndof is 1) otherwise
3210af9b551SBarry Smith   `array(0:dof-1,xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1)` where the values are obtained from
3220af9b551SBarry Smith   `DMDAGetCorners()` for a global vector or `DMDAGetGhostCorners()` for a local vector.
3231b82215eSBarry Smith 
324dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecRestoreArray()`, `DMDAVecGetArray()`, `DMDAVecRestoreArrayDOF()`,
3254ab966ffSPatrick Sanan           `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()`, `DMDAVecGetArrayDOFRead()`
32647c6ae99SBarry Smith @*/
327d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAVecGetArrayDOF(DM da, Vec vec, void *array)
328d71ae5a4SJacob Faibussowitsch {
32947c6ae99SBarry Smith   PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof;
33047c6ae99SBarry Smith 
33147c6ae99SBarry Smith   PetscFunctionBegin;
3329566063dSJacob Faibussowitsch   PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm));
3339566063dSJacob Faibussowitsch   PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm));
3349566063dSJacob Faibussowitsch   PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL));
33547c6ae99SBarry Smith 
33647c6ae99SBarry Smith   /* Handle case where user passes in global vector as opposed to local */
3379566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(vec, &N));
33847c6ae99SBarry Smith   if (N == xm * ym * zm * dof) {
33947c6ae99SBarry Smith     gxm = xm;
34047c6ae99SBarry Smith     gym = ym;
34147c6ae99SBarry Smith     gzm = zm;
34247c6ae99SBarry Smith     gxs = xs;
34347c6ae99SBarry Smith     gys = ys;
34447c6ae99SBarry Smith     gzs = zs;
34563a3b9bcSJacob 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);
34647c6ae99SBarry Smith 
34747c6ae99SBarry Smith   if (dim == 1) {
3489566063dSJacob Faibussowitsch     PetscCall(VecGetArray2d(vec, gxm, dof, gxs, 0, (PetscScalar ***)array));
34947c6ae99SBarry Smith   } else if (dim == 2) {
3509566063dSJacob Faibussowitsch     PetscCall(VecGetArray3d(vec, gym, gxm, dof, gys, gxs, 0, (PetscScalar ****)array));
35147c6ae99SBarry Smith   } else if (dim == 3) {
3529566063dSJacob Faibussowitsch     PetscCall(VecGetArray4d(vec, gzm, gym, gxm, dof, gzs, gys, gxs, 0, (PetscScalar *****)array));
35363a3b9bcSJacob Faibussowitsch   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim);
3543ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
35547c6ae99SBarry Smith }
35647c6ae99SBarry Smith 
35747c6ae99SBarry Smith /*@
358dce8aebaSBarry Smith   DMDAVecRestoreArrayDOF - Restores a multiple dimension array obtained with `DMDAVecGetArrayDOF()`
35947c6ae99SBarry Smith 
36020f4b53cSBarry Smith   Logically Collective
36147c6ae99SBarry Smith 
362d8d19677SJose E. Roman   Input Parameters:
36347c6ae99SBarry Smith + da    - the distributed array
3640af9b551SBarry Smith . vec   - vector the same size as one obtained with `DMCreateGlobalVector()` or `DMCreateLocalVector()`
3650af9b551SBarry Smith - array - the `array` point is zeroed
36647c6ae99SBarry Smith 
36747c6ae99SBarry Smith   Level: intermediate
36847c6ae99SBarry Smith 
36960225df5SJacob Faibussowitsch   Fortran Notes:
3700f99b6f4SBarry Smith   Use `DMDAVecRestoreArayF90()`
3710f99b6f4SBarry Smith 
372*42747ad1SJacob Faibussowitsch .seealso: `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecGetArray()`, `DMDAVecGetArrayDOF()`,
3734ab966ffSPatrick Sanan           `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()`
37447c6ae99SBarry Smith @*/
375d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAVecRestoreArrayDOF(DM da, Vec vec, void *array)
376d71ae5a4SJacob Faibussowitsch {
37747c6ae99SBarry Smith   PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof;
37847c6ae99SBarry Smith 
37947c6ae99SBarry Smith   PetscFunctionBegin;
3809566063dSJacob Faibussowitsch   PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm));
3819566063dSJacob Faibussowitsch   PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm));
3829566063dSJacob Faibussowitsch   PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL));
38347c6ae99SBarry Smith 
38447c6ae99SBarry Smith   /* Handle case where user passes in global vector as opposed to local */
3859566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(vec, &N));
38647c6ae99SBarry Smith   if (N == xm * ym * zm * dof) {
38747c6ae99SBarry Smith     gxm = xm;
38847c6ae99SBarry Smith     gym = ym;
38947c6ae99SBarry Smith     gzm = zm;
39047c6ae99SBarry Smith     gxs = xs;
39147c6ae99SBarry Smith     gys = ys;
39247c6ae99SBarry Smith     gzs = zs;
39347c6ae99SBarry Smith   }
39447c6ae99SBarry Smith 
39547c6ae99SBarry Smith   if (dim == 1) {
3969566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray2d(vec, gxm, dof, gxs, 0, (PetscScalar ***)array));
39747c6ae99SBarry Smith   } else if (dim == 2) {
3989566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray3d(vec, gym, gxm, dof, gys, gxs, 0, (PetscScalar ****)array));
39947c6ae99SBarry Smith   } else if (dim == 3) {
4009566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray4d(vec, gzm, gym, gxm, dof, gzs, gys, gxs, 0, (PetscScalar *****)array));
40163a3b9bcSJacob Faibussowitsch   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim);
4023ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
40347c6ae99SBarry Smith }
40447c6ae99SBarry Smith 
4050f99b6f4SBarry Smith /*MC
4060f99b6f4SBarry Smith   DMDAVecGetArrayReadF90 - check Fortran Notes at `DMDAVecGetArrayRead()`
40753c0d4aeSBarry Smith 
40853c0d4aeSBarry Smith   Level: intermediate
4090f99b6f4SBarry Smith M*/
4100f99b6f4SBarry Smith 
4115edff71fSBarry Smith /*@C
4125edff71fSBarry Smith   DMDAVecGetArrayRead - Returns a multiple dimension array that shares data with
4135edff71fSBarry Smith   the underlying vector and is indexed using the global dimensions.
4145edff71fSBarry Smith 
41520f4b53cSBarry Smith   Not Collective
4165edff71fSBarry Smith 
417d8d19677SJose E. Roman   Input Parameters:
4185edff71fSBarry Smith + da  - the distributed array
4190af9b551SBarry Smith - vec - a vector the same size as one obtained with `DMCreateGlobalVector()` or `DMCreateLocalVector()`
4205edff71fSBarry Smith 
4215edff71fSBarry Smith   Output Parameter:
4225edff71fSBarry Smith . array - the array
4235edff71fSBarry Smith 
424dce8aebaSBarry Smith   Level: intermediate
425dce8aebaSBarry Smith 
4265edff71fSBarry Smith   Notes:
427dce8aebaSBarry Smith   Call `DMDAVecRestoreArrayRead()` once you have finished accessing the vector entries.
4285edff71fSBarry Smith 
4295edff71fSBarry Smith   In C, the indexing is "backwards" from what expects: array[k][j][i] NOT array[i][j][k]!
4305edff71fSBarry Smith 
4310af9b551SBarry Smith   If `vec` is a local vector (obtained with `DMCreateLocalVector()` etc) then the ghost point locations are accessible. If it is
4325edff71fSBarry Smith   a global vector then the ghost points are not accessible. Of course with the local vector you will have had to do the
433dce8aebaSBarry Smith   appropriate `DMGlobalToLocalBegin()` and `DMGlobalToLocalEnd()` to have correct values in the ghost locations.
4345edff71fSBarry Smith 
4350af9b551SBarry Smith   The accessible indices are `array[zs:zs+zm-1][ys:ys+ym-1][xs:xs+xm-1]` where the values are obtained from
4360af9b551SBarry Smith   `DMDAGetCorners()` for a global vector or `DMDAGetGhostCorners()` for a local vector.
4370af9b551SBarry Smith 
43895452b02SPatrick Sanan   Fortran Notes:
4390f99b6f4SBarry Smith   Use `DMDAVecGetArrayReadF90()` and pass for the array type `PetscScalar`,pointer :: array(:,...,:) of the appropriate
440dce8aebaSBarry 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
4410f99b6f4SBarry Smith   dimension of the `DMDA`.
4420f99b6f4SBarry Smith 
4430af9b551SBarry 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
4440af9b551SBarry Smith   `array(0:dof-1,xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1)` where the values are obtained from
4450af9b551SBarry Smith   `DMDAGetCorners()` for a global vector or `DMDAGetGhostCorners()` for a local vector.
4465edff71fSBarry Smith 
447*42747ad1SJacob Faibussowitsch .seealso: `DM`, `DMDA`, `DMDAVecGetArrayReadF90()`, `DMDAGetGhostCorners()`,
448*42747ad1SJacob Faibussowitsch `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecRestoreArrayRead()`,
449*42747ad1SJacob Faibussowitsch `DMDAVecRestoreArrayDOF()`, `DMDAVecGetArrayDOF()`, `DMDAVecGetArray()`,
450*42747ad1SJacob Faibussowitsch `DMDAVecRestoreArray()`, `DMStagVecGetArrayRead()`
4515edff71fSBarry Smith @*/
452d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAVecGetArrayRead(DM da, Vec vec, void *array)
453d71ae5a4SJacob Faibussowitsch {
4545edff71fSBarry Smith   PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof;
4555edff71fSBarry Smith 
4565edff71fSBarry Smith   PetscFunctionBegin;
457a9a02de4SBarry Smith   PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA);
4585edff71fSBarry Smith   PetscValidHeaderSpecific(vec, VEC_CLASSID, 2);
4594f572ea9SToby Isaac   PetscAssertPointer(array, 3);
4609566063dSJacob Faibussowitsch   PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm));
4619566063dSJacob Faibussowitsch   PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm));
4629566063dSJacob Faibussowitsch   PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL));
4635edff71fSBarry Smith 
4645edff71fSBarry Smith   /* Handle case where user passes in global vector as opposed to local */
4659566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(vec, &N));
4665edff71fSBarry Smith   if (N == xm * ym * zm * dof) {
4675edff71fSBarry Smith     gxm = xm;
4685edff71fSBarry Smith     gym = ym;
4695edff71fSBarry Smith     gzm = zm;
4705edff71fSBarry Smith     gxs = xs;
4715edff71fSBarry Smith     gys = ys;
4725edff71fSBarry Smith     gzs = zs;
47363a3b9bcSJacob 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);
4745edff71fSBarry Smith 
4755edff71fSBarry Smith   if (dim == 1) {
4769566063dSJacob Faibussowitsch     PetscCall(VecGetArray1dRead(vec, gxm * dof, gxs * dof, (PetscScalar **)array));
4775edff71fSBarry Smith   } else if (dim == 2) {
4789566063dSJacob Faibussowitsch     PetscCall(VecGetArray2dRead(vec, gym, gxm * dof, gys, gxs * dof, (PetscScalar ***)array));
4795edff71fSBarry Smith   } else if (dim == 3) {
4809566063dSJacob Faibussowitsch     PetscCall(VecGetArray3dRead(vec, gzm, gym, gxm * dof, gzs, gys, gxs * dof, (PetscScalar ****)array));
48163a3b9bcSJacob Faibussowitsch   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim);
4823ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4835edff71fSBarry Smith }
4845edff71fSBarry Smith 
4850f99b6f4SBarry Smith /*MC
4860f99b6f4SBarry Smith   DMDAVecRestoreArrayReadF90 - check Fortran Notes at `DMDAVecRestoreArrayRead()`
48753c0d4aeSBarry Smith 
48853c0d4aeSBarry Smith   Level: intermediate
4890f99b6f4SBarry Smith M*/
4900f99b6f4SBarry Smith 
4915edff71fSBarry Smith /*@
492dce8aebaSBarry Smith   DMDAVecRestoreArrayRead - Restores a multiple dimension array obtained with `DMDAVecGetArrayRead()`
4935edff71fSBarry Smith 
49420f4b53cSBarry Smith   Not Collective
4955edff71fSBarry Smith 
496d8d19677SJose E. Roman   Input Parameters:
4975edff71fSBarry Smith + da    - the distributed array
4980af9b551SBarry Smith . vec   - vector the same size as one obtained with `DMCreateGlobalVector()` or `DMCreateLocalVector()`
4990af9b551SBarry Smith - array - the `array` pointer is zeroed
5005edff71fSBarry Smith 
5015edff71fSBarry Smith   Level: intermediate
5025edff71fSBarry Smith 
50360225df5SJacob Faibussowitsch   Fortran Notes:
5040f99b6f4SBarry Smith   Use `DMDAVecRestoreArrayReadF90()`
5055edff71fSBarry Smith 
5060f99b6f4SBarry Smith .seealso: `DM`, `DMDA`, `DMDAVecRestoreArrayReadF90()`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecGetArrayRead()`,
507db781477SPatrick Sanan           `DMDAVecGetArray()`, `DMDAVecRestoreArray()`, `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`,
508db781477SPatrick Sanan           `DMStagVecRestoreArrayRead()`
5095edff71fSBarry Smith @*/
510d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAVecRestoreArrayRead(DM da, Vec vec, void *array)
511d71ae5a4SJacob Faibussowitsch {
5125edff71fSBarry Smith   PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof;
5135edff71fSBarry Smith 
5145edff71fSBarry Smith   PetscFunctionBegin;
515a9a02de4SBarry Smith   PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA);
5165edff71fSBarry Smith   PetscValidHeaderSpecific(vec, VEC_CLASSID, 2);
5174f572ea9SToby Isaac   PetscAssertPointer(array, 3);
5189566063dSJacob Faibussowitsch   PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm));
5199566063dSJacob Faibussowitsch   PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm));
5209566063dSJacob Faibussowitsch   PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL));
5215edff71fSBarry Smith 
5225edff71fSBarry Smith   /* Handle case where user passes in global vector as opposed to local */
5239566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(vec, &N));
5245edff71fSBarry Smith   if (N == xm * ym * zm * dof) {
5255edff71fSBarry Smith     gxm = xm;
5265edff71fSBarry Smith     gym = ym;
5275edff71fSBarry Smith     gzm = zm;
5285edff71fSBarry Smith     gxs = xs;
5295edff71fSBarry Smith     gys = ys;
5305edff71fSBarry Smith     gzs = zs;
53163a3b9bcSJacob 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);
5325edff71fSBarry Smith 
5335edff71fSBarry Smith   if (dim == 1) {
5349566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray1dRead(vec, gxm * dof, gxs * dof, (PetscScalar **)array));
5355edff71fSBarry Smith   } else if (dim == 2) {
5369566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray2dRead(vec, gym, gxm * dof, gys, gxs * dof, (PetscScalar ***)array));
5375edff71fSBarry Smith   } else if (dim == 3) {
5389566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray3dRead(vec, gzm, gym, gxm * dof, gzs, gys, gxs * dof, (PetscScalar ****)array));
53963a3b9bcSJacob Faibussowitsch   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim);
5403ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5415edff71fSBarry Smith }
5425edff71fSBarry Smith 
5435edff71fSBarry Smith /*@C
5445edff71fSBarry Smith   DMDAVecGetArrayDOFRead - Returns a multiple dimension array that shares data with
5455edff71fSBarry Smith   the underlying vector and is indexed using the global dimensions.
5465edff71fSBarry Smith 
5475edff71fSBarry Smith   Not Collective
5485edff71fSBarry Smith 
549d8d19677SJose E. Roman   Input Parameters:
5505edff71fSBarry Smith + da  - the distributed array
5510af9b551SBarry Smith - vec - a vector the same size as one obtained with `DMCreateGlobalVector()` or `DMCreateLocalVector()`
5525edff71fSBarry Smith 
5535edff71fSBarry Smith   Output Parameter:
5545edff71fSBarry Smith . array - the array
5555edff71fSBarry Smith 
556dce8aebaSBarry Smith   Level: intermediate
557dce8aebaSBarry Smith 
5585edff71fSBarry Smith   Notes:
559dce8aebaSBarry Smith   Call `DMDAVecRestoreArrayDOFRead()` once you have finished accessing the vector entries.
5605edff71fSBarry Smith 
5615edff71fSBarry Smith   In C, the indexing is "backwards" from what expects: array[k][j][i][DOF] NOT array[i][j][k][DOF]!
5625edff71fSBarry Smith 
5630af9b551SBarry Smith   The accessible indices are `array[zs:zs+zm-1][ys:ys+ym-1][xs:xs+xm-1]` where the values are obtained from
5640af9b551SBarry Smith   `DMDAGetCorners()` for a global vector or `DMDAGetGhostCorners()` for a local vector.
5650af9b551SBarry Smith 
56660225df5SJacob Faibussowitsch   Fortran Notes:
5670f99b6f4SBarry Smith   Use  `DMDAVecGetArrayReadF90()` and pass for the array type PetscScalar,pointer :: array(:,...,:) of the appropriate
5680f99b6f4SBarry 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
5690f99b6f4SBarry Smith   dimension of the `DMDA`.
5700f99b6f4SBarry Smith 
5710af9b551SBarry 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
5720af9b551SBarry Smith   `array(0:dof-1,xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1)` where the values are obtained from
5730af9b551SBarry Smith   `DMDAGetCorners()` for a global vector or `DMDAGetGhostCorners()` for a local vector.
5745edff71fSBarry Smith 
575dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecRestoreArray()`, `DMDAVecGetArray()`, `DMDAVecGetArrayDOF()`,
5764ab966ffSPatrick Sanan           `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()`
5775edff71fSBarry Smith @*/
578d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAVecGetArrayDOFRead(DM da, Vec vec, void *array)
579d71ae5a4SJacob Faibussowitsch {
5805edff71fSBarry Smith   PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof;
5815edff71fSBarry Smith 
5825edff71fSBarry Smith   PetscFunctionBegin;
5839566063dSJacob Faibussowitsch   PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm));
5849566063dSJacob Faibussowitsch   PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm));
5859566063dSJacob Faibussowitsch   PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL));
5865edff71fSBarry Smith 
5875edff71fSBarry Smith   /* Handle case where user passes in global vector as opposed to local */
5889566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(vec, &N));
5895edff71fSBarry Smith   if (N == xm * ym * zm * dof) {
5905edff71fSBarry Smith     gxm = xm;
5915edff71fSBarry Smith     gym = ym;
5925edff71fSBarry Smith     gzm = zm;
5935edff71fSBarry Smith     gxs = xs;
5945edff71fSBarry Smith     gys = ys;
5955edff71fSBarry Smith     gzs = zs;
59663a3b9bcSJacob 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);
5975edff71fSBarry Smith 
5985edff71fSBarry Smith   if (dim == 1) {
5999566063dSJacob Faibussowitsch     PetscCall(VecGetArray2dRead(vec, gxm, dof, gxs, 0, (PetscScalar ***)array));
6005edff71fSBarry Smith   } else if (dim == 2) {
6019566063dSJacob Faibussowitsch     PetscCall(VecGetArray3dRead(vec, gym, gxm, dof, gys, gxs, 0, (PetscScalar ****)array));
6025edff71fSBarry Smith   } else if (dim == 3) {
6039566063dSJacob Faibussowitsch     PetscCall(VecGetArray4dRead(vec, gzm, gym, gxm, dof, gzs, gys, gxs, 0, (PetscScalar *****)array));
60463a3b9bcSJacob Faibussowitsch   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim);
6053ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6065edff71fSBarry Smith }
6075edff71fSBarry Smith 
6085edff71fSBarry Smith /*@
609dce8aebaSBarry Smith   DMDAVecRestoreArrayDOFRead - Restores a multiple dimension array obtained with `DMDAVecGetArrayDOFRead()`
6105edff71fSBarry Smith 
6115edff71fSBarry Smith   Not Collective
6125edff71fSBarry Smith 
613d8d19677SJose E. Roman   Input Parameters:
6145edff71fSBarry Smith + da    - the distributed array
6150af9b551SBarry Smith . vec   - a vector the same size as one obtained with `DMCreateGlobalVector()` or `DMCreateLocalVector()`
6160af9b551SBarry Smith - array - the `array` pointer is zeroed
6175edff71fSBarry Smith 
6185edff71fSBarry Smith   Level: intermediate
6195edff71fSBarry Smith 
62060225df5SJacob Faibussowitsch   Fortran Notes:
6210f99b6f4SBarry Smith   Use `DMDAVecRestoreArrayReadF90()`
6220f99b6f4SBarry Smith 
623dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecGetArray()`, `DMDAVecGetArrayDOF()`, `DMDAVecRestoreArrayDOF()`,
6244ab966ffSPatrick Sanan           `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()`
6255edff71fSBarry Smith @*/
626d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAVecRestoreArrayDOFRead(DM da, Vec vec, void *array)
627d71ae5a4SJacob Faibussowitsch {
6285edff71fSBarry Smith   PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof;
6295edff71fSBarry Smith 
6305edff71fSBarry Smith   PetscFunctionBegin;
6319566063dSJacob Faibussowitsch   PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm));
6329566063dSJacob Faibussowitsch   PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm));
6339566063dSJacob Faibussowitsch   PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL));
6345edff71fSBarry Smith 
6355edff71fSBarry Smith   /* Handle case where user passes in global vector as opposed to local */
6369566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(vec, &N));
6375edff71fSBarry Smith   if (N == xm * ym * zm * dof) {
6385edff71fSBarry Smith     gxm = xm;
6395edff71fSBarry Smith     gym = ym;
6405edff71fSBarry Smith     gzm = zm;
6415edff71fSBarry Smith     gxs = xs;
6425edff71fSBarry Smith     gys = ys;
6435edff71fSBarry Smith     gzs = zs;
6445edff71fSBarry Smith   }
6455edff71fSBarry Smith 
6465edff71fSBarry Smith   if (dim == 1) {
6479566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray2dRead(vec, gxm, dof, gxs, 0, (PetscScalar ***)array));
6485edff71fSBarry Smith   } else if (dim == 2) {
6499566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray3dRead(vec, gym, gxm, dof, gys, gxs, 0, (PetscScalar ****)array));
6505edff71fSBarry Smith   } else if (dim == 3) {
6519566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray4dRead(vec, gzm, gym, gxm, dof, gzs, gys, gxs, 0, (PetscScalar *****)array));
65263a3b9bcSJacob Faibussowitsch   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim);
6533ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6545edff71fSBarry Smith }
6555edff71fSBarry Smith 
6561e5d2365SBarry Smith /*@C
6571e5d2365SBarry Smith   DMDAVecGetArrayDOFWrite - Returns a multiple dimension array that shares data with
6581e5d2365SBarry Smith   the underlying vector and is indexed using the global dimensions.
6591e5d2365SBarry Smith 
6601e5d2365SBarry Smith   Not Collective
6611e5d2365SBarry Smith 
662d8d19677SJose E. Roman   Input Parameters:
6631e5d2365SBarry Smith + da  - the distributed array
6640af9b551SBarry Smith - vec - a vector the same size as one obtained with `DMCreateGlobalVector()` or `DMCreateLocalVector()`
6651e5d2365SBarry Smith 
6661e5d2365SBarry Smith   Output Parameter:
6671e5d2365SBarry Smith . array - the array
6681e5d2365SBarry Smith 
6690f99b6f4SBarry Smith   Level: intermediate
6700f99b6f4SBarry Smith 
6711e5d2365SBarry Smith   Notes:
672dce8aebaSBarry Smith   Call `DMDAVecRestoreArrayDOFWrite()` once you have finished accessing the vector entries.
6731e5d2365SBarry Smith 
6741e5d2365SBarry Smith   In C, the indexing is "backwards" from what expects: array[k][j][i][DOF] NOT array[i][j][k][DOF]!
6751e5d2365SBarry Smith 
6760af9b551SBarry Smith   The accessible indices are `array[zs:zs+zm-1][ys:ys+ym-1][xs:xs+xm-1][0:dof-1]` where the values are obtained from
6770af9b551SBarry Smith   `DMDAGetCorners()` for a global vector or `DMDAGetGhostCorners()` for a local vector.
6780af9b551SBarry Smith 
67960225df5SJacob Faibussowitsch   Fortran Notes:
6800f99b6f4SBarry Smith   Use  `DMDAVecGetArrayWriteF90()` and pass for the array type PetscScalar,pointer :: array(:,...,:) of the appropriate
6810f99b6f4SBarry 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
6820f99b6f4SBarry Smith   dimension of the `DMDA`.
6831e5d2365SBarry Smith 
6840af9b551SBarry 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
6850af9b551SBarry Smith   `array(0:dof-1,xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1)` where the values are obtained from
6860af9b551SBarry Smith   `DMDAGetCorners()` for a global vector or `DMDAGetGhostCorners()` for a local vector.
6871e5d2365SBarry Smith 
6880f99b6f4SBarry Smith .seealso: `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `DMDAVecRestoreArrayWriteF90()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecRestoreArray()`, `DMDAVecGetArray()`, `DMDAVecGetArrayDOF()`,
68960225df5SJacob Faibussowitsch           `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`
6901e5d2365SBarry Smith @*/
691d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAVecGetArrayDOFWrite(DM da, Vec vec, void *array)
692d71ae5a4SJacob Faibussowitsch {
6931e5d2365SBarry Smith   PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof;
6941e5d2365SBarry Smith 
6951e5d2365SBarry Smith   PetscFunctionBegin;
6969566063dSJacob Faibussowitsch   PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm));
6979566063dSJacob Faibussowitsch   PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm));
6989566063dSJacob Faibussowitsch   PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL));
6991e5d2365SBarry Smith 
7001e5d2365SBarry Smith   /* Handle case where user passes in global vector as opposed to local */
7019566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(vec, &N));
7021e5d2365SBarry Smith   if (N == xm * ym * zm * dof) {
7031e5d2365SBarry Smith     gxm = xm;
7041e5d2365SBarry Smith     gym = ym;
7051e5d2365SBarry Smith     gzm = zm;
7061e5d2365SBarry Smith     gxs = xs;
7071e5d2365SBarry Smith     gys = ys;
7081e5d2365SBarry Smith     gzs = zs;
70963a3b9bcSJacob 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);
7101e5d2365SBarry Smith 
7111e5d2365SBarry Smith   if (dim == 1) {
7129566063dSJacob Faibussowitsch     PetscCall(VecGetArray2dWrite(vec, gxm, dof, gxs, 0, (PetscScalar ***)array));
7131e5d2365SBarry Smith   } else if (dim == 2) {
7149566063dSJacob Faibussowitsch     PetscCall(VecGetArray3dWrite(vec, gym, gxm, dof, gys, gxs, 0, (PetscScalar ****)array));
7151e5d2365SBarry Smith   } else if (dim == 3) {
7169566063dSJacob Faibussowitsch     PetscCall(VecGetArray4dWrite(vec, gzm, gym, gxm, dof, gzs, gys, gxs, 0, (PetscScalar *****)array));
71763a3b9bcSJacob Faibussowitsch   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim);
7183ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7191e5d2365SBarry Smith }
7201e5d2365SBarry Smith 
7211e5d2365SBarry Smith /*@
722dce8aebaSBarry Smith   DMDAVecRestoreArrayDOFWrite - Restores a multiple dimension array obtained with `DMDAVecGetArrayDOFWrite()`
7231e5d2365SBarry Smith 
7241e5d2365SBarry Smith   Not Collective
7251e5d2365SBarry Smith 
726d8d19677SJose E. Roman   Input Parameters:
7271e5d2365SBarry Smith + da    - the distributed array
7280af9b551SBarry Smith . vec   - a vector the same size as one obtained with `DMCreateGlobalVector()` or `DMCreateLocalVector()`
7290af9b551SBarry Smith - array - the `array` pointer is zeroed
7301e5d2365SBarry Smith 
7311e5d2365SBarry Smith   Level: intermediate
7321e5d2365SBarry Smith 
73360225df5SJacob Faibussowitsch   Fortran Notes:
7340f99b6f4SBarry Smith   Use `DMDAVecRestoreArrayWriteF90()`
7350f99b6f4SBarry Smith 
736dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecGetArray()`, `DMDAVecGetArrayDOF()`, `DMDAVecRestoreArrayDOF()`,
73760225df5SJacob Faibussowitsch           `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`
7381e5d2365SBarry Smith @*/
739d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAVecRestoreArrayDOFWrite(DM da, Vec vec, void *array)
740d71ae5a4SJacob Faibussowitsch {
7411e5d2365SBarry Smith   PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof;
7421e5d2365SBarry Smith 
7431e5d2365SBarry Smith   PetscFunctionBegin;
7449566063dSJacob Faibussowitsch   PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm));
7459566063dSJacob Faibussowitsch   PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm));
7469566063dSJacob Faibussowitsch   PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL));
7471e5d2365SBarry Smith 
7481e5d2365SBarry Smith   /* Handle case where user passes in global vector as opposed to local */
7499566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(vec, &N));
7501e5d2365SBarry Smith   if (N == xm * ym * zm * dof) {
7511e5d2365SBarry Smith     gxm = xm;
7521e5d2365SBarry Smith     gym = ym;
7531e5d2365SBarry Smith     gzm = zm;
7541e5d2365SBarry Smith     gxs = xs;
7551e5d2365SBarry Smith     gys = ys;
7561e5d2365SBarry Smith     gzs = zs;
7571e5d2365SBarry Smith   }
7581e5d2365SBarry Smith 
7591e5d2365SBarry Smith   if (dim == 1) {
7609566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray2dWrite(vec, gxm, dof, gxs, 0, (PetscScalar ***)array));
7611e5d2365SBarry Smith   } else if (dim == 2) {
7629566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray3dWrite(vec, gym, gxm, dof, gys, gxs, 0, (PetscScalar ****)array));
7631e5d2365SBarry Smith   } else if (dim == 3) {
7649566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray4dWrite(vec, gzm, gym, gxm, dof, gzs, gys, gxs, 0, (PetscScalar *****)array));
76563a3b9bcSJacob Faibussowitsch   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim);
7663ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7671e5d2365SBarry Smith }
768