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()` 671b416bcSMatthew G. Knepley 771b416bcSMatthew G. Knepley Level: intermediate 80f99b6f4SBarry Smith M*/ 90f99b6f4SBarry Smith 1047c6ae99SBarry Smith /*@C 11aa219208SBarry Smith DMDAVecGetArray - Returns a multiple dimension array that shares data with 1247c6ae99SBarry Smith the underlying vector and is indexed using the global dimensions. 1347c6ae99SBarry Smith 1420f4b53cSBarry Smith Logically Collective 1547c6ae99SBarry Smith 16d8d19677SJose E. Roman Input Parameters: 1747c6ae99SBarry Smith + da - the distributed array 180af9b551SBarry Smith - vec - a vector the same size as one obtained with `DMCreateGlobalVector()` or `DMCreateLocalVector()` 1947c6ae99SBarry Smith 2047c6ae99SBarry Smith Output Parameter: 2147c6ae99SBarry Smith . array - the array 2247c6ae99SBarry Smith 23dce8aebaSBarry Smith Level: intermediate 24dce8aebaSBarry Smith 2547c6ae99SBarry Smith Notes: 26dce8aebaSBarry Smith Call `DMDAVecRestoreArray()` once you have finished accessing the vector entries. 2747c6ae99SBarry Smith 2847c6ae99SBarry Smith In C, the indexing is "backwards" from what expects: array[k][j][i] NOT array[i][j][k]! 2947c6ae99SBarry Smith 300af9b551SBarry Smith If `vec` is a local vector (obtained with DMCreateLocalVector() etc) then the ghost point locations are accessible. If it is 310af9b551SBarry Smith a global vector then the ghost points are not accessible. Of course, with a local vector you will have had to do the 32dce8aebaSBarry Smith appropriate `DMGlobalToLocalBegin()` and `DMGlobalToLocalEnd()` to have correct values in the ghost locations. 3347c6ae99SBarry Smith 340af9b551SBarry Smith The accessible indices are `array[zs:zs+zm-1][ys:ys+ym-1][xs:xs+xm-1]` where the values are obtained from 350af9b551SBarry Smith `DMDAGetCorners()` for a global vector or `DMDAGetGhostCorners()` for a local vector. 360af9b551SBarry Smith 3795452b02SPatrick Sanan Fortran Notes: 380f99b6f4SBarry Smith Use `DMDAVecGetArrayF90()` and pass for the array type `PetscScalar`,pointer :: array(:,...,:) of the appropriate 39dce8aebaSBarry 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 400f99b6f4SBarry Smith dimension of the `DMDA`. 4147c6ae99SBarry Smith 420af9b551SBarry 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 430af9b551SBarry Smith `array(0:dof-1,xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1)` where the values are obtained from 440af9b551SBarry Smith `DMDAGetCorners()` for a global vector or `DMDAGetGhostCorners()` for a local vector. 4547c6ae99SBarry Smith 46dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecRestoreArray()`, `DMDAVecRestoreArrayDOF()` 47db781477SPatrick Sanan `DMDAVecGetArrayDOF()`, `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()`, 48db781477SPatrick Sanan `DMStagVecGetArray()` 4947c6ae99SBarry Smith @*/ 50d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAVecGetArray(DM da, Vec vec, void *array) 51d71ae5a4SJacob Faibussowitsch { 5247c6ae99SBarry Smith PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof; 5347c6ae99SBarry Smith 5447c6ae99SBarry Smith PetscFunctionBegin; 55a9a02de4SBarry Smith PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA); 566db82c94SMatthew G Knepley PetscValidHeaderSpecific(vec, VEC_CLASSID, 2); 574f572ea9SToby Isaac PetscAssertPointer(array, 3); 589566063dSJacob Faibussowitsch PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm)); 599566063dSJacob Faibussowitsch PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm)); 609566063dSJacob Faibussowitsch PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL)); 6147c6ae99SBarry Smith 6247c6ae99SBarry Smith /* Handle case where user passes in global vector as opposed to local */ 639566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(vec, &N)); 6447c6ae99SBarry Smith if (N == xm * ym * zm * dof) { 6547c6ae99SBarry Smith gxm = xm; 6647c6ae99SBarry Smith gym = ym; 6747c6ae99SBarry Smith gzm = zm; 6847c6ae99SBarry Smith gxs = xs; 6947c6ae99SBarry Smith gys = ys; 7047c6ae99SBarry Smith gzs = zs; 7163a3b9bcSJacob 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); 7247c6ae99SBarry Smith 7347c6ae99SBarry Smith if (dim == 1) { 749566063dSJacob Faibussowitsch PetscCall(VecGetArray1d(vec, gxm * dof, gxs * dof, (PetscScalar **)array)); 7547c6ae99SBarry Smith } else if (dim == 2) { 769566063dSJacob Faibussowitsch PetscCall(VecGetArray2d(vec, gym, gxm * dof, gys, gxs * dof, (PetscScalar ***)array)); 7747c6ae99SBarry Smith } else if (dim == 3) { 789566063dSJacob Faibussowitsch PetscCall(VecGetArray3d(vec, gzm, gym, gxm * dof, gzs, gys, gxs * dof, (PetscScalar ****)array)); 7963a3b9bcSJacob Faibussowitsch } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim); 803ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8147c6ae99SBarry Smith } 8247c6ae99SBarry Smith 830f99b6f4SBarry Smith /*MC 840f99b6f4SBarry Smith DMDAVecRestoreArrayF90 - check Fortran Notes at `DMDAVecRestoreArray()` 8553c0d4aeSBarry Smith 8653c0d4aeSBarry Smith Level: intermediate 870f99b6f4SBarry Smith M*/ 880f99b6f4SBarry Smith 8947c6ae99SBarry Smith /*@ 90dce8aebaSBarry Smith DMDAVecRestoreArray - Restores a multiple dimension array obtained with `DMDAVecGetArray()` 9147c6ae99SBarry Smith 9220f4b53cSBarry Smith Logically Collective 9347c6ae99SBarry Smith 94d8d19677SJose E. Roman Input Parameters: 9547c6ae99SBarry Smith + da - the distributed array 960af9b551SBarry Smith . vec - a vector the same size as one obtained with `DMCreateGlobalVector()` or `DMCreateLocalVector()` 970af9b551SBarry Smith - array - the `array` pointer is zeroed 9847c6ae99SBarry Smith 9947c6ae99SBarry Smith Level: intermediate 10047c6ae99SBarry Smith 10160225df5SJacob Faibussowitsch Fortran Notes: 1020af9b551SBarry Smith Use `DMDAVecRestoreArayF90()` 10347c6ae99SBarry Smith 1040f99b6f4SBarry Smith .seealso: `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `DMDAVecRestoreArayF90()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecGetArray()`, 105db781477SPatrick Sanan `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()`, 106db781477SPatrick Sanan `DMDStagVecRestoreArray()` 10747c6ae99SBarry Smith @*/ 108d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAVecRestoreArray(DM da, Vec vec, void *array) 109d71ae5a4SJacob Faibussowitsch { 11047c6ae99SBarry Smith PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof; 11147c6ae99SBarry Smith 11247c6ae99SBarry Smith PetscFunctionBegin; 113a9a02de4SBarry Smith PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA); 1146db82c94SMatthew G Knepley PetscValidHeaderSpecific(vec, VEC_CLASSID, 2); 1154f572ea9SToby Isaac PetscAssertPointer(array, 3); 1169566063dSJacob Faibussowitsch PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm)); 1179566063dSJacob Faibussowitsch PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm)); 1189566063dSJacob Faibussowitsch PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL)); 11947c6ae99SBarry Smith 12047c6ae99SBarry Smith /* Handle case where user passes in global vector as opposed to local */ 1219566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(vec, &N)); 12247c6ae99SBarry Smith if (N == xm * ym * zm * dof) { 12347c6ae99SBarry Smith gxm = xm; 12447c6ae99SBarry Smith gym = ym; 12547c6ae99SBarry Smith gzm = zm; 12647c6ae99SBarry Smith gxs = xs; 12747c6ae99SBarry Smith gys = ys; 12847c6ae99SBarry Smith gzs = zs; 12963a3b9bcSJacob 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); 13047c6ae99SBarry Smith 13147c6ae99SBarry Smith if (dim == 1) { 1329566063dSJacob Faibussowitsch PetscCall(VecRestoreArray1d(vec, gxm * dof, gxs * dof, (PetscScalar **)array)); 13347c6ae99SBarry Smith } else if (dim == 2) { 1349566063dSJacob Faibussowitsch PetscCall(VecRestoreArray2d(vec, gym, gxm * dof, gys, gxs * dof, (PetscScalar ***)array)); 13547c6ae99SBarry Smith } else if (dim == 3) { 1369566063dSJacob Faibussowitsch PetscCall(VecRestoreArray3d(vec, gzm, gym, gxm * dof, gzs, gys, gxs * dof, (PetscScalar ****)array)); 13763a3b9bcSJacob Faibussowitsch } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim); 1383ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 13947c6ae99SBarry Smith } 14047c6ae99SBarry Smith 1410f99b6f4SBarry Smith /*MC 1420f99b6f4SBarry Smith DMDAVecGetArrayWriteF90 - check Fortran Notes at `DMDAVecGetArrayWrite()` 14353c0d4aeSBarry Smith 14453c0d4aeSBarry Smith Level: intermediate 1450f99b6f4SBarry Smith M*/ 1460f99b6f4SBarry Smith 14747c6ae99SBarry Smith /*@C 148fdc842d1SBarry Smith DMDAVecGetArrayWrite - Returns a multiple dimension array that shares data with 149fdc842d1SBarry Smith the underlying vector and is indexed using the global dimensions. 150fdc842d1SBarry Smith 15120f4b53cSBarry Smith Logically Collective 152fdc842d1SBarry Smith 153d8d19677SJose E. Roman Input Parameters: 154fdc842d1SBarry Smith + da - the distributed array 1550af9b551SBarry Smith - vec - a vector the same size as one obtained with `DMCreateGlobalVector()` or `DMCreateLocalVector()` 156fdc842d1SBarry Smith 157fdc842d1SBarry Smith Output Parameter: 158fdc842d1SBarry Smith . array - the array 159fdc842d1SBarry Smith 160dce8aebaSBarry Smith Level: intermediate 161dce8aebaSBarry Smith 162fdc842d1SBarry Smith Notes: 163dce8aebaSBarry Smith Call `DMDAVecRestoreArray()` once you have finished accessing the vector entries. 164fdc842d1SBarry Smith 165fdc842d1SBarry Smith In C, the indexing is "backwards" from what expects: array[k][j][i] NOT array[i][j][k]! 166fdc842d1SBarry Smith 1670af9b551SBarry Smith if `vec` is a local vector (obtained with `DMCreateLocalVector()` etc) then the ghost point locations are accessible. If it is 168fdc842d1SBarry Smith a global vector then the ghost points are not accessible. Of course with the local vector you will have had to do the 169dce8aebaSBarry Smith appropriate `DMGlobalToLocalBegin()` and `DMGlobalToLocalEnd()` to have correct values in the ghost locations. 170fdc842d1SBarry Smith 1710af9b551SBarry Smith The accessible indices are `array[zs:zs+zm-1][ys:ys+ym-1][xs:xs+xm-1]` where the values are obtained from 1720af9b551SBarry Smith `DMDAGetCorners()` for a global vector or `DMDAGetGhostCorners()` for a local vector. 1730af9b551SBarry Smith 174fdc842d1SBarry Smith Fortran Notes: 17560225df5SJacob Faibussowitsch 1760f99b6f4SBarry Smith From Fortran use `DMDAVecGetArrayWriteF90()` and pass for the array type PetscScalar,pointer :: array(:,...,:) of the appropriate 177dce8aebaSBarry 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 1780f99b6f4SBarry Smith dimension of the `DMDA`. 179fdc842d1SBarry Smith 1800af9b551SBarry 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 1810af9b551SBarry Smith `array(0:dof-1,xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1)` where the values are obtained from 1820af9b551SBarry Smith `DMDAGetCorners()` for a global vector or `DMDAGetGhostCorners()` for a local vector. 183fdc842d1SBarry Smith 18460225df5SJacob Faibussowitsch The order of the indices is array(xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1) (when dof is 1) otherwise 18560225df5SJacob Faibussowitsch array(0:dof-1,xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1) where the values are obtained from 18660225df5SJacob Faibussowitsch `DMDAGetCorners()` for a global array or `DMDAGetGhostCorners()` for a local array. 18760225df5SJacob Faibussowitsch 18860225df5SJacob Faibussowitsch Developer Notes: 189dce8aebaSBarry Smith This has code duplication with `DMDAVecGetArray()` and `DMDAVecGetArrayRead()` 190fdc842d1SBarry Smith 191dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecRestoreArrayWrite()`, `DMDAVecRestoreArrayDOF()` 192db781477SPatrick Sanan `DMDAVecGetArrayDOF()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()` 193fdc842d1SBarry Smith @*/ 194d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAVecGetArrayWrite(DM da, Vec vec, void *array) 195d71ae5a4SJacob Faibussowitsch { 196fdc842d1SBarry Smith PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof; 197fdc842d1SBarry Smith 198fdc842d1SBarry Smith PetscFunctionBegin; 199fdc842d1SBarry Smith PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA); 200fdc842d1SBarry Smith PetscValidHeaderSpecific(vec, VEC_CLASSID, 2); 2014f572ea9SToby Isaac PetscAssertPointer(array, 3); 2021bb6d2a8SBarry Smith if (da->localSection) { 2039566063dSJacob Faibussowitsch PetscCall(VecGetArrayWrite(vec, (PetscScalar **)array)); 2043ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 205fdc842d1SBarry Smith } 2069566063dSJacob Faibussowitsch PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm)); 2079566063dSJacob Faibussowitsch PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm)); 2089566063dSJacob Faibussowitsch PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL)); 209fdc842d1SBarry Smith 210fdc842d1SBarry Smith /* Handle case where user passes in global vector as opposed to local */ 2119566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(vec, &N)); 212fdc842d1SBarry Smith if (N == xm * ym * zm * dof) { 213fdc842d1SBarry Smith gxm = xm; 214fdc842d1SBarry Smith gym = ym; 215fdc842d1SBarry Smith gzm = zm; 216fdc842d1SBarry Smith gxs = xs; 217fdc842d1SBarry Smith gys = ys; 218fdc842d1SBarry Smith gzs = zs; 21963a3b9bcSJacob 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); 220fdc842d1SBarry Smith 221fdc842d1SBarry Smith if (dim == 1) { 2229566063dSJacob Faibussowitsch PetscCall(VecGetArray1dWrite(vec, gxm * dof, gxs * dof, (PetscScalar **)array)); 223fdc842d1SBarry Smith } else if (dim == 2) { 2249566063dSJacob Faibussowitsch PetscCall(VecGetArray2dWrite(vec, gym, gxm * dof, gys, gxs * dof, (PetscScalar ***)array)); 225fdc842d1SBarry Smith } else if (dim == 3) { 2269566063dSJacob Faibussowitsch PetscCall(VecGetArray3dWrite(vec, gzm, gym, gxm * dof, gzs, gys, gxs * dof, (PetscScalar ****)array)); 22763a3b9bcSJacob Faibussowitsch } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim); 2283ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 229fdc842d1SBarry Smith } 230fdc842d1SBarry Smith 2310f99b6f4SBarry Smith /*MC 2320f99b6f4SBarry Smith DMDAVecRestoreArrayWriteF90 - check Fortran Notes at `DMDAVecRestoreArrayWrite()` 23353c0d4aeSBarry Smith 23453c0d4aeSBarry Smith Level: intermediate 2350f99b6f4SBarry Smith M*/ 2360f99b6f4SBarry Smith 237fdc842d1SBarry Smith /*@ 238dce8aebaSBarry Smith DMDAVecRestoreArrayWrite - Restores a multiple dimension array obtained with `DMDAVecGetArrayWrite()` 239fdc842d1SBarry Smith 24020f4b53cSBarry Smith Logically Collective 241fdc842d1SBarry Smith 242d8d19677SJose E. Roman Input Parameters: 243fdc842d1SBarry Smith + da - the distributed array 2440af9b551SBarry Smith . vec - a vector the same size as one obtained with `DMCreateGlobalVector()` or `DMCreateLocalVector()` 2450af9b551SBarry Smith - array - the `array` pointer is zeroed 246fdc842d1SBarry Smith 247fdc842d1SBarry Smith Level: intermediate 248fdc842d1SBarry Smith 24960225df5SJacob Faibussowitsch Fortran Notes: 2500f99b6f4SBarry Smith Use `DMDAVecRestoreArayWriteF90()` 251fdc842d1SBarry Smith 252dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecGetArrayWrite()`, 253db781477SPatrick Sanan `DMDAVecGetArray()`, `DMDAVecRestoreArray()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()` 254fdc842d1SBarry Smith @*/ 255d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAVecRestoreArrayWrite(DM da, Vec vec, void *array) 256d71ae5a4SJacob Faibussowitsch { 257fdc842d1SBarry Smith PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof; 258fdc842d1SBarry Smith 259fdc842d1SBarry Smith PetscFunctionBegin; 260fdc842d1SBarry Smith PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA); 261fdc842d1SBarry Smith PetscValidHeaderSpecific(vec, VEC_CLASSID, 2); 2624f572ea9SToby Isaac PetscAssertPointer(array, 3); 2631bb6d2a8SBarry Smith if (da->localSection) { 2649566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(vec, (PetscScalar **)array)); 2653ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 266fdc842d1SBarry Smith } 2679566063dSJacob Faibussowitsch PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm)); 2689566063dSJacob Faibussowitsch PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm)); 2699566063dSJacob Faibussowitsch PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL)); 270fdc842d1SBarry Smith 271fdc842d1SBarry Smith /* Handle case where user passes in global vector as opposed to local */ 2729566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(vec, &N)); 273fdc842d1SBarry Smith if (N == xm * ym * zm * dof) { 274fdc842d1SBarry Smith gxm = xm; 275fdc842d1SBarry Smith gym = ym; 276fdc842d1SBarry Smith gzm = zm; 277fdc842d1SBarry Smith gxs = xs; 278fdc842d1SBarry Smith gys = ys; 279fdc842d1SBarry Smith gzs = zs; 28063a3b9bcSJacob 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); 281fdc842d1SBarry Smith 282fdc842d1SBarry Smith if (dim == 1) { 2839566063dSJacob Faibussowitsch PetscCall(VecRestoreArray1dWrite(vec, gxm * dof, gxs * dof, (PetscScalar **)array)); 284fdc842d1SBarry Smith } else if (dim == 2) { 2859566063dSJacob Faibussowitsch PetscCall(VecRestoreArray2dWrite(vec, gym, gxm * dof, gys, gxs * dof, (PetscScalar ***)array)); 286fdc842d1SBarry Smith } else if (dim == 3) { 2879566063dSJacob Faibussowitsch PetscCall(VecRestoreArray3dWrite(vec, gzm, gym, gxm * dof, gzs, gys, gxs * dof, (PetscScalar ****)array)); 28863a3b9bcSJacob Faibussowitsch } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim); 2893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 290fdc842d1SBarry Smith } 291fdc842d1SBarry Smith 292fdc842d1SBarry Smith /*@C 293aa219208SBarry Smith DMDAVecGetArrayDOF - Returns a multiple dimension array that shares data with 29447c6ae99SBarry Smith the underlying vector and is indexed using the global dimensions. 29547c6ae99SBarry Smith 29620f4b53cSBarry Smith Logically Collective 29747c6ae99SBarry Smith 298d8d19677SJose E. Roman Input Parameters: 29947c6ae99SBarry Smith + da - the distributed array 3000af9b551SBarry Smith - vec - a vector the same size as one obtained with `DMCreateGlobalVector()` or `DMCreateLocalVector()` 30147c6ae99SBarry Smith 30247c6ae99SBarry Smith Output Parameter: 3030af9b551SBarry Smith . array - the `array` pointer is zeroed 30447c6ae99SBarry Smith 305dce8aebaSBarry Smith Level: intermediate 306dce8aebaSBarry Smith 30747c6ae99SBarry Smith Notes: 308dce8aebaSBarry Smith Call `DMDAVecRestoreArrayDOF()` once you have finished accessing the vector entries. 30947c6ae99SBarry Smith 3100af9b551SBarry Smith In C, the indexing is "backwards" from what expects: array[k][j][i][DOF] NOT array[i][j][k][DOF] 3110af9b551SBarry Smith 3120af9b551SBarry Smith 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 3130af9b551SBarry Smith `DMDAGetCorners()` for a global vector or `DMDAGetGhostCorners()` for a local vector. 31447c6ae99SBarry Smith 3150f99b6f4SBarry Smith Fortran Notes: 3160f99b6f4SBarry Smith Use `DMDAVecGetArrayF90()` and pass for the array type PetscScalar,pointer :: array(:,...,:) of the appropriate 3170f99b6f4SBarry 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 3180f99b6f4SBarry Smith dimension of the `DMDA`. 3190f99b6f4SBarry Smith 3200af9b551SBarry Smith The order of the indices is `array(xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1)` (when ndof is 1) otherwise 3210af9b551SBarry Smith `array(0:dof-1,xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1)` where the values are obtained from 3220af9b551SBarry Smith `DMDAGetCorners()` for a global vector or `DMDAGetGhostCorners()` for a local vector. 3231b82215eSBarry Smith 324dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecRestoreArray()`, `DMDAVecGetArray()`, `DMDAVecRestoreArrayDOF()`, 3254ab966ffSPatrick Sanan `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()`, `DMDAVecGetArrayDOFRead()` 32647c6ae99SBarry Smith @*/ 327d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAVecGetArrayDOF(DM da, Vec vec, void *array) 328d71ae5a4SJacob Faibussowitsch { 32947c6ae99SBarry Smith PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof; 33047c6ae99SBarry Smith 33147c6ae99SBarry Smith PetscFunctionBegin; 3329566063dSJacob Faibussowitsch PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm)); 3339566063dSJacob Faibussowitsch PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm)); 3349566063dSJacob Faibussowitsch PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL)); 33547c6ae99SBarry Smith 33647c6ae99SBarry Smith /* Handle case where user passes in global vector as opposed to local */ 3379566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(vec, &N)); 33847c6ae99SBarry Smith if (N == xm * ym * zm * dof) { 33947c6ae99SBarry Smith gxm = xm; 34047c6ae99SBarry Smith gym = ym; 34147c6ae99SBarry Smith gzm = zm; 34247c6ae99SBarry Smith gxs = xs; 34347c6ae99SBarry Smith gys = ys; 34447c6ae99SBarry Smith gzs = zs; 34563a3b9bcSJacob 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); 34647c6ae99SBarry Smith 34747c6ae99SBarry Smith if (dim == 1) { 3489566063dSJacob Faibussowitsch PetscCall(VecGetArray2d(vec, gxm, dof, gxs, 0, (PetscScalar ***)array)); 34947c6ae99SBarry Smith } else if (dim == 2) { 3509566063dSJacob Faibussowitsch PetscCall(VecGetArray3d(vec, gym, gxm, dof, gys, gxs, 0, (PetscScalar ****)array)); 35147c6ae99SBarry Smith } else if (dim == 3) { 3529566063dSJacob Faibussowitsch PetscCall(VecGetArray4d(vec, gzm, gym, gxm, dof, gzs, gys, gxs, 0, (PetscScalar *****)array)); 35363a3b9bcSJacob Faibussowitsch } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim); 3543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 35547c6ae99SBarry Smith } 35647c6ae99SBarry Smith 35747c6ae99SBarry Smith /*@ 358dce8aebaSBarry Smith DMDAVecRestoreArrayDOF - Restores a multiple dimension array obtained with `DMDAVecGetArrayDOF()` 35947c6ae99SBarry Smith 36020f4b53cSBarry Smith Logically Collective 36147c6ae99SBarry Smith 362d8d19677SJose E. Roman Input Parameters: 36347c6ae99SBarry Smith + da - the distributed array 3640af9b551SBarry Smith . vec - vector the same size as one obtained with `DMCreateGlobalVector()` or `DMCreateLocalVector()` 3650af9b551SBarry Smith - array - the `array` point is zeroed 36647c6ae99SBarry Smith 36747c6ae99SBarry Smith Level: intermediate 36847c6ae99SBarry Smith 36960225df5SJacob Faibussowitsch Fortran Notes: 3700f99b6f4SBarry Smith Use `DMDAVecRestoreArayF90()` 3710f99b6f4SBarry Smith 372*42747ad1SJacob Faibussowitsch .seealso: `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecGetArray()`, `DMDAVecGetArrayDOF()`, 3734ab966ffSPatrick Sanan `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()` 37447c6ae99SBarry Smith @*/ 375d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAVecRestoreArrayDOF(DM da, Vec vec, void *array) 376d71ae5a4SJacob Faibussowitsch { 37747c6ae99SBarry Smith PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof; 37847c6ae99SBarry Smith 37947c6ae99SBarry Smith PetscFunctionBegin; 3809566063dSJacob Faibussowitsch PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm)); 3819566063dSJacob Faibussowitsch PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm)); 3829566063dSJacob Faibussowitsch PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL)); 38347c6ae99SBarry Smith 38447c6ae99SBarry Smith /* Handle case where user passes in global vector as opposed to local */ 3859566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(vec, &N)); 38647c6ae99SBarry Smith if (N == xm * ym * zm * dof) { 38747c6ae99SBarry Smith gxm = xm; 38847c6ae99SBarry Smith gym = ym; 38947c6ae99SBarry Smith gzm = zm; 39047c6ae99SBarry Smith gxs = xs; 39147c6ae99SBarry Smith gys = ys; 39247c6ae99SBarry Smith gzs = zs; 39347c6ae99SBarry Smith } 39447c6ae99SBarry Smith 39547c6ae99SBarry Smith if (dim == 1) { 3969566063dSJacob Faibussowitsch PetscCall(VecRestoreArray2d(vec, gxm, dof, gxs, 0, (PetscScalar ***)array)); 39747c6ae99SBarry Smith } else if (dim == 2) { 3989566063dSJacob Faibussowitsch PetscCall(VecRestoreArray3d(vec, gym, gxm, dof, gys, gxs, 0, (PetscScalar ****)array)); 39947c6ae99SBarry Smith } else if (dim == 3) { 4009566063dSJacob Faibussowitsch PetscCall(VecRestoreArray4d(vec, gzm, gym, gxm, dof, gzs, gys, gxs, 0, (PetscScalar *****)array)); 40163a3b9bcSJacob Faibussowitsch } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim); 4023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 40347c6ae99SBarry Smith } 40447c6ae99SBarry Smith 4050f99b6f4SBarry Smith /*MC 4060f99b6f4SBarry Smith DMDAVecGetArrayReadF90 - check Fortran Notes at `DMDAVecGetArrayRead()` 40753c0d4aeSBarry Smith 40853c0d4aeSBarry Smith Level: intermediate 4090f99b6f4SBarry Smith M*/ 4100f99b6f4SBarry Smith 4115edff71fSBarry Smith /*@C 4125edff71fSBarry Smith DMDAVecGetArrayRead - Returns a multiple dimension array that shares data with 4135edff71fSBarry Smith the underlying vector and is indexed using the global dimensions. 4145edff71fSBarry Smith 41520f4b53cSBarry Smith Not Collective 4165edff71fSBarry Smith 417d8d19677SJose E. Roman Input Parameters: 4185edff71fSBarry Smith + da - the distributed array 4190af9b551SBarry Smith - vec - a vector the same size as one obtained with `DMCreateGlobalVector()` or `DMCreateLocalVector()` 4205edff71fSBarry Smith 4215edff71fSBarry Smith Output Parameter: 4225edff71fSBarry Smith . array - the array 4235edff71fSBarry Smith 424dce8aebaSBarry Smith Level: intermediate 425dce8aebaSBarry Smith 4265edff71fSBarry Smith Notes: 427dce8aebaSBarry Smith Call `DMDAVecRestoreArrayRead()` once you have finished accessing the vector entries. 4285edff71fSBarry Smith 4295edff71fSBarry Smith In C, the indexing is "backwards" from what expects: array[k][j][i] NOT array[i][j][k]! 4305edff71fSBarry Smith 4310af9b551SBarry Smith If `vec` is a local vector (obtained with `DMCreateLocalVector()` etc) then the ghost point locations are accessible. If it is 4325edff71fSBarry Smith a global vector then the ghost points are not accessible. Of course with the local vector you will have had to do the 433dce8aebaSBarry Smith appropriate `DMGlobalToLocalBegin()` and `DMGlobalToLocalEnd()` to have correct values in the ghost locations. 4345edff71fSBarry Smith 4350af9b551SBarry Smith The accessible indices are `array[zs:zs+zm-1][ys:ys+ym-1][xs:xs+xm-1]` where the values are obtained from 4360af9b551SBarry Smith `DMDAGetCorners()` for a global vector or `DMDAGetGhostCorners()` for a local vector. 4370af9b551SBarry Smith 43895452b02SPatrick Sanan Fortran Notes: 4390f99b6f4SBarry Smith Use `DMDAVecGetArrayReadF90()` and pass for the array type `PetscScalar`,pointer :: array(:,...,:) of the appropriate 440dce8aebaSBarry 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 4410f99b6f4SBarry Smith dimension of the `DMDA`. 4420f99b6f4SBarry Smith 4430af9b551SBarry 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 4440af9b551SBarry Smith `array(0:dof-1,xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1)` where the values are obtained from 4450af9b551SBarry Smith `DMDAGetCorners()` for a global vector or `DMDAGetGhostCorners()` for a local vector. 4465edff71fSBarry Smith 447*42747ad1SJacob Faibussowitsch .seealso: `DM`, `DMDA`, `DMDAVecGetArrayReadF90()`, `DMDAGetGhostCorners()`, 448*42747ad1SJacob Faibussowitsch `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecRestoreArrayRead()`, 449*42747ad1SJacob Faibussowitsch `DMDAVecRestoreArrayDOF()`, `DMDAVecGetArrayDOF()`, `DMDAVecGetArray()`, 450*42747ad1SJacob Faibussowitsch `DMDAVecRestoreArray()`, `DMStagVecGetArrayRead()` 4515edff71fSBarry Smith @*/ 452d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAVecGetArrayRead(DM da, Vec vec, void *array) 453d71ae5a4SJacob Faibussowitsch { 4545edff71fSBarry Smith PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof; 4555edff71fSBarry Smith 4565edff71fSBarry Smith PetscFunctionBegin; 457a9a02de4SBarry Smith PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA); 4585edff71fSBarry Smith PetscValidHeaderSpecific(vec, VEC_CLASSID, 2); 4594f572ea9SToby Isaac PetscAssertPointer(array, 3); 4609566063dSJacob Faibussowitsch PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm)); 4619566063dSJacob Faibussowitsch PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm)); 4629566063dSJacob Faibussowitsch PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL)); 4635edff71fSBarry Smith 4645edff71fSBarry Smith /* Handle case where user passes in global vector as opposed to local */ 4659566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(vec, &N)); 4665edff71fSBarry Smith if (N == xm * ym * zm * dof) { 4675edff71fSBarry Smith gxm = xm; 4685edff71fSBarry Smith gym = ym; 4695edff71fSBarry Smith gzm = zm; 4705edff71fSBarry Smith gxs = xs; 4715edff71fSBarry Smith gys = ys; 4725edff71fSBarry Smith gzs = zs; 47363a3b9bcSJacob 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); 4745edff71fSBarry Smith 4755edff71fSBarry Smith if (dim == 1) { 4769566063dSJacob Faibussowitsch PetscCall(VecGetArray1dRead(vec, gxm * dof, gxs * dof, (PetscScalar **)array)); 4775edff71fSBarry Smith } else if (dim == 2) { 4789566063dSJacob Faibussowitsch PetscCall(VecGetArray2dRead(vec, gym, gxm * dof, gys, gxs * dof, (PetscScalar ***)array)); 4795edff71fSBarry Smith } else if (dim == 3) { 4809566063dSJacob Faibussowitsch PetscCall(VecGetArray3dRead(vec, gzm, gym, gxm * dof, gzs, gys, gxs * dof, (PetscScalar ****)array)); 48163a3b9bcSJacob Faibussowitsch } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim); 4823ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4835edff71fSBarry Smith } 4845edff71fSBarry Smith 4850f99b6f4SBarry Smith /*MC 4860f99b6f4SBarry Smith DMDAVecRestoreArrayReadF90 - check Fortran Notes at `DMDAVecRestoreArrayRead()` 48753c0d4aeSBarry Smith 48853c0d4aeSBarry Smith Level: intermediate 4890f99b6f4SBarry Smith M*/ 4900f99b6f4SBarry Smith 4915edff71fSBarry Smith /*@ 492dce8aebaSBarry Smith DMDAVecRestoreArrayRead - Restores a multiple dimension array obtained with `DMDAVecGetArrayRead()` 4935edff71fSBarry Smith 49420f4b53cSBarry Smith Not Collective 4955edff71fSBarry Smith 496d8d19677SJose E. Roman Input Parameters: 4975edff71fSBarry Smith + da - the distributed array 4980af9b551SBarry Smith . vec - vector the same size as one obtained with `DMCreateGlobalVector()` or `DMCreateLocalVector()` 4990af9b551SBarry Smith - array - the `array` pointer is zeroed 5005edff71fSBarry Smith 5015edff71fSBarry Smith Level: intermediate 5025edff71fSBarry Smith 50360225df5SJacob Faibussowitsch Fortran Notes: 5040f99b6f4SBarry Smith Use `DMDAVecRestoreArrayReadF90()` 5055edff71fSBarry Smith 5060f99b6f4SBarry Smith .seealso: `DM`, `DMDA`, `DMDAVecRestoreArrayReadF90()`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecGetArrayRead()`, 507db781477SPatrick Sanan `DMDAVecGetArray()`, `DMDAVecRestoreArray()`, `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`, 508db781477SPatrick Sanan `DMStagVecRestoreArrayRead()` 5095edff71fSBarry Smith @*/ 510d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAVecRestoreArrayRead(DM da, Vec vec, void *array) 511d71ae5a4SJacob Faibussowitsch { 5125edff71fSBarry Smith PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof; 5135edff71fSBarry Smith 5145edff71fSBarry Smith PetscFunctionBegin; 515a9a02de4SBarry Smith PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA); 5165edff71fSBarry Smith PetscValidHeaderSpecific(vec, VEC_CLASSID, 2); 5174f572ea9SToby Isaac PetscAssertPointer(array, 3); 5189566063dSJacob Faibussowitsch PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm)); 5199566063dSJacob Faibussowitsch PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm)); 5209566063dSJacob Faibussowitsch PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL)); 5215edff71fSBarry Smith 5225edff71fSBarry Smith /* Handle case where user passes in global vector as opposed to local */ 5239566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(vec, &N)); 5245edff71fSBarry Smith if (N == xm * ym * zm * dof) { 5255edff71fSBarry Smith gxm = xm; 5265edff71fSBarry Smith gym = ym; 5275edff71fSBarry Smith gzm = zm; 5285edff71fSBarry Smith gxs = xs; 5295edff71fSBarry Smith gys = ys; 5305edff71fSBarry Smith gzs = zs; 53163a3b9bcSJacob 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); 5325edff71fSBarry Smith 5335edff71fSBarry Smith if (dim == 1) { 5349566063dSJacob Faibussowitsch PetscCall(VecRestoreArray1dRead(vec, gxm * dof, gxs * dof, (PetscScalar **)array)); 5355edff71fSBarry Smith } else if (dim == 2) { 5369566063dSJacob Faibussowitsch PetscCall(VecRestoreArray2dRead(vec, gym, gxm * dof, gys, gxs * dof, (PetscScalar ***)array)); 5375edff71fSBarry Smith } else if (dim == 3) { 5389566063dSJacob Faibussowitsch PetscCall(VecRestoreArray3dRead(vec, gzm, gym, gxm * dof, gzs, gys, gxs * dof, (PetscScalar ****)array)); 53963a3b9bcSJacob Faibussowitsch } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim); 5403ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5415edff71fSBarry Smith } 5425edff71fSBarry Smith 5435edff71fSBarry Smith /*@C 5445edff71fSBarry Smith DMDAVecGetArrayDOFRead - Returns a multiple dimension array that shares data with 5455edff71fSBarry Smith the underlying vector and is indexed using the global dimensions. 5465edff71fSBarry Smith 5475edff71fSBarry Smith Not Collective 5485edff71fSBarry Smith 549d8d19677SJose E. Roman Input Parameters: 5505edff71fSBarry Smith + da - the distributed array 5510af9b551SBarry Smith - vec - a vector the same size as one obtained with `DMCreateGlobalVector()` or `DMCreateLocalVector()` 5525edff71fSBarry Smith 5535edff71fSBarry Smith Output Parameter: 5545edff71fSBarry Smith . array - the array 5555edff71fSBarry Smith 556dce8aebaSBarry Smith Level: intermediate 557dce8aebaSBarry Smith 5585edff71fSBarry Smith Notes: 559dce8aebaSBarry Smith Call `DMDAVecRestoreArrayDOFRead()` once you have finished accessing the vector entries. 5605edff71fSBarry Smith 5615edff71fSBarry Smith In C, the indexing is "backwards" from what expects: array[k][j][i][DOF] NOT array[i][j][k][DOF]! 5625edff71fSBarry Smith 5630af9b551SBarry Smith The accessible indices are `array[zs:zs+zm-1][ys:ys+ym-1][xs:xs+xm-1]` where the values are obtained from 5640af9b551SBarry Smith `DMDAGetCorners()` for a global vector or `DMDAGetGhostCorners()` for a local vector. 5650af9b551SBarry Smith 56660225df5SJacob Faibussowitsch Fortran Notes: 5670f99b6f4SBarry Smith Use `DMDAVecGetArrayReadF90()` and pass for the array type PetscScalar,pointer :: array(:,...,:) of the appropriate 5680f99b6f4SBarry 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 5690f99b6f4SBarry Smith dimension of the `DMDA`. 5700f99b6f4SBarry Smith 5710af9b551SBarry 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 5720af9b551SBarry Smith `array(0:dof-1,xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1)` where the values are obtained from 5730af9b551SBarry Smith `DMDAGetCorners()` for a global vector or `DMDAGetGhostCorners()` for a local vector. 5745edff71fSBarry Smith 575dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecRestoreArray()`, `DMDAVecGetArray()`, `DMDAVecGetArrayDOF()`, 5764ab966ffSPatrick Sanan `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()` 5775edff71fSBarry Smith @*/ 578d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAVecGetArrayDOFRead(DM da, Vec vec, void *array) 579d71ae5a4SJacob Faibussowitsch { 5805edff71fSBarry Smith PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof; 5815edff71fSBarry Smith 5825edff71fSBarry Smith PetscFunctionBegin; 5839566063dSJacob Faibussowitsch PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm)); 5849566063dSJacob Faibussowitsch PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm)); 5859566063dSJacob Faibussowitsch PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL)); 5865edff71fSBarry Smith 5875edff71fSBarry Smith /* Handle case where user passes in global vector as opposed to local */ 5889566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(vec, &N)); 5895edff71fSBarry Smith if (N == xm * ym * zm * dof) { 5905edff71fSBarry Smith gxm = xm; 5915edff71fSBarry Smith gym = ym; 5925edff71fSBarry Smith gzm = zm; 5935edff71fSBarry Smith gxs = xs; 5945edff71fSBarry Smith gys = ys; 5955edff71fSBarry Smith gzs = zs; 59663a3b9bcSJacob 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); 5975edff71fSBarry Smith 5985edff71fSBarry Smith if (dim == 1) { 5999566063dSJacob Faibussowitsch PetscCall(VecGetArray2dRead(vec, gxm, dof, gxs, 0, (PetscScalar ***)array)); 6005edff71fSBarry Smith } else if (dim == 2) { 6019566063dSJacob Faibussowitsch PetscCall(VecGetArray3dRead(vec, gym, gxm, dof, gys, gxs, 0, (PetscScalar ****)array)); 6025edff71fSBarry Smith } else if (dim == 3) { 6039566063dSJacob Faibussowitsch PetscCall(VecGetArray4dRead(vec, gzm, gym, gxm, dof, gzs, gys, gxs, 0, (PetscScalar *****)array)); 60463a3b9bcSJacob Faibussowitsch } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim); 6053ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6065edff71fSBarry Smith } 6075edff71fSBarry Smith 6085edff71fSBarry Smith /*@ 609dce8aebaSBarry Smith DMDAVecRestoreArrayDOFRead - Restores a multiple dimension array obtained with `DMDAVecGetArrayDOFRead()` 6105edff71fSBarry Smith 6115edff71fSBarry Smith Not Collective 6125edff71fSBarry Smith 613d8d19677SJose E. Roman Input Parameters: 6145edff71fSBarry Smith + da - the distributed array 6150af9b551SBarry Smith . vec - a vector the same size as one obtained with `DMCreateGlobalVector()` or `DMCreateLocalVector()` 6160af9b551SBarry Smith - array - the `array` pointer is zeroed 6175edff71fSBarry Smith 6185edff71fSBarry Smith Level: intermediate 6195edff71fSBarry Smith 62060225df5SJacob Faibussowitsch Fortran Notes: 6210f99b6f4SBarry Smith Use `DMDAVecRestoreArrayReadF90()` 6220f99b6f4SBarry Smith 623dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecGetArray()`, `DMDAVecGetArrayDOF()`, `DMDAVecRestoreArrayDOF()`, 6244ab966ffSPatrick Sanan `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()` 6255edff71fSBarry Smith @*/ 626d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAVecRestoreArrayDOFRead(DM da, Vec vec, void *array) 627d71ae5a4SJacob Faibussowitsch { 6285edff71fSBarry Smith PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof; 6295edff71fSBarry Smith 6305edff71fSBarry Smith PetscFunctionBegin; 6319566063dSJacob Faibussowitsch PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm)); 6329566063dSJacob Faibussowitsch PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm)); 6339566063dSJacob Faibussowitsch PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL)); 6345edff71fSBarry Smith 6355edff71fSBarry Smith /* Handle case where user passes in global vector as opposed to local */ 6369566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(vec, &N)); 6375edff71fSBarry Smith if (N == xm * ym * zm * dof) { 6385edff71fSBarry Smith gxm = xm; 6395edff71fSBarry Smith gym = ym; 6405edff71fSBarry Smith gzm = zm; 6415edff71fSBarry Smith gxs = xs; 6425edff71fSBarry Smith gys = ys; 6435edff71fSBarry Smith gzs = zs; 6445edff71fSBarry Smith } 6455edff71fSBarry Smith 6465edff71fSBarry Smith if (dim == 1) { 6479566063dSJacob Faibussowitsch PetscCall(VecRestoreArray2dRead(vec, gxm, dof, gxs, 0, (PetscScalar ***)array)); 6485edff71fSBarry Smith } else if (dim == 2) { 6499566063dSJacob Faibussowitsch PetscCall(VecRestoreArray3dRead(vec, gym, gxm, dof, gys, gxs, 0, (PetscScalar ****)array)); 6505edff71fSBarry Smith } else if (dim == 3) { 6519566063dSJacob Faibussowitsch PetscCall(VecRestoreArray4dRead(vec, gzm, gym, gxm, dof, gzs, gys, gxs, 0, (PetscScalar *****)array)); 65263a3b9bcSJacob Faibussowitsch } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim); 6533ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6545edff71fSBarry Smith } 6555edff71fSBarry Smith 6561e5d2365SBarry Smith /*@C 6571e5d2365SBarry Smith DMDAVecGetArrayDOFWrite - Returns a multiple dimension array that shares data with 6581e5d2365SBarry Smith the underlying vector and is indexed using the global dimensions. 6591e5d2365SBarry Smith 6601e5d2365SBarry Smith Not Collective 6611e5d2365SBarry Smith 662d8d19677SJose E. Roman Input Parameters: 6631e5d2365SBarry Smith + da - the distributed array 6640af9b551SBarry Smith - vec - a vector the same size as one obtained with `DMCreateGlobalVector()` or `DMCreateLocalVector()` 6651e5d2365SBarry Smith 6661e5d2365SBarry Smith Output Parameter: 6671e5d2365SBarry Smith . array - the array 6681e5d2365SBarry Smith 6690f99b6f4SBarry Smith Level: intermediate 6700f99b6f4SBarry Smith 6711e5d2365SBarry Smith Notes: 672dce8aebaSBarry Smith Call `DMDAVecRestoreArrayDOFWrite()` once you have finished accessing the vector entries. 6731e5d2365SBarry Smith 6741e5d2365SBarry Smith In C, the indexing is "backwards" from what expects: array[k][j][i][DOF] NOT array[i][j][k][DOF]! 6751e5d2365SBarry Smith 6760af9b551SBarry Smith 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 6770af9b551SBarry Smith `DMDAGetCorners()` for a global vector or `DMDAGetGhostCorners()` for a local vector. 6780af9b551SBarry Smith 67960225df5SJacob Faibussowitsch Fortran Notes: 6800f99b6f4SBarry Smith Use `DMDAVecGetArrayWriteF90()` and pass for the array type PetscScalar,pointer :: array(:,...,:) of the appropriate 6810f99b6f4SBarry 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 6820f99b6f4SBarry Smith dimension of the `DMDA`. 6831e5d2365SBarry Smith 6840af9b551SBarry 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 6850af9b551SBarry Smith `array(0:dof-1,xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1)` where the values are obtained from 6860af9b551SBarry Smith `DMDAGetCorners()` for a global vector or `DMDAGetGhostCorners()` for a local vector. 6871e5d2365SBarry Smith 6880f99b6f4SBarry Smith .seealso: `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `DMDAVecRestoreArrayWriteF90()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecRestoreArray()`, `DMDAVecGetArray()`, `DMDAVecGetArrayDOF()`, 68960225df5SJacob Faibussowitsch `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()` 6901e5d2365SBarry Smith @*/ 691d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAVecGetArrayDOFWrite(DM da, Vec vec, void *array) 692d71ae5a4SJacob Faibussowitsch { 6931e5d2365SBarry Smith PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof; 6941e5d2365SBarry Smith 6951e5d2365SBarry Smith PetscFunctionBegin; 6969566063dSJacob Faibussowitsch PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm)); 6979566063dSJacob Faibussowitsch PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm)); 6989566063dSJacob Faibussowitsch PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL)); 6991e5d2365SBarry Smith 7001e5d2365SBarry Smith /* Handle case where user passes in global vector as opposed to local */ 7019566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(vec, &N)); 7021e5d2365SBarry Smith if (N == xm * ym * zm * dof) { 7031e5d2365SBarry Smith gxm = xm; 7041e5d2365SBarry Smith gym = ym; 7051e5d2365SBarry Smith gzm = zm; 7061e5d2365SBarry Smith gxs = xs; 7071e5d2365SBarry Smith gys = ys; 7081e5d2365SBarry Smith gzs = zs; 70963a3b9bcSJacob 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); 7101e5d2365SBarry Smith 7111e5d2365SBarry Smith if (dim == 1) { 7129566063dSJacob Faibussowitsch PetscCall(VecGetArray2dWrite(vec, gxm, dof, gxs, 0, (PetscScalar ***)array)); 7131e5d2365SBarry Smith } else if (dim == 2) { 7149566063dSJacob Faibussowitsch PetscCall(VecGetArray3dWrite(vec, gym, gxm, dof, gys, gxs, 0, (PetscScalar ****)array)); 7151e5d2365SBarry Smith } else if (dim == 3) { 7169566063dSJacob Faibussowitsch PetscCall(VecGetArray4dWrite(vec, gzm, gym, gxm, dof, gzs, gys, gxs, 0, (PetscScalar *****)array)); 71763a3b9bcSJacob Faibussowitsch } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim); 7183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7191e5d2365SBarry Smith } 7201e5d2365SBarry Smith 7211e5d2365SBarry Smith /*@ 722dce8aebaSBarry Smith DMDAVecRestoreArrayDOFWrite - Restores a multiple dimension array obtained with `DMDAVecGetArrayDOFWrite()` 7231e5d2365SBarry Smith 7241e5d2365SBarry Smith Not Collective 7251e5d2365SBarry Smith 726d8d19677SJose E. Roman Input Parameters: 7271e5d2365SBarry Smith + da - the distributed array 7280af9b551SBarry Smith . vec - a vector the same size as one obtained with `DMCreateGlobalVector()` or `DMCreateLocalVector()` 7290af9b551SBarry Smith - array - the `array` pointer is zeroed 7301e5d2365SBarry Smith 7311e5d2365SBarry Smith Level: intermediate 7321e5d2365SBarry Smith 73360225df5SJacob Faibussowitsch Fortran Notes: 7340f99b6f4SBarry Smith Use `DMDAVecRestoreArrayWriteF90()` 7350f99b6f4SBarry Smith 736dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecGetArray()`, `DMDAVecGetArrayDOF()`, `DMDAVecRestoreArrayDOF()`, 73760225df5SJacob Faibussowitsch `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()` 7381e5d2365SBarry Smith @*/ 739d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAVecRestoreArrayDOFWrite(DM da, Vec vec, void *array) 740d71ae5a4SJacob Faibussowitsch { 7411e5d2365SBarry Smith PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof; 7421e5d2365SBarry Smith 7431e5d2365SBarry Smith PetscFunctionBegin; 7449566063dSJacob Faibussowitsch PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm)); 7459566063dSJacob Faibussowitsch PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm)); 7469566063dSJacob Faibussowitsch PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL)); 7471e5d2365SBarry Smith 7481e5d2365SBarry Smith /* Handle case where user passes in global vector as opposed to local */ 7499566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(vec, &N)); 7501e5d2365SBarry Smith if (N == xm * ym * zm * dof) { 7511e5d2365SBarry Smith gxm = xm; 7521e5d2365SBarry Smith gym = ym; 7531e5d2365SBarry Smith gzm = zm; 7541e5d2365SBarry Smith gxs = xs; 7551e5d2365SBarry Smith gys = ys; 7561e5d2365SBarry Smith gzs = zs; 7571e5d2365SBarry Smith } 7581e5d2365SBarry Smith 7591e5d2365SBarry Smith if (dim == 1) { 7609566063dSJacob Faibussowitsch PetscCall(VecRestoreArray2dWrite(vec, gxm, dof, gxs, 0, (PetscScalar ***)array)); 7611e5d2365SBarry Smith } else if (dim == 2) { 7629566063dSJacob Faibussowitsch PetscCall(VecRestoreArray3dWrite(vec, gym, gxm, dof, gys, gxs, 0, (PetscScalar ****)array)); 7631e5d2365SBarry Smith } else if (dim == 3) { 7649566063dSJacob Faibussowitsch PetscCall(VecRestoreArray4dWrite(vec, gzm, gym, gxm, dof, gzs, gys, gxs, 0, (PetscScalar *****)array)); 76563a3b9bcSJacob Faibussowitsch } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim); 7663ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7671e5d2365SBarry Smith } 768