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