88
99using namespace ::testing;
1010
11+ #include < pfasst/quadrature.hpp>
12+
1113#define PFASST_UNIT_TESTING
1214#include " ../examples/scalar/scalar_sdc.cpp"
1315#undef PFASST_UNIT_TESTING
@@ -16,76 +18,81 @@ using namespace ::testing;
1618 * parameterized test fixture with number of nodes as parameter
1719 */
1820class ConvergenceTest
19- : public ::testing:: TestWithParam<size_t >
21+ : public TestWithParam<tuple< size_t , pfasst::QuadratureType> >
2022{
2123 protected:
2224 size_t nnodes; // parameter
2325
24- complex <double > lambda = complex < double >(- 1.0 , 1.0 ) ;
25- double Tend = 4.0 ;
26- vector<size_t > nsteps = { 2 , 5 , 10 , 15 , 20 } ;
26+ complex <double > lambda;
27+ double Tend;
28+ vector<size_t > nsteps;
2729 size_t nsteps_l;
2830 vector<double > err;
29- vector<double > convrate_lobatto;
30- vector<double > convrate_legendre;
31+ vector<double > convrate;
3132 double dt;
3233 size_t niters;
33- pfasst::QuadratureType nodetype = pfasst::QuadratureType::GaussLobatto;
34+ pfasst::QuadratureType nodetype;
35+ size_t nnodes_in_call;
36+
37+ // set parameters base on node type
38+ void set_parameters ()
39+ {
40+ switch (this ->nodetype )
41+ {
42+ case pfasst::QuadratureType::GaussLobatto:
43+ this ->niters = 2 * this ->nnodes - 2 ;
44+ this ->Tend = 4.0 ;
45+ this ->lambda = complex <double >(-1.0 , 1.0 );
46+ this ->nsteps = { 2 , 5 , 10 , 15 , 20 };
47+ this ->nnodes_in_call = this ->nnodes ;
48+ break ;
49+
50+ case pfasst::QuadratureType::GaussLegendre:
51+ this ->niters = 2 * this ->nnodes ;
52+ this ->Tend = 6.0 ;
53+ this ->lambda = complex <double >(-1.0 , 2.0 );
54+ this ->nsteps = { 2 , 4 , 6 , 8 , 10 };
55+ this ->nnodes_in_call = this ->nnodes + 2 ;
56+ break ;
57+
58+ /*
59+ case pfasst::QuadratureType::GaussRadau:
60+ break;
61+
62+ case pfasst::QuadratureType::ClenshawCurtis:
63+ break;
64+
65+ case pfasst::QuadratureType::Uniform:
66+ break;
67+ */
68+
69+ default :
70+ break ;
71+ }
72+ }
3473
3574 public:
3675 virtual void SetUp ()
3776 {
38- this ->nnodes = this ->GetParam ();
77+ this ->nnodes = get<0 >(GetParam ());
78+ this ->nodetype = get<1 >(GetParam ());
79+ this ->set_parameters ();
3980 this ->nsteps_l = this ->nsteps .size ();
4081 this ->err .resize (this ->nsteps .size ());
41- this ->convrate_lobatto .resize (this ->nsteps .size ());
42-
43- // Run first for Lobatto nodes which is the default nodetype
44-
45- // Expect convergence rate of 2*nodes-2 from collocation formula,
46- // doing an identical number of iteration should suffice to reach this as each
47- // iteration should increase order by one
48- this ->niters = 2 * nnodes - 2 ;
82+ this ->convrate .resize (this ->nsteps .size ());
4983
5084 // run to compute errors
51- for (size_t i = 0 ; i <= nsteps_l - 1 ; ++i) {
52- dt = Tend / double (nsteps[i]);
53- err[i] = run_scalar_sdc (nsteps[i], dt, nnodes, niters, lambda, nodetype);
85+ for (size_t i = 0 ; i <= this ->nsteps_l - 1 ; ++i) {
86+ this ->dt = this ->Tend / double (this ->nsteps [i]);
87+ this ->err [i] = run_scalar_sdc (this ->nsteps [i], this ->dt , this ->nnodes_in_call ,
88+ this ->niters , this ->lambda , this ->nodetype );
5489 }
5590
5691 // compute convergence rates
57- for (size_t i = 0 ; i <= nsteps_l - 2 ; ++i) {
58- convrate_lobatto[i] = log10 (err[i+1 ] / err[i]) / log10 (double (nsteps[i]) / double (nsteps[i + 1 ]));
92+ for (size_t i = 0 ; i <= this ->nsteps_l - 2 ; ++i) {
93+ this ->convrate [i] = log10 (this ->err [i+1 ] / this ->err [i]) /
94+ log10 (double (this ->nsteps [i]) / double (this ->nsteps [i + 1 ]));
5995 }
60-
61- /*
62- * Compute convergence rates for Legendre nodes.
63- * Note that this is not a particularly nice way to do the test, because both types
64- * of nodes are tested in the same test. Having separate tests would be nicer...
65- */
66- nodetype = pfasst::QuadratureType::GaussLegendre;
67- this ->convrate_legendre .resize (this ->nsteps .size ());
68-
69- // refine parameter
70- complex <double > lambda = complex <double >(-1.0 , 2.0 );
71- this ->Tend = 6.0 ;
72- this ->nsteps = { 2 , 4 , 6 , 8 , 10 };
73- this ->niters = 2 *nnodes;
74-
75- // run to compute errors
76- for (size_t i = 0 ; i <= nsteps_l - 1 ; ++i) {
77- dt = Tend / double (nsteps[i]);
78-
79- // NOTE: Setting M for Legendre nodes actually only results in M-2 "real" nodes,
80- // because the first and the last are used for initial and final value.
81- // Hence us nnodes+2 as argument
82- err[i] = run_scalar_sdc (nsteps[i], dt, nnodes+2 , niters, lambda, nodetype);
83- }
84-
85- for (size_t i = 0 ; i <= nsteps_l - 2 ; ++i) {
86- convrate_legendre[i] = log10 (err[i+1 ] / err[i]) / log10 (double (nsteps[i]) / double (nsteps[i + 1 ]));
87- }
88-
8996 }
9097
9198 virtual void TearDown ()
@@ -94,29 +101,62 @@ class ConvergenceTest
94101
95102/*
96103 * The test below verifies that the code approximately (up to a safety factor) reproduces
97- * the theoretically expected rate of convergence for Lobatto and Legendre nodes
104+ * the theoretically expected rate of convergence
98105 */
99106TEST_P (ConvergenceTest, GaussNodes)
100107{
101108 for (size_t i = 0 ; i <= nsteps_l - 2 ; ++i) {
109+ switch (this ->nodetype )
110+ {
111+ case pfasst::QuadratureType::GaussLobatto:
112+ // Expect convergence rate of 2*nodes-2 from collocation formula, doing an identical number
113+ // of iteration should suffice to reach this as each iteration should increase order by one
114+ EXPECT_THAT (convrate[i],
115+ DoubleNear (double (2 * nnodes - 2 ), 0.99 )) << " Convergence rate for "
116+ << this ->nnodes
117+ << " Gauss-Lobatto nodes "
118+ << " at node " << i
119+ << " not within expected range." ;
120+ break ;
121+
122+ case pfasst::QuadratureType::GaussLegendre:
123+ // convergence rates for Legendre nodes should be 2*nodes but are actually better, so
124+ // use Ge here
125+ EXPECT_THAT (convrate[i], Ge<double >(2 * this ->nnodes )) << " Convergence rate for "
126+ << this ->nnodes
127+ << " Gauss-Legendre nodes "
128+ << " at node " << i
129+ << " not within expected range." ;
130+ break ;
102131
103- // Lobatto nodes reproduce the convergence rate quite accurately, so use DoubleNear
104- EXPECT_THAT (convrate_lobatto[i],
105- testing::DoubleNear (double (2 * nnodes - 2 ), 0.99 )) << " Convergence rate at node "
106- << i
107- << " not within expected range" ;
108-
109- // convergence rates for Legendre nodes should be 2*nodes but are actually better, so
110- // use Ge here
111- EXPECT_THAT (convrate_legendre[i],
112- testing::Ge (double (2 * nnodes))) << " Convergence rate at node "
113- << i
114- << " not within expected range" ;
132+ /*
133+ case pfasst::QuadratureType::GaussRadau:
134+ break;
115135
136+ case pfasst::QuadratureType::ClenshawCurtis:
137+ break;
138+
139+ case pfasst::QuadratureType::Uniform:
140+ break;
141+ */
142+
143+ default :
144+ EXPECT_TRUE (false );
145+ break ;
146+ }
116147 }
117148}
118149
119- INSTANTIATE_TEST_CASE_P (ScalarSDC, ConvergenceTest, Range<size_t >(2 , 7 ));
150+
151+ INSTANTIATE_TEST_CASE_P (ScalarSDC, ConvergenceTest,
152+ Combine (Range<size_t >(2 , 7 ),
153+ Values(pfasst::QuadratureType::GaussLobatto,
154+ pfasst::QuadratureType::GaussLegendre/* ,
155+ pfasst::QuadratureType::GaussRadau,
156+ pfasst::QuadratureType::ClenshawCurtis,
157+ pfasst::QuadratureType::Uniform*/ ))
158+ );
159+
120160
121161int main (int argc, char ** argv)
122162{
0 commit comments