Actual source code: ex25.c


  2: static char help[] = "Takes a patch of a large DMDA vector to one process.\n\n";

  4: #include <petscdm.h>
  5: #include <petscdmda.h>
  6: #include <petscdmpatch.h>
  7: #include <petscsf.h>

  9: typedef struct {
 10:   PetscScalar x, y;
 11: } Field;

 13: int main(int argc, char **argv)
 14: {
 15:   Vec         xy, sxy;
 16:   DM          da, sda = NULL;
 17:   PetscSF     sf;
 18:   PetscInt    m = 10, n = 10, dof = 2;
 19:   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 */
 20:   MPI_Comm    comm;
 21:   PetscMPIInt rank;

 24:   PetscInitialize(&argc, &argv, (char *)0, help);

 26:   /* create the large DMDA and set coordinates (which we will copy down to the small DA). */
 27:   DMDACreate2d(PETSC_COMM_WORLD, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE, DMDA_STENCIL_BOX, m, n, PETSC_DECIDE, PETSC_DECIDE, dof, 1, 0, 0, &da);
 28:   DMSetFromOptions(da);
 29:   DMSetUp(da);
 30:   DMDASetUniformCoordinates(da, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0);
 31:   /* Just as a simple example we use the coordinates as the variables in the vectors we wish to examine. */
 32:   DMGetCoordinates(da, &xy);
 33:   /* The vector entries are displayed in the "natural" ordering on the two dimensional grid; interlaced x and y with with the x variable increasing more rapidly than the y */
 34:   VecView(xy, 0);

 36:   MPI_Comm_rank(PETSC_COMM_WORLD, &rank);
 37:   if (rank == 0) comm = MPI_COMM_SELF;
 38:   else comm = MPI_COMM_NULL;

 40:   DMPatchZoom(da, lower, upper, comm, &sda, NULL, &sf);
 41:   if (rank == 0) {
 42:     DMCreateGlobalVector(sda, &sxy);
 43:   } else {
 44:     VecCreateSeq(PETSC_COMM_SELF, 0, &sxy);
 45:   }
 46:   /*  A PetscSF can also be used as a VecScatter context */
 47:   VecScatterBegin(sf, xy, sxy, INSERT_VALUES, SCATTER_FORWARD);
 48:   VecScatterEnd(sf, xy, sxy, INSERT_VALUES, SCATTER_FORWARD);
 49:   /* Only rank == 0 has the entries of the patch, so run code only at that rank */
 50:   if (rank == 0) {
 51:     Field       **vars;
 52:     DMDALocalInfo info;
 53:     PetscInt      i, j;
 54:     PetscScalar   sum = 0;

 56:     /* The vector entries of the patch are displayed in the "natural" ordering on the two grid; interlaced x and y with with the x variable increasing more rapidly */
 57:     VecView(sxy, PETSC_VIEWER_STDOUT_SELF);
 58:     /* Compute some trivial statistic of the coordinates */
 59:     DMDAGetLocalInfo(sda, &info);
 60:     DMDAVecGetArray(sda, sxy, &vars);
 61:     /* Loop over the patch of the entire domain */
 62:     for (j = info.ys; j < info.ys + info.ym; j++) {
 63:       for (i = info.xs; i < info.xs + info.xm; i++) sum += vars[j][i].x;
 64:     }
 65:     PetscPrintf(PETSC_COMM_SELF, "The sum of the x coordinates is %g\n", (double)PetscRealPart(sum));
 66:     DMDAVecRestoreArray(sda, sxy, &vars);
 67:   }

 69:   VecDestroy(&sxy);
 70:   PetscSFDestroy(&sf);
 71:   DMDestroy(&sda);
 72:   DMDestroy(&da);
 73:   PetscFinalize();
 74:   return 0;
 75: }

 77: /*TEST

 79:    test:

 81:    test:
 82:      nsize: 4
 83:      suffix: 2

 85: TEST*/