PlasCom2  1.0
XPACC Multi-physics simluation application
TestWENOSerial.C
Go to the documentation of this file.
1 // Serial unit tests for WENO routines and classes
2 
3 #include "Testing.H"
4 #include "Simulation.H"
5 #include "RKTestFixtures.H"
6 #include "EulerRHS.H"
7 #include "Stencil.H"
8 #include "PCPPCommUtil.H"
9 #include "PCPPReport.H"
10 #include "PCPPIntervalUtils.H"
11 #include "TestFixtures.H"
12 #include "EulerTestFixtures.H"
13 #include "SATKernels.H"
14 #include "WENO.H"
15 
16 
17 void TestWENO_Stencils(ix::test::results &serialUnitResults) {
18  // Tests WENO stencil collection classes/objects
19 
20  bool result;
21  double eps = 1e-8;
22 
23  WENO::CoeffsWENO coeffs;
24 
25  // --- nGroup ---
26  int nGroup = 2;
27 
28  result = (coeffs.nGroup == nGroup);
29  serialUnitResults.UpdateResult("WENO:Stencils:nGroup", result);
30 
31  // --- NSten ---
32  int nSten = 3; // both groups have 3 stencils
33 
34  result = true;
35  for (int g=0; g<nGroup; g++) {
36  result = result && (coeffs.NSten(g) == nSten);
37  }
38  serialUnitResults.UpdateResult("WENO:Stencils:nGroup", result);
39 
40  // --- siFirst ---
41  double siFirst = 13/12.0;
42 
43  result = (std::abs(coeffs.siFirst - siFirst) < eps);
44  serialUnitResults.UpdateResult("WENO:Stencils:siFirst", result);
45 
46  // --- siSecond ---
47  double siSecond = 1/4.0;
48 
49  result = (std::abs(coeffs.siSecond - siSecond) < eps);
50  serialUnitResults.UpdateResult("WENO:Stencils:siSecond", result);
51 
52  // --- epsW ---
53  double epsW = 1e-6;
54 
55  result = (std::abs(coeffs.epsW - epsW) < eps);
56  serialUnitResults.UpdateResult("WENO:Stencils:epsW", result);
57 
58  // --- pW ---
59  double pW = 2;
60 
61  result = (std::abs(coeffs.pW - pW) < eps);
62  serialUnitResults.UpdateResult("WENO:Stencils:pW", result);
63 
64  // --- linWeights ---
65  double linWeights[2][3] = {{0.1, 0.6, 0.3}, {0.1, 0.6, 0.3}};
66 
67  result = true;
68  for (int g=0; g<nGroup; g++) {
69  for (int i=0; i<nSten; i++) {
70  result = (std::abs(coeffs.LinWeight(g, i) - linWeights[g][i]) < eps);
71  }
72  }
73  serialUnitResults.UpdateResult("WENO:Stencils:linWeights", result);
74 
75  // --- HaloWidth ---
76  int loAll = -2;
77  int hiAll = 3;
78  int expHaloWidth = 3; // max(abs(loAll) + 1, abs(hiAll)), +1 is because we may need the flux on the left face of the leftmost cell
79 
80  result = (coeffs.HaloWidth() == expHaloWidth);
81  serialUnitResults.UpdateResult("WENO:Stencils:HaloWidth", result);
82 
83  // --- LoGroup ---
84  // Test that coeffs.LoGroup returns correct lo offset for each stencil group
85  // For now, 2 groups
86  // Group 0 = negative upwinding
87  // Group 1 = positive upwinding
88  int expLoGroup[2] = {-1, -2};
89 
90  result = true;
91  for (int g=0; g<nGroup; g++) {
92  result = result && (coeffs.LoGroup(g) == expLoGroup[g]);
93  }
94  serialUnitResults.UpdateResult("WENO:Stencils:LoGroup", result);
95 
96  // --- Lo ---
97  // Test that coeffs.Lo returns correct lo offset for each stencil
98  // Assumes stencils are entered in a prespecified order
99  // For now, 2 groups, 3 stencils in each
100  // Group 0 = negative upwinding
101  // Group 1 = positive upwinding
102  int expLo[2][3] = {{1, 0, -1}, {-2, -1, 0}};
103 
104  result = true;
105  for (int g=0; g<nGroup; g++) {
106  for (int s=0; s<nSten; s++) {
107  result = result && (coeffs.Lo(g, s) == expLo[g][s]);
108  }
109  }
110  serialUnitResults.UpdateResult("WENO:Stencils:Lo", result);
111 
112  // --- Reconst ---
113  // Test that coeffs.Reconst returns stencilset with reconstruction coefficients
114  // For now, 2 groups
115 
116  // Stencils (expected values)
117  // Group 0 = negative upwinding
118  // Group 1 = positive upwinding
119  int nVal = 9;
120  int rSizes[2][3] = {{3, 3, 3}, {3, 3, 3}};
121  int rStarts[2][3] = {{0, 3, 6}, {0, 3, 6}};
122  int rOffsets[2][9] = {{3, 2, 1, 2, 1, 0, 1, 0, -1}, {-2, -1, 0, -1, 0, 1, 0, 1, 2}};
123  double rWeights[2][9] = {{1/3.0, -7/6.0, 11/6.0, -1/6.0, 5/6.0, 1/3.0, 1/3.0, 5/6.0, -1/6.0},
124  {1/3.0, -7/6.0, 11/6.0, -1/6.0, 5/6.0, 1/3.0, 1/3.0, 5/6.0, -1/6.0}};
125 
126  result = true;
127  for (int g=0; g<nGroup; g++) {
128  WENO::StencilSet test = coeffs.Reconst(g);
129 
130  result = result && (test.numStencils == nSten);
131  }
132  serialUnitResults.UpdateResult("WENO:Stencils:Reconst:nSten", result);
133 
134  result = true;
135  for (int g=0; g<nGroup; g++) {
136  WENO::StencilSet test = coeffs.Reconst(g);
137 
138  result = result && (test.numValues == nVal);
139  }
140  serialUnitResults.UpdateResult("WENO:Stencils:Reconst:nVal", result);
141 
142  result = true;
143  for (int g=0; g<nGroup; g++) {
144  WENO::StencilSet test = coeffs.Reconst(g);
145 
146  for (int i=0; i<nSten; i++) {
147  result = result && (test.stencilSizes[i] == rSizes[g][i]);
148  }
149  }
150  serialUnitResults.UpdateResult("WENO:Stencils:Reconst:Sizes", result);
151 
152  result = true;
153  for (int g=0; g<nGroup; g++) {
154  WENO::StencilSet test = coeffs.Reconst(g);
155 
156  for (int i=0; i<nSten; i++) {
157  result = result && (test.stencilStarts[i] == rStarts[g][i]);
158  }
159  }
160  serialUnitResults.UpdateResult("WENO:Stencils:Reconst:Starts", result);
161 
162  result = true;
163  for (int g=0; g<nGroup; g++) {
164  WENO::StencilSet test = coeffs.Reconst(g);
165 
166  for (int i=0; i<nVal; i++) {
167  //std::cout << "Stencils:Reconst:Offsets -- g = " << g << ", i = " << i << ", Actual = " << test.stencilOffsets[i] << std::endl;
168  //std::cout << "Stencils:Reconst:Offsets -- g = " << g << ", i = " << i << ", Expected = " << rOffsets[g][i] << std::endl;
169  result = result && (test.stencilOffsets[i] == rOffsets[g][i]);
170  }
171  }
172  serialUnitResults.UpdateResult("WENO:Stencils:Reconst:Offsets", result);
173 
174  result = true;
175  for (int g=0; g<nGroup; g++) {
176  WENO::StencilSet test = coeffs.Reconst(g);
177 
178  for (int i=0; i<nVal; i++) {
179  result = result && (std::abs(test.stencilWeights[i] - rWeights[g][i]) < eps);
180  }
181  }
182  serialUnitResults.UpdateResult("WENO:Stencils:Reconst:Weights", result);
183 
184  // --- SmIndFirst ---
185  // Test that coeffs.SmIndFirst returns stencilset with first set of smoothness indicator coefficients
186  // For now, 2 groups
187 
188  // Stencils (expected values)
189  // Group 0 = negative upwinding
190  // Group 1 = positive upwinding
191  int si1Sizes[2][3] = {{3, 3, 3}, {3, 3, 3}};
192  int si1Starts[2][3] = {{0, 3, 6}, {0, 3, 6}};
193  int si1Offsets[2][9] = {{3, 2, 1, 2, 1, 0, 1, 0, -1}, {-2, -1, 0, -1, 0, 1, 0, 1, 2}};
194  double si1Weights[2][9] = {{1, -2, 1, 1, -2, 1, 1, -2, 1}, {1, -2, 1, 1, -2, 1, 1, -2, 1}};
195 
196  result = true;
197  for (int g=0; g<nGroup; g++) {
198  WENO::StencilSet test = coeffs.SmIndFirst(g);
199 
200  result = result && (test.numStencils == nSten);
201  }
202  serialUnitResults.UpdateResult("WENO:Stencils:SmIndFirst:nSten", result);
203 
204  result = true;
205  for (int g=0; g<nGroup; g++) {
206  WENO::StencilSet test = coeffs.SmIndFirst(g);
207 
208  result = result && (test.numValues == nVal);
209  }
210  serialUnitResults.UpdateResult("WENO:Stencils:SmIndFirst:nVal", result);
211 
212  result = true;
213  for (int g=0; g<nGroup; g++) {
214  WENO::StencilSet test = coeffs.SmIndFirst(g);
215 
216  for (int i=0; i<nSten; i++) {
217  result = result && (test.stencilSizes[i] == si1Sizes[g][i]);
218  }
219  }
220  serialUnitResults.UpdateResult("WENO:Stencils:SmIndFirst:Sizes", result);
221 
222  result = true;
223  for (int g=0; g<nGroup; g++) {
224  WENO::StencilSet test = coeffs.SmIndFirst(g);
225 
226  for (int i=0; i<nSten; i++) {
227  result = result && (test.stencilStarts[i] == si1Starts[g][i]);
228  }
229  }
230  serialUnitResults.UpdateResult("WENO:Stencils:SmIndFirst:Starts", result);
231 
232  result = true;
233  for (int g=0; g<nGroup; g++) {
234  WENO::StencilSet test = coeffs.SmIndFirst(g);
235 
236  for (int i=0; i<nVal; i++) {
237  //std::cout << "Stencils:SmIndFirst:Offsets -- g = " << g << ", i = " << i << ", Actual = " << test.stencilOffsets[i] << std::endl;
238  //std::cout << "Stencils:SmIndFirst:Offsets -- g = " << g << ", i = " << i << ", Expected = " << si1Offsets[g][i] << std::endl;
239  result = result && (test.stencilOffsets[i] == si1Offsets[g][i]);
240  }
241  }
242  serialUnitResults.UpdateResult("WENO:Stencils:SmIndFirst:Offsets", result);
243 
244  result = true;
245  for (int g=0; g<nGroup; g++) {
246  WENO::StencilSet test = coeffs.SmIndFirst(g);
247 
248  for (int i=0; i<nVal; i++) {
249  result = result && (std::abs(test.stencilWeights[i] - si1Weights[g][i]) < eps);
250  }
251  }
252  serialUnitResults.UpdateResult("WENO:Stencils:SmIndFirst:Weights", result);
253 
254  // --- SmIndSecond ---
255  // Test that coeffs.SmIndSecond returns stencilset with second set of smoothness indicator coefficients
256  // For now, 2 groups
257 
258  // Stencils (expected values)
259  // Group 0 = negative upwinding
260  // Group 1 = positive upwinding
261  nVal = 8;
262  int si2Sizes[2][3] = {{3, 2, 3}, {3, 2, 3}};
263  int si2Starts[2][3] = {{0, 3, 5}, {0, 3, 5}};
264  int si2Offsets[2][8] = {{3, 2, 1, 2, 0, 1, 0, -1}, {-2, -1, 0, -1, 1, 0, 1, 2}};
265  double si2Weights[2][8] = {{1, -4, 3, 1, -1, 3, -4, 1}, {1, -4, 3, 1, -1, 3, -4, 1}};
266 
267  result = true;
268  for (int g=0; g<nGroup; g++) {
269  WENO::StencilSet test = coeffs.SmIndSecond(g);
270 
271  result = result && (test.numStencils == nSten);
272  }
273  serialUnitResults.UpdateResult("WENO:Stencils:SmIndSecond:nSten", result);
274 
275  result = true;
276  for (int g=0; g<nGroup; g++) {
277  WENO::StencilSet test = coeffs.SmIndSecond(g);
278 
279  result = result && (test.numValues == nVal);
280  }
281  serialUnitResults.UpdateResult("WENO:Stencils:SmIndSecond:nVal", result);
282 
283  result = true;
284  for (int g=0; g<nGroup; g++) {
285  WENO::StencilSet test = coeffs.SmIndSecond(g);
286 
287  for (int i=0; i<nSten; i++) {
288  result = result && (test.stencilSizes[i] == si2Sizes[g][i]);
289  }
290  }
291  serialUnitResults.UpdateResult("WENO:Stencils:SmIndSecond:Sizes", result);
292 
293  result = true;
294  for (int g=0; g<nGroup; g++) {
295  WENO::StencilSet test = coeffs.SmIndSecond(g);
296 
297  for (int i=0; i<nSten; i++) {
298  result = result && (test.stencilStarts[i] == si2Starts[g][i]);
299  }
300  }
301  serialUnitResults.UpdateResult("WENO:Stencils:SmIndSecond:Starts", result);
302 
303  result = true;
304  for (int g=0; g<nGroup; g++) {
305  WENO::StencilSet test = coeffs.SmIndSecond(g);
306 
307  for (int i=0; i<nVal; i++) {
308  //std::cout << "Stencils:SmIndSecond:Offsets -- g = " << g << ", i = " << i << ", Actual = " << test.stencilOffsets[i] << std::endl;
309  //std::cout << "Stencils:SmIndSecond:Offsets -- g = " << g << ", i = " << i << ", Expected = " << si2Offsets[g][i] << std::endl;
310  result = result && (test.stencilOffsets[i] == si2Offsets[g][i]);
311  }
312  }
313  serialUnitResults.UpdateResult("WENO:Stencils:SmIndSecond:Offsets", result);
314 
315  result = true;
316  for (int g=0; g<nGroup; g++) {
317  WENO::StencilSet test = coeffs.SmIndSecond(g);
318 
319  for (int i=0; i<nVal; i++) {
320  result = result && (std::abs(test.stencilWeights[i] - si2Weights[g][i]) < eps);
321  }
322  }
323  serialUnitResults.UpdateResult("WENO:Stencils:SmIndSecond:Weights", result);
324 
325 }
326 
327 void TestWENO_ReconstPointVal(ix::test::results &serialUnitResults) {
328  // Tests for WENO point value reconstruction over a group of stencils
329  // Assumes formulation given in
330  // Jiang and Shu, J. Comput. Phys. 126 (1996) 202
331 
332  bool result;
333  double eps = 1e-8;
334  //std::cout << "WENO:ReconstPointVal" << std::endl;
335 
336  WENO::CoeffsWENO cw;
337 
338  // --- Equal ---
339  // Test for correct result if all values are equal
340  // Apply once for each group, should be same on both
341 
342  int nGroup = 2;
343  double vals[5] = {1, 1, 1, 1, 1};
344  double pvalExpRes = 1.0;
345 
346  result = true;
347  for (int g=0; g<nGroup; g++) {
348  double pval = -1000; // we don't want test to pass because this is initialized to 0
349  WENO::ReconstPointVal(vals, cw, g, pval);
350 
351  result = (std::abs(pval - pvalExpRes) < eps);
352  }
353  serialUnitResults.UpdateResult("WENO:ReconstPointVal:Equal", result);
354 
355  // --- Discontinuous ---
356  // Test for correct result if there is a discontinuity
357  // In all cases point values are reconstructed at face i+1/2, where central
358  // point is i
359  // Test for a discontinuity at each face
360  // Using group 1 -- positive upwinding
361 
362  // > Face-3/2 <
363  // Discontinuity occurs at face i-3/2, where central point is i
364 
365  double valsD[5] = {2, 1, 1, 1, 1};
366  double pvalExpResD = 1;
367 
368  double pval = -1000; // we don't want test to pass because this is initialized to 0
369  WENO::ReconstPointVal(valsD, cw, 1, pval);
370 
371  //std::cout << "Discontinuous:Face-3/2 -- Actual: " << pval << std::endl;
372  //std::cout << "Discontinuous:Face-3/2 -- Expected: " << pvalExpResD << std::endl;
373  result = (std::abs(pval - pvalExpResD) < eps);
374  serialUnitResults.UpdateResult("WENO:ReconstPointVal:Discontinuous:Face-3/2", result);
375 
376  // > Face-1/2 <
377  // Discontinuity occurs at face i-1/2, where central point is i
378  valsD[0] = 2;
379  valsD[1] = 2;
380  valsD[2] = 1;
381  valsD[3] = 1;
382  valsD[4] = 1;
383  pvalExpResD = 1;
384 
385  pval = -1000; // we don't want test to pass because this is initialized to 0
386  WENO::ReconstPointVal(valsD, cw, 1, pval);
387 
388  //std::cout << "Discontinuous:Face-1/2 -- Actual: " << pval << std::endl;
389  //std::cout << "Discontinuous:Face-1/2 -- Expected: " << pvalExpResD << std::endl;
390  result = (std::abs(pval - pvalExpResD) < eps);
391  serialUnitResults.UpdateResult("WENO:ReconstPointVal:Discontinuous:Face-1/2", result);
392 
393  // > Face+1/2 <
394  // Discontinuity occurs at face i+1/2, where central point is i
395  valsD[0] = 2;
396  valsD[1] = 2;
397  valsD[2] = 2;
398  valsD[3] = 1;
399  valsD[4] = 1;
400  pvalExpResD = 2;
401 
402  pval = -1000; // we don't want test to pass because this is initialized to 0
403  WENO::ReconstPointVal(valsD, cw, 1, pval);
404 
405  //std::cout << "Discontinuous:Face+1/2 -- Actual: " << pval << std::endl;
406  //std::cout << "Discontinuous:Face+1/2 -- Expected: " << pvalExpResD << std::endl;
407  result = (std::abs(pval - pvalExpResD) < eps);
408  serialUnitResults.UpdateResult("WENO:ReconstPointVal:Discontinuous:Face+1/2", result);
409 
410  // > Face+3/2 <
411  // Discontinuity occurs at face i+3/2, where central point is i
412  valsD[0] = 2;
413  valsD[1] = 2;
414  valsD[2] = 2;
415  valsD[3] = 2;
416  valsD[4] = 1;
417  pvalExpResD = 2;
418 
419  pval = -1000; // we don't want test to pass because this is initialized to 0
420  WENO::ReconstPointVal(valsD, cw, 1, pval);
421 
422  //std::cout << "Discontinuous:Face+3/2 -- Actual: " << pval << std::endl;
423  //std::cout << "Discontinuous:Face+3/2 -- Expected: " << pvalExpResD << std::endl;
424  result = (std::abs(pval - pvalExpResD) < eps);
425  serialUnitResults.UpdateResult("WENO:ReconstPointVal:Discontinuous:Face+3/2", result);
426 
427  // --- ReverseDiscont ---
428  // Test for correct result if there is a discontinuity
429  // In all cases point values are reconstructed at face i+1/2, where central
430  // point is i+1
431  // Test for a discontinuity at each face
432  // Using group 0 -- negative upwinding
433 
434  // > Face+5/2 <
435  // Discontinuity occurs at face i+5/2, where central point is i
436 
437  valsD[0] = 1;
438  valsD[1] = 1;
439  valsD[2] = 1;
440  valsD[3] = 1;
441  valsD[4] = 2;
442  pvalExpResD = 1;
443 
444  pval = -1000; // we don't want test to pass because this is initialized to 0
445  WENO::ReconstPointVal(valsD, cw, 0, pval);
446 
447  result = (std::abs(pval - pvalExpResD) < eps);
448  serialUnitResults.UpdateResult("WENO:ReconstPointVal:ReverseDiscont:Face+5/2", result);
449 
450  // > Face+3/2 <
451  // Discontinuity occurs at face i+3/2, where central point is i+1
452  valsD[0] = 1;
453  valsD[1] = 1;
454  valsD[2] = 1;
455  valsD[3] = 2;
456  valsD[4] = 2;
457  pvalExpResD = 1;
458 
459  pval = -1000; // we don't want test to pass because this is initialized to 0
460  WENO::ReconstPointVal(valsD, cw, 0, pval);
461 
462  result = (std::abs(pval - pvalExpResD) < eps);
463  serialUnitResults.UpdateResult("WENO:ReconstPointVal:ReverseDiscont:Face+3/2", result);
464 
465  // > Face+1/2 <
466  // Discontinuity occurs at face i+1/2, where central point is i+1
467  valsD[0] = 1;
468  valsD[1] = 1;
469  valsD[2] = 2;
470  valsD[3] = 2;
471  valsD[4] = 2;
472  pvalExpResD = 2;
473 
474  pval = -1000; // we don't want test to pass because this is initialized to 0
475  WENO::ReconstPointVal(valsD, cw, 0, pval);
476 
477  result = (std::abs(pval - pvalExpResD) < eps);
478  serialUnitResults.UpdateResult("WENO:ReconstPointVal:ReverseDiscont:Face+1/2", result);
479 
480  // > Face-1/2 <
481  // Discontinuity occurs at face i-1/2, where central point is i+1
482  valsD[0] = 1;
483  valsD[1] = 2;
484  valsD[2] = 2;
485  valsD[3] = 2;
486  valsD[4] = 2;
487  pvalExpResD = 2;
488 
489  pval = -1000; // we don't want test to pass because this is initialized to 0
490  WENO::ReconstPointVal(valsD, cw, 0, pval);
491 
492  result = (std::abs(pval - pvalExpResD) < eps);
493  serialUnitResults.UpdateResult("WENO:ReconstPointVal:ReverseDiscont:Face-1/2", result);
494 }
495 
497  // Tests for WENO point value reconstruction on a stencil
498  // Assumes formulation given in
499  // Jiang and Shu, J. Comput. Phys. 126 (1996) 202
500 
501  bool result;
502  double eps = 1e-8;
503  //std::cout << "WENO:ReconstPointValSten" << std::endl;
504 
505  WENO::CoeffsWENO cw;
506 
507  // --- Equal ---
508  // Test for correct result on each stencil if all values are equal
509  // Test all stencil groups
510  // Since stencils are all of length 3 and all values are equal, we can pass
511  // the same array of values for each stencil
512  int nGroups = 2;
513  int nSten = 3;
514  double vals[3] = {1, 1, 1};
515  double pValExpRes = 1;
516 
517  result = true;
518  for (int g=0; g<nGroups; g++) {
519  for (int i=0; i<nSten; i++) {
520  double pVal = -1000; // we don't want test to pass because this is initialized to 0
521  WENO::ReconstPointValSten(vals, cw, g, i, pVal);
522 
523  //std::cout << "ReconstPointValSten:Equal -- g = " << g << ", i = " << i << ", Actual = " << pVal << std::endl;
524  //std::cout << "ReconstPointValSten:Equal -- g = " << g << ", i = " << i << ", Expected = " << pValExpRes << std::endl;
525  result = result && (std::abs(pVal - pValExpRes) < eps);
526  }
527  }
528  serialUnitResults.UpdateResult("WENO:ReconstPointValSten:Equal", result);
529 
530  // --- Discontinuous ---
531  // Test for correct result on each stencil if there is a discontinuity
532  // In all cases point values are reconstructed at face i+1/2, where central
533  // point is i
534  // Test for a discontinuity at each face
535  // For this test vals will be long enough to cover all stencils
536  // Using group 1 -- positive upwinding
537 
538  // > Face-3/2 <
539  // Discontinuity occurs at face i-3/2, where central point is i
540  double valsD[5] = {2, 1, 1, 1, 1};
541  double pvalsExpResD[3] = {4/3.0, 1, 1};
542 
543  result = true;
544  for (int i=0; i<nSten; i++) {
545  double pval = -1000; // we don't want test to pass because this is initialized to 0
546  // note that using "i" to index valsD below takes advantage of knowledge about the stencils and their ordering
547  WENO::ReconstPointValSten(&valsD[i], cw, 1, i, pval);
548 
549  //std::cout << "Discontinuous:Face-3/2 (" << i << ") Actual: " << pval << std::endl;
550  //std::cout << "Discontinuous:Face-3/2 (" << i << ") Expected: " << pvalsExpResD[i] << std::endl;
551  result = result && (std::abs(pval - pvalsExpResD[i]) < eps);
552  }
553  serialUnitResults.UpdateResult("WENO:ReconstPointValSten:Discontinuous:Face-3/2", result);
554 
555  // > Face-1/2 <
556  // Discontinuity occurs at face i-1/2, where central point is i
557  valsD[0] = 2;
558  valsD[1] = 2;
559  valsD[2] = 1;
560  valsD[3] = 1;
561  valsD[4] = 1;
562  pvalsExpResD[0] = 1/6.0;
563  pvalsExpResD[1] = 5/6.0;
564  pvalsExpResD[2] = 1;
565 
566  result = true;
567  for (int i=0; i<nSten; i++) {
568  double pval = -1000; // we don't want test to pass because this is initialized to 0
569  // note that using "i" to index valsD below takes advantage of knowledge about the stencils and their ordering
570  WENO::ReconstPointValSten(&valsD[i], cw, 1, i, pval);
571 
572  //std::cout << "Discontinuous:Face-1/2 (" << i << ") Actual: " << pval << std::endl;
573  //std::cout << "Discontinuous:Face-1/2 (" << i << ") Expected: " << pvalsExpResD[i] << std::endl;
574  result = result && (std::abs(pval - pvalsExpResD[i]) < eps);
575  }
576  serialUnitResults.UpdateResult("WENO:ReconstPointValSten:Discontinuous:Face-1/2", result);
577 
578  // > Face+1/2 <
579  // Discontinuity occurs at face i+1/2, where central point is i
580  valsD[0] = 2;
581  valsD[1] = 2;
582  valsD[2] = 2;
583  valsD[3] = 1;
584  valsD[4] = 1;
585  pvalsExpResD[0] = 2;
586  pvalsExpResD[1] = 5/3.0;
587  pvalsExpResD[2] = 4/3.0;
588 
589  result = true;
590  for (int i=0; i<nSten; i++) {
591  double pval = -1000; // we don't want test to pass because this is initialized to 0
592  // note that using "i" to index valsD below takes advantage of knowledge about the stencils and their ordering
593  WENO::ReconstPointValSten(&valsD[i], cw, 1, i, pval);
594 
595  //std::cout << "Discontinuous:Face+1/2 (" << i << ") Actual: " << pval << std::endl;
596  //std::cout << "Discontinuous:Face+1/2 (" << i << ") Expected: " << pvalsExpResD[i] << std::endl;
597  result = result && (std::abs(pval - pvalsExpResD[i]) < eps);
598  }
599  serialUnitResults.UpdateResult("WENO:ReconstPointValSten:Discontinuous:Face+1/2", result);
600 
601  // > Face+3/2 <
602  // Discontinuity occurs at face i+3/2, where central point is i
603  valsD[0] = 2;
604  valsD[1] = 2;
605  valsD[2] = 2;
606  valsD[3] = 2;
607  valsD[4] = 1;
608  pvalsExpResD[0] = 2;
609  pvalsExpResD[1] = 2;
610  pvalsExpResD[2] = 13/6.0;
611 
612  result = true;
613  for (int i=0; i<nSten; i++) {
614  double pval = -1000; // we don't want test to pass because this is initialized to 0
615  // note that using "i" to index valsD below takes advantage of knowledge about the stencils and their ordering
616  WENO::ReconstPointValSten(&valsD[i], cw, 1, i, pval);
617 
618  //std::cout << "Discontinuous:Face+3/2 (" << i << ") Actual: " << pval << std::endl;
619  //std::cout << "Discontinuous:Face+3/2 (" << i << ") Expected: " << pvalsExpResD[i] << std::endl;
620  result = result && (std::abs(pval - pvalsExpResD[i]) < eps);
621  }
622  serialUnitResults.UpdateResult("WENO:ReconstPointValSten:Discontinuous:Face+3/2", result);
623 
624  // --- ReverseDiscont ---
625  // Same as Discontinuous above, but uses negative upwinding
626  // Test for correct result on each stencil if there is a discontinuity
627  // In all cases point values are reconstructed at face i+1/2, where central
628  // point is i+1
629  // Test for a discontinuity at each face
630  // For this test vals will be long enough to cover all stencils
631  // Using group 0 -- negative upwinding
632 
633  // > Face+5/2 <
634  // Discontinuity occurs at face i+5/2, where central point is i+1
635  valsD[0] = 1;
636  valsD[1] = 1;
637  valsD[2] = 1;
638  valsD[3] = 1;
639  valsD[4] = 2;
640  pvalsExpResD[0] = 4/3.0;
641  pvalsExpResD[1] = 1;
642  pvalsExpResD[2] = 1;
643 
644  result = true;
645  for (int i=0; i<nSten; i++) {
646  double pval = -1000; // we don't want test to pass because this is initialized to 0
647  // note that using "i" to index valsD below takes advantage of knowledge about the stencils and their ordering
648  WENO::ReconstPointValSten(&valsD[2-i], cw, 0, i, pval);
649 
650  //std::cout << "ReverseDiscont:Face+5/2 (" << i << ") Actual: " << pval << std::endl;
651  //std::cout << "ReverseDiscont:Face+5/2 (" << i << ") Expected: " << pvalsExpResD[i] << std::endl;
652  result = result && (std::abs(pval - pvalsExpResD[i]) < eps);
653  //std::cout << "ReverseDiscont:Face+5/2 (" << i << ") result: " << result << std::endl;
654  }
655  serialUnitResults.UpdateResult("WENO:ReconstPointValSten:ReverseDiscont:Face+5/2", result);
656 
657  // > Face+3/2 <
658  // Discontinuity occurs at face i+3/2, where central point is i+1
659  valsD[0] = 1;
660  valsD[1] = 1;
661  valsD[2] = 1;
662  valsD[3] = 2;
663  valsD[4] = 2;
664  pvalsExpResD[0] = 1/6.0;
665  pvalsExpResD[1] = 5/6.0;
666  pvalsExpResD[2] = 1;
667 
668  result = true;
669  for (int i=0; i<nSten; i++) {
670  double pval = -1000; // we don't want test to pass because this is initialized to 0
671  // note that using "i" to index valsD below takes advantage of knowledge about the stencils and their ordering
672  WENO::ReconstPointValSten(&valsD[2-i], cw, 0, i, pval);
673 
674  //std::cout << "ReverseDiscont:Face+3/2 (" << i << ") Actual: " << pval << std::endl;
675  //std::cout << "ReverseDiscont:Face+3/2 (" << i << ") Expected: " << pvalsExpResD[i] << std::endl;
676  result = result && (std::abs(pval - pvalsExpResD[i]) < eps);
677  //std::cout << "ReverseDiscont:Face+3/2 (" << i << ") result: " << result << std::endl;
678  }
679  serialUnitResults.UpdateResult("WENO:ReconstPointValSten:ReverseDiscont:Face+3/2", result);
680 
681  // > Face+1/2 <
682  // Discontinuity occurs at face i+1/2, where central point is i+1
683  valsD[0] = 1;
684  valsD[1] = 1;
685  valsD[2] = 2;
686  valsD[3] = 2;
687  valsD[4] = 2;
688  pvalsExpResD[0] = 2;
689  pvalsExpResD[1] = 5/3.0;
690  pvalsExpResD[2] = 4/3.0;
691 
692  result = true;
693  for (int i=0; i<nSten; i++) {
694  double pval = -1000; // we don't want test to pass because this is initialized to 0
695  // note that using "i" to index valsD below takes advantage of knowledge about the stencils and their ordering
696  WENO::ReconstPointValSten(&valsD[2-i], cw, 0, i, pval);
697 
698  //std::cout << "ReverseDiscont:Face+1/2 (" << i << ") Actual: " << pval << std::endl;
699  //std::cout << "ReverseDiscont:Face+1/2 (" << i << ") Expected: " << pvalsExpResD[i] << std::endl;
700  result = result && (std::abs(pval - pvalsExpResD[i]) < eps);
701  //std::cout << "ReverseDiscont:Face+1/2 (" << i << ") result: " << result << std::endl;
702  }
703  serialUnitResults.UpdateResult("WENO:ReconstPointValSten:ReverseDiscont:Face+1/2", result);
704 
705  // > Face-1/2 <
706  // Discontinuity occurs at face i-1/2, where central point is i+1
707  valsD[0] = 1;
708  valsD[1] = 2;
709  valsD[2] = 2;
710  valsD[3] = 2;
711  valsD[4] = 2;
712  pvalsExpResD[0] = 2;
713  pvalsExpResD[1] = 2;
714  pvalsExpResD[2] = 13/6.0;
715 
716  result = true;
717  for (int i=0; i<nSten; i++) {
718  double pval = -1000; // we don't want test to pass because this is initialized to 0
719  // note that using "i" to index valsD below takes advantage of knowledge about the stencils and their ordering
720  WENO::ReconstPointValSten(&valsD[2-i], cw, 0, i, pval);
721 
722  //std::cout << "ReverseDiscont:Face-1/2 (" << i << ") Actual: " << pval << std::endl;
723  //std::cout << "ReverseDiscont:Face-1/2 (" << i << ") Expected: " << pvalsExpResD[i] << std::endl;
724  result = result && (std::abs(pval - pvalsExpResD[i]) < eps);
725  //std::cout << "ReverseDiscont:Face-1/2 (" << i << ") result: " << result << std::endl;
726  }
727  serialUnitResults.UpdateResult("WENO:ReconstPointValSten:ReverseDiscont:Face-1/2", result);
728 
729 }
730 
731 void TestWENO_SmoothInd(ix::test::results &serialUnitResults) {
732  // Tests for WENO smoothness indicator
733  // Assumes formulation given in
734  // Jiang and Shu, J. Comput. Phys. 126 (1996) 202
735 
736  bool result;
737  double eps = 1e-8;
738  //std::cout << "WENO:SmoothInd" << std::endl;
739 
740  WENO::CoeffsWENO cw;
741 
742  // --- Equal ---
743  // Test for correct result on each stencil if all values are equal
744  // Since stencils are all of length 3 and all values are equal, we can pass
745  // the same array of values for each stencil
746  int nGroups = 2;
747  int nSten = 3;
748  double vals[3] = {1, 1, 1};
749  double siExpRes = 0; // all results should be same
750 
751  result = true;
752  for (int g=0; g<nGroups; g++) {
753  for (int i=0; i<nSten; i++) {
754  double si = -1000; // we don't want test to pass because this is initialized to 0
755  WENO::SmoothInd(vals, cw, g, i, si);
756 
757  result = result && (std::abs(si - siExpRes) < eps);
758  }
759  }
760  serialUnitResults.UpdateResult("WENO:SmoothInd:Equal", result);
761 
762  // --- Discontinuous ---
763  // Test for correct result on each stencil if there is a discontinuity
764  // Test for a discontinuity at each face
765  // For this test vals will be long enough to cover all stencils
766  // Using group 1 -- positive upwinding
767 
768  // > Face-3/2 <
769  // Discontinuity occurs at face i-3/2, where central point is i
770  double valsD[5] = {2, 1, 1, 1, 1};
771  double siExpResD[3] = {4/3.0, 0, 0};
772 
773  result = true;
774  for (int i=0; i<nSten; i++) {
775  double si = -1000; // we don't want test to pass because this is initialized to 0
776  WENO::SmoothInd(&valsD[i], cw, 1, i, si);
777 
778  //std::cout << "Discontinuous:Face-3/2 (" << i << ") Actual: " << si << std::endl;
779  //std::cout << "Discontinuous:Face-3/2 (" << i << ") Expected: " << siExpResD[i] << std::endl;
780  result = result && (std::abs(si - siExpResD[i]) < eps);
781  }
782  serialUnitResults.UpdateResult("WENO:SmoothInd:Discontinuous:Face-3/2", result);
783 
784  // > Face-1/2 <
785  // Discontinuity occurs at face i-1/2, where central point is i
786  valsD[0] = 2;
787  valsD[1] = 2;
788  valsD[2] = 1;
789  valsD[3] = 1;
790  valsD[4] = 1;
791  siExpResD[0] = 10/3.0;
792  siExpResD[1] = 4/3.0;
793  siExpResD[2] = 0;
794 
795  result = true;
796  for (int i=0; i<nSten; i++) {
797  double si = -1000; // we don't want test to pass because this is initialized to 0
798  WENO::SmoothInd(&valsD[i], cw, 1, i, si);
799 
800  //std::cout << "Discontinuous:Face-1/2 (" << i << ") Actual: " << si << std::endl;
801  //std::cout << "Discontinuous:Face-1/2 (" << i << ") Expected: " << siExpResD[i] << std::endl;
802  result = result && (std::abs(si - siExpResD[i]) < eps);
803  }
804  serialUnitResults.UpdateResult("WENO:SmoothInd:Discontinuous:Face-1/2", result);
805 
806  // > Face+1/2 <
807  // Discontinuity occurs at face i+1/2, where central point is i
808  valsD[0] = 2;
809  valsD[1] = 2;
810  valsD[2] = 2;
811  valsD[3] = 1;
812  valsD[4] = 1;
813  siExpResD[0] = 0;
814  siExpResD[1] = 4/3.0;
815  siExpResD[2] = 10/3.0;
816 
817  result = true;
818  for (int i=0; i<nSten; i++) {
819  double si = -1000; // we don't want test to pass because this is initialized to 0
820  WENO::SmoothInd(&valsD[i], cw, 1, i, si);
821 
822  //std::cout << "Discontinuous:Face+1/2 (" << i << ") Actual: " << si << std::endl;
823  //std::cout << "Discontinuous:Face+1/2 (" << i << ") Expected: " << siExpResD[i] << std::endl;
824  result = result && (std::abs(si - siExpResD[i]) < eps);
825  }
826  serialUnitResults.UpdateResult("WENO:SmoothInd:Discontinuous:Face+1/2", result);
827 
828  // > Face+3/2 <
829  // Discontinuity occurs at face i+3/2, where central point is i
830  valsD[0] = 2;
831  valsD[1] = 2;
832  valsD[2] = 2;
833  valsD[3] = 2;
834  valsD[4] = 1;
835  siExpResD[0] = 0;
836  siExpResD[1] = 0;
837  siExpResD[2] = 4/3.0;
838 
839  result = true;
840  for (int i=0; i<nSten; i++) {
841  double si = -1000; // we don't want test to pass because this is initialized to 0
842  WENO::SmoothInd(&valsD[i], cw, 1, i, si);
843 
844  //std::cout << "Discontinuous:Face+3/2 (" << i << ") Actual: " << si << std::endl;
845  //std::cout << "Discontinuous:Face+3/2 (" << i << ") Expected: " << siExpResD[i] << std::endl;
846  result = result && (std::abs(si - siExpResD[i]) < eps);
847  }
848  serialUnitResults.UpdateResult("WENO:SmoothInd:Discontinuous:Face+3/2", result);
849 
850  // --- ReverseDiscont ---
851  // Test for correct result on each stencil if there is a discontinuity
852  // Test for a discontinuity at each face
853  // For this test vals will be long enough to cover all stencils
854  // Using group 0 -- negative upwinding
855 
856  // > Face+5/2 <
857  // Discontinuity occurs at face i+5/2, where central point is i+1
858  valsD[0] = 1;
859  valsD[1] = 1;
860  valsD[2] = 1;
861  valsD[3] = 1;
862  valsD[4] = 2;
863  siExpResD[0] = 4/3.0;
864  siExpResD[1] = 0;
865  siExpResD[2] = 0;
866 
867  result = true;
868  for (int i=0; i<nSten; i++) {
869  double si = -1000; // we don't want test to pass because this is initialized to 0
870  WENO::SmoothInd(&valsD[2-i], cw, 0, i, si);
871 
872  //std::cout << "ReverseDiscont:Face+5/2 (" << i << ") Actual: " << si << std::endl;
873  //std::cout << "ReverseDiscont:Face+5/2 (" << i << ") Expected: " << siExpResD[i] << std::endl;
874  result = result && (std::abs(si - siExpResD[i]) < eps);
875  }
876  serialUnitResults.UpdateResult("WENO:SmoothInd:ReverseDiscont:Face+5/2", result);
877 
878  // > Face+3/2 <
879  // Discontinuity occurs at face i+3/2, where central point is i+1
880  valsD[0] = 1;
881  valsD[1] = 1;
882  valsD[2] = 1;
883  valsD[3] = 2;
884  valsD[4] = 2;
885  siExpResD[0] = 10/3.0;
886  siExpResD[1] = 4/3.0;
887  siExpResD[2] = 0;
888 
889  result = true;
890  for (int i=0; i<nSten; i++) {
891  double si = -1000; // we don't want test to pass because this is initialized to 0
892  WENO::SmoothInd(&valsD[2-i], cw, 0, i, si);
893 
894  //std::cout << "ReverseDiscont:Face+3/2 (" << i << ") Actual: " << si << std::endl;
895  //std::cout << "ReverseDiscont:Face+3/2 (" << i << ") Expected: " << siExpResD[i] << std::endl;
896  result = result && (std::abs(si - siExpResD[i]) < eps);
897  }
898  serialUnitResults.UpdateResult("WENO:SmoothInd:ReverseDiscont:Face+3/2", result);
899 
900  // > Face+1/2 <
901  // Discontinuity occurs at face i+1/2, where central point is i+1
902  valsD[0] = 1;
903  valsD[1] = 1;
904  valsD[2] = 2;
905  valsD[3] = 2;
906  valsD[4] = 2;
907  siExpResD[0] = 0;
908  siExpResD[1] = 4/3.0;
909  siExpResD[2] = 10/3.0;
910 
911  result = true;
912  for (int i=0; i<nSten; i++) {
913  double si = -1000; // we don't want test to pass because this is initialized to 0
914  WENO::SmoothInd(&valsD[2-i], cw, 0, i, si);
915 
916  //std::cout << "ReverseDiscont:Face+1/2 (" << i << ") Actual: " << si << std::endl;
917  //std::cout << "ReverseDiscont:Face+1/2 (" << i << ") Expected: " << siExpResD[i] << std::endl;
918  result = result && (std::abs(si - siExpResD[i]) < eps);
919  }
920  serialUnitResults.UpdateResult("WENO:SmoothInd:ReverseDiscont:Face+1/2", result);
921 
922  // > Face-1/2 <
923  // Discontinuity occurs at face i-1/2, where central point is i+1
924  valsD[0] = 1;
925  valsD[1] = 2;
926  valsD[2] = 2;
927  valsD[3] = 2;
928  valsD[4] = 2;
929  siExpResD[0] = 0;
930  siExpResD[1] = 0;
931  siExpResD[2] = 4/3.0;
932 
933  result = true;
934  for (int i=0; i<nSten; i++) {
935  double si = -1000; // we don't want test to pass because this is initialized to 0
936  WENO::SmoothInd(&valsD[2-i], cw, 0, i, si);
937 
938  //std::cout << "Discontinuous:Face-1/2 (" << i << ") Actual: " << si << std::endl;
939  //std::cout << "Discontinuous:Face-1/2 (" << i << ") Expected: " << siExpResD[i] << std::endl;
940  result = result && (std::abs(si - siExpResD[i]) < eps);
941  }
942  serialUnitResults.UpdateResult("WENO:SmoothInd:ReverseDiscont:Face-1/2", result);
943 
944 }
945 
946 void TestWENO_Project(ix::test::results &serialUnitResults) {
947  // Tests characteristic projection functions
948 
949  bool result;
950  double eps = 1e-8;
951 
952  // --- Mult ---
953  // Test multiplication routines (Project)
954  // First argument is 2D array stored in column-major order in a double[]
955  // Second argument is 2D array stored in row-major order in a double[]
956  // Result is 2D array stored in row-major order in a double[]
957 
958  // > MatMat <
959  // Test matrix-matrix multiplication
960  {
961  double a[4] = {1, 3, 2, 4};
962  double b[4] = {1, 2, 3, 4};
963  double c[4] = {-1000, -1000, -1000, -1000};
964  double cExp[4] = {7, 10, 15, 22};
965 
966  WENO::Project(2, 2, &a[0], &b[0], &c[0]);
967  result = true;
968  for (int i=0; i<4; i++) {
969  result = result && (std::abs(c[i] - cExp[i]) < eps);
970  }
971  serialUnitResults.UpdateResult("WENO:Project:Mult:MatMat", result);
972  }
973 
974  // > MatVec <
975  // Test matrix-vector multiplication
976  // Using same a matrix
977  {
978  double a[4] = {1, 3, 2, 4};
979  double b[2] = {5, 6};
980  double c[2] = {-1000, -1000};
981  double cExp[2] = {17, 39};
982 
983  WENO::Project(2, 1, &a[0], &b[0], &c[0]);
984  result = true;
985  for (int i=0; i<2; i++) {
986  result = result && (std::abs(c[i] - cExp[i]) < eps);
987  }
988  serialUnitResults.UpdateResult("WENO:Project:Mult:MatVec", result);
989  }
990 
991  // --- Roe ---
992  // Test Roe matrix routines
993  // Assumes Euler equations with ideal gas EOS, no species transport
994 
995  double gamma = 1.4;
996 
997  // > 2D <
998  // Test 2D matrix
999 
1000  {
1001  int numDim = 2;
1002  double uL[4] = {1, 1, 1, 5};
1003  double uR[4] = {2, 4, 4, 16};
1004  double ujump[4];
1005  for (int i=0; i<numDim+2; i++) ujump[i] = uR[i] - uL[i];
1006 
1007  double tmat[16];
1008  double tinv[16];
1009  double lambda[16];
1010 
1011  // > Identity <
1012  // Test the identity Tmat*Tinv = I
1013  for (int iDim=0; iDim<numDim && result; iDim++) {
1014  double norm[2];
1015  for (int i=0; i<numDim; i++) {
1016  if (i == iDim) {
1017  norm[i] = 1;
1018  } else {
1019  norm[i] = 0;
1020  }
1021  }
1022 
1023  FC_MODULE(satutil,sat_form_roe_matrices,SATUTIL,SAT_FORM_ROE_MATRICES)
1024  (&numDim, &uL[0], &uR[0], &gamma, &norm[0], &tmat[0], &tinv[0], &lambda[0]);
1025 
1026  double tmp1[4];
1027  double tmp[4];
1028  WENO::Project(numDim+2, 1, &tinv[0], &ujump[0], &tmp1[0]);
1029  WENO::Project(numDim+2, 1, &tmat[0], &tmp1[0], &tmp[0]);
1030 
1031  result = true;
1032  for (int i=0; i<numDim+2; i++) {
1033  //std::cout << "ujump[" << i << "] = " << ujump[i] << std::endl;
1034  //std::cout << "tmp[" << i << "] = " << tmp[i] << std::endl;
1035  result = result && (std::abs(ujump[i] - tmp[i]) < eps);
1036  }
1037  serialUnitResults.UpdateResult("WENO:Project:2D:Identity", result);
1038  }
1039 
1040  if (!result) return;
1041 
1042  // > RoeProp <
1043  // Test the identity A_hat [U] = [F], where A_hat = T*Lambda*Tinv
1044  for (int iDim=0; iDim<numDim && result; iDim++) {
1045  double norm[2];
1046  double fL[4];
1047  double fR[4];
1048  double fjump[4];
1049  fL[0] = 1;
1050  fL[numDim+1] = 6.6;
1051  fR[0] = 4;
1052  fR[numDim+1] = 38.4;
1053  for (int i=0; i<numDim; i++) {
1054  if (i == iDim) {
1055  norm[i] = 1;
1056  fL[i+1] = 2.6;
1057  fR[i+1] = 11.2;
1058  } else {
1059  norm[i] = 0;
1060  fL[i+1] = 1;
1061  fR[i+1] = 8;
1062  }
1063  }
1064  for (int i=0; i<numDim+2; i++) fjump[i] = fR[i] - fL[i];
1065 
1066  FC_MODULE(satutil,sat_form_roe_matrices,SATUTIL,SAT_FORM_ROE_MATRICES)
1067  (&numDim, &uL[0], &uR[0], &gamma, &norm[0], &tmat[0], &tinv[0], &lambda[0]);
1068 
1069  double tmp1[4];
1070  double tmp2[4];
1071  double tmp[4];
1072  WENO::Project(numDim+2, 1, &tinv[0], &ujump[0], &tmp1[0]);
1073  WENO::Project(numDim+2, 1, &lambda[0], &tmp1[0], &tmp2[0]);
1074  WENO::Project(numDim+2, 1, &tmat[0], &tmp2[0], &tmp[0]);
1075 
1076  result = true;
1077  for (int i=0; i<numDim+2; i++) {
1078  //std::cout << "fjump[" << i << "] = " << fjump[i] << std::endl;
1079  //std::cout << "tmp[" << i << "] = " << tmp[i] << std::endl;
1080  result = result && (std::abs(fjump[i] - tmp[i]) < eps);
1081  }
1082  serialUnitResults.UpdateResult("WENO:Project:2D:RoeProp", result);
1083  }
1084 
1085  if (!result) return;
1086  }
1087 
1088  // > 3D <
1089  // Test 3D matrix
1090 
1091  {
1092  int numDim = 3;
1093  double uL[5] = {1, 1, 1, 1, 5.5};
1094  double uR[5] = {2, 4, 4, 4, 20};
1095  double ujump[5];
1096  for (int i=0; i<numDim+2; i++) ujump[i] = uR[i] - uL[i];
1097 
1098  double tmat[25];
1099  double tinv[25];
1100  double lambda[25];
1101 
1102  // > Identity <
1103  // Test the identity Tmat*Tinv = I
1104  for (int iDim=0; iDim<numDim && result; iDim++) {
1105  double norm[3];
1106  for (int i=0; i<numDim; i++) {
1107  if (i == iDim) {
1108  norm[i] = 1;
1109  } else {
1110  norm[i] = 0;
1111  }
1112  }
1113 
1114  FC_MODULE(satutil,sat_form_roe_matrices,SATUTIL,SAT_FORM_ROE_MATRICES)
1115  (&numDim, &uL[0], &uR[0], &gamma, &norm[0], &tmat[0], &tinv[0], &lambda[0]);
1116 
1117  double tmp1[5];
1118  double tmp[5];
1119  WENO::Project(numDim+2, 1, &tinv[0], &ujump[0], &tmp1[0]);
1120  WENO::Project(numDim+2, 1, &tmat[0], &tmp1[0], &tmp[0]);
1121 
1122  result = true;
1123  for (int i=0; i<numDim+2; i++) {
1124  //std::cout << "ujump[" << i << "] = " << ujump[i] << std::endl;
1125  //std::cout << "tmp[" << i << "] = " << tmp[i] << std::endl;
1126  result = result && (std::abs(ujump[i] - tmp[i]) < eps);
1127  }
1128  serialUnitResults.UpdateResult("WENO:Project:3D:Identity", result);
1129  }
1130 
1131  if (!result) return;
1132 
1133  // > RoeProp <
1134  // Test the identity A_hat [U] = [F], where A_hat = T*Lambda*Tinv
1135  for (int iDim=0; iDim<numDim && result; iDim++) {
1136  double norm[3];
1137  double fL[5];
1138  double fR[5];
1139  double fjump[5];
1140  fL[0] = 1;
1141  fL[numDim+1] = 7.1;
1142  fR[0] = 4;
1143  fR[numDim+1] = 46.4;
1144  for (int i=0; i<numDim; i++) {
1145  if (i == iDim) {
1146  norm[i] = 1;
1147  fL[i+1] = 2.6;
1148  fR[i+1] = 11.2;
1149  } else {
1150  norm[i] = 0;
1151  fL[i+1] = 1;
1152  fR[i+1] = 8;
1153  }
1154  }
1155  for (int i=0; i<numDim+2; i++) fjump[i] = fR[i] - fL[i];
1156 
1157  FC_MODULE(satutil,sat_form_roe_matrices,SATUTIL,SAT_FORM_ROE_MATRICES)
1158  (&numDim, &uL[0], &uR[0], &gamma, &norm[0], &tmat[0], &tinv[0], &lambda[0]);
1159 
1160  double tmp1[5];
1161  double tmp2[5];
1162  double tmp[5];
1163  WENO::Project(numDim+2, 1, &tinv[0], &ujump[0], &tmp1[0]);
1164  WENO::Project(numDim+2, 1, &lambda[0], &tmp1[0], &tmp2[0]);
1165  WENO::Project(numDim+2, 1, &tmat[0], &tmp2[0], &tmp[0]);
1166 
1167  result = true;
1168  for (int i=0; i<numDim+2; i++) {
1169  //std::cout << "fjump[" << i << "] = " << fjump[i] << std::endl;
1170  //std::cout << "tmp[" << i << "] = " << tmp[i] << std::endl;
1171  result = result && (std::abs(fjump[i] - tmp[i]) < eps);
1172  }
1173  serialUnitResults.UpdateResult("WENO:Project:3D:RoeProp", result);
1174  }
1175  }
1176 
1177  // --- RoeNeg ---
1178  // Test Roe matrix routines with negative background speed
1179  // Assumes Euler equations with ideal gas EOS, no species transport
1180 
1181  // > 2D <
1182  // Test 2D matrix
1183 
1184  {
1185  int numDim = 2;
1186  double uL[4] = {1, -1, -1, 5};
1187  double uR[4] = {2, -4, -4, 16};
1188  double ujump[4];
1189  for (int i=0; i<numDim+2; i++) ujump[i] = uR[i] - uL[i];
1190 
1191  double tmat[16];
1192  double tinv[16];
1193  double lambda[16];
1194 
1195  // > Identity <
1196  // Test the identity Tmat*Tinv = I
1197  for (int iDim=0; iDim<numDim && result; iDim++) {
1198  double norm[2];
1199  for (int i=0; i<numDim; i++) {
1200  if (i == iDim) {
1201  norm[i] = 1;
1202  } else {
1203  norm[i] = 0;
1204  }
1205  }
1206 
1207  FC_MODULE(satutil,sat_form_roe_matrices,SATUTIL,SAT_FORM_ROE_MATRICES)
1208  (&numDim, &uL[0], &uR[0], &gamma, &norm[0], &tmat[0], &tinv[0], &lambda[0]);
1209 
1210  double tmp1[4];
1211  double tmp[4];
1212  WENO::Project(numDim+2, 1, &tinv[0], &ujump[0], &tmp1[0]);
1213  WENO::Project(numDim+2, 1, &tmat[0], &tmp1[0], &tmp[0]);
1214 
1215  result = true;
1216  for (int i=0; i<numDim+2; i++) {
1217  //std::cout << "ujump[" << i << "] = " << ujump[i] << std::endl;
1218  //std::cout << "tmp[" << i << "] = " << tmp[i] << std::endl;
1219  result = result && (std::abs(ujump[i] - tmp[i]) < eps);
1220  }
1221  serialUnitResults.UpdateResult("WENO:Project:Neg:2D:Identity", result);
1222  }
1223 
1224  if (!result) return;
1225 
1226  // > RoeProp <
1227  // Test the identity A_hat [U] = [F], where A_hat = T*Lambda*Tinv
1228  for (int iDim=0; iDim<numDim && result; iDim++) {
1229  double norm[2];
1230  double fL[4];
1231  double fR[4];
1232  double fjump[4];
1233  fL[0] = -1;
1234  fL[numDim+1] = -6.6;
1235  fR[0] = -4;
1236  fR[numDim+1] = -38.4;
1237  for (int i=0; i<numDim; i++) {
1238  if (i == iDim) {
1239  norm[i] = 1;
1240  fL[i+1] = 2.6;
1241  fR[i+1] = 11.2;
1242  } else {
1243  norm[i] = 0;
1244  fL[i+1] = 1;
1245  fR[i+1] = 8;
1246  }
1247  }
1248  for (int i=0; i<numDim+2; i++) fjump[i] = fR[i] - fL[i];
1249 
1250  FC_MODULE(satutil,sat_form_roe_matrices,SATUTIL,SAT_FORM_ROE_MATRICES)
1251  (&numDim, &uL[0], &uR[0], &gamma, &norm[0], &tmat[0], &tinv[0], &lambda[0]);
1252 
1253  double tmp1[4];
1254  double tmp2[4];
1255  double tmp[4];
1256  WENO::Project(numDim+2, 1, &tinv[0], &ujump[0], &tmp1[0]);
1257  WENO::Project(numDim+2, 1, &lambda[0], &tmp1[0], &tmp2[0]);
1258  WENO::Project(numDim+2, 1, &tmat[0], &tmp2[0], &tmp[0]);
1259 
1260  result = true;
1261  for (int i=0; i<numDim+2; i++) {
1262  //std::cout << "fjump[" << i << "] = " << fjump[i] << std::endl;
1263  //std::cout << "tmp[" << i << "] = " << tmp[i] << std::endl;
1264  result = result && (std::abs(fjump[i] - tmp[i]) < eps);
1265  }
1266  serialUnitResults.UpdateResult("WENO:Project:Neg:2D:RoeProp", result);
1267  }
1268 
1269  if (!result) return;
1270  }
1271 
1272  // > 3D <
1273  // Test 3D matrix
1274 
1275  {
1276  int numDim = 3;
1277  double uL[5] = {1, -1, -1, -1, 5.5};
1278  double uR[5] = {2, -4, -4, -4, 20};
1279  double ujump[5];
1280  for (int i=0; i<numDim+2; i++) ujump[i] = uR[i] - uL[i];
1281 
1282  double tmat[25];
1283  double tinv[25];
1284  double lambda[25];
1285 
1286  // > Identity <
1287  // Test the identity Tmat*Tinv = I
1288  for (int iDim=0; iDim<numDim && result; iDim++) {
1289  double norm[3];
1290  for (int i=0; i<numDim; i++) {
1291  if (i == iDim) {
1292  norm[i] = 1;
1293  } else {
1294  norm[i] = 0;
1295  }
1296  }
1297 
1298  FC_MODULE(satutil,sat_form_roe_matrices,SATUTIL,SAT_FORM_ROE_MATRICES)
1299  (&numDim, &uL[0], &uR[0], &gamma, &norm[0], &tmat[0], &tinv[0], &lambda[0]);
1300 
1301  double tmp1[5];
1302  double tmp[5];
1303  WENO::Project(numDim+2, 1, &tinv[0], &ujump[0], &tmp1[0]);
1304  WENO::Project(numDim+2, 1, &tmat[0], &tmp1[0], &tmp[0]);
1305 
1306  result = true;
1307  for (int i=0; i<numDim+2; i++) {
1308  //std::cout << "ujump[" << i << "] = " << ujump[i] << std::endl;
1309  //std::cout << "tmp[" << i << "] = " << tmp[i] << std::endl;
1310  result = result && (std::abs(ujump[i] - tmp[i]) < eps);
1311  }
1312  serialUnitResults.UpdateResult("WENO:Project:Neg:3D:Identity", result);
1313  }
1314 
1315  if (!result) return;
1316 
1317  // > RoeProp <
1318  // Test the identity A_hat [U] = [F], where A_hat = T*Lambda*Tinv
1319  for (int iDim=0; iDim<numDim && result; iDim++) {
1320  double norm[3];
1321  double fL[5];
1322  double fR[5];
1323  double fjump[5];
1324  fL[0] = -1;
1325  fL[numDim+1] = -7.1;
1326  fR[0] = -4;
1327  fR[numDim+1] = -46.4;
1328  for (int i=0; i<numDim; i++) {
1329  if (i == iDim) {
1330  norm[i] = 1;
1331  fL[i+1] = 2.6;
1332  fR[i+1] = 11.2;
1333  } else {
1334  norm[i] = 0;
1335  fL[i+1] = 1;
1336  fR[i+1] = 8;
1337  }
1338  }
1339  for (int i=0; i<numDim+2; i++) fjump[i] = fR[i] - fL[i];
1340 
1341  FC_MODULE(satutil,sat_form_roe_matrices,SATUTIL,SAT_FORM_ROE_MATRICES)
1342  (&numDim, &uL[0], &uR[0], &gamma, &norm[0], &tmat[0], &tinv[0], &lambda[0]);
1343 
1344  double tmp1[5];
1345  double tmp2[5];
1346  double tmp[5];
1347  WENO::Project(numDim+2, 1, &tinv[0], &ujump[0], &tmp1[0]);
1348  WENO::Project(numDim+2, 1, &lambda[0], &tmp1[0], &tmp2[0]);
1349  WENO::Project(numDim+2, 1, &tmat[0], &tmp2[0], &tmp[0]);
1350 
1351  result = true;
1352  for (int i=0; i<numDim+2; i++) {
1353  //std::cout << "fjump[" << i << "] = " << fjump[i] << std::endl;
1354  //std::cout << "tmp[" << i << "] = " << tmp[i] << std::endl;
1355  result = result && (std::abs(fjump[i] - tmp[i]) < eps);
1356  }
1357  serialUnitResults.UpdateResult("WENO:Project:Neg:3D:RoeProp", result);
1358  }
1359  }
1360 
1361  // --- RoeAlt ---
1362  // Test Roe matrix routines with negative background speed
1363  // Assumes Euler equations with ideal gas EOS, no species transport
1364 
1365  // > 2D <
1366  // Test 2D matrix
1367 
1368  {
1369  int numDim = 2;
1370  double uL[4] = {1, 2, 2, 8};
1371  double uR[4] = {2, 6, 6, 26};
1372  double ujump[4];
1373  for (int i=0; i<numDim+2; i++) ujump[i] = uR[i] - uL[i];
1374 
1375  double tmat[16];
1376  double tinv[16];
1377  double lambda[16];
1378 
1379  // > Identity <
1380  // Test the identity Tmat*Tinv = I
1381  for (int iDim=0; iDim<numDim && result; iDim++) {
1382  double norm[2];
1383  for (int i=0; i<numDim; i++) {
1384  if (i == iDim) {
1385  norm[i] = 1;
1386  } else {
1387  norm[i] = 0;
1388  }
1389  }
1390 
1391  FC_MODULE(satutil,sat_form_roe_matrices,SATUTIL,SAT_FORM_ROE_MATRICES)
1392  (&numDim, &uL[0], &uR[0], &gamma, &norm[0], &tmat[0], &tinv[0], &lambda[0]);
1393 
1394  double tmp1[4];
1395  double tmp[4];
1396  WENO::Project(numDim+2, 1, &tinv[0], &ujump[0], &tmp1[0]);
1397  WENO::Project(numDim+2, 1, &tmat[0], &tmp1[0], &tmp[0]);
1398 
1399  result = true;
1400  for (int i=0; i<numDim+2; i++) {
1401  //std::cout << "ujump[" << i << "] = " << ujump[i] << std::endl;
1402  //std::cout << "tmp[" << i << "] = " << tmp[i] << std::endl;
1403  result = result && (std::abs(ujump[i] - tmp[i]) < eps);
1404  }
1405  serialUnitResults.UpdateResult("WENO:Project:Alt:2D:Identity", result);
1406  }
1407 
1408  if (!result) return;
1409 
1410  // > RoeProp <
1411  // Test the identity A_hat [U] = [F], where A_hat = T*Lambda*Tinv
1412  for (int iDim=0; iDim<numDim && result; iDim++) {
1413  double norm[2];
1414  double fL[4];
1415  double fR[4];
1416  double fjump[4];
1417  fL[0] = 2;
1418  fL[numDim+1] = 19.2;
1419  fR[0] = 6;
1420  fR[numDim+1] = 87.6;
1421  for (int i=0; i<numDim; i++) {
1422  if (i == iDim) {
1423  norm[i] = 1;
1424  fL[i+1] = 5.6;
1425  fR[i+1] = 21.2;
1426  } else {
1427  norm[i] = 0;
1428  fL[i+1] = 4;
1429  fR[i+1] = 18;
1430  }
1431  }
1432  for (int i=0; i<numDim+2; i++) fjump[i] = fR[i] - fL[i];
1433 
1434  FC_MODULE(satutil,sat_form_roe_matrices,SATUTIL,SAT_FORM_ROE_MATRICES)
1435  (&numDim, &uL[0], &uR[0], &gamma, &norm[0], &tmat[0], &tinv[0], &lambda[0]);
1436 
1437  double tmp1[4];
1438  double tmp2[4];
1439  double tmp[4];
1440  WENO::Project(numDim+2, 1, &tinv[0], &ujump[0], &tmp1[0]);
1441  WENO::Project(numDim+2, 1, &lambda[0], &tmp1[0], &tmp2[0]);
1442  WENO::Project(numDim+2, 1, &tmat[0], &tmp2[0], &tmp[0]);
1443 
1444  result = true;
1445  for (int i=0; i<numDim+2; i++) {
1446  //std::cout << "fjump[" << i << "] = " << fjump[i] << std::endl;
1447  //std::cout << "tmp[" << i << "] = " << tmp[i] << std::endl;
1448  result = result && (std::abs(fjump[i] - tmp[i]) < eps);
1449  }
1450  serialUnitResults.UpdateResult("WENO:Project:Alt:2D:RoeProp", result);
1451  }
1452 
1453  if (!result) return;
1454  }
1455 
1456  // > 3D <
1457  // Test 3D matrix
1458 
1459  {
1460  int numDim = 3;
1461  double uL[5] = {1, 2, 2, 2, 10};
1462  double uR[5] = {2, 6, 6, 6, 35};
1463  double ujump[5];
1464  for (int i=0; i<numDim+2; i++) ujump[i] = uR[i] - uL[i];
1465 
1466  double tmat[25];
1467  double tinv[25];
1468  double lambda[25];
1469 
1470  // > Identity <
1471  // Test the identity Tmat*Tinv = I
1472  for (int iDim=0; iDim<numDim && result; iDim++) {
1473  double norm[3];
1474  for (int i=0; i<numDim; i++) {
1475  if (i == iDim) {
1476  norm[i] = 1;
1477  } else {
1478  norm[i] = 0;
1479  }
1480  }
1481 
1482  FC_MODULE(satutil,sat_form_roe_matrices,SATUTIL,SAT_FORM_ROE_MATRICES)
1483  (&numDim, &uL[0], &uR[0], &gamma, &norm[0], &tmat[0], &tinv[0], &lambda[0]);
1484 
1485  double tmp1[5];
1486  double tmp[5];
1487  WENO::Project(numDim+2, 1, &tinv[0], &ujump[0], &tmp1[0]);
1488  WENO::Project(numDim+2, 1, &tmat[0], &tmp1[0], &tmp[0]);
1489 
1490  result = true;
1491  for (int i=0; i<numDim+2; i++) {
1492  //std::cout << "ujump[" << i << "] = " << ujump[i] << std::endl;
1493  //std::cout << "tmp[" << i << "] = " << tmp[i] << std::endl;
1494  result = result && (std::abs(ujump[i] - tmp[i]) < eps);
1495  }
1496  serialUnitResults.UpdateResult("WENO:Project:Alt:3D:Identity", result);
1497  }
1498 
1499  if (!result) return;
1500 
1501  // > RoeProp <
1502  // Test the identity A_hat [U] = [F], where A_hat = T*Lambda*Tinv
1503  for (int iDim=0; iDim<numDim && result; iDim++) {
1504  double norm[3];
1505  double fL[5];
1506  double fR[5];
1507  double fjump[5];
1508  fL[0] = 2;
1509  fL[numDim+1] = 23.2;
1510  fR[0] = 6;
1511  fR[numDim+1] = 114.6;
1512  for (int i=0; i<numDim; i++) {
1513  if (i == iDim) {
1514  norm[i] = 1;
1515  fL[i+1] = 5.6;
1516  fR[i+1] = 21.2;
1517  } else {
1518  norm[i] = 0;
1519  fL[i+1] = 4;
1520  fR[i+1] = 18;
1521  }
1522  }
1523  for (int i=0; i<numDim+2; i++) fjump[i] = fR[i] - fL[i];
1524 
1525  FC_MODULE(satutil,sat_form_roe_matrices,SATUTIL,SAT_FORM_ROE_MATRICES)
1526  (&numDim, &uL[0], &uR[0], &gamma, &norm[0], &tmat[0], &tinv[0], &lambda[0]);
1527 
1528  double tmp1[5];
1529  double tmp2[5];
1530  double tmp[5];
1531  WENO::Project(numDim+2, 1, &tinv[0], &ujump[0], &tmp1[0]);
1532  WENO::Project(numDim+2, 1, &lambda[0], &tmp1[0], &tmp2[0]);
1533  WENO::Project(numDim+2, 1, &tmat[0], &tmp2[0], &tmp[0]);
1534 
1535  result = true;
1536  for (int i=0; i<numDim+2; i++) {
1537  //std::cout << "fjump[" << i << "] = " << fjump[i] << std::endl;
1538  //std::cout << "tmp[" << i << "] = " << tmp[i] << std::endl;
1539  result = result && (std::abs(fjump[i] - tmp[i]) < eps);
1540  }
1541  serialUnitResults.UpdateResult("WENO:Project:Alt:3D:RoeProp", result);
1542  }
1543  }
1544 
1545 }
1546 
1547 void TestWENO_EntropyFix(ix::test::results &serialUnitResults) {
1548  // Tests for Roe entropy fix
1549 
1550  bool result = true;
1551  double eps = 1e-15;
1552 
1553  // --- Eta ---
1554  // Tests that entropy fix parameter eta is computed correctly
1555 
1556  int len = 4;
1557  int nCases = 3;
1558  double lambdaL[3][4] = {{1, 2, 2, 3}, {4, 2, 2, 0}, {1, -1, -1, -3}};
1559  double lambdaR[3][4] = {{1.5, 2, 2, 2.5}, {4, 1, 1, -2}, {0, -2, -2, -4}};
1560  double etaExp[3] = {0.25, 1, 0.5};
1561  double lambdaUseL[len*len];
1562  double lambdaUseR[len*len];
1563 
1564  for (int iCase=0; iCase<nCases && result; iCase++) {
1565  for (int i=0; i<len; i++) {
1566  for (int j=0; j<len; j++) {
1567  if (i == j) {
1568  lambdaUseL[i*len+j] = lambdaL[iCase][i];
1569  lambdaUseR[i*len+j] = lambdaR[iCase][i];
1570  } else {
1571  lambdaUseL[i*len+j] = 0;
1572  lambdaUseR[i*len+j] = 0;
1573  }
1574  }
1575  }
1576 
1577  double eta = WENO::EntropyFixEta(len, &lambdaUseL[0], &lambdaUseR[0]);
1578  if (std::abs(eta - etaExp[iCase]) > eps) {
1579  result = false;
1580  std::cout << "Case " << iCase << ", eta (actual/expected) = " << eta << " / " << etaExp[iCase] << std::endl;
1581  }
1582  }
1583 
1584  serialUnitResults.UpdateResult("WENO:EntropyFix:Eta", result);
1585 
1586 }
double pW
Definition: WENO.H:37
int * stencilSizes
The number of weights for each stencil.
Definition: Stencil.H:102
int LoGroup(int group)
Definition: WENO.H:268
double epsW
Definition: WENO.H:36
void TestWENO_Project(ix::test::results &serialUnitResults)
void ReconstPointVal(double vals[], CoeffsWENO &coeffs, int group, double &pVal)
Definition: WENO.C:11
double EntropyFixEta(int n, double lambdaL[], double lambdaR[])
Definition: WENO.C:113
int * stencilStarts
The starting index into the stencilWeight and stencilOffset arrays for each stencil.
Definition: Stencil.H:104
int * stencilOffsets
The offsets wrt the grid point at which the stencil is being applied.
Definition: Stencil.H:106
void TestWENO_EntropyFix(ix::test::results &serialUnitResults)
Encapsulating class for collections of test results.
Definition: Testing.H:18
StencilSet SmIndSecond(int group)
Definition: WENO.H:292
double siSecond
Definition: WENO.H:35
void ReconstPointValSten(double vals[], CoeffsWENO &coeffs, int group, int sten, double &pVal)
Definition: WENO.C:43
StencilSet SmIndFirst(int group)
Definition: WENO.H:286
int HaloWidth()
Definition: WENO.H:257
void Project(int n, int m, double T[], double vals[], double res[])
Definition: WENO.C:89
void TestWENO_SmoothInd(ix::test::results &serialUnitResults)
void size_t int size_t int size_t int int int int double int int double double *void size_t int size_t int int int int int double int size_t size_t size_t double double *void size_t int size_t int size_t size_t int double int double double *void size_t size_t size_t double * a
Testing constructs for unit testing.
void TestWENO_ReconstPointVal(ix::test::results &serialUnitResults)
Encapsulation for a collection of operator stencils.
Definition: Stencil.H:26
int numValues
The total number of weights for all stencils (reqd for Fortran)
Definition: Stencil.H:98
int Lo(int group, int sten)
Definition: WENO.H:272
int NSten(int group)
Definition: WENO.H:264
void UpdateResult(const std::string &name, const ValueType &result)
Updates an existing test result.
Definition: Testing.H:55
StencilSet Reconst(int group)
Definition: WENO.H:280
double * stencilWeights
The stencil weights.
Definition: Stencil.H:108
int nGroup
Definition: WENO.H:31
void TestWENO_ReconstPointValSten(ix::test::results &serialUnitResults)
int numStencils
The number of stencils (e.g. interior + boundary)
Definition: Stencil.H:93
void SmoothInd(double vals[], CoeffsWENO &coeffs, int group, int sten, double &si)
Definition: WENO.C:62
double LinWeight(int group, int sten)
Definition: WENO.H:276
double siFirst
Definition: WENO.H:34
subroutine sat_form_roe_matrices(ND, u_in, u_out, gamma, norm, tmat, tinv, lambda)
Definition: SATUtil.f90:1673
void FC_MODULE(euler, flux1d, EULER, FLUX1D)(const int *numDim
void TestWENO_Stencils(ix::test::results &serialUnitResults)