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