Actual source code: ex7.c

  1: static char help[] = "Test DMStag 3d periodic and ghosted boundary conditions\n\n";
  2: #include <petscdm.h>
  3: #include <petscdmstag.h>

  5: int main(int argc, char **argv)
  6: {
  7:   DM             dm;
  8:   Vec            vec, vecLocal1, vecLocal2;
  9:   PetscScalar   *a, ****a1, ****a2, expected;
 10:   PetscInt       startx, starty, startz, nx, ny, nz, i, j, k, d, is, js, ks, dof0, dof1, dof2, dof3, dofTotal, stencilWidth, Nx, Ny, Nz;
 11:   DMBoundaryType boundaryTypex, boundaryTypey, boundaryTypez;
 12:   PetscMPIInt    rank;

 14:   PetscFunctionBeginUser;
 15:   PetscCall(PetscInitialize(&argc, &argv, NULL, help));
 16:   PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank));
 17:   dof0         = 1;
 18:   dof1         = 1;
 19:   dof2         = 1;
 20:   dof3         = 1;
 21:   stencilWidth = 2;
 22:   PetscCall(DMStagCreate3d(PETSC_COMM_WORLD, DM_BOUNDARY_PERIODIC, DM_BOUNDARY_PERIODIC, DM_BOUNDARY_PERIODIC, 4, 4, 4, PETSC_DECIDE, PETSC_DECIDE, PETSC_DECIDE, dof0, dof1, dof2, dof3, DMSTAG_STENCIL_BOX, stencilWidth, NULL, NULL, NULL, &dm));
 23:   PetscCall(DMSetFromOptions(dm));
 24:   PetscCall(DMSetUp(dm));
 25:   PetscCall(DMStagGetDOF(dm, &dof0, &dof1, &dof2, &dof3));
 26:   dofTotal = dof0 + 3 * dof1 + 3 * dof2 + dof3;
 27:   PetscCall(DMStagGetStencilWidth(dm, &stencilWidth));

 29:   PetscCall(DMCreateLocalVector(dm, &vecLocal1));
 30:   PetscCall(VecDuplicate(vecLocal1, &vecLocal2));

 32:   PetscCall(DMCreateGlobalVector(dm, &vec));
 33:   PetscCall(VecSet(vec, 1.0));
 34:   PetscCall(DMGlobalToLocalBegin(dm, vec, INSERT_VALUES, vecLocal1));
 35:   PetscCall(DMGlobalToLocalEnd(dm, vec, INSERT_VALUES, vecLocal1));

 37:   PetscCall(DMStagGetCorners(dm, &startx, &starty, &startz, &nx, &ny, &nz, NULL, NULL, NULL));
 38:   PetscCall(DMStagVecGetArrayRead(dm, vecLocal1, &a1));
 39:   PetscCall(DMStagVecGetArray(dm, vecLocal2, &a2));
 40:   for (k = startz; k < startz + nz; ++k) {
 41:     for (j = starty; j < starty + ny; ++j) {
 42:       for (i = startx; i < startx + nx; ++i) {
 43:         for (d = 0; d < dofTotal; ++d) {
 44:           if (a1[k][j][i][d] != 1.0) PetscCall(PetscPrintf(PETSC_COMM_SELF, "[%d] Unexpected value %g (expecting %g)\n", rank, (double)PetscRealPart(a1[k][j][i][d]), 1.0));
 45:           a2[k][j][i][d] = 0.0;
 46:           for (ks = -stencilWidth; ks <= stencilWidth; ++ks) {
 47:             for (js = -stencilWidth; js <= stencilWidth; ++js) {
 48:               for (is = -stencilWidth; is <= stencilWidth; ++is) a2[k][j][i][d] += a1[k + ks][j + js][i + is][d];
 49:             }
 50:           }
 51:         }
 52:       }
 53:     }
 54:   }
 55:   PetscCall(DMStagVecRestoreArrayRead(dm, vecLocal1, &a1));
 56:   PetscCall(DMStagVecRestoreArray(dm, vecLocal2, &a2));

 58:   PetscCall(DMLocalToGlobalBegin(dm, vecLocal2, INSERT_VALUES, vec));
 59:   PetscCall(DMLocalToGlobalEnd(dm, vecLocal2, INSERT_VALUES, vec));

 61:   /* For the all-periodic case, all values are the same . Otherwise, just check the local version */
 62:   PetscCall(DMStagGetBoundaryTypes(dm, &boundaryTypex, &boundaryTypey, &boundaryTypez));
 63:   if (boundaryTypex == DM_BOUNDARY_PERIODIC && boundaryTypey == DM_BOUNDARY_PERIODIC && boundaryTypez == DM_BOUNDARY_PERIODIC) {
 64:     PetscCall(VecGetArray(vec, &a));
 65:     expected = 1.0;
 66:     for (d = 0; d < 3; ++d) expected *= (2 * stencilWidth + 1);
 67:     for (i = 0; i < nz * ny * nx * dofTotal; ++i) {
 68:       if (a[i] != expected) PetscCall(PetscPrintf(PETSC_COMM_SELF, "[%d] Unexpected value %g (expecting %g)\n", rank, (double)PetscRealPart(a[i]), (double)PetscRealPart(expected)));
 69:     }
 70:     PetscCall(VecRestoreArray(vec, &a));
 71:   } else {
 72:     PetscCall(DMStagVecGetArrayRead(dm, vecLocal2, &a2));
 73:     PetscCall(DMStagGetGlobalSizes(dm, &Nx, &Ny, &Nz));
 74:     PetscCheck(stencilWidth <= 1, PETSC_COMM_WORLD, PETSC_ERR_SUP, "Check implemented assuming stencilWidth = 1");
 75:     for (k = startz; k < startz + nz; ++k) {
 76:       for (j = starty; j < starty + ny; ++j) {
 77:         for (i = startx; i < startx + nx; ++i) {
 78:           PetscInt  dd, extra[3];
 79:           PetscBool bnd[3];
 80:           bnd[0]   = (PetscBool)((i == 0 || i == Nx - 1) && boundaryTypex != DM_BOUNDARY_PERIODIC);
 81:           bnd[1]   = (PetscBool)((j == 0 || j == Ny - 1) && boundaryTypey != DM_BOUNDARY_PERIODIC);
 82:           bnd[2]   = (PetscBool)((k == 0 || k == Nz - 1) && boundaryTypez != DM_BOUNDARY_PERIODIC);
 83:           extra[0] = i == Nx - 1 && boundaryTypex != DM_BOUNDARY_PERIODIC ? 1 : 0;
 84:           extra[1] = j == Ny - 1 && boundaryTypey != DM_BOUNDARY_PERIODIC ? 1 : 0;
 85:           extra[2] = k == Nz - 1 && boundaryTypez != DM_BOUNDARY_PERIODIC ? 1 : 0;
 86:           { /* vertices */
 87:             PetscScalar expected = 1.0;
 88:             for (dd = 0; dd < 3; ++dd) expected *= (bnd[dd] ? stencilWidth + 1 + extra[dd] : 2 * stencilWidth + 1);
 89:             for (d = 0; d < dof0; ++d) {
 90:               if (a2[k][j][i][d] != expected) {
 91:                 PetscCall(PetscPrintf(PETSC_COMM_SELF, "[%d] Element (%" PetscInt_FMT ",%" PetscInt_FMT ",%" PetscInt_FMT ")[%" PetscInt_FMT "] Unexpected value %g (expecting %g)\n", rank, i, j, k, d, (double)PetscRealPart(a2[k][j][i][d]), (double)PetscRealPart(expected)));
 92:               }
 93:             }
 94:           }
 95:           { /* back down edges */
 96:             PetscScalar expected = ((bnd[0] ? 1 : 2) * stencilWidth + 1);
 97:             for (dd = 1; dd < 3; ++dd) expected *= (bnd[dd] ? stencilWidth + 1 + extra[dd] : 2 * stencilWidth + 1);
 98:             for (d = dof0; d < dof0 + dof1; ++d) {
 99:               if (a2[k][j][i][d] != expected) {
100:                 PetscCall(PetscPrintf(PETSC_COMM_SELF, "[%d] Element (%" PetscInt_FMT ",%" PetscInt_FMT ",%" PetscInt_FMT ")[%" PetscInt_FMT "] Unexpected value %g (expecting %g)\n", rank, i, j, k, d, (double)PetscRealPart(a2[k][j][i][d]), (double)PetscRealPart(expected)));
101:               }
102:             }
103:           }
104:           { /* back left edges */
105:             PetscScalar expected = ((bnd[1] ? 1 : 2) * stencilWidth + 1);
106:             for (dd = 0; dd < 3; dd += 2) expected *= (bnd[dd] ? stencilWidth + 1 + extra[dd] : 2 * stencilWidth + 1);
107:             for (d = dof0 + dof1; d < dof0 + 2 * dof1; ++d) {
108:               if (a2[k][j][i][d] != expected) {
109:                 PetscCall(PetscPrintf(PETSC_COMM_SELF, "[%d] Element (%" PetscInt_FMT ",%" PetscInt_FMT ",%" PetscInt_FMT ")[%" PetscInt_FMT "] Unexpected value %g (expecting %g)\n", rank, i, j, k, d, (double)PetscRealPart(a2[k][j][i][d]), (double)PetscRealPart(expected)));
110:               }
111:             }
112:           }
113:           { /* back faces */
114:             PetscScalar expected = (bnd[2] ? stencilWidth + 1 + extra[2] : 2 * stencilWidth + 1);
115:             for (dd = 0; dd < 2; ++dd) expected *= ((bnd[dd] ? 1 : 2) * stencilWidth + 1);
116:             for (d = dof0 + 2 * dof1; d < dof0 + 2 * dof1 + dof2; ++d) {
117:               if (a2[k][j][i][d] != expected) {
118:                 PetscCall(PetscPrintf(PETSC_COMM_SELF, "[%d] Element (%" PetscInt_FMT ",%" PetscInt_FMT ",%" PetscInt_FMT ")[%" PetscInt_FMT "] Unexpected value %g (expecting %g)\n", rank, i, j, k, d, (double)PetscRealPart(a2[k][j][i][d]), (double)PetscRealPart(expected)));
119:               }
120:             }
121:           }
122:           { /* down left edges */
123:             PetscScalar expected = ((bnd[2] ? 1 : 2) * stencilWidth + 1);
124:             for (dd = 0; dd < 2; ++dd) expected *= (bnd[dd] ? stencilWidth + 1 + extra[dd] : 2 * stencilWidth + 1);
125:             for (d = dof0 + 2 * dof1 + dof2; d < dof0 + 3 * dof1 + dof2; ++d) {
126:               if (a2[k][j][i][d] != expected) {
127:                 PetscCall(PetscPrintf(PETSC_COMM_SELF, "[%d] Element (%" PetscInt_FMT ",%" PetscInt_FMT ",%" PetscInt_FMT ")[%" PetscInt_FMT "] Unexpected value %g (expecting %g)\n", rank, i, j, k, d, (double)PetscRealPart(a2[k][j][i][d]), (double)PetscRealPart(expected)));
128:               }
129:             }
130:           }
131:           { /* down faces */
132:             PetscScalar expected = (bnd[1] ? stencilWidth + 1 + extra[1] : 2 * stencilWidth + 1);
133:             for (dd = 0; dd < 3; dd += 2) expected *= ((bnd[dd] ? 1 : 2) * stencilWidth + 1);
134:             for (d = dof0 + 3 * dof1 + dof2; d < dof0 + 3 * dof1 + 2 * dof2; ++d) {
135:               if (a2[k][j][i][d] != expected) {
136:                 PetscCall(PetscPrintf(PETSC_COMM_SELF, "[%d] Element (%" PetscInt_FMT ",%" PetscInt_FMT ",%" PetscInt_FMT ")[%" PetscInt_FMT "] Unexpected value %g (expecting %g)\n", rank, i, j, k, d, (double)PetscRealPart(a2[k][j][i][d]), (double)PetscRealPart(expected)));
137:               }
138:             }
139:           }
140:           { /* left faces */
141:             PetscScalar expected = (bnd[0] ? stencilWidth + 1 + extra[0] : 2 * stencilWidth + 1);
142:             for (dd = 1; dd < 3; ++dd) expected *= ((bnd[dd] ? 1 : 2) * stencilWidth + 1);
143:             for (d = dof0 + 3 * dof1 + 2 * dof2; d < dof0 + 3 * dof1 + 3 * dof2; ++d) {
144:               if (a2[k][j][i][d] != expected) {
145:                 PetscCall(PetscPrintf(PETSC_COMM_SELF, "[%d] Element (%" PetscInt_FMT ",%" PetscInt_FMT ",%" PetscInt_FMT ")[%" PetscInt_FMT "] Unexpected value %g (expecting %g)\n", rank, i, j, k, d, (double)PetscRealPart(a2[k][j][i][d]), (double)PetscRealPart(expected)));
146:               }
147:             }
148:           }
149:           { /* elements */
150:             PetscScalar expected = 1.0;
151:             for (dd = 0; dd < 3; ++dd) expected *= ((bnd[dd] ? 1 : 2) * stencilWidth + 1);
152:             for (d = dofTotal - dof3; d < dofTotal; ++d) {
153:               if (a2[k][j][i][d] != expected) {
154:                 PetscCall(PetscPrintf(PETSC_COMM_SELF, "[%d] Element (%" PetscInt_FMT ",%" PetscInt_FMT ",%" PetscInt_FMT ")[%" PetscInt_FMT "] Unexpected value %g (expecting %g)\n", rank, i, j, k, d, (double)PetscRealPart(a2[k][j][i][d]), (double)PetscRealPart(expected)));
155:               }
156:             }
157:           }
158:         }
159:       }
160:     }
161:     PetscCall(DMStagVecRestoreArrayRead(dm, vecLocal2, &a2));
162:   }

164:   PetscCall(VecDestroy(&vec));
165:   PetscCall(VecDestroy(&vecLocal1));
166:   PetscCall(VecDestroy(&vecLocal2));
167:   PetscCall(DMDestroy(&dm));
168:   PetscCall(PetscFinalize());
169:   return 0;
170: }

172: /*TEST

174:    test:
175:       suffix: 1
176:       nsize: 8
177:       args: -stag_ranks_x 2 -stag_ranks_y 2 -stag_ranks_z 2 -stag_stencil_width 1 -stag_dof_3 2 -stag_grid_z 3
178:       output_file: output/empty.out

180:    test:
181:       suffix: 2
182:       nsize: 8
183:       args: -stag_ranks_x 2 -stag_ranks_y 2 -stag_ranks_z 2 -stag_dof_2 2 -stag_grid_y 5
184:       output_file: output/empty.out

186:    test:
187:       suffix: 3
188:       nsize: 12
189:       args: -stag_ranks_x 3 -stag_ranks_y 2 -stag_ranks_z 2 -stag_dof_0 2 -stag_grid_x 6
190:       output_file: output/empty.out

192:    test:
193:       suffix: 4
194:       nsize: 12
195:       args: -stag_ranks_x 3 -stag_ranks_y 2 -stag_ranks_z 2 -stag_dof_0 0 -stag_dof_1 0 -stag_dof_2 0 -stag_grid_x 4 -stag_boundary_type_x ghosted -stag_boundary_type_y ghosted -stag_boundary_type_z ghosted -stag_stencil_width 1
196:       output_file: output/empty.out

198:    test:
199:       suffix: 5
200:       nsize: 12
201:       args: -stag_ranks_x 3 -stag_ranks_y 2 -stag_ranks_z 2 -stag_dof_0 0 -stag_dof_1 0 -stag_dof_2 0 -stag_grid_x 4 -stag_boundary_type_x ghosted -stag_boundary_type_z ghosted -stag_stencil_width 1
202:       output_file: output/empty.out

204:    test:
205:       suffix: 6
206:       nsize: 8
207:       args: -stag_dof_0 3 -stag_dof_1 2 -stag_dof_2 4 -stag_dof_3 2 -stag_boundary_type_y ghosted -stag_boundary_type_z ghosted -stag_stencil_width 1
208:       output_file: output/empty.out
209: TEST*/