PFASST++
test_quadrature.cpp
Go to the documentation of this file.
1 /*
2  * Tests for quadrature related routines: nodes and matrices.
3  */
4 #include <iostream>
5 #include <algorithm>
6 #include <iostream>
7 #include <tuple>
8 #include <type_traits>
9 
10 #include <gtest/gtest.h>
11 #include <gmock/gmock.h>
12 
13 #include <Eigen/Dense>
14 
15 using namespace ::testing;
16 
17 #include <pfasst/quadrature.hpp>
18 
19 #include "fixtures/concepts.hpp"
20 
21 using namespace std;
22 using namespace pfasst::quadrature;
23 
24 MATCHER(DoubleNear, "")
25 {
26  return abs(get<0>(arg) - get<1>(arg)) < 1e-15;
27 }
28 
29 TEST(NodesTest, GaussLegendreNodes)
30 {
31  EXPECT_FALSE(GaussLegendre<>(3).left_is_node());
32  EXPECT_FALSE(GaussLegendre<>(3).right_is_node());
33 
34  const long double l3e[3] = { 0.11270166537925831,
35  0.5,
36  0.8872983346207417
37  };
38 
39  const long double l5e[5] = { 0.046910077030668004,
40  0.23076534494715845,
41  0.5,
42  0.7692346550528415,
43  0.953089922969332
44  };
45 
46  const long double l7e[7] = { 0.025446043828620736,
47  0.12923440720030277,
48  0.2970774243113014,
49  0.5,
50  0.7029225756886985,
51  0.8707655927996972,
52  0.9745539561713793
53  };
54 
55  auto l3 = compute_nodes<long double>(3, QuadratureType::GaussLegendre);
56  EXPECT_THAT(l3, Pointwise(DoubleNear(), l3e));
57 
58  auto l5 = compute_nodes<long double>(5, QuadratureType::GaussLegendre);
59  EXPECT_THAT(l5, Pointwise(DoubleNear(), l5e));
60 
61  auto l7 = compute_nodes<long double>(7, QuadratureType::GaussLegendre);
62  EXPECT_THAT(l7, Pointwise(DoubleNear(), l7e));
63 }
64 
65 TEST(NodesTest, GaussLobattoNodes)
66 {
67  EXPECT_TRUE(GaussLobatto<>(3).left_is_node());
68  EXPECT_TRUE(GaussLobatto<>(3).right_is_node());
69 
70  const long double l2e[2] = { 0.0,
71  1.0
72  };
73 
74  const long double l3e[3] = { 0.0,
75  0.5,
76  1.0
77  };
78 
79  const long double l5e[5] = { 0.0,
80  0.17267316464601143,
81  0.5,
82  0.8273268353539885,
83  1.0
84  };
85 
86  const long double l7e[7] = { 0.0,
87  0.08488805186071653,
88  0.2655756032646429,
89  0.5,
90  0.7344243967353571,
91  0.9151119481392834,
92  1.0
93  };
94 
95  const long double l9e[9] = { 0.0,
96  0.05012100229426992,
97  0.16140686024463113,
98  0.3184412680869109,
99  0.5,
100  0.6815587319130891,
101  0.8385931397553689,
102  0.94987899770573,
103  1.0
104  };
105 
106  auto l2 = compute_nodes<long double>(2, QuadratureType::GaussLobatto);
107  EXPECT_THAT(l2, Pointwise(DoubleNear(), l2e));
108 
109  auto l3 = compute_nodes<long double>(3, QuadratureType::GaussLobatto);
110  EXPECT_THAT(l3, Pointwise(DoubleNear(), l3e));
111 
112  auto l5 = compute_nodes<long double>(5, QuadratureType::GaussLobatto);
113  EXPECT_THAT(l5, Pointwise(DoubleNear(), l5e));
114 
115  auto l7 = compute_nodes<long double>(7, QuadratureType::GaussLobatto);
116  EXPECT_THAT(l7, Pointwise(DoubleNear(), l7e));
117 
118  auto l9 = compute_nodes<long double>(9, QuadratureType::GaussLobatto);
119  EXPECT_THAT(l9, Pointwise(DoubleNear(), l9e));
120 }
121 
122 TEST(NodesTest, ClenshawCurtisNodes)
123 {
124  EXPECT_TRUE(ClenshawCurtis<>(3).left_is_node());
125  EXPECT_TRUE(ClenshawCurtis<>(3).right_is_node());
126 
127  const long double cc2e[2] = { 0.0,
128  1.0
129  };
130 
131  const long double cc3e[3] = { 0.0,
132  0.5,
133  1.0
134  };
135 
136  const long double cc5e[5] = { 0.0,
137  0.14644660940672623779957781894757548,
138  0.5,
139  0.85355339059327376220042218105242452,
140  1.0
141  };
142 
143  const long double cc7e[7] = { 0.0,
144  0.066987298107780676618138414623531908,
145  0.25,
146  0.5,
147  0.75,
148  0.93301270189221932338186158537646809,
149  1.0
150  };
151 
152  const long double cc9e[9] = { 0.0,
153  0.038060233744356621935908405301605857,
154  0.14644660940672623779957781894757548,
155  0.30865828381745511413577000798480057,
156  0.5,
157  0.69134171618254488586422999201519943,
158  0.85355339059327376220042218105242452,
159  0.96193976625564337806409159469839414,
160  1.0
161  };
162 
163  auto cc2 = compute_nodes<long double>(2, QuadratureType::ClenshawCurtis);
164  EXPECT_THAT(cc2, Pointwise(DoubleNear(), cc2e));
165 
166  auto cc3 = compute_nodes<long double>(3, QuadratureType::ClenshawCurtis);
167  EXPECT_THAT(cc3, Pointwise(DoubleNear(), cc3e));
168 
169  auto cc5 = compute_nodes<long double>(5, QuadratureType::ClenshawCurtis);
170  EXPECT_THAT(cc5, Pointwise(DoubleNear(), cc5e));
171 
172  auto cc7 = compute_nodes<long double>(7, QuadratureType::ClenshawCurtis);
173  EXPECT_THAT(cc7, Pointwise(DoubleNear(), cc7e));
174 
175  auto cc9 = compute_nodes<long double>(9, QuadratureType::ClenshawCurtis);
176  EXPECT_THAT(cc9, Pointwise(DoubleNear(), cc9e));
177 }
178 
179 TEST(NodesTest, UniformNodes)
180 {
181  EXPECT_TRUE(Uniform<>(3).left_is_node());
182  EXPECT_TRUE(Uniform<>(3).right_is_node());
183 
184  const long double u2e[2] = { 0.0,
185  1.0
186  };
187 
188  const long double u3e[3] = { 0.0,
189  0.5,
190  1.0
191  };
192 
193  const long double u5e[5] = { 0.0,
194  0.25,
195  0.5,
196  0.75,
197  1.0
198  };
199 
200  auto u2 = compute_nodes<long double>(2, QuadratureType::Uniform);
201  EXPECT_THAT(u2, Pointwise(DoubleNear(), u2e));
202 
203  auto u3 = compute_nodes<long double>(3, QuadratureType::Uniform);
204  EXPECT_THAT(u3, Pointwise(DoubleNear(), u3e));
205 
206  auto u5 = compute_nodes<long double>(5, QuadratureType::Uniform);
207  EXPECT_THAT(u5, Pointwise(DoubleNear(), u5e));
208 }
209 
210 
211 TEST(QuadratureTest, GaussLobattoNodes)
212 {
213  Eigen::Matrix<double, 3, 3> s_mat_3 = GaussLobatto<double>(3).get_s_mat();
214  Eigen::Matrix<double, 3, 3> s_mat_3_expected;
215  s_mat_3_expected << 0.0, 0.0, 0.0,
216  0.20833333333333333, 0.33333333333333333, -0.04166666666666666,
217  -0.04166666666666666, 0.33333333333333333, 0.20833333333333333;
218  for (size_t row = 0; row < 3; ++row) {
219  for (size_t col = 0; col < 3; ++col) {
220  EXPECT_THAT(s_mat_3(row, col), ::testing::DoubleNear((s_mat_3_expected(row, col)), (double)(1e-14)));
221  }
222  }
223 
224  Eigen::Matrix<double, 5, 5> s_mat_5 = GaussLobatto<double>(5).get_s_mat();
225  Eigen::Matrix<double, 5, 5> s_mat_5_expected;
226  s_mat_5_expected << 0.0, 0.0, 0.0, 0.0, 0.0,
227  0.067728432186156897969267419174073482, 0.11974476934341168251615379970493965,
228  -0.021735721866558113665511351745074292, 0.010635824225415491883105056997129926,
229  -0.0037001392424145306021611522544979462,
230  -0.027103432186156897969267419174073483, 0.1834394139796310955018131986775051,
231  0.19951349964433589144328912952285207, -0.041597785326236047678849833157352459,
232  0.013075139242414530602161152254497946,
233  0.013075139242414530602161152254497944, -0.041597785326236047678849833157352467,
234  0.19951349964433589144328912952285207, 0.1834394139796310955018131986775051,
235  -0.027103432186156897969267419174073483,
236  -0.0037001392424145306021611522544979483, 0.010635824225415491883105056997129916,
237  -0.021735721866558113665511351745074289, 0.11974476934341168251615379970493965,
238  0.067728432186156897969267419174073482;
239 
240  for (size_t row = 0; row < 5; ++row) {
241  for (size_t col = 0; col < 5; ++col) {
242  EXPECT_THAT(s_mat_5(row, col), ::testing::DoubleNear((s_mat_5_expected(row, col)), (double)(1e-14)));
243  }
244  }
245 
246  Eigen::Matrix<double, 5, 5> q_mat_5 = GaussLobatto<double>(5).get_q_mat();
247  vector<double> q_vec = GaussLobatto<double>(5).get_q_vec();
248 
249  for (size_t col = 0; col < 5; ++col) {
250  EXPECT_THAT(q_vec[col], ::testing::DoubleEq(q_mat_5(4, col)));
251  }
252 }
253 
254 TEST(QuadratureTest, ClenshawCurtisNodes)
255 {
256  Eigen::Matrix<double, 4, 4> s_mat_4 = ClenshawCurtis<double>(4).get_s_mat();
257  Eigen::Matrix<double, 4, 4> s_mat_4_expected;
258  s_mat_4_expected << 0.0, 0.0, 0.0, 0.0,
259  0.10243055555555555555555555555555556, 0.16319444444444444444444444444444444,
260  -0.024305555555555555555555555555555556, 0.0086805555555555555555555555555555557,
261  -0.055555555555555555555555555555555556, 0.30555555555555555555555555555555556,
262  0.30555555555555555555555555555555556, -0.055555555555555555555555555555555556,
263  0.0086805555555555555555555555555555545, -0.024305555555555555555555555555555554,
264  0.16319444444444444444444444444444444, 0.10243055555555555555555555555555556;
265 
266  for (size_t row = 0; row < 4; ++row) {
267  for (size_t col = 0; col < 4; ++col) {
268  EXPECT_THAT(s_mat_4(row, col), ::testing::DoubleNear((s_mat_4_expected(row, col)), (double)(1e-14)));
269  }
270  }
271 }
272 
273 
274 class QmatTest
275  : public ::TestWithParam<tuple<size_t, QuadratureType>>
276 {
277  protected:
278  size_t nnodes;
280  shared_ptr<IQuadrature<long double>> quad;
281 
282  public:
283  virtual void SetUp()
284  {
285  nnodes = get<0>(GetParam());
286  qtype = get<1>(GetParam());
287 
288  this->quad = quadrature_factory<long double>(nnodes, qtype);
289 
290  cout << "Quadrature type no. " << int(qtype) << " -- Number of nodes " << nnodes << endl;
291  }
292 };
293 
294 TEST_P(QmatTest, AllNodes)
295 {
296  for (int m = 0; m < this->quad->get_q_mat().rows(); ++m) {
297  long double qsum = 0;
298  for (int j = 0; j < this->quad->get_q_mat().cols(); ++j) {
299  qsum += this->quad->get_q_mat()(m,j);
300  }
301  EXPECT_NEAR(qsum, this->quad->get_nodes()[m], (long double)(3E-12));
302  }
303 }
304 
305 
307  ::Combine(::Range<size_t>(2, 14),
308  Values<QuadratureType>(QuadratureType::GaussLegendre,
309  QuadratureType::GaussLobatto,
310  QuadratureType::GaussRadau,
311  QuadratureType::ClenshawCurtis,
312  QuadratureType::Uniform)));
313 
314 
315 typedef ::testing::Types<GaussLegendre<>,
317  GaussRadau<>,
320 INSTANTIATE_TYPED_TEST_CASE_P(Quadrature, ConceptsTest, QuadratureTypes);
321 
322 
323 int main(int argc, char** argv)
324 {
325  InitGoogleTest(&argc, argv);
326  return RUN_ALL_TESTS();
327 }
virtual void SetUp()
shared_ptr< IQuadrature< long double > > quad
INSTANTIATE_TEST_CASE_P(Quadrature, QmatTest,::Combine(::Range< size_t >(2, 14), Values< QuadratureType >(QuadratureType::GaussLegendre, QuadratureType::GaussLobatto, QuadratureType::GaussRadau, QuadratureType::ClenshawCurtis, QuadratureType::Uniform)))
INSTANTIATE_TYPED_TEST_CASE_P(Quadrature, ConceptsTest, QuadratureTypes)
Quadrature handler for Clenshaw-Curtis quadrature.
QuadratureType
Quadrature type descriptors.
Definition: interface.hpp:32
Quadrature handler for uniform distributed nodes.
Definition: uniform.hpp:23
MATCHER(DoubleNear,"")
STL namespace.
QuadratureType qtype
Quadrature handler for Gauss-Lobatto quadrature.
Quadrature handler for Gauss-Radau quadrature.
Definition: gauss_radau.hpp:23
::testing::Types< GaussLegendre<>, GaussLobatto<>, GaussRadau<>, ClenshawCurtis<>, Uniform<> > QuadratureTypes
Functionality related to computing quadrature nodes and weights.
Quadrature handler for Gauss-Legendre quadrature.
TEST_P(QmatTest, AllNodes)
TEST(NodesTest, GaussLegendreNodes)
int main(int argc, char **argv)