Actual source code: dagetarray.c
1: #include <petsc/private/dmdaimpl.h>
3: /*@C
4: DMDAVecGetArray - Returns a multiple dimension array that shares data with
5: the underlying vector and is indexed using the global or local dimensions of a `DMDA`.
7: Logically Collective
9: Input Parameters:
10: + da - the `DMDA`
11: - vec - a vector the same size as one obtained with `DMCreateGlobalVector()` or `DMCreateLocalVector()`
13: Output Parameter:
14: . array - the array
16: Level: intermediate
18: Notes:
19: Call `DMDAVecRestoreArray()` once you have finished accessing the vector entries.
21: In C, the indexing is "backwards" from what expects: array[k][j][i] NOT array[i][j][k]!
23: If `vec` is a local vector (obtained with DMCreateLocalVector() etc) then the ghost point locations are accessible. If it is
24: a global vector then the ghost points are not accessible. Of course, with a local vector you will have had to do the
25: appropriate `DMGlobalToLocalBegin()` and `DMGlobalToLocalEnd()` to have correct values in the ghost locations.
27: The accessible indices are `array[zs:zs+zm-1][ys:ys+ym-1][xs:xs+xm-1]` where the values are obtained from
28: `DMDAGetCorners()` for a global vector or `DMDAGetGhostCorners()` for a local vector.
30: Fortran Notes:
31: Use `DMDAVecGetArray()` and pass for the array type `PetscScalar`,pointer :: array(:,...,:) of the appropriate
32: 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
33: dimension of the `DMDA`.
35: The order of the indices is `array(xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1)` (when dof is 1) otherwise
36: `array(0:dof-1,xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1)` where the values are obtained from
37: `DMDAGetCorners()` for a global vector or `DMDAGetGhostCorners()` for a local vector.
39: .seealso: [](sec_struct), [](sec_struct_set), `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecRestoreArray()`, `DMDAVecRestoreArrayDOF()`
40: `DMDAVecGetArrayDOF()`, `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()`,
41: `DMStagVecGetArray()`
42: @*/
43: PetscErrorCode DMDAVecGetArray(DM da, Vec vec, void *array)
44: {
45: PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof;
47: PetscFunctionBegin;
50: PetscAssertPointer(array, 3);
51: PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm));
52: PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm));
53: PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL));
55: /* Handle case where user passes in global vector as opposed to local */
56: PetscCall(VecGetLocalSize(vec, &N));
57: if (N == xm * ym * zm * dof) {
58: gxm = xm;
59: gym = ym;
60: gzm = zm;
61: gxs = xs;
62: gys = ys;
63: gzs = zs;
64: } 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);
66: if (dim == 1) {
67: PetscCall(VecGetArray1d(vec, gxm * dof, gxs * dof, (PetscScalar **)array));
68: } else if (dim == 2) {
69: PetscCall(VecGetArray2d(vec, gym, gxm * dof, gys, gxs * dof, (PetscScalar ***)array));
70: } else if (dim == 3) {
71: PetscCall(VecGetArray3d(vec, gzm, gym, gxm * dof, gzs, gys, gxs * dof, (PetscScalar ****)array));
72: } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim);
73: PetscFunctionReturn(PETSC_SUCCESS);
74: }
76: /*@
77: DMDAVecRestoreArray - Restores a multiple dimension array obtained with `DMDAVecGetArray()`
79: Logically Collective
81: Input Parameters:
82: + da - the `DMDA`
83: . vec - a vector the same size as one obtained with `DMCreateGlobalVector()` or `DMCreateLocalVector()`
84: - array - the `array` pointer
86: Level: intermediate
88: .seealso: [](sec_struct), [](sec_struct_set), `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecGetArray()`,
89: `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()`,
90: `DMStagVecRestoreArray()`
91: @*/
92: PetscErrorCode DMDAVecRestoreArray(DM da, Vec vec, void *array)
93: {
94: PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof;
96: PetscFunctionBegin;
99: PetscAssertPointer(array, 3);
100: PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm));
101: PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm));
102: PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL));
104: /* Handle case where user passes in global vector as opposed to local */
105: PetscCall(VecGetLocalSize(vec, &N));
106: if (N == xm * ym * zm * dof) {
107: gxm = xm;
108: gym = ym;
109: gzm = zm;
110: gxs = xs;
111: gys = ys;
112: gzs = zs;
113: } 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);
115: if (dim == 1) {
116: PetscCall(VecRestoreArray1d(vec, gxm * dof, gxs * dof, (PetscScalar **)array));
117: } else if (dim == 2) {
118: PetscCall(VecRestoreArray2d(vec, gym, gxm * dof, gys, gxs * dof, (PetscScalar ***)array));
119: } else if (dim == 3) {
120: PetscCall(VecRestoreArray3d(vec, gzm, gym, gxm * dof, gzs, gys, gxs * dof, (PetscScalar ****)array));
121: } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim);
122: PetscFunctionReturn(PETSC_SUCCESS);
123: }
125: /*@C
126: DMDAVecGetArrayWrite - Returns a multiple dimension array that shares data with
127: the underlying vector and is indexed using the global or local dimensions of a `DMDA`.
129: Logically Collective
131: Input Parameters:
132: + da - the `DMDA`
133: - vec - a vector the same size as one obtained with `DMCreateGlobalVector()` or `DMCreateLocalVector()`
135: Output Parameter:
136: . array - the array
138: Level: intermediate
140: Notes:
141: Call `DMDAVecRestoreArray()` once you have finished accessing the vector entries.
143: In C, the indexing is "backwards" from what expects: array[k][j][i] NOT array[i][j][k]!
145: if `vec` is a local vector (obtained with `DMCreateLocalVector()` etc) then the ghost point locations are accessible. If it is
146: a global vector then the ghost points are not accessible. Of course with the local vector you will have had to do the
147: appropriate `DMGlobalToLocalBegin()` and `DMGlobalToLocalEnd()` to have correct values in the ghost locations.
149: The accessible indices are `array[zs:zs+zm-1][ys:ys+ym-1][xs:xs+xm-1]` where the values are obtained from
150: `DMDAGetCorners()` for a global vector or `DMDAGetGhostCorners()` for a local vector.
152: Fortran Notes:
153: Use `DMDAVecGetArrayWrite()` and pass for the array type PetscScalar,pointer :: array(:,...,:) of the appropriate
154: 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
155: dimension of the `DMDA`.
157: The order of the indices is `array(xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1)` (when dof is 1) otherwise
158: `array(0:dof-1,xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1)` where the values are obtained from
159: `DMDAGetCorners()` for a global vector or `DMDAGetGhostCorners()` for a local vector.
161: Developer Note:
162: This has code duplication with `DMDAVecGetArray()` and `DMDAVecGetArrayRead()`
164: .seealso: [](sec_struct), [](sec_struct_set), `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecRestoreArrayWrite()`, `DMDAVecRestoreArrayDOF()`
165: `DMDAVecGetArrayDOF()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()`
166: @*/
167: PetscErrorCode DMDAVecGetArrayWrite(DM da, Vec vec, void *array)
168: {
169: PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof;
171: PetscFunctionBegin;
174: PetscAssertPointer(array, 3);
175: if (da->localSection) {
176: PetscCall(VecGetArrayWrite(vec, (PetscScalar **)array));
177: PetscFunctionReturn(PETSC_SUCCESS);
178: }
179: PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm));
180: PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm));
181: PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL));
183: /* Handle case where user passes in global vector as opposed to local */
184: PetscCall(VecGetLocalSize(vec, &N));
185: if (N == xm * ym * zm * dof) {
186: gxm = xm;
187: gym = ym;
188: gzm = zm;
189: gxs = xs;
190: gys = ys;
191: gzs = zs;
192: } 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);
194: if (dim == 1) {
195: PetscCall(VecGetArray1dWrite(vec, gxm * dof, gxs * dof, (PetscScalar **)array));
196: } else if (dim == 2) {
197: PetscCall(VecGetArray2dWrite(vec, gym, gxm * dof, gys, gxs * dof, (PetscScalar ***)array));
198: } else if (dim == 3) {
199: PetscCall(VecGetArray3dWrite(vec, gzm, gym, gxm * dof, gzs, gys, gxs * dof, (PetscScalar ****)array));
200: } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim);
201: PetscFunctionReturn(PETSC_SUCCESS);
202: }
204: /*@
205: DMDAVecRestoreArrayWrite - Restores a multiple dimension array obtained with `DMDAVecGetArrayWrite()`
207: Logically Collective
209: Input Parameters:
210: + da - the `DMDA`
211: . vec - a vector the same size as one obtained with `DMCreateGlobalVector()` or `DMCreateLocalVector()`
212: - array - the `array` pointer
214: Level: intermediate
216: .seealso: [](sec_struct), [](sec_struct_set), `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecGetArrayWrite()`,
217: `DMDAVecGetArray()`, `DMDAVecRestoreArray()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()`
218: @*/
219: PetscErrorCode DMDAVecRestoreArrayWrite(DM da, Vec vec, void *array)
220: {
221: PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof;
223: PetscFunctionBegin;
226: PetscAssertPointer(array, 3);
227: if (da->localSection) {
228: PetscCall(VecRestoreArray(vec, (PetscScalar **)array));
229: PetscFunctionReturn(PETSC_SUCCESS);
230: }
231: PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm));
232: PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm));
233: PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL));
235: /* Handle case where user passes in global vector as opposed to local */
236: PetscCall(VecGetLocalSize(vec, &N));
237: if (N == xm * ym * zm * dof) {
238: gxm = xm;
239: gym = ym;
240: gzm = zm;
241: gxs = xs;
242: gys = ys;
243: gzs = zs;
244: } 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);
246: if (dim == 1) {
247: PetscCall(VecRestoreArray1dWrite(vec, gxm * dof, gxs * dof, (PetscScalar **)array));
248: } else if (dim == 2) {
249: PetscCall(VecRestoreArray2dWrite(vec, gym, gxm * dof, gys, gxs * dof, (PetscScalar ***)array));
250: } else if (dim == 3) {
251: PetscCall(VecRestoreArray3dWrite(vec, gzm, gym, gxm * dof, gzs, gys, gxs * dof, (PetscScalar ****)array));
252: } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim);
253: PetscFunctionReturn(PETSC_SUCCESS);
254: }
256: /*@C
257: DMDAVecGetArrayDOF - Returns a multiple dimension array that shares data with
258: the underlying vector and is indexed using the global or local dimensions of a `DMDA`
260: Logically Collective
262: Input Parameters:
263: + da - the `DMDA`
264: - vec - a vector the same size as one obtained with `DMCreateGlobalVector()` or `DMCreateLocalVector()`
266: Output Parameter:
267: . array - the `array` pointer
269: Level: intermediate
271: Notes:
272: Call `DMDAVecRestoreArrayDOF()` once you have finished accessing the vector entries.
274: In C, the indexing is "backwards" from what expects: array[k][j][i][DOF] NOT array[i][j][k][DOF]
276: 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
277: `DMDAGetCorners()` for a global vector or `DMDAGetGhostCorners()` for a local vector.
279: Fortran Notes:
280: Use `DMDAVecGetArray()` and pass for the array type PetscScalar,pointer :: array(:,...,:) of the appropriate
281: 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
282: dimension of the `DMDA`.
284: The order of the indices is `array(xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1)` (when ndof is 1) otherwise
285: `array(0:dof-1,xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1)` where the values are obtained from
286: `DMDAGetCorners()` for a global vector or `DMDAGetGhostCorners()` for a local vector.
288: .seealso: [](sec_struct), [](sec_struct_set), `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecRestoreArray()`, `DMDAVecGetArray()`, `DMDAVecRestoreArrayDOF()`,
289: `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()`, `DMDAVecGetArrayDOFRead()`
290: @*/
291: PetscErrorCode DMDAVecGetArrayDOF(DM da, Vec vec, void *array)
292: {
293: PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof;
295: PetscFunctionBegin;
296: PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm));
297: PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm));
298: PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL));
300: /* Handle case where user passes in global vector as opposed to local */
301: PetscCall(VecGetLocalSize(vec, &N));
302: if (N == xm * ym * zm * dof) {
303: gxm = xm;
304: gym = ym;
305: gzm = zm;
306: gxs = xs;
307: gys = ys;
308: gzs = zs;
309: } 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);
311: if (dim == 1) {
312: PetscCall(VecGetArray2d(vec, gxm, dof, gxs, 0, (PetscScalar ***)array));
313: } else if (dim == 2) {
314: PetscCall(VecGetArray3d(vec, gym, gxm, dof, gys, gxs, 0, (PetscScalar ****)array));
315: } else if (dim == 3) {
316: PetscCall(VecGetArray4d(vec, gzm, gym, gxm, dof, gzs, gys, gxs, 0, (PetscScalar *****)array));
317: } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim);
318: PetscFunctionReturn(PETSC_SUCCESS);
319: }
321: /*@
322: DMDAVecRestoreArrayDOF - Restores a multiple dimension array obtained with `DMDAVecGetArrayDOF()`
324: Logically Collective
326: Input Parameters:
327: + da - the `DMDA`
328: . vec - vector the same size as one obtained with `DMCreateGlobalVector()` or `DMCreateLocalVector()`
329: - array - the `array` point
331: Level: intermediate
333: .seealso: [](sec_struct), [](sec_struct_set), `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecGetArray()`, `DMDAVecGetArrayDOF()`,
334: `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()`
335: @*/
336: PetscErrorCode DMDAVecRestoreArrayDOF(DM da, Vec vec, void *array)
337: {
338: PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof;
340: PetscFunctionBegin;
341: PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm));
342: PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm));
343: PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL));
345: /* Handle case where user passes in global vector as opposed to local */
346: PetscCall(VecGetLocalSize(vec, &N));
347: if (N == xm * ym * zm * dof) {
348: gxm = xm;
349: gym = ym;
350: gzm = zm;
351: gxs = xs;
352: gys = ys;
353: gzs = zs;
354: }
356: if (dim == 1) {
357: PetscCall(VecRestoreArray2d(vec, gxm, dof, gxs, 0, (PetscScalar ***)array));
358: } else if (dim == 2) {
359: PetscCall(VecRestoreArray3d(vec, gym, gxm, dof, gys, gxs, 0, (PetscScalar ****)array));
360: } else if (dim == 3) {
361: PetscCall(VecRestoreArray4d(vec, gzm, gym, gxm, dof, gzs, gys, gxs, 0, (PetscScalar *****)array));
362: } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim);
363: PetscFunctionReturn(PETSC_SUCCESS);
364: }
366: /*@C
367: DMDAVecGetArrayRead - Returns a multiple dimension array that shares data with
368: the underlying vector and is indexed using the global or local dimensions of a `DMDA`.
370: Not Collective
372: Input Parameters:
373: + da - the `DMDA`
374: - vec - a vector the same size as one obtained with `DMCreateGlobalVector()` or `DMCreateLocalVector()`
376: Output Parameter:
377: . array - the array
379: Level: intermediate
381: Notes:
382: Call `DMDAVecRestoreArrayRead()` once you have finished accessing the vector entries.
384: In C, the indexing is "backwards" from what expects: array[k][j][i] NOT array[i][j][k]!
386: If `vec` is a local vector (obtained with `DMCreateLocalVector()` etc) then the ghost point locations are accessible. If it is
387: a global vector then the ghost points are not accessible. Of course with the local vector you will have had to do the
388: appropriate `DMGlobalToLocalBegin()` and `DMGlobalToLocalEnd()` to have correct values in the ghost locations.
390: The accessible indices are `array[zs:zs+zm-1][ys:ys+ym-1][xs:xs+xm-1]` where the values are obtained from
391: `DMDAGetCorners()` for a global vector or `DMDAGetGhostCorners()` for a local vector.
393: Fortran Notes:
394: Use `DMDAVecGetArrayRead()` and pass for the array type `PetscScalar`,pointer :: array(:,...,:) of the appropriate
395: 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
396: dimension of the `DMDA`.
398: The order of the indices is `array(xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1)` (when dof is 1) otherwise
399: `array(0:dof-1,xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1)` where the values are obtained from
400: `DMDAGetCorners()` for a global vector or `DMDAGetGhostCorners()` for a local vector.
402: .seealso: [](sec_struct), [](sec_struct_set), `DM`, `DMDA`, `DMDAGetGhostCorners()`,
403: `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecRestoreArrayRead()`,
404: `DMDAVecRestoreArrayDOF()`, `DMDAVecGetArrayDOF()`, `DMDAVecGetArray()`,
405: `DMDAVecRestoreArray()`, `DMStagVecGetArrayRead()`
406: @*/
407: PetscErrorCode DMDAVecGetArrayRead(DM da, Vec vec, void *array)
408: {
409: PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof;
411: PetscFunctionBegin;
414: PetscAssertPointer(array, 3);
415: PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm));
416: PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm));
417: PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL));
419: /* Handle case where user passes in global vector as opposed to local */
420: PetscCall(VecGetLocalSize(vec, &N));
421: if (N == xm * ym * zm * dof) {
422: gxm = xm;
423: gym = ym;
424: gzm = zm;
425: gxs = xs;
426: gys = ys;
427: gzs = zs;
428: } 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);
430: if (dim == 1) {
431: PetscCall(VecGetArray1dRead(vec, gxm * dof, gxs * dof, (PetscScalar **)array));
432: } else if (dim == 2) {
433: PetscCall(VecGetArray2dRead(vec, gym, gxm * dof, gys, gxs * dof, (PetscScalar ***)array));
434: } else if (dim == 3) {
435: PetscCall(VecGetArray3dRead(vec, gzm, gym, gxm * dof, gzs, gys, gxs * dof, (PetscScalar ****)array));
436: } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim);
437: PetscFunctionReturn(PETSC_SUCCESS);
438: }
440: /*@
441: DMDAVecRestoreArrayRead - Restores a multiple dimension array obtained with `DMDAVecGetArrayRead()`
443: Not Collective
445: Input Parameters:
446: + da - the `DMDA`
447: . vec - vector the same size as one obtained with `DMCreateGlobalVector()` or `DMCreateLocalVector()`
448: - array - the `array` pointer
450: Level: intermediate
452: .seealso: [](sec_struct), [](sec_struct_set), `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecGetArrayRead()`,
453: `DMDAVecGetArray()`, `DMDAVecRestoreArray()`, `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`,
454: `DMStagVecRestoreArrayRead()`
455: @*/
456: PetscErrorCode DMDAVecRestoreArrayRead(DM da, Vec vec, void *array)
457: {
458: PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof;
460: PetscFunctionBegin;
463: PetscAssertPointer(array, 3);
464: PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm));
465: PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm));
466: PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL));
468: /* Handle case where user passes in global vector as opposed to local */
469: PetscCall(VecGetLocalSize(vec, &N));
470: if (N == xm * ym * zm * dof) {
471: gxm = xm;
472: gym = ym;
473: gzm = zm;
474: gxs = xs;
475: gys = ys;
476: gzs = zs;
477: } 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);
479: if (dim == 1) {
480: PetscCall(VecRestoreArray1dRead(vec, gxm * dof, gxs * dof, (PetscScalar **)array));
481: } else if (dim == 2) {
482: PetscCall(VecRestoreArray2dRead(vec, gym, gxm * dof, gys, gxs * dof, (PetscScalar ***)array));
483: } else if (dim == 3) {
484: PetscCall(VecRestoreArray3dRead(vec, gzm, gym, gxm * dof, gzs, gys, gxs * dof, (PetscScalar ****)array));
485: } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim);
486: PetscFunctionReturn(PETSC_SUCCESS);
487: }
489: /*@C
490: DMDAVecGetArrayDOFRead - Returns a multiple dimension array that shares data with
491: the underlying vector and is indexed using the global or local dimensions of a `DMDA`
493: Not Collective
495: Input Parameters:
496: + da - the `DMDA`
497: - vec - a vector the same size as one obtained with `DMCreateGlobalVector()` or `DMCreateLocalVector()`
499: Output Parameter:
500: . array - the array
502: Level: intermediate
504: Notes:
505: Call `DMDAVecRestoreArrayDOFRead()` once you have finished accessing the vector entries.
507: In C, the indexing is "backwards" from what expects: array[k][j][i][DOF] NOT array[i][j][k][DOF]!
509: The accessible indices are `array[zs:zs+zm-1][ys:ys+ym-1][xs:xs+xm-1]` where the values are obtained from
510: `DMDAGetCorners()` for a global vector or `DMDAGetGhostCorners()` for a local vector.
512: Fortran Notes:
513: Use `DMDAVecGetArrayRead()` and pass for the array type PetscScalar,pointer :: array(:,...,:) of the appropriate
514: 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
515: dimension of the `DMDA`.
517: The order of the indices is `array(xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1)` (when dof is 1) otherwise
518: `array(0:dof-1,xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1)` where the values are obtained from
519: `DMDAGetCorners()` for a global vector or `DMDAGetGhostCorners()` for a local vector.
521: .seealso: [](sec_struct), [](sec_struct_set), `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecRestoreArray()`, `DMDAVecGetArray()`, `DMDAVecGetArrayDOF()`,
522: `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()`
523: @*/
524: PetscErrorCode DMDAVecGetArrayDOFRead(DM da, Vec vec, void *array)
525: {
526: PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof;
528: PetscFunctionBegin;
529: PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm));
530: PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm));
531: PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL));
533: /* Handle case where user passes in global vector as opposed to local */
534: PetscCall(VecGetLocalSize(vec, &N));
535: if (N == xm * ym * zm * dof) {
536: gxm = xm;
537: gym = ym;
538: gzm = zm;
539: gxs = xs;
540: gys = ys;
541: gzs = zs;
542: } 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);
544: if (dim == 1) {
545: PetscCall(VecGetArray2dRead(vec, gxm, dof, gxs, 0, (PetscScalar ***)array));
546: } else if (dim == 2) {
547: PetscCall(VecGetArray3dRead(vec, gym, gxm, dof, gys, gxs, 0, (PetscScalar ****)array));
548: } else if (dim == 3) {
549: PetscCall(VecGetArray4dRead(vec, gzm, gym, gxm, dof, gzs, gys, gxs, 0, (PetscScalar *****)array));
550: } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim);
551: PetscFunctionReturn(PETSC_SUCCESS);
552: }
554: /*@
555: DMDAVecRestoreArrayDOFRead - Restores a multiple dimension array obtained with `DMDAVecGetArrayDOFRead()`
557: Not Collective
559: Input Parameters:
560: + da - the `DMDA`
561: . vec - a vector the same size as one obtained with `DMCreateGlobalVector()` or `DMCreateLocalVector()`
562: - array - the `array` pointer
564: Level: intermediate
566: .seealso: [](sec_struct), [](sec_struct_set), `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecGetArray()`, `DMDAVecGetArrayDOF()`, `DMDAVecRestoreArrayDOF()`,
567: `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()`
568: @*/
569: PetscErrorCode DMDAVecRestoreArrayDOFRead(DM da, Vec vec, void *array)
570: {
571: PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof;
573: PetscFunctionBegin;
574: PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm));
575: PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm));
576: PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL));
578: /* Handle case where user passes in global vector as opposed to local */
579: PetscCall(VecGetLocalSize(vec, &N));
580: if (N == xm * ym * zm * dof) {
581: gxm = xm;
582: gym = ym;
583: gzm = zm;
584: gxs = xs;
585: gys = ys;
586: gzs = zs;
587: }
589: if (dim == 1) {
590: PetscCall(VecRestoreArray2dRead(vec, gxm, dof, gxs, 0, (PetscScalar ***)array));
591: } else if (dim == 2) {
592: PetscCall(VecRestoreArray3dRead(vec, gym, gxm, dof, gys, gxs, 0, (PetscScalar ****)array));
593: } else if (dim == 3) {
594: PetscCall(VecRestoreArray4dRead(vec, gzm, gym, gxm, dof, gzs, gys, gxs, 0, (PetscScalar *****)array));
595: } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim);
596: PetscFunctionReturn(PETSC_SUCCESS);
597: }
599: /*@C
600: DMDAVecGetArrayDOFWrite - Returns a multiple dimension array that shares data with
601: the underlying vector and is indexed using the global or local dimensions of a `DMDA`
603: Not Collective
605: Input Parameters:
606: + da - the `DMDA`
607: - vec - a vector the same size as one obtained with `DMCreateGlobalVector()` or `DMCreateLocalVector()`
609: Output Parameter:
610: . array - the array
612: Level: intermediate
614: Notes:
615: Call `DMDAVecRestoreArrayDOFWrite()` once you have finished accessing the vector entries.
617: In C, the indexing is "backwards" from what expects: array[k][j][i][DOF] NOT array[i][j][k][DOF]!
619: 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
620: `DMDAGetCorners()` for a global vector or `DMDAGetGhostCorners()` for a local vector.
622: Fortran Notes:
623: Use `DMDAVecGetArrayWrite()` and pass for the array type PetscScalar,pointer :: array(:,...,:) of the appropriate
624: 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
625: dimension of the `DMDA`.
627: The order of the indices is `array(xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1)` (when dof is 1) otherwise
628: `array(0:dof-1,xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1)` where the values are obtained from
629: `DMDAGetCorners()` for a global vector or `DMDAGetGhostCorners()` for a local vector.
631: .seealso: [](sec_struct), [](sec_struct_set), `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecRestoreArray()`, `DMDAVecGetArray()`, `DMDAVecGetArrayDOF()`,
632: `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`
633: @*/
634: PetscErrorCode DMDAVecGetArrayDOFWrite(DM da, Vec vec, void *array)
635: {
636: PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof;
638: PetscFunctionBegin;
639: PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm));
640: PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm));
641: PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL));
643: /* Handle case where user passes in global vector as opposed to local */
644: PetscCall(VecGetLocalSize(vec, &N));
645: if (N == xm * ym * zm * dof) {
646: gxm = xm;
647: gym = ym;
648: gzm = zm;
649: gxs = xs;
650: gys = ys;
651: gzs = zs;
652: } 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);
654: if (dim == 1) {
655: PetscCall(VecGetArray2dWrite(vec, gxm, dof, gxs, 0, (PetscScalar ***)array));
656: } else if (dim == 2) {
657: PetscCall(VecGetArray3dWrite(vec, gym, gxm, dof, gys, gxs, 0, (PetscScalar ****)array));
658: } else if (dim == 3) {
659: PetscCall(VecGetArray4dWrite(vec, gzm, gym, gxm, dof, gzs, gys, gxs, 0, (PetscScalar *****)array));
660: } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim);
661: PetscFunctionReturn(PETSC_SUCCESS);
662: }
664: /*@
665: DMDAVecRestoreArrayDOFWrite - Restores a multiple dimension array obtained with `DMDAVecGetArrayDOFWrite()`
667: Not Collective
669: Input Parameters:
670: + da - the `DMDA`
671: . vec - a vector the same size as one obtained with `DMCreateGlobalVector()` or `DMCreateLocalVector()`
672: - array - the `array` pointer
674: Level: intermediate
676: .seealso: [](sec_struct), [](sec_struct_set), `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecGetArray()`, `DMDAVecGetArrayDOF()`, `DMDAVecRestoreArrayDOF()`,
677: `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`
678: @*/
679: PetscErrorCode DMDAVecRestoreArrayDOFWrite(DM da, Vec vec, void *array)
680: {
681: PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof;
683: PetscFunctionBegin;
684: PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm));
685: PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm));
686: PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL));
688: /* Handle case where user passes in global vector as opposed to local */
689: PetscCall(VecGetLocalSize(vec, &N));
690: if (N == xm * ym * zm * dof) {
691: gxm = xm;
692: gym = ym;
693: gzm = zm;
694: gxs = xs;
695: gys = ys;
696: gzs = zs;
697: }
699: if (dim == 1) {
700: PetscCall(VecRestoreArray2dWrite(vec, gxm, dof, gxs, 0, (PetscScalar ***)array));
701: } else if (dim == 2) {
702: PetscCall(VecRestoreArray3dWrite(vec, gym, gxm, dof, gys, gxs, 0, (PetscScalar ****)array));
703: } else if (dim == 3) {
704: PetscCall(VecRestoreArray4dWrite(vec, gzm, gym, gxm, dof, gzs, gys, gxs, 0, (PetscScalar *****)array));
705: } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim);
706: PetscFunctionReturn(PETSC_SUCCESS);
707: }