1 2 #include <petsc/private/dmdaimpl.h> /*I "petscdmda.h" I*/ 3 4 /*MC 5 DMDAVecGetArrayF90 - check Fortran Notes at `DMDAVecGetArray()` 6 7 Level: intermediate 8 M*/ 9 10 /*@C 11 DMDAVecGetArray - Returns a multiple dimension array that shares data with 12 the underlying vector and is indexed using the global dimensions. 13 14 Logically collective on da 15 16 Input Parameters: 17 + da - the distributed array 18 - vec - the vector, either a vector the same size as one obtained with `DMCreateGlobalVector()` or `DMCreateLocalVector()` 19 20 Output Parameter: 21 . array - the array 22 23 Level: intermediate 24 25 Notes: 26 Call `DMDAVecRestoreArray()` once you have finished accessing the vector entries. 27 28 In C, the indexing is "backwards" from what expects: array[k][j][i] NOT array[i][j][k]! 29 30 If vec is a local vector (obtained with DMCreateLocalVector() etc) then the ghost point locations are accessible. If it is 31 a global vector then the ghost points are not accessible. Of course with the local vector you will have had to do the 32 33 appropriate `DMGlobalToLocalBegin()` and `DMGlobalToLocalEnd()` to have correct values in the ghost locations. 34 35 Fortran Notes: 36 Use `DMDAVecGetArrayF90()` and pass for the array type `PetscScalar`,pointer :: array(:,...,:) of the appropriate 37 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 38 dimension of the `DMDA`. 39 40 The order of the indices is array(xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1) (when dof is 1) otherwise 41 array(0:dof-1,xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1) where the values are obtained from 42 `DMDAGetCorners()` for a global array or `DMDAGetGhostCorners()` for a local array. 43 44 .seealso: `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecRestoreArray()`, `DMDAVecRestoreArrayDOF()` 45 `DMDAVecGetArrayDOF()`, `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()`, 46 `DMStagVecGetArray()` 47 @*/ 48 PetscErrorCode DMDAVecGetArray(DM da, Vec vec, void *array) 49 { 50 PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof; 51 52 PetscFunctionBegin; 53 PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA); 54 PetscValidHeaderSpecific(vec, VEC_CLASSID, 2); 55 PetscValidPointer(array, 3); 56 PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm)); 57 PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm)); 58 PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL)); 59 60 /* Handle case where user passes in global vector as opposed to local */ 61 PetscCall(VecGetLocalSize(vec, &N)); 62 if (N == xm * ym * zm * dof) { 63 gxm = xm; 64 gym = ym; 65 gzm = zm; 66 gxs = xs; 67 gys = ys; 68 gzs = zs; 69 } 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); 70 71 if (dim == 1) { 72 PetscCall(VecGetArray1d(vec, gxm * dof, gxs * dof, (PetscScalar **)array)); 73 } else if (dim == 2) { 74 PetscCall(VecGetArray2d(vec, gym, gxm * dof, gys, gxs * dof, (PetscScalar ***)array)); 75 } else if (dim == 3) { 76 PetscCall(VecGetArray3d(vec, gzm, gym, gxm * dof, gzs, gys, gxs * dof, (PetscScalar ****)array)); 77 } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim); 78 PetscFunctionReturn(PETSC_SUCCESS); 79 } 80 81 /*MC 82 DMDAVecRestoreArrayF90 - check Fortran Notes at `DMDAVecRestoreArray()` 83 84 Level: intermediate 85 M*/ 86 87 /*@ 88 DMDAVecRestoreArray - Restores a multiple dimension array obtained with `DMDAVecGetArray()` 89 90 Logically collective on da 91 92 Input Parameters: 93 + da - the distributed array 94 . vec - the vector, either a vector the same size as one obtained with 95 `DMCreateGlobalVector()` or `DMCreateLocalVector()` 96 - array - the array, non-NULL pointer is zeroed 97 98 Level: intermediate 99 100 Fortran Note: 101 From Fortran use `DMDAVecRestoreArayF90()` 102 103 .seealso: `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `DMDAVecRestoreArayF90()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecGetArray()`, 104 `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()`, 105 `DMDStagVecRestoreArray()` 106 @*/ 107 PetscErrorCode DMDAVecRestoreArray(DM da, Vec vec, void *array) 108 { 109 PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof; 110 111 PetscFunctionBegin; 112 PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA); 113 PetscValidHeaderSpecific(vec, VEC_CLASSID, 2); 114 PetscValidPointer(array, 3); 115 PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm)); 116 PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm)); 117 PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL)); 118 119 /* Handle case where user passes in global vector as opposed to local */ 120 PetscCall(VecGetLocalSize(vec, &N)); 121 if (N == xm * ym * zm * dof) { 122 gxm = xm; 123 gym = ym; 124 gzm = zm; 125 gxs = xs; 126 gys = ys; 127 gzs = zs; 128 } 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); 129 130 if (dim == 1) { 131 PetscCall(VecRestoreArray1d(vec, gxm * dof, gxs * dof, (PetscScalar **)array)); 132 } else if (dim == 2) { 133 PetscCall(VecRestoreArray2d(vec, gym, gxm * dof, gys, gxs * dof, (PetscScalar ***)array)); 134 } else if (dim == 3) { 135 PetscCall(VecRestoreArray3d(vec, gzm, gym, gxm * dof, gzs, gys, gxs * dof, (PetscScalar ****)array)); 136 } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim); 137 PetscFunctionReturn(PETSC_SUCCESS); 138 } 139 140 /*MC 141 DMDAVecGetArrayWriteF90 - check Fortran Notes at `DMDAVecGetArrayWrite()` 142 143 Level: intermediate 144 M*/ 145 146 /*@C 147 DMDAVecGetArrayWrite - Returns a multiple dimension array that shares data with 148 the underlying vector and is indexed using the global dimensions. 149 150 Logically collective on Vec 151 152 Input Parameters: 153 + da - the distributed array 154 - vec - the vector, either a vector the same size as one obtained with `DMCreateGlobalVector()` or `DMCreateLocalVector()` 155 156 Output Parameter: 157 . array - the array 158 159 Level: intermediate 160 161 Notes: 162 Call `DMDAVecRestoreArray()` once you have finished accessing the vector entries. 163 164 In C, the indexing is "backwards" from what expects: array[k][j][i] NOT array[i][j][k]! 165 166 If vec is a local vector (obtained with `DMCreateLocalVector()` etc) then the ghost point locations are accessible. If it is 167 a global vector then the ghost points are not accessible. Of course with the local vector you will have had to do the 168 appropriate `DMGlobalToLocalBegin()` and `DMGlobalToLocalEnd()` to have correct values in the ghost locations. 169 170 Fortran Notes: 171 From Fortran use `DMDAVecGetArrayWriteF90()` and pass for the array type PetscScalar,pointer :: array(:,...,:) of the appropriate 172 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 173 dimension of the `DMDA`. 174 175 The order of the indices is array(xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1) (when dof is 1) otherwise 176 array(0:dof-1,xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1) where the values are obtained from 177 `DMDAGetCorners()` for a global array or `DMDAGetGhostCorners()` for a local array. 178 179 Developer Note: 180 This has code duplication with `DMDAVecGetArray()` and `DMDAVecGetArrayRead()` 181 182 .seealso: `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecRestoreArrayWrite()`, `DMDAVecRestoreArrayDOF()` 183 `DMDAVecGetArrayDOF()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()` 184 @*/ 185 PetscErrorCode DMDAVecGetArrayWrite(DM da, Vec vec, void *array) 186 { 187 PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof; 188 189 PetscFunctionBegin; 190 PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA); 191 PetscValidHeaderSpecific(vec, VEC_CLASSID, 2); 192 PetscValidPointer(array, 3); 193 if (da->localSection) { 194 PetscCall(VecGetArrayWrite(vec, (PetscScalar **)array)); 195 PetscFunctionReturn(PETSC_SUCCESS); 196 } 197 PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm)); 198 PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm)); 199 PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL)); 200 201 /* Handle case where user passes in global vector as opposed to local */ 202 PetscCall(VecGetLocalSize(vec, &N)); 203 if (N == xm * ym * zm * dof) { 204 gxm = xm; 205 gym = ym; 206 gzm = zm; 207 gxs = xs; 208 gys = ys; 209 gzs = zs; 210 } 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); 211 212 if (dim == 1) { 213 PetscCall(VecGetArray1dWrite(vec, gxm * dof, gxs * dof, (PetscScalar **)array)); 214 } else if (dim == 2) { 215 PetscCall(VecGetArray2dWrite(vec, gym, gxm * dof, gys, gxs * dof, (PetscScalar ***)array)); 216 } else if (dim == 3) { 217 PetscCall(VecGetArray3dWrite(vec, gzm, gym, gxm * dof, gzs, gys, gxs * dof, (PetscScalar ****)array)); 218 } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim); 219 PetscFunctionReturn(PETSC_SUCCESS); 220 } 221 222 /*MC 223 DMDAVecRestoreArrayWriteF90 - check Fortran Notes at `DMDAVecRestoreArrayWrite()` 224 225 Level: intermediate 226 M*/ 227 228 /*@ 229 DMDAVecRestoreArrayWrite - Restores a multiple dimension array obtained with `DMDAVecGetArrayWrite()` 230 231 Logically collective on vec 232 233 Input Parameters: 234 + da - the distributed array 235 . vec - the vector, either a vector the same size as one obtained with 236 `DMCreateGlobalVector()` or `DMCreateLocalVector()` 237 - array - the array, non-NULL pointer is zeroed 238 239 Level: intermediate 240 241 Fortran Note: 242 Use `DMDAVecRestoreArayWriteF90()` 243 244 .seealso: `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecGetArrayWrite()`, 245 `DMDAVecGetArray()`, `DMDAVecRestoreArray()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()` 246 @*/ 247 PetscErrorCode DMDAVecRestoreArrayWrite(DM da, Vec vec, void *array) 248 { 249 PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof; 250 251 PetscFunctionBegin; 252 PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA); 253 PetscValidHeaderSpecific(vec, VEC_CLASSID, 2); 254 PetscValidPointer(array, 3); 255 if (da->localSection) { 256 PetscCall(VecRestoreArray(vec, (PetscScalar **)array)); 257 PetscFunctionReturn(PETSC_SUCCESS); 258 } 259 PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm)); 260 PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm)); 261 PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL)); 262 263 /* Handle case where user passes in global vector as opposed to local */ 264 PetscCall(VecGetLocalSize(vec, &N)); 265 if (N == xm * ym * zm * dof) { 266 gxm = xm; 267 gym = ym; 268 gzm = zm; 269 gxs = xs; 270 gys = ys; 271 gzs = zs; 272 } 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); 273 274 if (dim == 1) { 275 PetscCall(VecRestoreArray1dWrite(vec, gxm * dof, gxs * dof, (PetscScalar **)array)); 276 } else if (dim == 2) { 277 PetscCall(VecRestoreArray2dWrite(vec, gym, gxm * dof, gys, gxs * dof, (PetscScalar ***)array)); 278 } else if (dim == 3) { 279 PetscCall(VecRestoreArray3dWrite(vec, gzm, gym, gxm * dof, gzs, gys, gxs * dof, (PetscScalar ****)array)); 280 } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim); 281 PetscFunctionReturn(PETSC_SUCCESS); 282 } 283 284 /*@C 285 DMDAVecGetArrayDOF - Returns a multiple dimension array that shares data with 286 the underlying vector and is indexed using the global dimensions. 287 288 Logically collective 289 290 Input Parameters: 291 + da - the distributed array 292 - vec - the vector, either a vector the same size as one obtained with 293 `DMCreateGlobalVector()` or `DMCreateLocalVector()` 294 295 Output Parameter: 296 . array - the array 297 298 Level: intermediate 299 300 Notes: 301 Call `DMDAVecRestoreArrayDOF()` once you have finished accessing the vector entries. 302 303 In C, the indexing is "backwards" from what expects: array[k][j][i][DOF] NOT array[i][j][k][DOF]! 304 305 Fortran Notes: 306 Use `DMDAVecGetArrayF90()` and pass for the array type PetscScalar,pointer :: array(:,...,:) of the appropriate 307 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 308 dimension of the `DMDA`. 309 310 The order of the indices is array(xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1) (when dof is 1) otherwise 311 array(0:dof-1,xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1) where the values are obtained from 312 `DMDAGetCorners()` for a global array or `DMDAGetGhostCorners()` for a local array. 313 314 .seealso: `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecRestoreArray()`, `DMDAVecGetArray()`, `DMDAVecRestoreArrayDOF()`, 315 `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()`, `DMDAVecGetArrayDOFRead()` 316 @*/ 317 PetscErrorCode DMDAVecGetArrayDOF(DM da, Vec vec, void *array) 318 { 319 PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof; 320 321 PetscFunctionBegin; 322 PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm)); 323 PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm)); 324 PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL)); 325 326 /* Handle case where user passes in global vector as opposed to local */ 327 PetscCall(VecGetLocalSize(vec, &N)); 328 if (N == xm * ym * zm * dof) { 329 gxm = xm; 330 gym = ym; 331 gzm = zm; 332 gxs = xs; 333 gys = ys; 334 gzs = zs; 335 } 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); 336 337 if (dim == 1) { 338 PetscCall(VecGetArray2d(vec, gxm, dof, gxs, 0, (PetscScalar ***)array)); 339 } else if (dim == 2) { 340 PetscCall(VecGetArray3d(vec, gym, gxm, dof, gys, gxs, 0, (PetscScalar ****)array)); 341 } else if (dim == 3) { 342 PetscCall(VecGetArray4d(vec, gzm, gym, gxm, dof, gzs, gys, gxs, 0, (PetscScalar *****)array)); 343 } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim); 344 PetscFunctionReturn(PETSC_SUCCESS); 345 } 346 347 /*@ 348 DMDAVecRestoreArrayDOF - Restores a multiple dimension array obtained with `DMDAVecGetArrayDOF()` 349 350 Logically collective 351 352 Input Parameters: 353 + da - the distributed array 354 . vec - the vector, either a vector the same size as one obtained with 355 `DMCreateGlobalVector()` or `DMCreateLocalVector()` 356 - array - the array 357 358 Level: intermediate 359 360 Fortran Note: 361 Use `DMDAVecRestoreArayF90()` 362 363 .seealso: `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecGetArray()`, `DMDAVecGetArrayDOF()`, `DMDAVecRestoreArrayDOF()`, 364 `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()` 365 @*/ 366 PetscErrorCode DMDAVecRestoreArrayDOF(DM da, Vec vec, void *array) 367 { 368 PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof; 369 370 PetscFunctionBegin; 371 PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm)); 372 PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm)); 373 PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL)); 374 375 /* Handle case where user passes in global vector as opposed to local */ 376 PetscCall(VecGetLocalSize(vec, &N)); 377 if (N == xm * ym * zm * dof) { 378 gxm = xm; 379 gym = ym; 380 gzm = zm; 381 gxs = xs; 382 gys = ys; 383 gzs = zs; 384 } 385 386 if (dim == 1) { 387 PetscCall(VecRestoreArray2d(vec, gxm, dof, gxs, 0, (PetscScalar ***)array)); 388 } else if (dim == 2) { 389 PetscCall(VecRestoreArray3d(vec, gym, gxm, dof, gys, gxs, 0, (PetscScalar ****)array)); 390 } else if (dim == 3) { 391 PetscCall(VecRestoreArray4d(vec, gzm, gym, gxm, dof, gzs, gys, gxs, 0, (PetscScalar *****)array)); 392 } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim); 393 PetscFunctionReturn(PETSC_SUCCESS); 394 } 395 396 /*MC 397 DMDAVecGetArrayReadF90 - check Fortran Notes at `DMDAVecGetArrayRead()` 398 399 Level: intermediate 400 M*/ 401 402 /*@C 403 DMDAVecGetArrayRead - Returns a multiple dimension array that shares data with 404 the underlying vector and is indexed using the global dimensions. 405 406 Not collective 407 408 Input Parameters: 409 + da - the distributed array 410 - vec - the vector, either a vector the same size as one obtained with `DMCreateGlobalVector()` or `DMCreateLocalVector()` 411 412 Output Parameter: 413 . array - the array 414 415 Level: intermediate 416 417 Notes: 418 Call `DMDAVecRestoreArrayRead()` once you have finished accessing the vector entries. 419 420 In C, the indexing is "backwards" from what expects: array[k][j][i] NOT array[i][j][k]! 421 422 If vec is a local vector (obtained with `DMCreateLocalVector()` etc) then the ghost point locations are accessible. If it is 423 a global vector then the ghost points are not accessible. Of course with the local vector you will have had to do the 424 appropriate `DMGlobalToLocalBegin()` and `DMGlobalToLocalEnd()` to have correct values in the ghost locations. 425 426 Fortran Notes: 427 Use `DMDAVecGetArrayReadF90()` and pass for the array type `PetscScalar`,pointer :: array(:,...,:) of the appropriate 428 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 429 dimension of the `DMDA`. 430 431 The order of the indices is array(xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1) (when dof is 1) otherwise 432 array(0:dof-1,xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1) where the values are obtained from 433 `DMDAGetCorners()` for a global array or `DMDAGetGhostCorners()` for a local array. 434 435 .seealso: `DM`, `DMDA`, `DMDAVecGetArrayReadF90()`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecRestoreArrayRead()`, `DMDAVecRestoreArrayDOF()` 436 `DMDAVecGetArrayDOF()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()`, 437 `DMStagVecGetArrayRead()` 438 @*/ 439 PetscErrorCode DMDAVecGetArrayRead(DM da, Vec vec, void *array) 440 { 441 PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof; 442 443 PetscFunctionBegin; 444 PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA); 445 PetscValidHeaderSpecific(vec, VEC_CLASSID, 2); 446 PetscValidPointer(array, 3); 447 PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm)); 448 PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm)); 449 PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL)); 450 451 /* Handle case where user passes in global vector as opposed to local */ 452 PetscCall(VecGetLocalSize(vec, &N)); 453 if (N == xm * ym * zm * dof) { 454 gxm = xm; 455 gym = ym; 456 gzm = zm; 457 gxs = xs; 458 gys = ys; 459 gzs = zs; 460 } 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); 461 462 if (dim == 1) { 463 PetscCall(VecGetArray1dRead(vec, gxm * dof, gxs * dof, (PetscScalar **)array)); 464 } else if (dim == 2) { 465 PetscCall(VecGetArray2dRead(vec, gym, gxm * dof, gys, gxs * dof, (PetscScalar ***)array)); 466 } else if (dim == 3) { 467 PetscCall(VecGetArray3dRead(vec, gzm, gym, gxm * dof, gzs, gys, gxs * dof, (PetscScalar ****)array)); 468 } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim); 469 PetscFunctionReturn(PETSC_SUCCESS); 470 } 471 472 /*MC 473 DMDAVecRestoreArrayReadF90 - check Fortran Notes at `DMDAVecRestoreArrayRead()` 474 475 Level: intermediate 476 M*/ 477 478 /*@ 479 DMDAVecRestoreArrayRead - Restores a multiple dimension array obtained with `DMDAVecGetArrayRead()` 480 481 Not collective 482 483 Input Parameters: 484 + da - the distributed array 485 . vec - the vector, either a vector the same size as one obtained with 486 `DMCreateGlobalVector()` or `DMCreateLocalVector()` 487 - array - the array, non-NULL pointer is zeroed 488 489 Level: intermediate 490 491 Fortran Note: 492 Use `DMDAVecRestoreArrayReadF90()` 493 494 .seealso: `DM`, `DMDA`, `DMDAVecRestoreArrayReadF90()`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecGetArrayRead()`, 495 `DMDAVecGetArray()`, `DMDAVecRestoreArray()`, `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`, 496 `DMStagVecRestoreArrayRead()` 497 @*/ 498 PetscErrorCode DMDAVecRestoreArrayRead(DM da, Vec vec, void *array) 499 { 500 PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof; 501 502 PetscFunctionBegin; 503 PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA); 504 PetscValidHeaderSpecific(vec, VEC_CLASSID, 2); 505 PetscValidPointer(array, 3); 506 PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm)); 507 PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm)); 508 PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL)); 509 510 /* Handle case where user passes in global vector as opposed to local */ 511 PetscCall(VecGetLocalSize(vec, &N)); 512 if (N == xm * ym * zm * dof) { 513 gxm = xm; 514 gym = ym; 515 gzm = zm; 516 gxs = xs; 517 gys = ys; 518 gzs = zs; 519 } 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); 520 521 if (dim == 1) { 522 PetscCall(VecRestoreArray1dRead(vec, gxm * dof, gxs * dof, (PetscScalar **)array)); 523 } else if (dim == 2) { 524 PetscCall(VecRestoreArray2dRead(vec, gym, gxm * dof, gys, gxs * dof, (PetscScalar ***)array)); 525 } else if (dim == 3) { 526 PetscCall(VecRestoreArray3dRead(vec, gzm, gym, gxm * dof, gzs, gys, gxs * dof, (PetscScalar ****)array)); 527 } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim); 528 PetscFunctionReturn(PETSC_SUCCESS); 529 } 530 531 /*@C 532 DMDAVecGetArrayDOFRead - Returns a multiple dimension array that shares data with 533 the underlying vector and is indexed using the global dimensions. 534 535 Not Collective 536 537 Input Parameters: 538 + da - the distributed array 539 - vec - the vector, either a vector the same size as one obtained with 540 `DMCreateGlobalVector()` or `DMCreateLocalVector()` 541 542 Output Parameter: 543 . array - the array 544 545 Level: intermediate 546 547 Notes: 548 Call `DMDAVecRestoreArrayDOFRead()` once you have finished accessing the vector entries. 549 550 In C, the indexing is "backwards" from what expects: array[k][j][i][DOF] NOT array[i][j][k][DOF]! 551 552 Fortran Note: 553 Use `DMDAVecGetArrayReadF90()` and pass for the array type PetscScalar,pointer :: array(:,...,:) of the appropriate 554 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 555 dimension of the `DMDA`. 556 557 The order of the indices is array(xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1) (when dof is 1) otherwise 558 array(0:dof-1,xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1) where the values are obtained from 559 `DMDAGetCorners()` for a global array or `DMDAGetGhostCorners()` for a local array. 560 561 .seealso: `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecRestoreArray()`, `DMDAVecGetArray()`, `DMDAVecGetArrayDOF()`, 562 `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()` 563 @*/ 564 PetscErrorCode DMDAVecGetArrayDOFRead(DM da, Vec vec, void *array) 565 { 566 PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof; 567 568 PetscFunctionBegin; 569 PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm)); 570 PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm)); 571 PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL)); 572 573 /* Handle case where user passes in global vector as opposed to local */ 574 PetscCall(VecGetLocalSize(vec, &N)); 575 if (N == xm * ym * zm * dof) { 576 gxm = xm; 577 gym = ym; 578 gzm = zm; 579 gxs = xs; 580 gys = ys; 581 gzs = zs; 582 } 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); 583 584 if (dim == 1) { 585 PetscCall(VecGetArray2dRead(vec, gxm, dof, gxs, 0, (PetscScalar ***)array)); 586 } else if (dim == 2) { 587 PetscCall(VecGetArray3dRead(vec, gym, gxm, dof, gys, gxs, 0, (PetscScalar ****)array)); 588 } else if (dim == 3) { 589 PetscCall(VecGetArray4dRead(vec, gzm, gym, gxm, dof, gzs, gys, gxs, 0, (PetscScalar *****)array)); 590 } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim); 591 PetscFunctionReturn(PETSC_SUCCESS); 592 } 593 594 /*@ 595 DMDAVecRestoreArrayDOFRead - Restores a multiple dimension array obtained with `DMDAVecGetArrayDOFRead()` 596 597 Not Collective 598 599 Input Parameters: 600 + da - the distributed array 601 . vec - the vector, either a vector the same size as one obtained with 602 `DMCreateGlobalVector()` or `DMCreateLocalVector()` 603 - array - the array 604 605 Level: intermediate 606 607 Fortran Note: 608 Use `DMDAVecRestoreArrayReadF90()` 609 610 .seealso: `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecGetArray()`, `DMDAVecGetArrayDOF()`, `DMDAVecRestoreArrayDOF()`, 611 `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()` 612 @*/ 613 PetscErrorCode DMDAVecRestoreArrayDOFRead(DM da, Vec vec, void *array) 614 { 615 PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof; 616 617 PetscFunctionBegin; 618 PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm)); 619 PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm)); 620 PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL)); 621 622 /* Handle case where user passes in global vector as opposed to local */ 623 PetscCall(VecGetLocalSize(vec, &N)); 624 if (N == xm * ym * zm * dof) { 625 gxm = xm; 626 gym = ym; 627 gzm = zm; 628 gxs = xs; 629 gys = ys; 630 gzs = zs; 631 } 632 633 if (dim == 1) { 634 PetscCall(VecRestoreArray2dRead(vec, gxm, dof, gxs, 0, (PetscScalar ***)array)); 635 } else if (dim == 2) { 636 PetscCall(VecRestoreArray3dRead(vec, gym, gxm, dof, gys, gxs, 0, (PetscScalar ****)array)); 637 } else if (dim == 3) { 638 PetscCall(VecRestoreArray4dRead(vec, gzm, gym, gxm, dof, gzs, gys, gxs, 0, (PetscScalar *****)array)); 639 } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim); 640 PetscFunctionReturn(PETSC_SUCCESS); 641 } 642 643 /*@C 644 DMDAVecGetArrayDOFWrite - Returns a multiple dimension array that shares data with 645 the underlying vector and is indexed using the global dimensions. 646 647 Not Collective 648 649 Input Parameters: 650 + da - the distributed array 651 - vec - the vector, either a vector the same size as one obtained with 652 `DMCreateGlobalVector()` or `DMCreateLocalVector()` 653 654 Output Parameter: 655 . array - the array 656 657 Level: intermediate 658 659 Notes: 660 Call `DMDAVecRestoreArrayDOFWrite()` once you have finished accessing the vector entries. 661 662 In C, the indexing is "backwards" from what expects: array[k][j][i][DOF] NOT array[i][j][k][DOF]! 663 664 Fortran Note: 665 Use `DMDAVecGetArrayWriteF90()` and pass for the array type PetscScalar,pointer :: array(:,...,:) of the appropriate 666 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 667 dimension of the `DMDA`. 668 669 The order of the indices is array(xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1) (when dof is 1) otherwise 670 array(0:dof-1,xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1) where the values are obtained from 671 `DMDAGetCorners()` for a global array or `DMDAGetGhostCorners()` for a local array. 672 673 .seealso: `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `DMDAVecRestoreArrayWriteF90()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecRestoreArray()`, `DMDAVecGetArray()`, `DMDAVecGetArrayDOF()`, 674 `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`, `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()` 675 @*/ 676 PetscErrorCode DMDAVecGetArrayDOFWrite(DM da, Vec vec, void *array) 677 { 678 PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof; 679 680 PetscFunctionBegin; 681 PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm)); 682 PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm)); 683 PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL)); 684 685 /* Handle case where user passes in global vector as opposed to local */ 686 PetscCall(VecGetLocalSize(vec, &N)); 687 if (N == xm * ym * zm * dof) { 688 gxm = xm; 689 gym = ym; 690 gzm = zm; 691 gxs = xs; 692 gys = ys; 693 gzs = zs; 694 } 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); 695 696 if (dim == 1) { 697 PetscCall(VecGetArray2dWrite(vec, gxm, dof, gxs, 0, (PetscScalar ***)array)); 698 } else if (dim == 2) { 699 PetscCall(VecGetArray3dWrite(vec, gym, gxm, dof, gys, gxs, 0, (PetscScalar ****)array)); 700 } else if (dim == 3) { 701 PetscCall(VecGetArray4dWrite(vec, gzm, gym, gxm, dof, gzs, gys, gxs, 0, (PetscScalar *****)array)); 702 } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim); 703 PetscFunctionReturn(PETSC_SUCCESS); 704 } 705 706 /*@ 707 DMDAVecRestoreArrayDOFWrite - Restores a multiple dimension array obtained with `DMDAVecGetArrayDOFWrite()` 708 709 Not Collective 710 711 Input Parameters: 712 + da - the distributed array 713 . vec - the vector, either a vector the same size as one obtained with 714 `DMCreateGlobalVector()` or `DMCreateLocalVector()` 715 - array - the array 716 717 Level: intermediate 718 719 Fortran Note: 720 Use `DMDAVecRestoreArrayWriteF90()` 721 722 .seealso: `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecGetArray()`, `DMDAVecGetArrayDOF()`, `DMDAVecRestoreArrayDOF()`, 723 `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`, `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()` 724 @*/ 725 PetscErrorCode DMDAVecRestoreArrayDOFWrite(DM da, Vec vec, void *array) 726 { 727 PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof; 728 729 PetscFunctionBegin; 730 PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm)); 731 PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm)); 732 PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL)); 733 734 /* Handle case where user passes in global vector as opposed to local */ 735 PetscCall(VecGetLocalSize(vec, &N)); 736 if (N == xm * ym * zm * dof) { 737 gxm = xm; 738 gym = ym; 739 gzm = zm; 740 gxs = xs; 741 gys = ys; 742 gzs = zs; 743 } 744 745 if (dim == 1) { 746 PetscCall(VecRestoreArray2dWrite(vec, gxm, dof, gxs, 0, (PetscScalar ***)array)); 747 } else if (dim == 2) { 748 PetscCall(VecRestoreArray3dWrite(vec, gym, gxm, dof, gys, gxs, 0, (PetscScalar ****)array)); 749 } else if (dim == 3) { 750 PetscCall(VecRestoreArray4dWrite(vec, gzm, gym, gxm, dof, gzs, gys, gxs, 0, (PetscScalar *****)array)); 751 } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim); 752 PetscFunctionReturn(PETSC_SUCCESS); 753 } 754