xref: /petsc/src/dm/tutorials/ex25.c (revision 732aec7a18f2199fb53bb9a2f3aef439a834ce31)
160c22052SBarry Smith static char help[] = "Takes a patch of a large DMDA vector to one process.\n\n";
260c22052SBarry Smith 
360c22052SBarry Smith #include <petscdm.h>
460c22052SBarry Smith #include <petscdmda.h>
560c22052SBarry Smith #include <petscdmpatch.h>
660c22052SBarry Smith #include <petscsf.h>
760c22052SBarry Smith 
860c22052SBarry Smith typedef struct {
960c22052SBarry Smith   PetscScalar x, y;
1060c22052SBarry Smith } Field;
1160c22052SBarry Smith 
main(int argc,char ** argv)12d71ae5a4SJacob Faibussowitsch int main(int argc, char **argv)
13d71ae5a4SJacob Faibussowitsch {
1460c22052SBarry Smith   Vec         xy, sxy;
1560c22052SBarry Smith   DM          da, sda = NULL;
1660c22052SBarry Smith   PetscSF     sf;
1760c22052SBarry Smith   PetscInt    m = 10, n = 10, dof = 2;
1860c22052SBarry Smith   MatStencil  lower = {0, 3, 2, 0}, upper = {0, 7, 8, 0}; /* These are in the order of the z, y, x, logical coordinates, the fourth entry is ignored */
1960c22052SBarry Smith   MPI_Comm    comm;
2060c22052SBarry Smith   PetscMPIInt rank;
2160c22052SBarry Smith 
22327415f7SBarry Smith   PetscFunctionBeginUser;
23*c8025a54SPierre Jolivet   PetscCall(PetscInitialize(&argc, &argv, NULL, help));
2460c22052SBarry Smith 
25a5b23f4aSJose E. Roman   /* create the large DMDA and set coordinates (which we will copy down to the small DA). */
269566063dSJacob Faibussowitsch   PetscCall(DMDACreate2d(PETSC_COMM_WORLD, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE, DMDA_STENCIL_BOX, m, n, PETSC_DECIDE, PETSC_DECIDE, dof, 1, 0, 0, &da));
279566063dSJacob Faibussowitsch   PetscCall(DMSetFromOptions(da));
289566063dSJacob Faibussowitsch   PetscCall(DMSetUp(da));
299566063dSJacob Faibussowitsch   PetscCall(DMDASetUniformCoordinates(da, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0));
3060c22052SBarry Smith   /* Just as a simple example we use the coordinates as the variables in the vectors we wish to examine. */
319566063dSJacob Faibussowitsch   PetscCall(DMGetCoordinates(da, &xy));
3215229ffcSPierre Jolivet   /* The vector entries are displayed in the "natural" ordering on the two dimensional grid; interlaced x and y with the x variable increasing more rapidly than the y */
339566063dSJacob Faibussowitsch   PetscCall(VecView(xy, 0));
3460c22052SBarry Smith 
359566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank));
36dd400576SPatrick Sanan   if (rank == 0) comm = MPI_COMM_SELF;
3760c22052SBarry Smith   else comm = MPI_COMM_NULL;
3860c22052SBarry Smith 
399566063dSJacob Faibussowitsch   PetscCall(DMPatchZoom(da, lower, upper, comm, &sda, NULL, &sf));
40dd400576SPatrick Sanan   if (rank == 0) {
419566063dSJacob Faibussowitsch     PetscCall(DMCreateGlobalVector(sda, &sxy));
4260c22052SBarry Smith   } else {
439566063dSJacob Faibussowitsch     PetscCall(VecCreateSeq(PETSC_COMM_SELF, 0, &sxy));
4460c22052SBarry Smith   }
4560c22052SBarry Smith   /*  A PetscSF can also be used as a VecScatter context */
469566063dSJacob Faibussowitsch   PetscCall(VecScatterBegin(sf, xy, sxy, INSERT_VALUES, SCATTER_FORWARD));
479566063dSJacob Faibussowitsch   PetscCall(VecScatterEnd(sf, xy, sxy, INSERT_VALUES, SCATTER_FORWARD));
4860c22052SBarry Smith   /* Only rank == 0 has the entries of the patch, so run code only at that rank */
49dd400576SPatrick Sanan   if (rank == 0) {
5060c22052SBarry Smith     Field       **vars;
5160c22052SBarry Smith     DMDALocalInfo info;
5260c22052SBarry Smith     PetscInt      i, j;
5360c22052SBarry Smith     PetscScalar   sum = 0;
5460c22052SBarry Smith 
5515229ffcSPierre Jolivet     /* The vector entries of the patch are displayed in the "natural" ordering on the two grid; interlaced x and y with the x variable increasing more rapidly */
569566063dSJacob Faibussowitsch     PetscCall(VecView(sxy, PETSC_VIEWER_STDOUT_SELF));
5760c22052SBarry Smith     /* Compute some trivial statistic of the coordinates */
589566063dSJacob Faibussowitsch     PetscCall(DMDAGetLocalInfo(sda, &info));
599566063dSJacob Faibussowitsch     PetscCall(DMDAVecGetArray(sda, sxy, &vars));
6060c22052SBarry Smith     /* Loop over the patch of the entire domain */
6160c22052SBarry Smith     for (j = info.ys; j < info.ys + info.ym; j++) {
62ad540459SPierre Jolivet       for (i = info.xs; i < info.xs + info.xm; i++) sum += vars[j][i].x;
6360c22052SBarry Smith     }
649566063dSJacob Faibussowitsch     PetscCall(PetscPrintf(PETSC_COMM_SELF, "The sum of the x coordinates is %g\n", (double)PetscRealPart(sum)));
659566063dSJacob Faibussowitsch     PetscCall(DMDAVecRestoreArray(sda, sxy, &vars));
6660c22052SBarry Smith   }
6760c22052SBarry Smith 
689566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&sxy));
699566063dSJacob Faibussowitsch   PetscCall(PetscSFDestroy(&sf));
709566063dSJacob Faibussowitsch   PetscCall(DMDestroy(&sda));
719566063dSJacob Faibussowitsch   PetscCall(DMDestroy(&da));
729566063dSJacob Faibussowitsch   PetscCall(PetscFinalize());
73b122ec5aSJacob Faibussowitsch   return 0;
7460c22052SBarry Smith }
7560c22052SBarry Smith 
7660c22052SBarry Smith /*TEST
7760c22052SBarry Smith 
7860c22052SBarry Smith    test:
7960c22052SBarry Smith 
8060c22052SBarry Smith    test:
8160c22052SBarry Smith      nsize: 4
8260c22052SBarry Smith      suffix: 2
8360c22052SBarry Smith 
8460c22052SBarry Smith TEST*/
85