1 static char help[] = "Test DMStagPopulateLocalToGlobalInjective.\n\n";
2
3 #include <petscdm.h>
4 #include <petscdmstag.h>
5
6 static PetscErrorCode Test1(DM dm);
7 static PetscErrorCode Test2_1d(DM dm);
8 static PetscErrorCode Test2_2d(DM dm);
9 static PetscErrorCode Test2_3d(DM dm);
10
main(int argc,char ** argv)11 int main(int argc, char **argv)
12 {
13 DM dm;
14 PetscInt dim;
15 PetscBool setSizes, useInjective;
16
17 /* Initialize PETSc and process command line arguments */
18 PetscFunctionBeginUser;
19 PetscCall(PetscInitialize(&argc, &argv, NULL, help));
20 dim = 2;
21 PetscCall(PetscOptionsGetInt(NULL, NULL, "-dim", &dim, NULL));
22 setSizes = PETSC_FALSE;
23 PetscCall(PetscOptionsGetBool(NULL, NULL, "-setsizes", &setSizes, NULL));
24 useInjective = PETSC_TRUE;
25 PetscCall(PetscOptionsGetBool(NULL, NULL, "-useinjective", &useInjective, NULL));
26
27 /* Creation (normal) */
28 if (!setSizes) {
29 switch (dim) {
30 case 1:
31 PetscCall(DMStagCreate1d(PETSC_COMM_WORLD, DM_BOUNDARY_NONE, 3, 1, 1, DMSTAG_STENCIL_BOX, 1, NULL, &dm));
32 break;
33 case 2:
34 PetscCall(DMStagCreate2d(PETSC_COMM_WORLD, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE, 3, 2, PETSC_DECIDE, PETSC_DECIDE, 1, 1, 1, DMSTAG_STENCIL_BOX, 1, NULL, NULL, &dm));
35 break;
36 case 3:
37 PetscCall(DMStagCreate3d(PETSC_COMM_WORLD, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE, 3, 2, 4, PETSC_DECIDE, PETSC_DECIDE, PETSC_DECIDE, 1, 1, 1, 1, DMSTAG_STENCIL_BOX, 1, NULL, NULL, NULL, &dm));
38 break;
39 default:
40 SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_SUP, "No support for dimension %" PetscInt_FMT, dim);
41 }
42 } else {
43 /* Creation (test providing decomp exactly)*/
44 PetscMPIInt size;
45 PetscInt lx[4] = {2, 3, 4}, ranksx = 3, mx = 9;
46 PetscInt ly[3] = {4, 5}, ranksy = 2, my = 9;
47 PetscInt lz[2] = {6, 7}, ranksz = 2, mz = 13;
48
49 PetscCallMPI(MPI_Comm_size(PETSC_COMM_WORLD, &size));
50 switch (dim) {
51 case 1:
52 PetscCheck(size == ranksx, PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONG, "Must run on %" PetscInt_FMT " ranks with -dim 1 -setSizes", ranksx);
53 PetscCall(DMStagCreate1d(PETSC_COMM_WORLD, DM_BOUNDARY_NONE, mx, 1, 1, DMSTAG_STENCIL_BOX, 1, lx, &dm));
54 break;
55 case 2:
56 PetscCheck(size == ranksx * ranksy, PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONG, "Must run on %" PetscInt_FMT " ranks with -dim 2 -setSizes", ranksx * ranksy);
57 PetscCall(DMStagCreate2d(PETSC_COMM_WORLD, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE, mx, my, ranksx, ranksy, 1, 1, 1, DMSTAG_STENCIL_BOX, 1, lx, ly, &dm));
58 break;
59 case 3:
60 PetscCheck(size == ranksx * ranksy * ranksz, PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONG, "Must run on %" PetscInt_FMT " ranks with -dim 3 -setSizes", ranksx * ranksy * ranksz);
61 PetscCall(DMStagCreate3d(PETSC_COMM_WORLD, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE, mx, my, mz, ranksx, ranksy, ranksz, 1, 1, 1, 1, DMSTAG_STENCIL_BOX, 1, lx, ly, lz, &dm));
62 break;
63 default:
64 SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_SUP, "No support for dimension %" PetscInt_FMT, dim);
65 }
66 }
67
68 /* Setup */
69 PetscCall(DMSetFromOptions(dm));
70 PetscCall(DMSetUp(dm));
71
72 /* Populate Additional Injective Local-to-Global Map */
73 if (useInjective) PetscCall(DMStagPopulateLocalToGlobalInjective(dm));
74
75 /* Test: Make sure L2G inverts G2L */
76 PetscCall(Test1(dm));
77
78 /* Test: Make sure that G2L inverts L2G, on its domain */
79 PetscCall(DMGetDimension(dm, &dim));
80 switch (dim) {
81 case 1:
82 PetscCall(Test2_1d(dm));
83 break;
84 case 2:
85 PetscCall(Test2_2d(dm));
86 break;
87 case 3:
88 PetscCall(Test2_3d(dm));
89 break;
90 default:
91 SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Not implemented for dimension %" PetscInt_FMT, dim);
92 }
93
94 /* Clean up and finalize PETSc */
95 PetscCall(DMDestroy(&dm));
96 PetscCall(PetscFinalize());
97 return 0;
98 }
99
Test1(DM dm)100 static PetscErrorCode Test1(DM dm)
101 {
102 Vec vecLocal, vecGlobal, vecGlobalCheck;
103 PetscRandom rctx;
104 PetscBool equal;
105
106 PetscFunctionBeginUser;
107 PetscCall(DMCreateLocalVector(dm, &vecLocal));
108 PetscCall(DMCreateGlobalVector(dm, &vecGlobal));
109 PetscCall(PetscRandomCreate(PETSC_COMM_WORLD, &rctx));
110 PetscCall(VecSetRandom(vecGlobal, rctx));
111 PetscCall(VecSetRandom(vecLocal, rctx)); /* garbage */
112 PetscCall(PetscRandomDestroy(&rctx));
113 PetscCall(VecDuplicate(vecGlobal, &vecGlobalCheck));
114 PetscCall(DMGlobalToLocal(dm, vecGlobal, INSERT_VALUES, vecLocal));
115 PetscCall(DMLocalToGlobal(dm, vecLocal, INSERT_VALUES, vecGlobalCheck));
116 PetscCall(VecEqual(vecGlobal, vecGlobalCheck, &equal));
117 PetscCheck(equal, PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Check failed - vectors should be bitwise identical");
118 PetscCall(VecDestroy(&vecLocal));
119 PetscCall(VecDestroy(&vecGlobal));
120 PetscCall(VecDestroy(&vecGlobalCheck));
121 PetscFunctionReturn(PETSC_SUCCESS);
122 }
123
124 /* Test function with positive values for positive arguments */
125 #define TEST_FUNCTION(i, j, k, idx, c) (8.33 * i + 7.343 * j + 1.234 * idx + 99.011 * c)
126
127 /* Helper function to check */
CompareValues(PetscInt i,PetscInt j,PetscInt k,PetscInt c,PetscScalar val,PetscScalar valRef)128 static PetscErrorCode CompareValues(PetscInt i, PetscInt j, PetscInt k, PetscInt c, PetscScalar val, PetscScalar valRef)
129 {
130 PetscFunctionBeginUser;
131 PetscCheck(val == valRef || PetscAbsScalar(val - valRef) / PetscAbsScalar(valRef) <= 10 * PETSC_MACHINE_EPSILON, PETSC_COMM_SELF, PETSC_ERR_PLIB, "(%" PetscInt_FMT ",%" PetscInt_FMT ",%" PetscInt_FMT ",%" PetscInt_FMT ") Value %.17g does not match the expected %.17g", i, j, k, c, (double)PetscRealPart(val), (double)PetscRealPart(valRef));
132 PetscFunctionReturn(PETSC_SUCCESS);
133 }
134
Test2_1d(DM dm)135 static PetscErrorCode Test2_1d(DM dm)
136 {
137 Vec vecLocal, vecLocalCheck, vecGlobal;
138 PetscInt i, startx, nx, nExtrax, dof0, dof1, c, idxLeft, idxElement;
139 PetscScalar **arr;
140 const PetscInt j = -1, k = -1;
141
142 PetscFunctionBeginUser;
143 PetscCall(DMCreateLocalVector(dm, &vecLocal));
144 PetscCall(VecSet(vecLocal, -1.0));
145 PetscCall(DMStagGetCorners(dm, &startx, NULL, NULL, &nx, NULL, NULL, &nExtrax, NULL, NULL));
146 PetscCall(DMStagGetDOF(dm, &dof0, &dof1, NULL, NULL));
147 PetscCall(DMStagVecGetArray(dm, vecLocal, &arr));
148 if (dof0 > 0) PetscCall(DMStagGetLocationSlot(dm, DMSTAG_LEFT, 0, &idxLeft));
149 if (dof1 > 0) PetscCall(DMStagGetLocationSlot(dm, DMSTAG_ELEMENT, 0, &idxElement));
150 for (i = startx; i < startx + nx + nExtrax; ++i) {
151 for (c = 0; c < dof0; ++c) {
152 const PetscScalar valRef = TEST_FUNCTION(i, 0, 0, idxLeft, c);
153 arr[i][idxLeft + c] = valRef;
154 }
155 if (i < startx + nx) {
156 for (c = 0; c < dof1; ++c) {
157 const PetscScalar valRef = TEST_FUNCTION(i, 0, 0, idxElement, c);
158 arr[i][idxElement + c] = valRef;
159 }
160 }
161 }
162 PetscCall(DMStagVecRestoreArray(dm, vecLocal, &arr));
163 PetscCall(DMCreateGlobalVector(dm, &vecGlobal));
164 PetscCall(DMLocalToGlobal(dm, vecLocal, INSERT_VALUES, vecGlobal));
165 PetscCall(VecDuplicate(vecLocal, &vecLocalCheck));
166 PetscCall(VecSet(vecLocalCheck, -1.0));
167 PetscCall(DMGlobalToLocal(dm, vecGlobal, INSERT_VALUES, vecLocalCheck));
168 PetscCall(DMStagVecGetArrayRead(dm, vecLocalCheck, &arr));
169 for (i = startx; i < startx + nx + nExtrax; ++i) {
170 for (c = 0; c < dof0; ++c) {
171 const PetscScalar valRef = TEST_FUNCTION(i, 0, 0, idxLeft, c);
172 const PetscScalar val = arr[i][idxLeft + c];
173 PetscCall(CompareValues(i, j, k, c, val, valRef));
174 }
175 if (i < startx + nx) {
176 for (c = 0; c < dof1; ++c) {
177 const PetscScalar valRef = TEST_FUNCTION(i, 0, 0, idxElement, c);
178 const PetscScalar val = arr[i][idxElement + c];
179 PetscCall(CompareValues(i, j, k, c, val, valRef));
180 }
181 } else {
182 for (c = 0; c < dof1; ++c) {
183 const PetscScalar valRef = -1.0;
184 const PetscScalar val = arr[i][idxElement + c];
185 PetscCall(CompareValues(i, j, k, c, val, valRef));
186 }
187 }
188 }
189 PetscCall(DMStagVecRestoreArrayRead(dm, vecLocalCheck, &arr));
190 PetscCall(VecDestroy(&vecLocal));
191 PetscCall(VecDestroy(&vecLocalCheck));
192 PetscCall(VecDestroy(&vecGlobal));
193 PetscFunctionReturn(PETSC_SUCCESS);
194 }
195
Test2_2d(DM dm)196 static PetscErrorCode Test2_2d(DM dm)
197 {
198 Vec vecLocal, vecLocalCheck, vecGlobal;
199 PetscInt i, j, startx, starty, nx, ny, nExtrax, nExtray, dof0, dof1, dof2, c, idxLeft, idxDown, idxDownLeft, idxElement;
200 PetscScalar ***arr;
201 const PetscInt k = -1;
202
203 PetscFunctionBeginUser;
204 PetscCall(DMCreateLocalVector(dm, &vecLocal));
205 PetscCall(VecSet(vecLocal, -1.0));
206 PetscCall(DMStagGetCorners(dm, &startx, &starty, NULL, &nx, &ny, NULL, &nExtrax, &nExtray, NULL));
207 PetscCall(DMStagGetDOF(dm, &dof0, &dof1, &dof2, NULL));
208 PetscCall(DMStagVecGetArray(dm, vecLocal, &arr));
209 if (dof0 > 0) PetscCall(DMStagGetLocationSlot(dm, DMSTAG_DOWN_LEFT, 0, &idxDownLeft));
210 if (dof1 > 0) {
211 PetscCall(DMStagGetLocationSlot(dm, DMSTAG_LEFT, 0, &idxLeft));
212 PetscCall(DMStagGetLocationSlot(dm, DMSTAG_DOWN, 0, &idxDown));
213 }
214 if (dof2 > 0) PetscCall(DMStagGetLocationSlot(dm, DMSTAG_ELEMENT, 0, &idxElement));
215 for (j = starty; j < starty + ny + nExtray; ++j) {
216 for (i = startx; i < startx + nx + nExtrax; ++i) {
217 for (c = 0; c < dof0; ++c) {
218 const PetscScalar valRef = TEST_FUNCTION(i, j, 0, idxDownLeft, c);
219 arr[j][i][idxDownLeft + c] = valRef;
220 }
221 if (j < starty + ny) {
222 for (c = 0; c < dof1; ++c) {
223 const PetscScalar valRef = TEST_FUNCTION(i, j, 0, idxLeft, c);
224 arr[j][i][idxLeft + c] = valRef;
225 }
226 }
227 if (i < startx + nx) {
228 for (c = 0; c < dof1; ++c) {
229 const PetscScalar valRef = TEST_FUNCTION(i, j, 0, idxDown, c);
230 arr[j][i][idxDown + c] = valRef;
231 }
232 }
233 if (i < startx + nx && j < starty + ny) {
234 for (c = 0; c < dof2; ++c) {
235 const PetscScalar valRef = TEST_FUNCTION(i, j, 0, idxElement, c);
236 arr[j][i][idxElement + c] = valRef;
237 }
238 }
239 }
240 }
241 PetscCall(DMStagVecRestoreArray(dm, vecLocal, &arr));
242 PetscCall(DMCreateGlobalVector(dm, &vecGlobal));
243 PetscCall(DMLocalToGlobal(dm, vecLocal, INSERT_VALUES, vecGlobal));
244 PetscCall(VecDuplicate(vecLocal, &vecLocalCheck));
245 PetscCall(VecSet(vecLocalCheck, -1.0));
246 PetscCall(DMGlobalToLocal(dm, vecGlobal, INSERT_VALUES, vecLocalCheck));
247 PetscCall(DMStagVecGetArrayRead(dm, vecLocalCheck, &arr));
248 for (j = starty; j < starty + ny + nExtray; ++j) {
249 for (i = startx; i < startx + nx + nExtrax; ++i) {
250 for (c = 0; c < dof0; ++c) {
251 const PetscScalar valRef = TEST_FUNCTION(i, j, 0, idxDownLeft, c);
252 const PetscScalar val = arr[j][i][idxDownLeft + c];
253 PetscCall(CompareValues(i, j, k, c, val, valRef));
254 }
255 if (j < starty + ny) {
256 for (c = 0; c < dof1; ++c) {
257 const PetscScalar valRef = TEST_FUNCTION(i, j, 0, idxLeft, c);
258 const PetscScalar val = arr[j][i][idxLeft + c];
259 PetscCall(CompareValues(i, j, k, c, val, valRef));
260 }
261 } else {
262 for (c = 0; c < dof1; ++c) {
263 const PetscScalar valRef = -1.0;
264 const PetscScalar val = arr[j][i][idxLeft + c];
265 PetscCall(CompareValues(i, j, k, c, val, valRef));
266 }
267 }
268 if (i < startx + nx) {
269 for (c = 0; c < dof1; ++c) {
270 const PetscScalar valRef = TEST_FUNCTION(i, j, 0, idxDown, c);
271 const PetscScalar val = arr[j][i][idxDown + c];
272 PetscCall(CompareValues(i, j, k, c, val, valRef));
273 }
274 } else {
275 for (c = 0; c < dof1; ++c) {
276 const PetscScalar valRef = -1.0;
277 const PetscScalar val = arr[j][i][idxDown + c];
278 PetscCall(CompareValues(i, j, k, c, val, valRef));
279 }
280 }
281 if (i < startx + nx && j < starty + ny) {
282 for (c = 0; c < dof2; ++c) {
283 const PetscScalar valRef = TEST_FUNCTION(i, j, 0, idxElement, c);
284 const PetscScalar val = arr[j][i][idxElement + c];
285 PetscCall(CompareValues(i, j, k, c, val, valRef));
286 }
287 } else {
288 for (c = 0; c < dof2; ++c) {
289 const PetscScalar valRef = -1.0;
290 const PetscScalar val = arr[j][i][idxElement + c];
291 PetscCall(CompareValues(i, j, k, c, val, valRef));
292 }
293 }
294 }
295 }
296 PetscCall(DMStagVecRestoreArrayRead(dm, vecLocalCheck, &arr));
297 PetscCall(VecDestroy(&vecLocal));
298 PetscCall(VecDestroy(&vecLocalCheck));
299 PetscCall(VecDestroy(&vecGlobal));
300 PetscFunctionReturn(PETSC_SUCCESS);
301 }
302
Test2_3d(DM dm)303 static PetscErrorCode Test2_3d(DM dm)
304 {
305 Vec vecLocal, vecLocalCheck, vecGlobal;
306 PetscInt i, j, k, startx, starty, startz, nx, ny, nz, nExtrax, nExtray, nExtraz, dof0, dof1, dof2, dof3, c, idxLeft, idxDown, idxDownLeft, idxBackDownLeft, idxBackDown, idxBack, idxBackLeft, idxElement;
307 PetscScalar ****arr;
308
309 PetscFunctionBeginUser;
310 PetscCall(DMCreateLocalVector(dm, &vecLocal));
311 PetscCall(VecSet(vecLocal, -1.0));
312 PetscCall(DMStagGetCorners(dm, &startx, &starty, &startz, &nx, &ny, &nz, &nExtrax, &nExtray, &nExtraz));
313 PetscCall(DMStagGetDOF(dm, &dof0, &dof1, &dof2, &dof3));
314 PetscCall(DMStagVecGetArray(dm, vecLocal, &arr));
315 if (dof0 > 0) PetscCall(DMStagGetLocationSlot(dm, DMSTAG_BACK_DOWN_LEFT, 0, &idxBackDownLeft));
316 if (dof1 > 0) {
317 PetscCall(DMStagGetLocationSlot(dm, DMSTAG_BACK_LEFT, 0, &idxBackLeft));
318 PetscCall(DMStagGetLocationSlot(dm, DMSTAG_BACK_DOWN, 0, &idxBackDown));
319 PetscCall(DMStagGetLocationSlot(dm, DMSTAG_DOWN_LEFT, 0, &idxDownLeft));
320 }
321 if (dof2 > 0) {
322 PetscCall(DMStagGetLocationSlot(dm, DMSTAG_LEFT, 0, &idxLeft));
323 PetscCall(DMStagGetLocationSlot(dm, DMSTAG_DOWN, 0, &idxDown));
324 PetscCall(DMStagGetLocationSlot(dm, DMSTAG_BACK, 0, &idxBack));
325 }
326 if (dof3 > 0) PetscCall(DMStagGetLocationSlot(dm, DMSTAG_ELEMENT, 0, &idxElement));
327 for (k = startz; k < startz + nz + nExtraz; ++k) {
328 for (j = starty; j < starty + ny + nExtray; ++j) {
329 for (i = startx; i < startx + nx + nExtrax; ++i) {
330 for (c = 0; c < dof0; ++c) {
331 const PetscScalar valRef = TEST_FUNCTION(i, j, k, idxBackDownLeft, c);
332 arr[k][j][i][idxBackDownLeft + c] = valRef;
333 }
334 if (k < startz + nz) {
335 for (c = 0; c < dof1; ++c) {
336 const PetscScalar valRef = TEST_FUNCTION(i, j, k, idxDownLeft, c);
337 arr[k][j][i][idxDownLeft + c] = valRef;
338 }
339 }
340 if (j < starty + ny) {
341 for (c = 0; c < dof1; ++c) {
342 const PetscScalar valRef = TEST_FUNCTION(i, j, k, idxBackLeft, c);
343 arr[k][j][i][idxBackLeft + c] = valRef;
344 }
345 }
346 if (i < startx + nx) {
347 for (c = 0; c < dof1; ++c) {
348 const PetscScalar valRef = TEST_FUNCTION(i, j, k, idxBackDown, c);
349 arr[k][j][i][idxBackDown + c] = valRef;
350 }
351 }
352 if (j < starty + ny && k < startz + nz) {
353 for (c = 0; c < dof2; ++c) {
354 const PetscScalar valRef = TEST_FUNCTION(i, j, k, idxLeft, c);
355 arr[k][j][i][idxLeft + c] = valRef;
356 }
357 }
358 if (i < startx + nx && k < startz + nz) {
359 for (c = 0; c < dof2; ++c) {
360 const PetscScalar valRef = TEST_FUNCTION(i, j, k, idxDown, c);
361 arr[k][j][i][idxDown + c] = valRef;
362 }
363 }
364 if (i < startx + nx && j < starty + ny) {
365 for (c = 0; c < dof2; ++c) {
366 const PetscScalar valRef = TEST_FUNCTION(i, j, k, idxBack, c);
367 arr[k][j][i][idxBack + c] = valRef;
368 }
369 }
370 if (i < startx + nx && j < starty + ny && k < startz + nz) {
371 for (c = 0; c < dof3; ++c) {
372 const PetscScalar valRef = TEST_FUNCTION(i, j, k, idxElement, c);
373 arr[k][j][i][idxElement + c] = valRef;
374 }
375 }
376 }
377 }
378 }
379 PetscCall(DMStagVecRestoreArray(dm, vecLocal, &arr));
380 PetscCall(DMCreateGlobalVector(dm, &vecGlobal));
381 PetscCall(DMLocalToGlobal(dm, vecLocal, INSERT_VALUES, vecGlobal));
382 PetscCall(VecDuplicate(vecLocal, &vecLocalCheck));
383 PetscCall(VecSet(vecLocalCheck, -1.0));
384 PetscCall(DMGlobalToLocal(dm, vecGlobal, INSERT_VALUES, vecLocalCheck));
385 PetscCall(DMStagVecGetArrayRead(dm, vecLocalCheck, &arr));
386 for (k = startz; k < startz + nz + nExtraz; ++k) {
387 for (j = starty; j < starty + ny + nExtray; ++j) {
388 for (i = startx; i < startx + nx + nExtrax; ++i) {
389 for (c = 0; c < dof0; ++c) {
390 const PetscScalar valRef = TEST_FUNCTION(i, j, k, idxBackDownLeft, c);
391 const PetscScalar val = arr[k][j][i][idxBackDownLeft + c];
392 PetscCall(CompareValues(i, j, k, c, val, valRef));
393 }
394 if (k < startz + nz) {
395 for (c = 0; c < dof1; ++c) {
396 const PetscScalar valRef = TEST_FUNCTION(i, j, k, idxDownLeft, c);
397 const PetscScalar val = arr[k][j][i][idxDownLeft + c];
398 PetscCall(CompareValues(i, j, k, c, val, valRef));
399 }
400 } else {
401 for (c = 0; c < dof1; ++c) {
402 const PetscScalar valRef = -1.0;
403 const PetscScalar val = arr[k][j][i][idxDownLeft + c];
404 PetscCall(CompareValues(i, j, k, c, val, valRef));
405 }
406 }
407 if (j < starty + ny) {
408 for (c = 0; c < dof1; ++c) {
409 const PetscScalar valRef = TEST_FUNCTION(i, j, k, idxBackLeft, c);
410 const PetscScalar val = arr[k][j][i][idxBackLeft + c];
411 PetscCall(CompareValues(i, j, k, c, val, valRef));
412 }
413 } else {
414 for (c = 0; c < dof1; ++c) {
415 const PetscScalar valRef = -1.0;
416 const PetscScalar val = arr[k][j][i][idxBackLeft + c];
417 PetscCall(CompareValues(i, j, k, c, val, valRef));
418 }
419 }
420 if (i < startx + nx) {
421 for (c = 0; c < dof1; ++c) {
422 const PetscScalar valRef = TEST_FUNCTION(i, j, k, idxBackDown, c);
423 const PetscScalar val = arr[k][j][i][idxBackDown + c];
424 PetscCall(CompareValues(i, j, k, c, val, valRef));
425 }
426 } else {
427 for (c = 0; c < dof1; ++c) {
428 const PetscScalar valRef = -1.0;
429 const PetscScalar val = arr[k][j][i][idxBackDown + c];
430 PetscCall(CompareValues(i, j, k, c, val, valRef));
431 }
432 }
433 if (j < starty + ny && k < startz + nz) {
434 for (c = 0; c < dof2; ++c) {
435 const PetscScalar valRef = TEST_FUNCTION(i, j, k, idxLeft, c);
436 const PetscScalar val = arr[k][j][i][idxLeft + c];
437 PetscCall(CompareValues(i, j, k, c, val, valRef));
438 }
439 } else {
440 for (c = 0; c < dof2; ++c) {
441 const PetscScalar valRef = -1.0;
442 const PetscScalar val = arr[k][j][i][idxLeft + c];
443 PetscCall(CompareValues(i, j, k, c, val, valRef));
444 }
445 }
446 if (i < startx + nx && k < startz + nz) {
447 for (c = 0; c < dof2; ++c) {
448 const PetscScalar valRef = TEST_FUNCTION(i, j, k, idxDown, c);
449 const PetscScalar val = arr[k][j][i][idxDown + c];
450 PetscCall(CompareValues(i, j, k, c, val, valRef));
451 }
452 } else {
453 for (c = 0; c < dof2; ++c) {
454 const PetscScalar valRef = -1.0;
455 const PetscScalar val = arr[k][j][i][idxDown + c];
456 PetscCall(CompareValues(i, j, k, c, val, valRef));
457 }
458 }
459 if (i < startx + nx && j < starty + ny) {
460 for (c = 0; c < dof2; ++c) {
461 const PetscScalar valRef = TEST_FUNCTION(i, j, k, idxBack, c);
462 const PetscScalar val = arr[k][j][i][idxBack + c];
463 PetscCall(CompareValues(i, j, k, c, val, valRef));
464 }
465 } else {
466 for (c = 0; c < dof2; ++c) {
467 const PetscScalar valRef = -1.0;
468 const PetscScalar val = arr[k][j][i][idxBack + c];
469 PetscCall(CompareValues(i, j, k, c, val, valRef));
470 }
471 }
472 if (i < startx + nx && j < starty + ny && k < startz + nz) {
473 for (c = 0; c < dof3; ++c) {
474 const PetscScalar valRef = TEST_FUNCTION(i, j, k, idxElement, c);
475 const PetscScalar val = arr[k][j][i][idxElement + c];
476 PetscCall(CompareValues(i, j, k, c, val, valRef));
477 }
478 } else {
479 for (c = 0; c < dof3; ++c) {
480 const PetscScalar valRef = -1.0;
481 const PetscScalar val = arr[k][j][i][idxElement + c];
482 PetscCall(CompareValues(i, j, k, c, val, valRef));
483 }
484 }
485 }
486 }
487 }
488 PetscCall(DMStagVecRestoreArrayRead(dm, vecLocalCheck, &arr));
489 PetscCall(VecDestroy(&vecLocal));
490 PetscCall(VecDestroy(&vecLocalCheck));
491 PetscCall(VecDestroy(&vecGlobal));
492 PetscFunctionReturn(PETSC_SUCCESS);
493 }
494 #undef TEST_FUNCTION
495
496 /*TEST
497
498 testset:
499 suffix: periodic_1d_seq
500 nsize: 1
501 args: -dm_view -dim 1 -stag_grid_x 4 -stag_boundary_type_x periodic -stag_stencil_width {{0 1 2}separate output}
502
503 testset:
504 suffix: ghosted_1d_seq
505 nsize: 1
506 args: -dm_view -dim 1 -stag_grid_x 4 -stag_boundary_type_x ghosted -stag_stencil_width {{0 1 2}separate output}
507
508 testset:
509 suffix: none_1d_seq
510 nsize: 1
511 args: -dm_view -dim 1 -stag_grid_x 4 -stag_boundary_type_x ghosted -stag_stencil_width {{0 1 2}separate output}
512
513 testset:
514 suffix: periodic_1d_par
515 nsize: 3
516 args: -dm_view -dim 1 -setsizes -stag_boundary_type_x periodic -stag_stencil_width {{0 1 2}separate output}
517
518 testset:
519 suffix: ghosted_1d_par
520 nsize: 3
521 args: -dm_view -dim 1 -setsizes -stag_boundary_type_x ghosted -stag_stencil_width {{0 1 2}separate output}
522
523 testset:
524 suffix: none_1d_par
525 nsize: 3
526 args: -dm_view -dim 1 -setsizes -stag_boundary_type_x ghosted -stag_stencil_width {{0 1 2}separate output}
527
528 testset:
529 suffix: periodic_periodic_2d_seq
530 nsize: 1
531 args: -dm_view -dim 2 -stag_grid_x 4 -stag_grid_y 5 -stag_boundary_type_x periodic -stag_boundary_type_y periodic -stag_stencil_width {{0 1 2}separate output}
532
533 testset:
534 suffix: periodic_ghosted_2d_seq
535 nsize: 1
536 args: -dm_view -dim 2 -stag_grid_x 4 -stag_grid_y 5 -stag_boundary_type_x periodic -stag_boundary_type_y ghosted -stag_stencil_width {{0 1 2}separate output}
537
538 testset:
539 suffix: none_none_2d_seq
540 nsize: 1
541 args: -dm_view -dim 2 -stag_grid_x 4 -stag_grid_y 5 -stag_boundary_type_x none -stag_boundary_type_y none -stag_stencil_width {{0 1 2}separate output}
542
543 testset:
544 suffix: none_ghosted_2d_seq
545 nsize: 1
546 args: -dm_view -dim 2 -stag_grid_x 4 -stag_grid_y 5 -stag_boundary_type_x none -stag_boundary_type_y ghosted -stag_stencil_width {{0 1 2}separate output}
547
548 testset:
549 suffix: none_periodic_2d_seq
550 nsize: 1
551 args: -dm_view -dim 2 -stag_grid_x 4 -stag_grid_y 5 -stag_boundary_type_x none -stag_boundary_type_y periodic -stag_stencil_width {{0 1 2}separate output}
552
553 testset:
554 suffix: periodic_periodic_2d_par
555 nsize: 6
556 args: -dm_view -dim 2 -setsizes -stag_boundary_type_x periodic -stag_boundary_type_y periodic -stag_stencil_width {{0 1 2}separate output}
557
558 testset:
559 suffix: periodic_ghosted_2d_par
560 nsize: 6
561 args: -dm_view -dim 2 -setsizes -stag_boundary_type_x periodic -stag_boundary_type_y ghosted -stag_stencil_width {{0 1 2}separate output}
562
563 testset:
564 suffix: none_none_2d_par
565 nsize: 6
566 args: -dm_view -dim 2 -setsizes -stag_boundary_type_x none -stag_boundary_type_y none -stag_stencil_width {{0 1 2}separate output}
567
568 testset:
569 suffix: none_ghosted_2d_par
570 nsize: 6
571 args: -dm_view -dim 2 -setsizes -stag_boundary_type_x none -stag_boundary_type_y ghosted -stag_stencil_width {{0 1 2}separate output}
572
573 testset:
574 suffix: none_periodic_2d_par
575 nsize: 6
576 args: -dm_view -dim 2 -setsizes -stag_boundary_type_x none -stag_boundary_type_y periodic -stag_stencil_width {{0 1 2}separate output}
577
578 testset:
579 suffix: periodic_periodic_periodic_3d_seq
580 nsize: 1
581 args: -dm_view -dim 3 -stag_grid_x 4 -stag_grid_y 5 -stag_grid_z 3 -stag_boundary_type_x periodic -stag_boundary_type_y periodic -stag_boundary_type_z periodic -stag_stencil_width {{0 1 2}separate output}
582
583 testset:
584 suffix: periodic_ghosted_periodic_3d_seq
585 nsize: 1
586 args: -dm_view -dim 3 -stag_grid_x 4 -stag_grid_y 5 -stag_grid_z 3 -stag_boundary_type_x periodic -stag_boundary_type_y ghosted -stag_boundary_type_z periodic -stag_stencil_width {{0 1 2}separate output}
587
588 testset:
589 suffix: none_periodic_ghosted_3d_seq
590 nsize: 1
591 args: -dm_view -dim 3 -stag_grid_x 4 -stag_grid_y 5 -stag_grid_z 3 -stag_boundary_type_x none -stag_boundary_type_y periodic -stag_boundary_type_z ghosted -stag_stencil_width {{0 1 2}separate output}
592
593 testset:
594 suffix: none_none_none_3d_seq
595 nsize: 1
596 args: -dm_view -dim 3 -stag_grid_x 4 -stag_grid_y 5 -stag_grid_z 3 -stag_boundary_type_x none -stag_boundary_type_y none -stag_boundary_type_z none -stag_stencil_width {{0 1 2}separate output}
597
598 testset:
599 suffix: periodic_periodic_periodic_3d_par
600 nsize: 12
601 args: -dm_view -dim 3 -setsizes -stag_boundary_type_x periodic -stag_boundary_type_y periodic -stag_boundary_type_z periodic -stag_stencil_width {{0 1 2}separate output}
602
603 testset:
604 suffix: periodic_ghosted_ghosted_3d_par
605 nsize: 12
606 args: -dm_view -dim 3 -setsizes -stag_boundary_type_x periodic -stag_boundary_type_y ghosted -stag_boundary_type_z ghosted -stag_stencil_width {{0 1 2}separate output}
607
608 testset:
609 suffix: ghosted_periodic_periodic_3d_par
610 nsize: 12
611 args: -dm_view -dim 3 -setsizes -stag_boundary_type_x ghosted -stag_boundary_type_y periodic -stag_boundary_type_z periodic -stag_stencil_width {{0 1 2}separate output}
612
613 testset:
614 suffix: none_none_none_3d_par
615 nsize: 12
616 args: -dm_view -dim 3 -setsizes -stag_boundary_type_x none -stag_boundary_type_y none -stag_boundary_type_z none -stag_stencil_width {{0 1 2}separate output}
617
618 test:
619 suffix: periodic_none_none_3d_skinny_seq
620 nsize: 1
621 args: -dm_view -dim 3 -stag_boundary_type_x periodic -stag_boundary_type_y none -stag_boundary_type_z none -stag_grid_x 3 -stag_grid_y 6 -stag_grid_z 5 -stag_stencil_width 1 -useinjective 0
622
623 test:
624 suffix: periodic_none_none_3d_skinny_par
625 nsize: 4
626 args: -dm_view -dim 3 -stag_boundary_type_x periodic -stag_boundary_type_y none -stag_boundary_type_z none -stag_grid_x 3 -stag_grid_y 6 -stag_grid_z 5 -stag_ranks_x 1 -stag_ranks_y 2 -stag_ranks_z 2 -stag_stencil_width 1 -useinjective 0
627
628 TEST*/
629