Skip to content

Commit 8926751

Browse files
author
Daniel Ruprecht
committed
Merge pull request #1 from torbjoernk/feature/parameterized-scalar-tests
tests: scalar: Yo Dawg, I herd you like better tests
2 parents ad2bcee + 5497418 commit 8926751

File tree

2 files changed

+115
-66
lines changed

2 files changed

+115
-66
lines changed

include/pfasst/quadrature.hpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,8 +160,17 @@ namespace pfasst
160160
return p2;
161161
}
162162
};
163-
164-
enum class QuadratureType { GaussLegendre, GaussLobatto, GaussRadau, ClenshawCurtis, Uniform };
163+
164+
165+
enum class QuadratureType {
166+
GaussLegendre
167+
, GaussLobatto
168+
, GaussRadau
169+
, ClenshawCurtis
170+
, Uniform
171+
};
172+
173+
165174
template<typename node = time_precision>
166175
vector<node> compute_nodes(size_t nnodes, QuadratureType qtype)
167176
{

tests/examples/scalar/test_scalar.cpp

Lines changed: 104 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
using 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
*/
1820
class 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
*/
99106
TEST_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

121161
int main(int argc, char** argv)
122162
{

0 commit comments

Comments
 (0)