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 @*/ 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 @*/ 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 @*/ 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 @*/ 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 @*/ 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 @*/ 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 @*/ 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 @*/ 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 @*/ 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 @*/ 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 @*/ 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 @*/ 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