1 #include <petsc/private/dmdaimpl.h> /*I "petscdmda.h" I*/
2
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`.
6
7 Logically Collective
8
9 Input Parameters:
10 + da - the `DMDA`
11 - vec - a vector the same size as one obtained with `DMCreateGlobalVector()` or `DMCreateLocalVector()`
12
13 Output Parameter:
14 . array - the array
15
16 Level: intermediate
17
18 Notes:
19 Call `DMDAVecRestoreArray()` once you have finished accessing the vector entries.
20
21 In C, the indexing is "backwards" from what expects: array[k][j][i] NOT array[i][j][k]!
22
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.
26
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.
29
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`.
34
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.
38
39 .seealso: [](sec_struct), [](sec_struct_set), `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecRestoreArray()`, `DMDAVecRestoreArrayDOF()`
40 `DMDAVecGetArrayDOF()`, `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()`,
41 `DMStagVecGetArray()`
42 @*/
DMDAVecGetArray(DM da,Vec vec,void * array)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;
46
47 PetscFunctionBegin;
48 PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA);
49 PetscValidHeaderSpecific(vec, VEC_CLASSID, 2);
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));
54
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);
65
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 }
75
76 /*@
77 DMDAVecRestoreArray - Restores a multiple dimension array obtained with `DMDAVecGetArray()`
78
79 Logically Collective
80
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
85
86 Level: intermediate
87
88 .seealso: [](sec_struct), [](sec_struct_set), `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecGetArray()`,
89 `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()`,
90 `DMStagVecRestoreArray()`
91 @*/
DMDAVecRestoreArray(DM da,Vec vec,void * array)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;
95
96 PetscFunctionBegin;
97 PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA);
98 PetscValidHeaderSpecific(vec, VEC_CLASSID, 2);
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));
103
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);
114
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 }
124
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`.
128
129 Logically Collective
130
131 Input Parameters:
132 + da - the `DMDA`
133 - vec - a vector the same size as one obtained with `DMCreateGlobalVector()` or `DMCreateLocalVector()`
134
135 Output Parameter:
136 . array - the array
137
138 Level: intermediate
139
140 Notes:
141 Call `DMDAVecRestoreArray()` once you have finished accessing the vector entries.
142
143 In C, the indexing is "backwards" from what expects: array[k][j][i] NOT array[i][j][k]!
144
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.
148
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.
151
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`.
156
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.
160
161 Developer Note:
162 This has code duplication with `DMDAVecGetArray()` and `DMDAVecGetArrayRead()`
163
164 .seealso: [](sec_struct), [](sec_struct_set), `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecRestoreArrayWrite()`, `DMDAVecRestoreArrayDOF()`
165 `DMDAVecGetArrayDOF()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()`
166 @*/
DMDAVecGetArrayWrite(DM da,Vec vec,void * array)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;
170
171 PetscFunctionBegin;
172 PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA);
173 PetscValidHeaderSpecific(vec, VEC_CLASSID, 2);
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));
182
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);
193
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 }
203
204 /*@
205 DMDAVecRestoreArrayWrite - Restores a multiple dimension array obtained with `DMDAVecGetArrayWrite()`
206
207 Logically Collective
208
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
213
214 Level: intermediate
215
216 .seealso: [](sec_struct), [](sec_struct_set), `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecGetArrayWrite()`,
217 `DMDAVecGetArray()`, `DMDAVecRestoreArray()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()`
218 @*/
DMDAVecRestoreArrayWrite(DM da,Vec vec,void * array)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;
222
223 PetscFunctionBegin;
224 PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA);
225 PetscValidHeaderSpecific(vec, VEC_CLASSID, 2);
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));
234
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);
245
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 }
255
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`
259
260 Logically Collective
261
262 Input Parameters:
263 + da - the `DMDA`
264 - vec - a vector the same size as one obtained with `DMCreateGlobalVector()` or `DMCreateLocalVector()`
265
266 Output Parameter:
267 . array - the `array` pointer
268
269 Level: intermediate
270
271 Notes:
272 Call `DMDAVecRestoreArrayDOF()` once you have finished accessing the vector entries.
273
274 In C, the indexing is "backwards" from what expects: array[k][j][i][DOF] NOT array[i][j][k][DOF]
275
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.
278
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`.
283
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.
287
288 .seealso: [](sec_struct), [](sec_struct_set), `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecRestoreArray()`, `DMDAVecGetArray()`, `DMDAVecRestoreArrayDOF()`,
289 `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()`, `DMDAVecGetArrayDOFRead()`
290 @*/
DMDAVecGetArrayDOF(DM da,Vec vec,void * array)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;
294
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));
299
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);
310
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 }
320
321 /*@
322 DMDAVecRestoreArrayDOF - Restores a multiple dimension array obtained with `DMDAVecGetArrayDOF()`
323
324 Logically Collective
325
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
330
331 Level: intermediate
332
333 .seealso: [](sec_struct), [](sec_struct_set), `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecGetArray()`, `DMDAVecGetArrayDOF()`,
334 `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()`
335 @*/
DMDAVecRestoreArrayDOF(DM da,Vec vec,void * array)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;
339
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));
344
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 }
355
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 }
365
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`.
369
370 Not Collective
371
372 Input Parameters:
373 + da - the `DMDA`
374 - vec - a vector the same size as one obtained with `DMCreateGlobalVector()` or `DMCreateLocalVector()`
375
376 Output Parameter:
377 . array - the array
378
379 Level: intermediate
380
381 Notes:
382 Call `DMDAVecRestoreArrayRead()` once you have finished accessing the vector entries.
383
384 In C, the indexing is "backwards" from what expects: array[k][j][i] NOT array[i][j][k]!
385
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.
389
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.
392
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`.
397
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.
401
402 .seealso: [](sec_struct), [](sec_struct_set), `DM`, `DMDA`, `DMDAGetGhostCorners()`,
403 `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecRestoreArrayRead()`,
404 `DMDAVecRestoreArrayDOF()`, `DMDAVecGetArrayDOF()`, `DMDAVecGetArray()`,
405 `DMDAVecRestoreArray()`, `DMStagVecGetArrayRead()`
406 @*/
DMDAVecGetArrayRead(DM da,Vec vec,void * array)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;
410
411 PetscFunctionBegin;
412 PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA);
413 PetscValidHeaderSpecific(vec, VEC_CLASSID, 2);
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));
418
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);
429
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 }
439
440 /*@
441 DMDAVecRestoreArrayRead - Restores a multiple dimension array obtained with `DMDAVecGetArrayRead()`
442
443 Not Collective
444
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
449
450 Level: intermediate
451
452 .seealso: [](sec_struct), [](sec_struct_set), `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecGetArrayRead()`,
453 `DMDAVecGetArray()`, `DMDAVecRestoreArray()`, `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`,
454 `DMStagVecRestoreArrayRead()`
455 @*/
DMDAVecRestoreArrayRead(DM da,Vec vec,void * array)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;
459
460 PetscFunctionBegin;
461 PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA);
462 PetscValidHeaderSpecific(vec, VEC_CLASSID, 2);
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));
467
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);
478
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 }
488
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`
492
493 Not Collective
494
495 Input Parameters:
496 + da - the `DMDA`
497 - vec - a vector the same size as one obtained with `DMCreateGlobalVector()` or `DMCreateLocalVector()`
498
499 Output Parameter:
500 . array - the array
501
502 Level: intermediate
503
504 Notes:
505 Call `DMDAVecRestoreArrayDOFRead()` once you have finished accessing the vector entries.
506
507 In C, the indexing is "backwards" from what expects: array[k][j][i][DOF] NOT array[i][j][k][DOF]!
508
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.
511
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`.
516
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.
520
521 .seealso: [](sec_struct), [](sec_struct_set), `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecRestoreArray()`, `DMDAVecGetArray()`, `DMDAVecGetArrayDOF()`,
522 `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()`
523 @*/
DMDAVecGetArrayDOFRead(DM da,Vec vec,void * array)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;
527
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));
532
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);
543
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 }
553
554 /*@
555 DMDAVecRestoreArrayDOFRead - Restores a multiple dimension array obtained with `DMDAVecGetArrayDOFRead()`
556
557 Not Collective
558
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
563
564 Level: intermediate
565
566 .seealso: [](sec_struct), [](sec_struct_set), `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecGetArray()`, `DMDAVecGetArrayDOF()`, `DMDAVecRestoreArrayDOF()`,
567 `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()`
568 @*/
DMDAVecRestoreArrayDOFRead(DM da,Vec vec,void * array)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;
572
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));
577
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 }
588
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 }
598
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`
602
603 Not Collective
604
605 Input Parameters:
606 + da - the `DMDA`
607 - vec - a vector the same size as one obtained with `DMCreateGlobalVector()` or `DMCreateLocalVector()`
608
609 Output Parameter:
610 . array - the array
611
612 Level: intermediate
613
614 Notes:
615 Call `DMDAVecRestoreArrayDOFWrite()` once you have finished accessing the vector entries.
616
617 In C, the indexing is "backwards" from what expects: array[k][j][i][DOF] NOT array[i][j][k][DOF]!
618
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.
621
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`.
626
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.
630
631 .seealso: [](sec_struct), [](sec_struct_set), `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecRestoreArray()`, `DMDAVecGetArray()`, `DMDAVecGetArrayDOF()`,
632 `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`
633 @*/
DMDAVecGetArrayDOFWrite(DM da,Vec vec,void * array)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;
637
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));
642
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);
653
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 }
663
664 /*@
665 DMDAVecRestoreArrayDOFWrite - Restores a multiple dimension array obtained with `DMDAVecGetArrayDOFWrite()`
666
667 Not Collective
668
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
673
674 Level: intermediate
675
676 .seealso: [](sec_struct), [](sec_struct_set), `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecGetArray()`, `DMDAVecGetArrayDOF()`, `DMDAVecRestoreArrayDOF()`,
677 `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`
678 @*/
DMDAVecRestoreArrayDOFWrite(DM da,Vec vec,void * array)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;
682
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));
687
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 }
698
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 }
708