147c6ae99SBarry Smith 2af0996ceSBarry Smith #include <petsc/private/dmdaimpl.h> /*I "petscdmda.h" I*/ 347c6ae99SBarry Smith 40f99b6f4SBarry Smith /*MC 50f99b6f4SBarry Smith DMDAVecGetArrayF90 - check Fortran Notes at `DMDAVecGetArray()` 60f99b6f4SBarry Smith M*/ 70f99b6f4SBarry Smith 847c6ae99SBarry Smith /*@C 9aa219208SBarry Smith DMDAVecGetArray - Returns a multiple dimension array that shares data with 1047c6ae99SBarry Smith the underlying vector and is indexed using the global dimensions. 1147c6ae99SBarry Smith 12d083f849SBarry Smith Logically collective on da 1347c6ae99SBarry Smith 14d8d19677SJose E. Roman Input Parameters: 1547c6ae99SBarry Smith + da - the distributed array 16dce8aebaSBarry Smith - vec - the vector, either a vector the same size as one obtained with `DMCreateGlobalVector()` or `DMCreateLocalVector()` 1747c6ae99SBarry Smith 1847c6ae99SBarry Smith Output Parameter: 1947c6ae99SBarry Smith . array - the array 2047c6ae99SBarry Smith 21dce8aebaSBarry Smith Level: intermediate 22dce8aebaSBarry Smith 2347c6ae99SBarry Smith Notes: 24dce8aebaSBarry Smith Call `DMDAVecRestoreArray()` once you have finished accessing the vector entries. 2547c6ae99SBarry Smith 2647c6ae99SBarry Smith In C, the indexing is "backwards" from what expects: array[k][j][i] NOT array[i][j][k]! 2747c6ae99SBarry Smith 287e57d48aSBarry Smith If vec is a local vector (obtained with DMCreateLocalVector() etc) then the ghost point locations are accessible. If it is 297e57d48aSBarry Smith a global vector then the ghost points are not accessible. Of course with the local vector you will have had to do the 3047c6ae99SBarry Smith 31dce8aebaSBarry Smith appropriate `DMGlobalToLocalBegin()` and `DMGlobalToLocalEnd()` to have correct values in the ghost locations. 3247c6ae99SBarry Smith 3395452b02SPatrick Sanan Fortran Notes: 340f99b6f4SBarry Smith Use `DMDAVecGetArrayF90()` and pass for the array type `PetscScalar`,pointer :: array(:,...,:) of the appropriate 35dce8aebaSBarry Smith 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 360f99b6f4SBarry Smith dimension of the `DMDA`. 3747c6ae99SBarry Smith 380f99b6f4SBarry Smith The order of the indices is array(xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1) (when dof is 1) otherwise 390f99b6f4SBarry Smith array(0:dof-1,xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1) where the values are obtained from 400f99b6f4SBarry Smith `DMDAGetCorners()` for a global array or `DMDAGetGhostCorners()` for a local array. 4147c6ae99SBarry Smith 42dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecRestoreArray()`, `DMDAVecRestoreArrayDOF()` 43db781477SPatrick Sanan `DMDAVecGetArrayDOF()`, `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()`, 44db781477SPatrick Sanan `DMStagVecGetArray()` 4547c6ae99SBarry Smith @*/ 46d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAVecGetArray(DM da, Vec vec, void *array) 47d71ae5a4SJacob Faibussowitsch { 4847c6ae99SBarry Smith PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof; 4947c6ae99SBarry Smith 5047c6ae99SBarry Smith PetscFunctionBegin; 51a9a02de4SBarry Smith PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA); 526db82c94SMatthew G Knepley PetscValidHeaderSpecific(vec, VEC_CLASSID, 2); 536db82c94SMatthew G Knepley PetscValidPointer(array, 3); 549566063dSJacob Faibussowitsch PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm)); 559566063dSJacob Faibussowitsch PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm)); 569566063dSJacob Faibussowitsch PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL)); 5747c6ae99SBarry Smith 5847c6ae99SBarry Smith /* Handle case where user passes in global vector as opposed to local */ 599566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(vec, &N)); 6047c6ae99SBarry Smith if (N == xm * ym * zm * dof) { 6147c6ae99SBarry Smith gxm = xm; 6247c6ae99SBarry Smith gym = ym; 6347c6ae99SBarry Smith gzm = zm; 6447c6ae99SBarry Smith gxs = xs; 6547c6ae99SBarry Smith gys = ys; 6647c6ae99SBarry Smith gzs = zs; 6763a3b9bcSJacob Faibussowitsch } 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); 6847c6ae99SBarry Smith 6947c6ae99SBarry Smith if (dim == 1) { 709566063dSJacob Faibussowitsch PetscCall(VecGetArray1d(vec, gxm * dof, gxs * dof, (PetscScalar **)array)); 7147c6ae99SBarry Smith } else if (dim == 2) { 729566063dSJacob Faibussowitsch PetscCall(VecGetArray2d(vec, gym, gxm * dof, gys, gxs * dof, (PetscScalar ***)array)); 7347c6ae99SBarry Smith } else if (dim == 3) { 749566063dSJacob Faibussowitsch PetscCall(VecGetArray3d(vec, gzm, gym, gxm * dof, gzs, gys, gxs * dof, (PetscScalar ****)array)); 7563a3b9bcSJacob Faibussowitsch } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim); 763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7747c6ae99SBarry Smith } 7847c6ae99SBarry Smith 790f99b6f4SBarry Smith /*MC 800f99b6f4SBarry Smith DMDAVecRestoreArrayF90 - check Fortran Notes at `DMDAVecRestoreArray()` 81*53c0d4aeSBarry Smith 82*53c0d4aeSBarry Smith Level: intermediate 830f99b6f4SBarry Smith M*/ 840f99b6f4SBarry Smith 8547c6ae99SBarry Smith /*@ 86dce8aebaSBarry Smith DMDAVecRestoreArray - Restores a multiple dimension array obtained with `DMDAVecGetArray()` 8747c6ae99SBarry Smith 88d083f849SBarry Smith Logically collective on da 8947c6ae99SBarry Smith 90d8d19677SJose E. Roman Input Parameters: 9147c6ae99SBarry Smith + da - the distributed array 9247c6ae99SBarry Smith . vec - the vector, either a vector the same size as one obtained with 930f99b6f4SBarry Smith `DMCreateGlobalVector()` or `DMCreateLocalVector()` 94e5c84f05SJed Brown - array - the array, non-NULL pointer is zeroed 9547c6ae99SBarry Smith 9647c6ae99SBarry Smith Level: intermediate 9747c6ae99SBarry Smith 98dce8aebaSBarry Smith Fortran Note: 99dce8aebaSBarry Smith From Fortran use `DMDAVecRestoreArayF90()` 10047c6ae99SBarry Smith 1010f99b6f4SBarry Smith .seealso: `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `DMDAVecRestoreArayF90()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecGetArray()`, 102db781477SPatrick Sanan `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()`, 103db781477SPatrick Sanan `DMDStagVecRestoreArray()` 10447c6ae99SBarry Smith @*/ 105d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAVecRestoreArray(DM da, Vec vec, void *array) 106d71ae5a4SJacob Faibussowitsch { 10747c6ae99SBarry Smith PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof; 10847c6ae99SBarry Smith 10947c6ae99SBarry Smith PetscFunctionBegin; 110a9a02de4SBarry Smith PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA); 1116db82c94SMatthew G Knepley PetscValidHeaderSpecific(vec, VEC_CLASSID, 2); 1126db82c94SMatthew G Knepley PetscValidPointer(array, 3); 1139566063dSJacob Faibussowitsch PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm)); 1149566063dSJacob Faibussowitsch PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm)); 1159566063dSJacob Faibussowitsch PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL)); 11647c6ae99SBarry Smith 11747c6ae99SBarry Smith /* Handle case where user passes in global vector as opposed to local */ 1189566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(vec, &N)); 11947c6ae99SBarry Smith if (N == xm * ym * zm * dof) { 12047c6ae99SBarry Smith gxm = xm; 12147c6ae99SBarry Smith gym = ym; 12247c6ae99SBarry Smith gzm = zm; 12347c6ae99SBarry Smith gxs = xs; 12447c6ae99SBarry Smith gys = ys; 12547c6ae99SBarry Smith gzs = zs; 12663a3b9bcSJacob Faibussowitsch } 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); 12747c6ae99SBarry Smith 12847c6ae99SBarry Smith if (dim == 1) { 1299566063dSJacob Faibussowitsch PetscCall(VecRestoreArray1d(vec, gxm * dof, gxs * dof, (PetscScalar **)array)); 13047c6ae99SBarry Smith } else if (dim == 2) { 1319566063dSJacob Faibussowitsch PetscCall(VecRestoreArray2d(vec, gym, gxm * dof, gys, gxs * dof, (PetscScalar ***)array)); 13247c6ae99SBarry Smith } else if (dim == 3) { 1339566063dSJacob Faibussowitsch PetscCall(VecRestoreArray3d(vec, gzm, gym, gxm * dof, gzs, gys, gxs * dof, (PetscScalar ****)array)); 13463a3b9bcSJacob Faibussowitsch } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim); 1353ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 13647c6ae99SBarry Smith } 13747c6ae99SBarry Smith 1380f99b6f4SBarry Smith /*MC 1390f99b6f4SBarry Smith DMDAVecGetArrayWriteF90 - check Fortran Notes at `DMDAVecGetArrayWrite()` 140*53c0d4aeSBarry Smith 141*53c0d4aeSBarry Smith Level: intermediate 1420f99b6f4SBarry Smith M*/ 1430f99b6f4SBarry Smith 14447c6ae99SBarry Smith /*@C 145fdc842d1SBarry Smith DMDAVecGetArrayWrite - Returns a multiple dimension array that shares data with 146fdc842d1SBarry Smith the underlying vector and is indexed using the global dimensions. 147fdc842d1SBarry Smith 148fdc842d1SBarry Smith Logically collective on Vec 149fdc842d1SBarry Smith 150d8d19677SJose E. Roman Input Parameters: 151fdc842d1SBarry Smith + da - the distributed array 152dce8aebaSBarry Smith - vec - the vector, either a vector the same size as one obtained with `DMCreateGlobalVector()` or `DMCreateLocalVector()` 153fdc842d1SBarry Smith 154fdc842d1SBarry Smith Output Parameter: 155fdc842d1SBarry Smith . array - the array 156fdc842d1SBarry Smith 157dce8aebaSBarry Smith Level: intermediate 158dce8aebaSBarry Smith 159fdc842d1SBarry Smith Notes: 160dce8aebaSBarry Smith Call `DMDAVecRestoreArray()` once you have finished accessing the vector entries. 161fdc842d1SBarry Smith 162fdc842d1SBarry Smith In C, the indexing is "backwards" from what expects: array[k][j][i] NOT array[i][j][k]! 163fdc842d1SBarry Smith 164dce8aebaSBarry Smith If vec is a local vector (obtained with `DMCreateLocalVector()` etc) then the ghost point locations are accessible. If it is 165fdc842d1SBarry Smith a global vector then the ghost points are not accessible. Of course with the local vector you will have had to do the 166dce8aebaSBarry Smith appropriate `DMGlobalToLocalBegin()` and `DMGlobalToLocalEnd()` to have correct values in the ghost locations. 167fdc842d1SBarry Smith 168fdc842d1SBarry Smith Fortran Notes: 1690f99b6f4SBarry Smith From Fortran use `DMDAVecGetArrayWriteF90()` and pass for the array type PetscScalar,pointer :: array(:,...,:) of the appropriate 170dce8aebaSBarry Smith 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 1710f99b6f4SBarry Smith dimension of the `DMDA`. 172fdc842d1SBarry Smith 1730f99b6f4SBarry Smith The order of the indices is array(xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1) (when dof is 1) otherwise 1740f99b6f4SBarry Smith array(0:dof-1,xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1) where the values are obtained from 1750f99b6f4SBarry Smith `DMDAGetCorners()` for a global array or `DMDAGetGhostCorners()` for a local array. 176fdc842d1SBarry Smith 177dce8aebaSBarry Smith Developer Note: 178dce8aebaSBarry Smith This has code duplication with `DMDAVecGetArray()` and `DMDAVecGetArrayRead()` 179fdc842d1SBarry Smith 180dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecRestoreArrayWrite()`, `DMDAVecRestoreArrayDOF()` 181db781477SPatrick Sanan `DMDAVecGetArrayDOF()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()` 182fdc842d1SBarry Smith @*/ 183d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAVecGetArrayWrite(DM da, Vec vec, void *array) 184d71ae5a4SJacob Faibussowitsch { 185fdc842d1SBarry Smith PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof; 186fdc842d1SBarry Smith 187fdc842d1SBarry Smith PetscFunctionBegin; 188fdc842d1SBarry Smith PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA); 189fdc842d1SBarry Smith PetscValidHeaderSpecific(vec, VEC_CLASSID, 2); 190fdc842d1SBarry Smith PetscValidPointer(array, 3); 1911bb6d2a8SBarry Smith if (da->localSection) { 1929566063dSJacob Faibussowitsch PetscCall(VecGetArrayWrite(vec, (PetscScalar **)array)); 1933ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 194fdc842d1SBarry Smith } 1959566063dSJacob Faibussowitsch PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm)); 1969566063dSJacob Faibussowitsch PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm)); 1979566063dSJacob Faibussowitsch PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL)); 198fdc842d1SBarry Smith 199fdc842d1SBarry Smith /* Handle case where user passes in global vector as opposed to local */ 2009566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(vec, &N)); 201fdc842d1SBarry Smith if (N == xm * ym * zm * dof) { 202fdc842d1SBarry Smith gxm = xm; 203fdc842d1SBarry Smith gym = ym; 204fdc842d1SBarry Smith gzm = zm; 205fdc842d1SBarry Smith gxs = xs; 206fdc842d1SBarry Smith gys = ys; 207fdc842d1SBarry Smith gzs = zs; 20863a3b9bcSJacob Faibussowitsch } 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); 209fdc842d1SBarry Smith 210fdc842d1SBarry Smith if (dim == 1) { 2119566063dSJacob Faibussowitsch PetscCall(VecGetArray1dWrite(vec, gxm * dof, gxs * dof, (PetscScalar **)array)); 212fdc842d1SBarry Smith } else if (dim == 2) { 2139566063dSJacob Faibussowitsch PetscCall(VecGetArray2dWrite(vec, gym, gxm * dof, gys, gxs * dof, (PetscScalar ***)array)); 214fdc842d1SBarry Smith } else if (dim == 3) { 2159566063dSJacob Faibussowitsch PetscCall(VecGetArray3dWrite(vec, gzm, gym, gxm * dof, gzs, gys, gxs * dof, (PetscScalar ****)array)); 21663a3b9bcSJacob Faibussowitsch } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim); 2173ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 218fdc842d1SBarry Smith } 219fdc842d1SBarry Smith 2200f99b6f4SBarry Smith /*MC 2210f99b6f4SBarry Smith DMDAVecRestoreArrayWriteF90 - check Fortran Notes at `DMDAVecRestoreArrayWrite()` 222*53c0d4aeSBarry Smith 223*53c0d4aeSBarry Smith Level: intermediate 2240f99b6f4SBarry Smith M*/ 2250f99b6f4SBarry Smith 226fdc842d1SBarry Smith /*@ 227dce8aebaSBarry Smith DMDAVecRestoreArrayWrite - Restores a multiple dimension array obtained with `DMDAVecGetArrayWrite()` 228fdc842d1SBarry Smith 229dce8aebaSBarry Smith Logically collective on vec 230fdc842d1SBarry Smith 231d8d19677SJose E. Roman Input Parameters: 232fdc842d1SBarry Smith + da - the distributed array 233fdc842d1SBarry Smith . vec - the vector, either a vector the same size as one obtained with 234dce8aebaSBarry Smith `DMCreateGlobalVector()` or `DMCreateLocalVector()` 235fdc842d1SBarry Smith - array - the array, non-NULL pointer is zeroed 236fdc842d1SBarry Smith 237fdc842d1SBarry Smith Level: intermediate 238fdc842d1SBarry Smith 239dce8aebaSBarry Smith Fortran Note: 2400f99b6f4SBarry Smith Use `DMDAVecRestoreArayWriteF90()` 241fdc842d1SBarry Smith 242dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecGetArrayWrite()`, 243db781477SPatrick Sanan `DMDAVecGetArray()`, `DMDAVecRestoreArray()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()` 244fdc842d1SBarry Smith @*/ 245d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAVecRestoreArrayWrite(DM da, Vec vec, void *array) 246d71ae5a4SJacob Faibussowitsch { 247fdc842d1SBarry Smith PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof; 248fdc842d1SBarry Smith 249fdc842d1SBarry Smith PetscFunctionBegin; 250fdc842d1SBarry Smith PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA); 251fdc842d1SBarry Smith PetscValidHeaderSpecific(vec, VEC_CLASSID, 2); 252fdc842d1SBarry Smith PetscValidPointer(array, 3); 2531bb6d2a8SBarry Smith if (da->localSection) { 2549566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(vec, (PetscScalar **)array)); 2553ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 256fdc842d1SBarry Smith } 2579566063dSJacob Faibussowitsch PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm)); 2589566063dSJacob Faibussowitsch PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm)); 2599566063dSJacob Faibussowitsch PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL)); 260fdc842d1SBarry Smith 261fdc842d1SBarry Smith /* Handle case where user passes in global vector as opposed to local */ 2629566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(vec, &N)); 263fdc842d1SBarry Smith if (N == xm * ym * zm * dof) { 264fdc842d1SBarry Smith gxm = xm; 265fdc842d1SBarry Smith gym = ym; 266fdc842d1SBarry Smith gzm = zm; 267fdc842d1SBarry Smith gxs = xs; 268fdc842d1SBarry Smith gys = ys; 269fdc842d1SBarry Smith gzs = zs; 27063a3b9bcSJacob Faibussowitsch } 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); 271fdc842d1SBarry Smith 272fdc842d1SBarry Smith if (dim == 1) { 2739566063dSJacob Faibussowitsch PetscCall(VecRestoreArray1dWrite(vec, gxm * dof, gxs * dof, (PetscScalar **)array)); 274fdc842d1SBarry Smith } else if (dim == 2) { 2759566063dSJacob Faibussowitsch PetscCall(VecRestoreArray2dWrite(vec, gym, gxm * dof, gys, gxs * dof, (PetscScalar ***)array)); 276fdc842d1SBarry Smith } else if (dim == 3) { 2779566063dSJacob Faibussowitsch PetscCall(VecRestoreArray3dWrite(vec, gzm, gym, gxm * dof, gzs, gys, gxs * dof, (PetscScalar ****)array)); 27863a3b9bcSJacob Faibussowitsch } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim); 2793ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 280fdc842d1SBarry Smith } 281fdc842d1SBarry Smith 282fdc842d1SBarry Smith /*@C 283aa219208SBarry Smith DMDAVecGetArrayDOF - Returns a multiple dimension array that shares data with 28447c6ae99SBarry Smith the underlying vector and is indexed using the global dimensions. 28547c6ae99SBarry Smith 2862ddbf755SMatthew G. Knepley Logically collective 28747c6ae99SBarry Smith 288d8d19677SJose E. Roman Input Parameters: 28947c6ae99SBarry Smith + da - the distributed array 29047c6ae99SBarry Smith - vec - the vector, either a vector the same size as one obtained with 291dce8aebaSBarry Smith `DMCreateGlobalVector()` or `DMCreateLocalVector()` 29247c6ae99SBarry Smith 29347c6ae99SBarry Smith Output Parameter: 29447c6ae99SBarry Smith . array - the array 29547c6ae99SBarry Smith 296dce8aebaSBarry Smith Level: intermediate 297dce8aebaSBarry Smith 29847c6ae99SBarry Smith Notes: 299dce8aebaSBarry Smith Call `DMDAVecRestoreArrayDOF()` once you have finished accessing the vector entries. 30047c6ae99SBarry Smith 30147c6ae99SBarry Smith In C, the indexing is "backwards" from what expects: array[k][j][i][DOF] NOT array[i][j][k][DOF]! 30247c6ae99SBarry Smith 3030f99b6f4SBarry Smith Fortran Notes: 3040f99b6f4SBarry Smith Use `DMDAVecGetArrayF90()` and pass for the array type PetscScalar,pointer :: array(:,...,:) of the appropriate 3050f99b6f4SBarry Smith 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 3060f99b6f4SBarry Smith dimension of the `DMDA`. 3070f99b6f4SBarry Smith 3080f99b6f4SBarry Smith The order of the indices is array(xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1) (when dof is 1) otherwise 3090f99b6f4SBarry Smith array(0:dof-1,xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1) where the values are obtained from 3100f99b6f4SBarry Smith `DMDAGetCorners()` for a global array or `DMDAGetGhostCorners()` for a local array. 3111b82215eSBarry Smith 312dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecRestoreArray()`, `DMDAVecGetArray()`, `DMDAVecRestoreArrayDOF()`, 3134ab966ffSPatrick Sanan `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()`, `DMDAVecGetArrayDOFRead()` 31447c6ae99SBarry Smith @*/ 315d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAVecGetArrayDOF(DM da, Vec vec, void *array) 316d71ae5a4SJacob Faibussowitsch { 31747c6ae99SBarry Smith PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof; 31847c6ae99SBarry Smith 31947c6ae99SBarry Smith PetscFunctionBegin; 3209566063dSJacob Faibussowitsch PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm)); 3219566063dSJacob Faibussowitsch PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm)); 3229566063dSJacob Faibussowitsch PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL)); 32347c6ae99SBarry Smith 32447c6ae99SBarry Smith /* Handle case where user passes in global vector as opposed to local */ 3259566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(vec, &N)); 32647c6ae99SBarry Smith if (N == xm * ym * zm * dof) { 32747c6ae99SBarry Smith gxm = xm; 32847c6ae99SBarry Smith gym = ym; 32947c6ae99SBarry Smith gzm = zm; 33047c6ae99SBarry Smith gxs = xs; 33147c6ae99SBarry Smith gys = ys; 33247c6ae99SBarry Smith gzs = zs; 33363a3b9bcSJacob Faibussowitsch } 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); 33447c6ae99SBarry Smith 33547c6ae99SBarry Smith if (dim == 1) { 3369566063dSJacob Faibussowitsch PetscCall(VecGetArray2d(vec, gxm, dof, gxs, 0, (PetscScalar ***)array)); 33747c6ae99SBarry Smith } else if (dim == 2) { 3389566063dSJacob Faibussowitsch PetscCall(VecGetArray3d(vec, gym, gxm, dof, gys, gxs, 0, (PetscScalar ****)array)); 33947c6ae99SBarry Smith } else if (dim == 3) { 3409566063dSJacob Faibussowitsch PetscCall(VecGetArray4d(vec, gzm, gym, gxm, dof, gzs, gys, gxs, 0, (PetscScalar *****)array)); 34163a3b9bcSJacob Faibussowitsch } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim); 3423ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 34347c6ae99SBarry Smith } 34447c6ae99SBarry Smith 34547c6ae99SBarry Smith /*@ 346dce8aebaSBarry Smith DMDAVecRestoreArrayDOF - Restores a multiple dimension array obtained with `DMDAVecGetArrayDOF()` 34747c6ae99SBarry Smith 3482ddbf755SMatthew G. Knepley Logically collective 34947c6ae99SBarry Smith 350d8d19677SJose E. Roman Input Parameters: 35147c6ae99SBarry Smith + da - the distributed array 35247c6ae99SBarry Smith . vec - the vector, either a vector the same size as one obtained with 353dce8aebaSBarry Smith `DMCreateGlobalVector()` or `DMCreateLocalVector()` 35447c6ae99SBarry Smith - array - the array 35547c6ae99SBarry Smith 35647c6ae99SBarry Smith Level: intermediate 35747c6ae99SBarry Smith 3580f99b6f4SBarry Smith Fortran Note: 3590f99b6f4SBarry Smith Use `DMDAVecRestoreArayF90()` 3600f99b6f4SBarry Smith 361dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecGetArray()`, `DMDAVecGetArrayDOF()`, `DMDAVecRestoreArrayDOF()`, 3624ab966ffSPatrick Sanan `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()` 36347c6ae99SBarry Smith @*/ 364d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAVecRestoreArrayDOF(DM da, Vec vec, void *array) 365d71ae5a4SJacob Faibussowitsch { 36647c6ae99SBarry Smith PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof; 36747c6ae99SBarry Smith 36847c6ae99SBarry Smith PetscFunctionBegin; 3699566063dSJacob Faibussowitsch PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm)); 3709566063dSJacob Faibussowitsch PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm)); 3719566063dSJacob Faibussowitsch PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL)); 37247c6ae99SBarry Smith 37347c6ae99SBarry Smith /* Handle case where user passes in global vector as opposed to local */ 3749566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(vec, &N)); 37547c6ae99SBarry Smith if (N == xm * ym * zm * dof) { 37647c6ae99SBarry Smith gxm = xm; 37747c6ae99SBarry Smith gym = ym; 37847c6ae99SBarry Smith gzm = zm; 37947c6ae99SBarry Smith gxs = xs; 38047c6ae99SBarry Smith gys = ys; 38147c6ae99SBarry Smith gzs = zs; 38247c6ae99SBarry Smith } 38347c6ae99SBarry Smith 38447c6ae99SBarry Smith if (dim == 1) { 3859566063dSJacob Faibussowitsch PetscCall(VecRestoreArray2d(vec, gxm, dof, gxs, 0, (PetscScalar ***)array)); 38647c6ae99SBarry Smith } else if (dim == 2) { 3879566063dSJacob Faibussowitsch PetscCall(VecRestoreArray3d(vec, gym, gxm, dof, gys, gxs, 0, (PetscScalar ****)array)); 38847c6ae99SBarry Smith } else if (dim == 3) { 3899566063dSJacob Faibussowitsch PetscCall(VecRestoreArray4d(vec, gzm, gym, gxm, dof, gzs, gys, gxs, 0, (PetscScalar *****)array)); 39063a3b9bcSJacob Faibussowitsch } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim); 3913ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 39247c6ae99SBarry Smith } 39347c6ae99SBarry Smith 3940f99b6f4SBarry Smith /*MC 3950f99b6f4SBarry Smith DMDAVecGetArrayReadF90 - check Fortran Notes at `DMDAVecGetArrayRead()` 396*53c0d4aeSBarry Smith 397*53c0d4aeSBarry Smith Level: intermediate 3980f99b6f4SBarry Smith M*/ 3990f99b6f4SBarry Smith 4005edff71fSBarry Smith /*@C 4015edff71fSBarry Smith DMDAVecGetArrayRead - Returns a multiple dimension array that shares data with 4025edff71fSBarry Smith the underlying vector and is indexed using the global dimensions. 4035edff71fSBarry Smith 4042ddbf755SMatthew G. Knepley Not collective 4055edff71fSBarry Smith 406d8d19677SJose E. Roman Input Parameters: 4075edff71fSBarry Smith + da - the distributed array 408dce8aebaSBarry Smith - vec - the vector, either a vector the same size as one obtained with `DMCreateGlobalVector()` or `DMCreateLocalVector()` 4095edff71fSBarry Smith 4105edff71fSBarry Smith Output Parameter: 4115edff71fSBarry Smith . array - the array 4125edff71fSBarry Smith 413dce8aebaSBarry Smith Level: intermediate 414dce8aebaSBarry Smith 4155edff71fSBarry Smith Notes: 416dce8aebaSBarry Smith Call `DMDAVecRestoreArrayRead()` once you have finished accessing the vector entries. 4175edff71fSBarry Smith 4185edff71fSBarry Smith In C, the indexing is "backwards" from what expects: array[k][j][i] NOT array[i][j][k]! 4195edff71fSBarry Smith 420dce8aebaSBarry Smith If vec is a local vector (obtained with `DMCreateLocalVector()` etc) then the ghost point locations are accessible. If it is 4215edff71fSBarry Smith a global vector then the ghost points are not accessible. Of course with the local vector you will have had to do the 422dce8aebaSBarry Smith appropriate `DMGlobalToLocalBegin()` and `DMGlobalToLocalEnd()` to have correct values in the ghost locations. 4235edff71fSBarry Smith 42495452b02SPatrick Sanan Fortran Notes: 4250f99b6f4SBarry Smith Use `DMDAVecGetArrayReadF90()` and pass for the array type `PetscScalar`,pointer :: array(:,...,:) of the appropriate 426dce8aebaSBarry Smith 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 4270f99b6f4SBarry Smith dimension of the `DMDA`. 4280f99b6f4SBarry Smith 4290f99b6f4SBarry Smith The order of the indices is array(xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1) (when dof is 1) otherwise 4305edff71fSBarry Smith array(0:dof-1,xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1) where the values are obtained from 4310f99b6f4SBarry Smith `DMDAGetCorners()` for a global array or `DMDAGetGhostCorners()` for a local array. 4325edff71fSBarry Smith 4330f99b6f4SBarry Smith .seealso: `DM`, `DMDA`, `DMDAVecGetArrayReadF90()`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecRestoreArrayRead()`, `DMDAVecRestoreArrayDOF()` 434db781477SPatrick Sanan `DMDAVecGetArrayDOF()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()`, 435db781477SPatrick Sanan `DMStagVecGetArrayRead()` 4365edff71fSBarry Smith @*/ 437d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAVecGetArrayRead(DM da, Vec vec, void *array) 438d71ae5a4SJacob Faibussowitsch { 4395edff71fSBarry Smith PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof; 4405edff71fSBarry Smith 4415edff71fSBarry Smith PetscFunctionBegin; 442a9a02de4SBarry Smith PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA); 4435edff71fSBarry Smith PetscValidHeaderSpecific(vec, VEC_CLASSID, 2); 4445edff71fSBarry Smith PetscValidPointer(array, 3); 4459566063dSJacob Faibussowitsch PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm)); 4469566063dSJacob Faibussowitsch PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm)); 4479566063dSJacob Faibussowitsch PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL)); 4485edff71fSBarry Smith 4495edff71fSBarry Smith /* Handle case where user passes in global vector as opposed to local */ 4509566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(vec, &N)); 4515edff71fSBarry Smith if (N == xm * ym * zm * dof) { 4525edff71fSBarry Smith gxm = xm; 4535edff71fSBarry Smith gym = ym; 4545edff71fSBarry Smith gzm = zm; 4555edff71fSBarry Smith gxs = xs; 4565edff71fSBarry Smith gys = ys; 4575edff71fSBarry Smith gzs = zs; 45863a3b9bcSJacob Faibussowitsch } 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); 4595edff71fSBarry Smith 4605edff71fSBarry Smith if (dim == 1) { 4619566063dSJacob Faibussowitsch PetscCall(VecGetArray1dRead(vec, gxm * dof, gxs * dof, (PetscScalar **)array)); 4625edff71fSBarry Smith } else if (dim == 2) { 4639566063dSJacob Faibussowitsch PetscCall(VecGetArray2dRead(vec, gym, gxm * dof, gys, gxs * dof, (PetscScalar ***)array)); 4645edff71fSBarry Smith } else if (dim == 3) { 4659566063dSJacob Faibussowitsch PetscCall(VecGetArray3dRead(vec, gzm, gym, gxm * dof, gzs, gys, gxs * dof, (PetscScalar ****)array)); 46663a3b9bcSJacob Faibussowitsch } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim); 4673ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4685edff71fSBarry Smith } 4695edff71fSBarry Smith 4700f99b6f4SBarry Smith /*MC 4710f99b6f4SBarry Smith DMDAVecRestoreArrayReadF90 - check Fortran Notes at `DMDAVecRestoreArrayRead()` 472*53c0d4aeSBarry Smith 473*53c0d4aeSBarry Smith Level: intermediate 4740f99b6f4SBarry Smith M*/ 4750f99b6f4SBarry Smith 4765edff71fSBarry Smith /*@ 477dce8aebaSBarry Smith DMDAVecRestoreArrayRead - Restores a multiple dimension array obtained with `DMDAVecGetArrayRead()` 4785edff71fSBarry Smith 4792ddbf755SMatthew G. Knepley Not collective 4805edff71fSBarry Smith 481d8d19677SJose E. Roman Input Parameters: 4825edff71fSBarry Smith + da - the distributed array 4835edff71fSBarry Smith . vec - the vector, either a vector the same size as one obtained with 484dce8aebaSBarry Smith `DMCreateGlobalVector()` or `DMCreateLocalVector()` 4855edff71fSBarry Smith - array - the array, non-NULL pointer is zeroed 4865edff71fSBarry Smith 4875edff71fSBarry Smith Level: intermediate 4885edff71fSBarry Smith 489dce8aebaSBarry Smith Fortran Note: 4900f99b6f4SBarry Smith Use `DMDAVecRestoreArrayReadF90()` 4915edff71fSBarry Smith 4920f99b6f4SBarry Smith .seealso: `DM`, `DMDA`, `DMDAVecRestoreArrayReadF90()`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecGetArrayRead()`, 493db781477SPatrick Sanan `DMDAVecGetArray()`, `DMDAVecRestoreArray()`, `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`, 494db781477SPatrick Sanan `DMStagVecRestoreArrayRead()` 4955edff71fSBarry Smith @*/ 496d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAVecRestoreArrayRead(DM da, Vec vec, void *array) 497d71ae5a4SJacob Faibussowitsch { 4985edff71fSBarry Smith PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof; 4995edff71fSBarry Smith 5005edff71fSBarry Smith PetscFunctionBegin; 501a9a02de4SBarry Smith PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA); 5025edff71fSBarry Smith PetscValidHeaderSpecific(vec, VEC_CLASSID, 2); 5035edff71fSBarry Smith PetscValidPointer(array, 3); 5049566063dSJacob Faibussowitsch PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm)); 5059566063dSJacob Faibussowitsch PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm)); 5069566063dSJacob Faibussowitsch PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL)); 5075edff71fSBarry Smith 5085edff71fSBarry Smith /* Handle case where user passes in global vector as opposed to local */ 5099566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(vec, &N)); 5105edff71fSBarry Smith if (N == xm * ym * zm * dof) { 5115edff71fSBarry Smith gxm = xm; 5125edff71fSBarry Smith gym = ym; 5135edff71fSBarry Smith gzm = zm; 5145edff71fSBarry Smith gxs = xs; 5155edff71fSBarry Smith gys = ys; 5165edff71fSBarry Smith gzs = zs; 51763a3b9bcSJacob Faibussowitsch } 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); 5185edff71fSBarry Smith 5195edff71fSBarry Smith if (dim == 1) { 5209566063dSJacob Faibussowitsch PetscCall(VecRestoreArray1dRead(vec, gxm * dof, gxs * dof, (PetscScalar **)array)); 5215edff71fSBarry Smith } else if (dim == 2) { 5229566063dSJacob Faibussowitsch PetscCall(VecRestoreArray2dRead(vec, gym, gxm * dof, gys, gxs * dof, (PetscScalar ***)array)); 5235edff71fSBarry Smith } else if (dim == 3) { 5249566063dSJacob Faibussowitsch PetscCall(VecRestoreArray3dRead(vec, gzm, gym, gxm * dof, gzs, gys, gxs * dof, (PetscScalar ****)array)); 52563a3b9bcSJacob Faibussowitsch } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim); 5263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5275edff71fSBarry Smith } 5285edff71fSBarry Smith 5295edff71fSBarry Smith /*@C 5305edff71fSBarry Smith DMDAVecGetArrayDOFRead - Returns a multiple dimension array that shares data with 5315edff71fSBarry Smith the underlying vector and is indexed using the global dimensions. 5325edff71fSBarry Smith 5335edff71fSBarry Smith Not Collective 5345edff71fSBarry Smith 535d8d19677SJose E. Roman Input Parameters: 5365edff71fSBarry Smith + da - the distributed array 5375edff71fSBarry Smith - vec - the vector, either a vector the same size as one obtained with 538dce8aebaSBarry Smith `DMCreateGlobalVector()` or `DMCreateLocalVector()` 5395edff71fSBarry Smith 5405edff71fSBarry Smith Output Parameter: 5415edff71fSBarry Smith . array - the array 5425edff71fSBarry Smith 543dce8aebaSBarry Smith Level: intermediate 544dce8aebaSBarry Smith 5455edff71fSBarry Smith Notes: 546dce8aebaSBarry Smith Call `DMDAVecRestoreArrayDOFRead()` once you have finished accessing the vector entries. 5475edff71fSBarry Smith 5485edff71fSBarry Smith In C, the indexing is "backwards" from what expects: array[k][j][i][DOF] NOT array[i][j][k][DOF]! 5495edff71fSBarry Smith 550dce8aebaSBarry Smith Fortran Note: 5510f99b6f4SBarry Smith Use `DMDAVecGetArrayReadF90()` and pass for the array type PetscScalar,pointer :: array(:,...,:) of the appropriate 5520f99b6f4SBarry Smith 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 5530f99b6f4SBarry Smith dimension of the `DMDA`. 5540f99b6f4SBarry Smith 5550f99b6f4SBarry Smith The order of the indices is array(xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1) (when dof is 1) otherwise 5560f99b6f4SBarry Smith array(0:dof-1,xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1) where the values are obtained from 5570f99b6f4SBarry Smith `DMDAGetCorners()` for a global array or `DMDAGetGhostCorners()` for a local array. 5585edff71fSBarry Smith 559dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecRestoreArray()`, `DMDAVecGetArray()`, `DMDAVecGetArrayDOF()`, 5604ab966ffSPatrick Sanan `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()` 5615edff71fSBarry Smith @*/ 562d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAVecGetArrayDOFRead(DM da, Vec vec, void *array) 563d71ae5a4SJacob Faibussowitsch { 5645edff71fSBarry Smith PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof; 5655edff71fSBarry Smith 5665edff71fSBarry Smith PetscFunctionBegin; 5679566063dSJacob Faibussowitsch PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm)); 5689566063dSJacob Faibussowitsch PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm)); 5699566063dSJacob Faibussowitsch PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL)); 5705edff71fSBarry Smith 5715edff71fSBarry Smith /* Handle case where user passes in global vector as opposed to local */ 5729566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(vec, &N)); 5735edff71fSBarry Smith if (N == xm * ym * zm * dof) { 5745edff71fSBarry Smith gxm = xm; 5755edff71fSBarry Smith gym = ym; 5765edff71fSBarry Smith gzm = zm; 5775edff71fSBarry Smith gxs = xs; 5785edff71fSBarry Smith gys = ys; 5795edff71fSBarry Smith gzs = zs; 58063a3b9bcSJacob Faibussowitsch } 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); 5815edff71fSBarry Smith 5825edff71fSBarry Smith if (dim == 1) { 5839566063dSJacob Faibussowitsch PetscCall(VecGetArray2dRead(vec, gxm, dof, gxs, 0, (PetscScalar ***)array)); 5845edff71fSBarry Smith } else if (dim == 2) { 5859566063dSJacob Faibussowitsch PetscCall(VecGetArray3dRead(vec, gym, gxm, dof, gys, gxs, 0, (PetscScalar ****)array)); 5865edff71fSBarry Smith } else if (dim == 3) { 5879566063dSJacob Faibussowitsch PetscCall(VecGetArray4dRead(vec, gzm, gym, gxm, dof, gzs, gys, gxs, 0, (PetscScalar *****)array)); 58863a3b9bcSJacob Faibussowitsch } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim); 5893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5905edff71fSBarry Smith } 5915edff71fSBarry Smith 5925edff71fSBarry Smith /*@ 593dce8aebaSBarry Smith DMDAVecRestoreArrayDOFRead - Restores a multiple dimension array obtained with `DMDAVecGetArrayDOFRead()` 5945edff71fSBarry Smith 5955edff71fSBarry Smith Not Collective 5965edff71fSBarry Smith 597d8d19677SJose E. Roman Input Parameters: 5985edff71fSBarry Smith + da - the distributed array 5995edff71fSBarry Smith . vec - the vector, either a vector the same size as one obtained with 600dce8aebaSBarry Smith `DMCreateGlobalVector()` or `DMCreateLocalVector()` 6015edff71fSBarry Smith - array - the array 6025edff71fSBarry Smith 6035edff71fSBarry Smith Level: intermediate 6045edff71fSBarry Smith 6050f99b6f4SBarry Smith Fortran Note: 6060f99b6f4SBarry Smith Use `DMDAVecRestoreArrayReadF90()` 6070f99b6f4SBarry Smith 608dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecGetArray()`, `DMDAVecGetArrayDOF()`, `DMDAVecRestoreArrayDOF()`, 6094ab966ffSPatrick Sanan `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()` 6105edff71fSBarry Smith @*/ 611d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAVecRestoreArrayDOFRead(DM da, Vec vec, void *array) 612d71ae5a4SJacob Faibussowitsch { 6135edff71fSBarry Smith PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof; 6145edff71fSBarry Smith 6155edff71fSBarry Smith PetscFunctionBegin; 6169566063dSJacob Faibussowitsch PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm)); 6179566063dSJacob Faibussowitsch PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm)); 6189566063dSJacob Faibussowitsch PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL)); 6195edff71fSBarry Smith 6205edff71fSBarry Smith /* Handle case where user passes in global vector as opposed to local */ 6219566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(vec, &N)); 6225edff71fSBarry Smith if (N == xm * ym * zm * dof) { 6235edff71fSBarry Smith gxm = xm; 6245edff71fSBarry Smith gym = ym; 6255edff71fSBarry Smith gzm = zm; 6265edff71fSBarry Smith gxs = xs; 6275edff71fSBarry Smith gys = ys; 6285edff71fSBarry Smith gzs = zs; 6295edff71fSBarry Smith } 6305edff71fSBarry Smith 6315edff71fSBarry Smith if (dim == 1) { 6329566063dSJacob Faibussowitsch PetscCall(VecRestoreArray2dRead(vec, gxm, dof, gxs, 0, (PetscScalar ***)array)); 6335edff71fSBarry Smith } else if (dim == 2) { 6349566063dSJacob Faibussowitsch PetscCall(VecRestoreArray3dRead(vec, gym, gxm, dof, gys, gxs, 0, (PetscScalar ****)array)); 6355edff71fSBarry Smith } else if (dim == 3) { 6369566063dSJacob Faibussowitsch PetscCall(VecRestoreArray4dRead(vec, gzm, gym, gxm, dof, gzs, gys, gxs, 0, (PetscScalar *****)array)); 63763a3b9bcSJacob Faibussowitsch } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim); 6383ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6395edff71fSBarry Smith } 6405edff71fSBarry Smith 6411e5d2365SBarry Smith /*@C 6421e5d2365SBarry Smith DMDAVecGetArrayDOFWrite - Returns a multiple dimension array that shares data with 6431e5d2365SBarry Smith the underlying vector and is indexed using the global dimensions. 6441e5d2365SBarry Smith 6451e5d2365SBarry Smith Not Collective 6461e5d2365SBarry Smith 647d8d19677SJose E. Roman Input Parameters: 6481e5d2365SBarry Smith + da - the distributed array 6491e5d2365SBarry Smith - vec - the vector, either a vector the same size as one obtained with 650dce8aebaSBarry Smith `DMCreateGlobalVector()` or `DMCreateLocalVector()` 6511e5d2365SBarry Smith 6521e5d2365SBarry Smith Output Parameter: 6531e5d2365SBarry Smith . array - the array 6541e5d2365SBarry Smith 6550f99b6f4SBarry Smith Level: intermediate 6560f99b6f4SBarry Smith 6571e5d2365SBarry Smith Notes: 658dce8aebaSBarry Smith Call `DMDAVecRestoreArrayDOFWrite()` once you have finished accessing the vector entries. 6591e5d2365SBarry Smith 6601e5d2365SBarry Smith In C, the indexing is "backwards" from what expects: array[k][j][i][DOF] NOT array[i][j][k][DOF]! 6611e5d2365SBarry Smith 6620f99b6f4SBarry Smith Fortran Note: 6630f99b6f4SBarry Smith Use `DMDAVecGetArrayWriteF90()` and pass for the array type PetscScalar,pointer :: array(:,...,:) of the appropriate 6640f99b6f4SBarry Smith 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 6650f99b6f4SBarry Smith dimension of the `DMDA`. 6661e5d2365SBarry Smith 6670f99b6f4SBarry Smith The order of the indices is array(xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1) (when dof is 1) otherwise 6680f99b6f4SBarry Smith array(0:dof-1,xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1) where the values are obtained from 6690f99b6f4SBarry Smith `DMDAGetCorners()` for a global array or `DMDAGetGhostCorners()` for a local array. 6701e5d2365SBarry Smith 6710f99b6f4SBarry Smith .seealso: `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `DMDAVecRestoreArrayWriteF90()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecRestoreArray()`, `DMDAVecGetArray()`, `DMDAVecGetArrayDOF()`, 6724ab966ffSPatrick Sanan `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`, `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()` 6731e5d2365SBarry Smith @*/ 674d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAVecGetArrayDOFWrite(DM da, Vec vec, void *array) 675d71ae5a4SJacob Faibussowitsch { 6761e5d2365SBarry Smith PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof; 6771e5d2365SBarry Smith 6781e5d2365SBarry Smith PetscFunctionBegin; 6799566063dSJacob Faibussowitsch PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm)); 6809566063dSJacob Faibussowitsch PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm)); 6819566063dSJacob Faibussowitsch PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL)); 6821e5d2365SBarry Smith 6831e5d2365SBarry Smith /* Handle case where user passes in global vector as opposed to local */ 6849566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(vec, &N)); 6851e5d2365SBarry Smith if (N == xm * ym * zm * dof) { 6861e5d2365SBarry Smith gxm = xm; 6871e5d2365SBarry Smith gym = ym; 6881e5d2365SBarry Smith gzm = zm; 6891e5d2365SBarry Smith gxs = xs; 6901e5d2365SBarry Smith gys = ys; 6911e5d2365SBarry Smith gzs = zs; 69263a3b9bcSJacob Faibussowitsch } 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); 6931e5d2365SBarry Smith 6941e5d2365SBarry Smith if (dim == 1) { 6959566063dSJacob Faibussowitsch PetscCall(VecGetArray2dWrite(vec, gxm, dof, gxs, 0, (PetscScalar ***)array)); 6961e5d2365SBarry Smith } else if (dim == 2) { 6979566063dSJacob Faibussowitsch PetscCall(VecGetArray3dWrite(vec, gym, gxm, dof, gys, gxs, 0, (PetscScalar ****)array)); 6981e5d2365SBarry Smith } else if (dim == 3) { 6999566063dSJacob Faibussowitsch PetscCall(VecGetArray4dWrite(vec, gzm, gym, gxm, dof, gzs, gys, gxs, 0, (PetscScalar *****)array)); 70063a3b9bcSJacob Faibussowitsch } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim); 7013ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7021e5d2365SBarry Smith } 7031e5d2365SBarry Smith 7041e5d2365SBarry Smith /*@ 705dce8aebaSBarry Smith DMDAVecRestoreArrayDOFWrite - Restores a multiple dimension array obtained with `DMDAVecGetArrayDOFWrite()` 7061e5d2365SBarry Smith 7071e5d2365SBarry Smith Not Collective 7081e5d2365SBarry Smith 709d8d19677SJose E. Roman Input Parameters: 7101e5d2365SBarry Smith + da - the distributed array 7111e5d2365SBarry Smith . vec - the vector, either a vector the same size as one obtained with 712dce8aebaSBarry Smith `DMCreateGlobalVector()` or `DMCreateLocalVector()` 7131e5d2365SBarry Smith - array - the array 7141e5d2365SBarry Smith 7151e5d2365SBarry Smith Level: intermediate 7161e5d2365SBarry Smith 7170f99b6f4SBarry Smith Fortran Note: 7180f99b6f4SBarry Smith Use `DMDAVecRestoreArrayWriteF90()` 7190f99b6f4SBarry Smith 720dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecGetArray()`, `DMDAVecGetArrayDOF()`, `DMDAVecRestoreArrayDOF()`, 7214ab966ffSPatrick Sanan `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`, `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()` 7221e5d2365SBarry Smith @*/ 723d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAVecRestoreArrayDOFWrite(DM da, Vec vec, void *array) 724d71ae5a4SJacob Faibussowitsch { 7251e5d2365SBarry Smith PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof; 7261e5d2365SBarry Smith 7271e5d2365SBarry Smith PetscFunctionBegin; 7289566063dSJacob Faibussowitsch PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm)); 7299566063dSJacob Faibussowitsch PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm)); 7309566063dSJacob Faibussowitsch PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL)); 7311e5d2365SBarry Smith 7321e5d2365SBarry Smith /* Handle case where user passes in global vector as opposed to local */ 7339566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(vec, &N)); 7341e5d2365SBarry Smith if (N == xm * ym * zm * dof) { 7351e5d2365SBarry Smith gxm = xm; 7361e5d2365SBarry Smith gym = ym; 7371e5d2365SBarry Smith gzm = zm; 7381e5d2365SBarry Smith gxs = xs; 7391e5d2365SBarry Smith gys = ys; 7401e5d2365SBarry Smith gzs = zs; 7411e5d2365SBarry Smith } 7421e5d2365SBarry Smith 7431e5d2365SBarry Smith if (dim == 1) { 7449566063dSJacob Faibussowitsch PetscCall(VecRestoreArray2dWrite(vec, gxm, dof, gxs, 0, (PetscScalar ***)array)); 7451e5d2365SBarry Smith } else if (dim == 2) { 7469566063dSJacob Faibussowitsch PetscCall(VecRestoreArray3dWrite(vec, gym, gxm, dof, gys, gxs, 0, (PetscScalar ****)array)); 7471e5d2365SBarry Smith } else if (dim == 3) { 7489566063dSJacob Faibussowitsch PetscCall(VecRestoreArray4dWrite(vec, gzm, gym, gxm, dof, gzs, gys, gxs, 0, (PetscScalar *****)array)); 74963a3b9bcSJacob Faibussowitsch } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim); 7503ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7511e5d2365SBarry Smith } 752