|
1 | 1 | /* |
2 | 2 | * Tests for the scalar example solving the test equation |
3 | 3 | */ |
4 | | - |
| 4 | + |
| 5 | +#include <cmath> |
5 | 6 | #include <gtest/gtest.h> |
6 | 7 | #include <gmock/gmock.h> |
7 | 8 |
|
8 | 9 | #define PFASST_UNIT_TESTING |
9 | 10 | #include "../examples/scalar/scalar_sdc.cpp" |
10 | 11 | #undef PFASST_UNIT_TESTING |
11 | 12 |
|
| 13 | +MATCHER (DoubleMore, "") |
| 14 | +{ |
| 15 | + return get<0>(arg) > get<1>(arg); |
| 16 | +} |
| 17 | + |
| 18 | +/* |
| 19 | + * For Lobatto nodes, the resulting method should of order 2*M-2 with M=number of nodes |
| 20 | + * The test below verifies that the code approximately (up to a safety factor) reproduces |
| 21 | + * the theoretically expected rate of convergence |
| 22 | + */ |
| 23 | +TEST(ConvergenceTest, ScalarSDC) |
| 24 | +{ |
| 25 | + |
| 26 | + const complex<double> lambda = complex<double>(-1.0, 1.0); |
| 27 | + const double Tend = 4.0; |
| 28 | + const vector<int> nsteps = { 2, 5, 10, 15, 20 }; |
| 29 | + int nsteps_l = nsteps.size(); |
| 30 | + |
| 31 | + vector<double> err(nsteps.size()); |
| 32 | + vector<double> convrate(nsteps.size()-1); |
| 33 | + vector<double> expected_cr(nsteps.size()-1); |
| 34 | + |
| 35 | + double dt; |
| 36 | + |
| 37 | + // Test converge up to 6 nodes: For more nodes, errors are of the order of machine |
| 38 | + // precision and convergence can no longer be monitored |
| 39 | + for ( int nnodes = 2; nnodes<=6; ++nnodes) |
| 40 | + { |
| 41 | + // Expect convergence rate of 2*nodes-2 from collocation formula, |
| 42 | + // doing an identical number of iteration should suffice to reach this as each |
| 43 | + // iteration should increase order by one |
| 44 | + int niters = 2*nnodes-2; |
| 45 | + |
| 46 | + for ( int i = 0; i<=nsteps_l-1; ++i) |
| 47 | + { |
| 48 | + dt = Tend/double(nsteps[i]); |
| 49 | + err[i] = run_scalar_sdc(nsteps[i], dt, nnodes, niters, lambda); |
| 50 | + } |
| 51 | + |
| 52 | + for (int i = 0; i<=nsteps_l-2; ++i) |
| 53 | + { |
| 54 | + convrate[i] = log10(err[i+1]/err[i])/log10(double(nsteps[i])/double(nsteps[i+1])); |
| 55 | + // The expected convergence rate for Lobatto nodes is 2*nnodes-2, but because |
| 56 | + // it will typically be not matched exactly, put in a security factor |
| 57 | + expected_cr[i] = 0.9*double(2*nnodes-2); |
| 58 | + } |
| 59 | + |
| 60 | + // NOTE: There is probably a much more elegant way to test this, because |
| 61 | + // expected_cr contains the same value in all entries. But I could not so far figure |
| 62 | + // out how to build a more clever MATCHER here so far.... |
| 63 | + EXPECT_THAT(convrate, testing::Pointwise(DoubleMore(), expected_cr )); |
| 64 | + |
| 65 | + } |
| 66 | +} |
| 67 | + |
12 | 68 | int main(int argc, char** argv) |
13 | 69 | { |
14 | 70 | testing::InitGoogleTest(&argc, argv); |
|
0 commit comments