Date: 2025-03-29T05:58:20+00:00

Actual source code: dagetarray.c

      1: #include <petsc/private/dmdaimpl.h>

      3: /*MC
      4:   DMDAVecGetArrayF90 - see Fortran Notes at `DMDAVecGetArray()`

      6:   Level: intermediate
      7: M*/

      9: /*@C
     10:   DMDAVecGetArray - Returns a multiple dimension array that shares data with
     11:   the underlying vector and is indexed using the global or local dimensions of a `DMDA`.

     13:   Logically Collective

     15:   Input Parameters:
     16: + da  - the `DMDA`
     17: - vec - a vector the same size as one obtained with `DMCreateGlobalVector()` or `DMCreateLocalVector()`

     19:   Output Parameter:
     20: . array - the array

     22:   Level: intermediate

     24:   Notes:
     25:   Call `DMDAVecRestoreArray()` once you have finished accessing the vector entries.

     27:   In C, the indexing is "backwards" from what expects: array[k][j][i] NOT array[i][j][k]!

     29:   If `vec` is a local vector (obtained with DMCreateLocalVector() etc) then the ghost point locations are accessible. If it is
     30:   a global vector then the ghost points are not accessible. Of course, with a local vector you will have had to do the
     31:   appropriate `DMGlobalToLocalBegin()` and `DMGlobalToLocalEnd()` to have correct values in the ghost locations.

     33:   The accessible indices are `array[zs:zs+zm-1][ys:ys+ym-1][xs:xs+xm-1]` where the values are obtained from
     34:   `DMDAGetCorners()` for a global vector or `DMDAGetGhostCorners()` for a local vector.

     36:   Fortran Notes:
     37:   Use `DMDAVecGetArray()` and pass for the array type `PetscScalar`,pointer :: array(:,...,:) of the appropriate
     38:   dimension. For a `DMDA` created with a dof of 1 use the dimension of the `DMDA`, for a `DMDA` created with a dof greater than 1 use one more than the
     39:   dimension of the `DMDA`.

     41:   The order of the indices is `array(xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1)` (when dof is 1) otherwise
     42:   `array(0:dof-1,xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1)` where the values are obtained from
     43:   `DMDAGetCorners()` for a global vector or `DMDAGetGhostCorners()` for a local vector.

     45: .seealso: [](sec_struct), [](sec_struct_set), `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecRestoreArray()`, `DMDAVecRestoreArrayDOF()`
     46:           `DMDAVecGetArrayDOF()`, `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()`,
     47:           `DMStagVecGetArray()`
     48: @*/
     49: PetscErrorCode DMDAVecGetArray(DM da, Vec vec, void *array)
     50: {
     51:   PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof;

     53:   PetscFunctionBegin;
     56:   PetscAssertPointer(array, 3);
     57:   PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm));
     58:   PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm));
     59:   PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL));

     61:   /* Handle case where user passes in global vector as opposed to local */
     62:   PetscCall(VecGetLocalSize(vec, &N));
     63:   if (N == xm * ym * zm * dof) {
     64:     gxm = xm;
     65:     gym = ym;
     66:     gzm = zm;
     67:     gxs = xs;
     68:     gys = ys;
     69:     gzs = zs;
     70:   } else PetscCheck(N == gxm * gym * gzm * dof, PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Vector local size %" PetscInt_FMT " is not compatible with DMDA local sizes %" PetscInt_FMT " %" PetscInt_FMT, N, xm * ym * zm * dof, gxm * gym * gzm * dof);

     72:   if (dim == 1) {
     73:     PetscCall(VecGetArray1d(vec, gxm * dof, gxs * dof, (PetscScalar **)array));
     74:   } else if (dim == 2) {
     75:     PetscCall(VecGetArray2d(vec, gym, gxm * dof, gys, gxs * dof, (PetscScalar ***)array));
     76:   } else if (dim == 3) {
     77:     PetscCall(VecGetArray3d(vec, gzm, gym, gxm * dof, gzs, gys, gxs * dof, (PetscScalar ****)array));
     78:   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim);
     79:   PetscFunctionReturn(PETSC_SUCCESS);
     80: }

     82: /*MC
     83:   DMDAVecRestoreArrayF90 - see Fortran Notes at `DMDAVecRestoreArray()`

     85:   Level: intermediate
     86: M*/

     88: /*@
     89:   DMDAVecRestoreArray - Restores a multiple dimension array obtained with `DMDAVecGetArray()`

     91:   Logically Collective

     93:   Input Parameters:
     94: + da    - the `DMDA`
     95: . vec   - a vector the same size as one obtained with `DMCreateGlobalVector()` or `DMCreateLocalVector()`
     96: - array - the `array` pointer

     98:   Level: intermediate

    100: .seealso: [](sec_struct), [](sec_struct_set), `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecGetArray()`,
    101:           `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()`,
    102:           `DMStagVecRestoreArray()`
    103: @*/
    104: PetscErrorCode DMDAVecRestoreArray(DM da, Vec vec, void *array)
    105: {
    106:   PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof;

    108:   PetscFunctionBegin;
    111:   PetscAssertPointer(array, 3);
    112:   PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm));
    113:   PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm));
    114:   PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL));

    116:   /* Handle case where user passes in global vector as opposed to local */
    117:   PetscCall(VecGetLocalSize(vec, &N));
    118:   if (N == xm * ym * zm * dof) {
    119:     gxm = xm;
    120:     gym = ym;
    121:     gzm = zm;
    122:     gxs = xs;
    123:     gys = ys;
    124:     gzs = zs;
    125:   } 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);

    127:   if (dim == 1) {
    128:     PetscCall(VecRestoreArray1d(vec, gxm * dof, gxs * dof, (PetscScalar **)array));
    129:   } else if (dim == 2) {
    130:     PetscCall(VecRestoreArray2d(vec, gym, gxm * dof, gys, gxs * dof, (PetscScalar ***)array));
    131:   } else if (dim == 3) {
    132:     PetscCall(VecRestoreArray3d(vec, gzm, gym, gxm * dof, gzs, gys, gxs * dof, (PetscScalar ****)array));
    133:   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim);
    134:   PetscFunctionReturn(PETSC_SUCCESS);
    135: }

    137: /*MC
    138:   DMDAVecGetArrayWriteF90 - see Fortran Notes at `DMDAVecGetArrayWrite()`

    140:   Level: intermediate
    141: M*/

    143: /*@C
    144:   DMDAVecGetArrayWrite - Returns a multiple dimension array that shares data with
    145:   the underlying vector and is indexed using the global or local dimensions of a `DMDA`.

    147:   Logically Collective

    149:   Input Parameters:
    150: + da  - the `DMDA`
    151: - vec - a vector the same size as one obtained with `DMCreateGlobalVector()` or `DMCreateLocalVector()`

    153:   Output Parameter:
    154: . array - the array

    156:   Level: intermediate

    158:   Notes:
    159:   Call `DMDAVecRestoreArray()` once you have finished accessing the vector entries.

    161:   In C, the indexing is "backwards" from what expects: array[k][j][i] NOT array[i][j][k]!

    163:   if `vec` is a local vector (obtained with `DMCreateLocalVector()` etc) then the ghost point locations are accessible. If it is
    164:   a global vector then the ghost points are not accessible. Of course with the local vector you will have had to do the
    165:   appropriate `DMGlobalToLocalBegin()` and `DMGlobalToLocalEnd()` to have correct values in the ghost locations.

    167:   The accessible indices are `array[zs:zs+zm-1][ys:ys+ym-1][xs:xs+xm-1]` where the values are obtained from
    168:   `DMDAGetCorners()` for a global vector or `DMDAGetGhostCorners()` for a local vector.

    170:   Fortran Notes:
    171:   Use `DMDAVecGetArrayWrite()` and pass for the array type PetscScalar,pointer :: array(:,...,:) of the appropriate
    172:   dimension. For a `DMDA` created with a dof of 1 use the dimension of the `DMDA`, for a `DMDA` created with a dof greater than 1 use one more than the
    173:   dimension of the `DMDA`.

    175:   The order of the indices is `array(xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1)` (when dof is 1) otherwise
    176:   `array(0:dof-1,xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1)` where the values are obtained from
    177:   `DMDAGetCorners()` for a global vector or `DMDAGetGhostCorners()` for a local vector.

    179:   Developer Note:
    180:   This has code duplication with `DMDAVecGetArray()` and `DMDAVecGetArrayRead()`

    182: .seealso: [](sec_struct), [](sec_struct_set), `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecRestoreArrayWrite()`, `DMDAVecRestoreArrayDOF()`
    183:           `DMDAVecGetArrayDOF()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()`
    184: @*/
    185: PetscErrorCode DMDAVecGetArrayWrite(DM da, Vec vec, void *array)
    186: {
    187:   PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof;

    189:   PetscFunctionBegin;
    192:   PetscAssertPointer(array, 3);
    193:   if (da->localSection) {
    194:     PetscCall(VecGetArrayWrite(vec, (PetscScalar **)array));
    195:     PetscFunctionReturn(PETSC_SUCCESS);
    196:   }
    197:   PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm));
    198:   PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm));
    199:   PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL));

    201:   /* Handle case where user passes in global vector as opposed to local */
    202:   PetscCall(VecGetLocalSize(vec, &N));
    203:   if (N == xm * ym * zm * dof) {
    204:     gxm = xm;
    205:     gym = ym;
    206:     gzm = zm;
    207:     gxs = xs;
    208:     gys = ys;
    209:     gzs = zs;
    210:   } else PetscCheck(N == gxm * gym * gzm * dof, PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Vector local size %" PetscInt_FMT " is not compatible with DMDA local sizes %" PetscInt_FMT " %" PetscInt_FMT, N, xm * ym * zm * dof, gxm * gym * gzm * dof);

    212:   if (dim == 1) {
    213:     PetscCall(VecGetArray1dWrite(vec, gxm * dof, gxs * dof, (PetscScalar **)array));
    214:   } else if (dim == 2) {
    215:     PetscCall(VecGetArray2dWrite(vec, gym, gxm * dof, gys, gxs * dof, (PetscScalar ***)array));
    216:   } else if (dim == 3) {
    217:     PetscCall(VecGetArray3dWrite(vec, gzm, gym, gxm * dof, gzs, gys, gxs * dof, (PetscScalar ****)array));
    218:   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim);
    219:   PetscFunctionReturn(PETSC_SUCCESS);
    220: }

    222: /*MC
    223:   DMDAVecRestoreArrayWriteF90 - see Fortran Notes at `DMDAVecRestoreArrayWrite()`

    225:   Level: intermediate
    226: M*/

    228: /*@
    229:   DMDAVecRestoreArrayWrite - Restores a multiple dimension array obtained with `DMDAVecGetArrayWrite()`

    231:   Logically Collective

    233:   Input Parameters:
    234: + da    - the `DMDA`
    235: . vec   - a vector the same size as one obtained with `DMCreateGlobalVector()` or `DMCreateLocalVector()`
    236: - array - the `array` pointer

    238:   Level: intermediate

    240: .seealso: [](sec_struct), [](sec_struct_set), `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecGetArrayWrite()`,
    241:           `DMDAVecGetArray()`, `DMDAVecRestoreArray()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()`
    242: @*/
    243: PetscErrorCode DMDAVecRestoreArrayWrite(DM da, Vec vec, void *array)
    244: {
    245:   PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof;

    247:   PetscFunctionBegin;
    250:   PetscAssertPointer(array, 3);
    251:   if (da->localSection) {
    252:     PetscCall(VecRestoreArray(vec, (PetscScalar **)array));
    253:     PetscFunctionReturn(PETSC_SUCCESS);
    254:   }
    255:   PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm));
    256:   PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm));
    257:   PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL));

    259:   /* Handle case where user passes in global vector as opposed to local */
    260:   PetscCall(VecGetLocalSize(vec, &N));
    261:   if (N == xm * ym * zm * dof) {
    262:     gxm = xm;
    263:     gym = ym;
    264:     gzm = zm;
    265:     gxs = xs;
    266:     gys = ys;
    267:     gzs = zs;
    268:   } 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);

    270:   if (dim == 1) {
    271:     PetscCall(VecRestoreArray1dWrite(vec, gxm * dof, gxs * dof, (PetscScalar **)array));
    272:   } else if (dim == 2) {
    273:     PetscCall(VecRestoreArray2dWrite(vec, gym, gxm * dof, gys, gxs * dof, (PetscScalar ***)array));
    274:   } else if (dim == 3) {
    275:     PetscCall(VecRestoreArray3dWrite(vec, gzm, gym, gxm * dof, gzs, gys, gxs * dof, (PetscScalar ****)array));
    276:   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim);
    277:   PetscFunctionReturn(PETSC_SUCCESS);
    278: }

    280: /*@C
    281:   DMDAVecGetArrayDOF - Returns a multiple dimension array that shares data with
    282:   the underlying vector and is indexed using the global or local dimensions of a `DMDA`

    284:   Logically Collective

    286:   Input Parameters:
    287: + da  - the `DMDA`
    288: - vec - a vector the same size as one obtained with `DMCreateGlobalVector()` or `DMCreateLocalVector()`

    290:   Output Parameter:
    291: . array - the `array` pointer

    293:   Level: intermediate

    295:   Notes:
    296:   Call `DMDAVecRestoreArrayDOF()` once you have finished accessing the vector entries.

    298:   In C, the indexing is "backwards" from what expects: array[k][j][i][DOF] NOT array[i][j][k][DOF]

    300:   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
    301:   `DMDAGetCorners()` for a global vector or `DMDAGetGhostCorners()` for a local vector.

    303:   Fortran Notes:
    304:   Use `DMDAVecGetArray()` and pass for the array type PetscScalar,pointer :: array(:,...,:) of the appropriate
    305:   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
    306:   dimension of the `DMDA`.

    308:   The order of the indices is `array(xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1)` (when ndof is 1) otherwise
    309:   `array(0:dof-1,xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1)` where the values are obtained from
    310:   `DMDAGetCorners()` for a global vector or `DMDAGetGhostCorners()` for a local vector.

    312: .seealso: [](sec_struct), [](sec_struct_set), `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecRestoreArray()`, `DMDAVecGetArray()`, `DMDAVecRestoreArrayDOF()`,
    313:           `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()`, `DMDAVecGetArrayDOFRead()`
    314: @*/
    315: PetscErrorCode DMDAVecGetArrayDOF(DM da, Vec vec, void *array)
    316: {
    317:   PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof;

    319:   PetscFunctionBegin;
    320:   PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm));
    321:   PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm));
    322:   PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL));

    324:   /* Handle case where user passes in global vector as opposed to local */
    325:   PetscCall(VecGetLocalSize(vec, &N));
    326:   if (N == xm * ym * zm * dof) {
    327:     gxm = xm;
    328:     gym = ym;
    329:     gzm = zm;
    330:     gxs = xs;
    331:     gys = ys;
    332:     gzs = zs;
    333:   } 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);

    335:   if (dim == 1) {
    336:     PetscCall(VecGetArray2d(vec, gxm, dof, gxs, 0, (PetscScalar ***)array));
    337:   } else if (dim == 2) {
    338:     PetscCall(VecGetArray3d(vec, gym, gxm, dof, gys, gxs, 0, (PetscScalar ****)array));
    339:   } else if (dim == 3) {
    340:     PetscCall(VecGetArray4d(vec, gzm, gym, gxm, dof, gzs, gys, gxs, 0, (PetscScalar *****)array));
    341:   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim);
    342:   PetscFunctionReturn(PETSC_SUCCESS);
    343: }

    345: /*@
    346:   DMDAVecRestoreArrayDOF - Restores a multiple dimension array obtained with `DMDAVecGetArrayDOF()`

    348:   Logically Collective

    350:   Input Parameters:
    351: + da    - the `DMDA`
    352: . vec   - vector the same size as one obtained with `DMCreateGlobalVector()` or `DMCreateLocalVector()`
    353: - array - the `array` point

    355:   Level: intermediate

    357: .seealso: [](sec_struct), [](sec_struct_set), `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecGetArray()`, `DMDAVecGetArrayDOF()`,
    358:           `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()`
    359: @*/
    360: PetscErrorCode DMDAVecRestoreArrayDOF(DM da, Vec vec, void *array)
    361: {
    362:   PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof;

    364:   PetscFunctionBegin;
    365:   PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm));
    366:   PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm));
    367:   PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL));

    369:   /* Handle case where user passes in global vector as opposed to local */
    370:   PetscCall(VecGetLocalSize(vec, &N));
    371:   if (N == xm * ym * zm * dof) {
    372:     gxm = xm;
    373:     gym = ym;
    374:     gzm = zm;
    375:     gxs = xs;
    376:     gys = ys;
    377:     gzs = zs;
    378:   }

    380:   if (dim == 1) {
    381:     PetscCall(VecRestoreArray2d(vec, gxm, dof, gxs, 0, (PetscScalar ***)array));
    382:   } else if (dim == 2) {
    383:     PetscCall(VecRestoreArray3d(vec, gym, gxm, dof, gys, gxs, 0, (PetscScalar ****)array));
    384:   } else if (dim == 3) {
    385:     PetscCall(VecRestoreArray4d(vec, gzm, gym, gxm, dof, gzs, gys, gxs, 0, (PetscScalar *****)array));
    386:   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim);
    387:   PetscFunctionReturn(PETSC_SUCCESS);
    388: }

    390: /*MC
    391:   DMDAVecGetArrayReadF90 - see Fortran Notes at `DMDAVecGetArrayRead()`

    393:   Level: intermediate
    394: M*/

    396: /*@C
    397:   DMDAVecGetArrayRead - Returns a multiple dimension array that shares data with
    398:   the underlying vector and is indexed using the global or local dimensions of a `DMDA`.

    400:   Not Collective

    402:   Input Parameters:
    403: + da  - the `DMDA`
    404: - vec - a vector the same size as one obtained with `DMCreateGlobalVector()` or `DMCreateLocalVector()`

    406:   Output Parameter:
    407: . array - the array

    409:   Level: intermediate

    411:   Notes:
    412:   Call `DMDAVecRestoreArrayRead()` once you have finished accessing the vector entries.

    414:   In C, the indexing is "backwards" from what expects: array[k][j][i] NOT array[i][j][k]!

    416:   If `vec` is a local vector (obtained with `DMCreateLocalVector()` etc) then the ghost point locations are accessible. If it is
    417:   a global vector then the ghost points are not accessible. Of course with the local vector you will have had to do the
    418:   appropriate `DMGlobalToLocalBegin()` and `DMGlobalToLocalEnd()` to have correct values in the ghost locations.

    420:   The accessible indices are `array[zs:zs+zm-1][ys:ys+ym-1][xs:xs+xm-1]` where the values are obtained from
    421:   `DMDAGetCorners()` for a global vector or `DMDAGetGhostCorners()` for a local vector.

    423:   Fortran Notes:
    424:   Use `DMDAVecGetArrayRead()` and pass for the array type `PetscScalar`,pointer :: array(:,...,:) of the appropriate
    425:   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
    426:   dimension of the `DMDA`.

    428:   The order of the indices is `array(xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1)` (when dof is 1) otherwise
    429:   `array(0:dof-1,xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1)` where the values are obtained from
    430:   `DMDAGetCorners()` for a global vector or `DMDAGetGhostCorners()` for a local vector.

    432: .seealso: [](sec_struct), [](sec_struct_set), `DM`, `DMDA`, `DMDAGetGhostCorners()`,
    433: `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecRestoreArrayRead()`,
    434: `DMDAVecRestoreArrayDOF()`, `DMDAVecGetArrayDOF()`, `DMDAVecGetArray()`,
    435: `DMDAVecRestoreArray()`, `DMStagVecGetArrayRead()`
    436: @*/
    437: PetscErrorCode DMDAVecGetArrayRead(DM da, Vec vec, void *array)
    438: {
    439:   PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof;

    441:   PetscFunctionBegin;
    444:   PetscAssertPointer(array, 3);
    445:   PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm));
    446:   PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm));
    447:   PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL));

    449:   /* Handle case where user passes in global vector as opposed to local */
    450:   PetscCall(VecGetLocalSize(vec, &N));
    451:   if (N == xm * ym * zm * dof) {
    452:     gxm = xm;
    453:     gym = ym;
    454:     gzm = zm;
    455:     gxs = xs;
    456:     gys = ys;
    457:     gzs = zs;
    458:   } 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);

    460:   if (dim == 1) {
    461:     PetscCall(VecGetArray1dRead(vec, gxm * dof, gxs * dof, (PetscScalar **)array));
    462:   } else if (dim == 2) {
    463:     PetscCall(VecGetArray2dRead(vec, gym, gxm * dof, gys, gxs * dof, (PetscScalar ***)array));
    464:   } else if (dim == 3) {
    465:     PetscCall(VecGetArray3dRead(vec, gzm, gym, gxm * dof, gzs, gys, gxs * dof, (PetscScalar ****)array));
    466:   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim);
    467:   PetscFunctionReturn(PETSC_SUCCESS);
    468: }

    470: /*MC
    471:   DMDAVecRestoreArrayReadF90 - see Fortran Notes at `DMDAVecRestoreArrayRead()`

    473:   Level: intermediate
    474: M*/

    476: /*@
    477:   DMDAVecRestoreArrayRead - Restores a multiple dimension array obtained with `DMDAVecGetArrayRead()`

    479:   Not Collective

    481:   Input Parameters:
    482: + da    - the `DMDA`
    483: . vec   - vector the same size as one obtained with `DMCreateGlobalVector()` or `DMCreateLocalVector()`
    484: - array - the `array` pointer

    486:   Level: intermediate

    488: .seealso: [](sec_struct), [](sec_struct_set), `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecGetArrayRead()`,
    489:           `DMDAVecGetArray()`, `DMDAVecRestoreArray()`, `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`,
    490:           `DMStagVecRestoreArrayRead()`
    491: @*/
    492: PetscErrorCode DMDAVecRestoreArrayRead(DM da, Vec vec, void *array)
    493: {
    494:   PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof;

    496:   PetscFunctionBegin;
    499:   PetscAssertPointer(array, 3);
    500:   PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm));
    501:   PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm));
    502:   PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL));

    504:   /* Handle case where user passes in global vector as opposed to local */
    505:   PetscCall(VecGetLocalSize(vec, &N));
    506:   if (N == xm * ym * zm * dof) {
    507:     gxm = xm;
    508:     gym = ym;
    509:     gzm = zm;
    510:     gxs = xs;
    511:     gys = ys;
    512:     gzs = zs;
    513:   } 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);

    515:   if (dim == 1) {
    516:     PetscCall(VecRestoreArray1dRead(vec, gxm * dof, gxs * dof, (PetscScalar **)array));
    517:   } else if (dim == 2) {
    518:     PetscCall(VecRestoreArray2dRead(vec, gym, gxm * dof, gys, gxs * dof, (PetscScalar ***)array));
    519:   } else if (dim == 3) {
    520:     PetscCall(VecRestoreArray3dRead(vec, gzm, gym, gxm * dof, gzs, gys, gxs * dof, (PetscScalar ****)array));
    521:   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim);
    522:   PetscFunctionReturn(PETSC_SUCCESS);
    523: }

    525: /*@C
    526:   DMDAVecGetArrayDOFRead - Returns a multiple dimension array that shares data with
    527:   the underlying vector and is indexed using the global or local dimensions of a `DMDA`

    529:   Not Collective

    531:   Input Parameters:
    532: + da  - the `DMDA`
    533: - vec - a vector the same size as one obtained with `DMCreateGlobalVector()` or `DMCreateLocalVector()`

    535:   Output Parameter:
    536: . array - the array

    538:   Level: intermediate

    540:   Notes:
    541:   Call `DMDAVecRestoreArrayDOFRead()` once you have finished accessing the vector entries.

    543:   In C, the indexing is "backwards" from what expects: array[k][j][i][DOF] NOT array[i][j][k][DOF]!

    545:   The accessible indices are `array[zs:zs+zm-1][ys:ys+ym-1][xs:xs+xm-1]` where the values are obtained from
    546:   `DMDAGetCorners()` for a global vector or `DMDAGetGhostCorners()` for a local vector.

    548:   Fortran Notes:
    549:   Use  `DMDAVecGetArrayRead()` and pass for the array type PetscScalar,pointer :: array(:,...,:) of the appropriate
    550:   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
    551:   dimension of the `DMDA`.

    553:   The order of the indices is `array(xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1)` (when dof is 1) otherwise
    554:   `array(0:dof-1,xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1)` where the values are obtained from
    555:   `DMDAGetCorners()` for a global vector or `DMDAGetGhostCorners()` for a local vector.

    557: .seealso: [](sec_struct), [](sec_struct_set), `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecRestoreArray()`, `DMDAVecGetArray()`, `DMDAVecGetArrayDOF()`,
    558:           `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()`
    559: @*/
    560: PetscErrorCode DMDAVecGetArrayDOFRead(DM da, Vec vec, void *array)
    561: {
    562:   PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof;

    564:   PetscFunctionBegin;
    565:   PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm));
    566:   PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm));
    567:   PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL));

    569:   /* Handle case where user passes in global vector as opposed to local */
    570:   PetscCall(VecGetLocalSize(vec, &N));
    571:   if (N == xm * ym * zm * dof) {
    572:     gxm = xm;
    573:     gym = ym;
    574:     gzm = zm;
    575:     gxs = xs;
    576:     gys = ys;
    577:     gzs = zs;
    578:   } 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);

    580:   if (dim == 1) {
    581:     PetscCall(VecGetArray2dRead(vec, gxm, dof, gxs, 0, (PetscScalar ***)array));
    582:   } else if (dim == 2) {
    583:     PetscCall(VecGetArray3dRead(vec, gym, gxm, dof, gys, gxs, 0, (PetscScalar ****)array));
    584:   } else if (dim == 3) {
    585:     PetscCall(VecGetArray4dRead(vec, gzm, gym, gxm, dof, gzs, gys, gxs, 0, (PetscScalar *****)array));
    586:   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim);
    587:   PetscFunctionReturn(PETSC_SUCCESS);
    588: }

    590: /*@
    591:   DMDAVecRestoreArrayDOFRead - Restores a multiple dimension array obtained with `DMDAVecGetArrayDOFRead()`

    593:   Not Collective

    595:   Input Parameters:
    596: + da    - the `DMDA`
    597: . vec   - a vector the same size as one obtained with `DMCreateGlobalVector()` or `DMCreateLocalVector()`
    598: - array - the `array` pointer

    600:   Level: intermediate

    602: .seealso: [](sec_struct), [](sec_struct_set), `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecGetArray()`, `DMDAVecGetArrayDOF()`, `DMDAVecRestoreArrayDOF()`,
    603:           `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`, `DMDAVecGetArrayRead()`, `DMDAVecRestoreArrayRead()`
    604: @*/
    605: PetscErrorCode DMDAVecRestoreArrayDOFRead(DM da, Vec vec, void *array)
    606: {
    607:   PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof;

    609:   PetscFunctionBegin;
    610:   PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm));
    611:   PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm));
    612:   PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL));

    614:   /* Handle case where user passes in global vector as opposed to local */
    615:   PetscCall(VecGetLocalSize(vec, &N));
    616:   if (N == xm * ym * zm * dof) {
    617:     gxm = xm;
    618:     gym = ym;
    619:     gzm = zm;
    620:     gxs = xs;
    621:     gys = ys;
    622:     gzs = zs;
    623:   }

    625:   if (dim == 1) {
    626:     PetscCall(VecRestoreArray2dRead(vec, gxm, dof, gxs, 0, (PetscScalar ***)array));
    627:   } else if (dim == 2) {
    628:     PetscCall(VecRestoreArray3dRead(vec, gym, gxm, dof, gys, gxs, 0, (PetscScalar ****)array));
    629:   } else if (dim == 3) {
    630:     PetscCall(VecRestoreArray4dRead(vec, gzm, gym, gxm, dof, gzs, gys, gxs, 0, (PetscScalar *****)array));
    631:   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim);
    632:   PetscFunctionReturn(PETSC_SUCCESS);
    633: }

    635: /*@C
    636:   DMDAVecGetArrayDOFWrite - Returns a multiple dimension array that shares data with
    637:   the underlying vector and is indexed using the global or local dimensions of a `DMDA`

    639:   Not Collective

    641:   Input Parameters:
    642: + da  - the `DMDA`
    643: - vec - a vector the same size as one obtained with `DMCreateGlobalVector()` or `DMCreateLocalVector()`

    645:   Output Parameter:
    646: . array - the array

    648:   Level: intermediate

    650:   Notes:
    651:   Call `DMDAVecRestoreArrayDOFWrite()` once you have finished accessing the vector entries.

    653:   In C, the indexing is "backwards" from what expects: array[k][j][i][DOF] NOT array[i][j][k][DOF]!

    655:   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
    656:   `DMDAGetCorners()` for a global vector or `DMDAGetGhostCorners()` for a local vector.

    658:   Fortran Notes:
    659:   Use  `DMDAVecGetArrayWrite()` and pass for the array type PetscScalar,pointer :: array(:,...,:) of the appropriate
    660:   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
    661:   dimension of the `DMDA`.

    663:   The order of the indices is `array(xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1)` (when dof is 1) otherwise
    664:   `array(0:dof-1,xs:xs+xm-1,ys:ys+ym-1,zs:zs+zm-1)` where the values are obtained from
    665:   `DMDAGetCorners()` for a global vector or `DMDAGetGhostCorners()` for a local vector.

    667: .seealso: [](sec_struct), [](sec_struct_set), `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecRestoreArray()`, `DMDAVecGetArray()`, `DMDAVecGetArrayDOF()`,
    668:           `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`
    669: @*/
    670: PetscErrorCode DMDAVecGetArrayDOFWrite(DM da, Vec vec, void *array)
    671: {
    672:   PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof;

    674:   PetscFunctionBegin;
    675:   PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm));
    676:   PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm));
    677:   PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL));

    679:   /* Handle case where user passes in global vector as opposed to local */
    680:   PetscCall(VecGetLocalSize(vec, &N));
    681:   if (N == xm * ym * zm * dof) {
    682:     gxm = xm;
    683:     gym = ym;
    684:     gzm = zm;
    685:     gxs = xs;
    686:     gys = ys;
    687:     gzs = zs;
    688:   } 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);

    690:   if (dim == 1) {
    691:     PetscCall(VecGetArray2dWrite(vec, gxm, dof, gxs, 0, (PetscScalar ***)array));
    692:   } else if (dim == 2) {
    693:     PetscCall(VecGetArray3dWrite(vec, gym, gxm, dof, gys, gxs, 0, (PetscScalar ****)array));
    694:   } else if (dim == 3) {
    695:     PetscCall(VecGetArray4dWrite(vec, gzm, gym, gxm, dof, gzs, gys, gxs, 0, (PetscScalar *****)array));
    696:   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim);
    697:   PetscFunctionReturn(PETSC_SUCCESS);
    698: }

    700: /*@
    701:   DMDAVecRestoreArrayDOFWrite - Restores a multiple dimension array obtained with `DMDAVecGetArrayDOFWrite()`

    703:   Not Collective

    705:   Input Parameters:
    706: + da    - the `DMDA`
    707: . vec   - a vector the same size as one obtained with `DMCreateGlobalVector()` or `DMCreateLocalVector()`
    708: - array - the `array` pointer

    710:   Level: intermediate

    712: .seealso: [](sec_struct), [](sec_struct_set), `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `VecGetArray()`, `VecRestoreArray()`, `DMDAVecGetArray()`, `DMDAVecGetArrayDOF()`, `DMDAVecRestoreArrayDOF()`,
    713:           `DMDAVecGetArrayWrite()`, `DMDAVecRestoreArrayWrite()`
    714: @*/
    715: PetscErrorCode DMDAVecRestoreArrayDOFWrite(DM da, Vec vec, void *array)
    716: {
    717:   PetscInt xs, ys, zs, xm, ym, zm, gxs, gys, gzs, gxm, gym, gzm, N, dim, dof;

    719:   PetscFunctionBegin;
    720:   PetscCall(DMDAGetCorners(da, &xs, &ys, &zs, &xm, &ym, &zm));
    721:   PetscCall(DMDAGetGhostCorners(da, &gxs, &gys, &gzs, &gxm, &gym, &gzm));
    722:   PetscCall(DMDAGetInfo(da, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL));

    724:   /* Handle case where user passes in global vector as opposed to local */
    725:   PetscCall(VecGetLocalSize(vec, &N));
    726:   if (N == xm * ym * zm * dof) {
    727:     gxm = xm;
    728:     gym = ym;
    729:     gzm = zm;
    730:     gxs = xs;
    731:     gys = ys;
    732:     gzs = zs;
    733:   }

    735:   if (dim == 1) {
    736:     PetscCall(VecRestoreArray2dWrite(vec, gxm, dof, gxs, 0, (PetscScalar ***)array));
    737:   } else if (dim == 2) {
    738:     PetscCall(VecRestoreArray3dWrite(vec, gym, gxm, dof, gys, gxs, 0, (PetscScalar ****)array));
    739:   } else if (dim == 3) {
    740:     PetscCall(VecRestoreArray4dWrite(vec, gzm, gym, gxm, dof, gzs, gys, gxs, 0, (PetscScalar *****)array));
    741:   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_CORRUPT, "DMDA dimension not 1, 2, or 3, it is %" PetscInt_FMT, dim);
    742:   PetscFunctionReturn(PETSC_SUCCESS);
    743: }