PFASST++
test_boris_particle_util.cpp
Go to the documentation of this file.
1 #include <memory>
2 #include <random>
3 #include <type_traits>
4 using namespace std;
5 
6 #include <gtest/gtest.h>
7 #include <gmock/gmock.h>
8 using namespace ::testing;
9 
10 #include "../examples/boris/particle.hpp"
11 #include "../examples/boris/particle_cloud.hpp"
12 #include "../examples/boris/particle_util.hpp"
13 using namespace pfasst::examples::boris;
14 
15 #define DIMS 3
16 #define PRECISION double
17 
19 {
20  static default_random_engine rd_gen;
21  static uniform_real_distribution<PRECISION> dist;
22 
23  static PRECISION roll()
24  {
25  return dist(rd_gen);
26  }
27 };
28 
29 default_random_engine RandomGenerator::rd_gen = default_random_engine(42);
30 uniform_real_distribution<PRECISION> RandomGenerator::dist = uniform_real_distribution<PRECISION>(-10.0, 10.0);
31 
32 
34 {
35  for (auto&& elem : vec) {
36  elem = RandomGenerator::roll();
37  }
38 }
39 
40 #define create_single(name, num)\
41  ParticleComponent<PRECISION> name(num)
42 #define create_and_fill_single(name, num)\
43  create_single(name, num);\
44  fill_single(name)
45 #define create_cloud(name, num)\
46  create_single(name, num * DIMS)
47 #define create_and_fill_cloud(name, num)\
48  create_and_fill_single(name, num * DIMS)
49 
50 
51 TEST(OperatorTests, AddSingleOnSingle)
52 {
53  create_and_fill_single(first_single, DIMS);
54  create_and_fill_single(second_single, DIMS);
55  create_single(expected_single, DIMS);
56  for(size_t i = 0; i < DIMS; ++i) {
57  expected_single[i] = first_single[i] + second_single[i];
58  }
59  ParticleComponent<PRECISION> result_single = first_single + second_single;
60  EXPECT_THAT(result_single, Pointwise(Eq(), expected_single));
61 }
62 
63 TEST(OperatorTests, AddCloudOnCloud)
64 {
65  create_and_fill_cloud(first_cloud, 5);
66  create_and_fill_cloud(second_cloud, 5);
67  create_cloud(expected_cloud, 5);
68  for (size_t i = 0; i < 5; ++i) {
69  for (size_t j = 0; j < DIMS; ++j) {
70  expected_cloud[i * DIMS + j] = first_cloud[i * DIMS + j] + second_cloud[i * DIMS + j];
71  }
72  }
73  ParticleCloudComponent<PRECISION> result_cloud = first_cloud + second_cloud;
74  EXPECT_THAT(result_cloud, Pointwise(Eq(), expected_cloud));
75 }
76 
77 TEST(OperatorTests, AddSingleOnCloud)
78 {
79  create_and_fill_cloud(cloud, 5);
81  create_cloud(expected_cloud, 5);
82  for (size_t i = 0; i < 5; ++i) {
83  for (size_t j = 0; j < DIMS; ++j) {
84  expected_cloud[i * DIMS + j] = cloud[i * DIMS + j] + single[j];
85  }
86  }
87  ParticleCloudComponent<PRECISION> result_cloud = cloud + single;
88  EXPECT_THAT(result_cloud, Pointwise(Eq(), expected_cloud));
89 }
90 
91 TEST(OperatorTests, InplaceAddSingleOnSingle)
92 {
93  create_and_fill_single(first_single, DIMS);
94  create_and_fill_single(second_single, DIMS);
95  create_single(expected_single, DIMS);
96  for(size_t i = 0; i < DIMS; ++i) {
97  expected_single[i] = first_single[i] + second_single[i];
98  }
99  first_single += second_single;
100  EXPECT_THAT(first_single, Pointwise(Eq(), expected_single));
101 }
102 
103 TEST(OperatorTests, InplaceAddCloudOnCloud)
104 {
105  create_and_fill_cloud(first_cloud, 5);
106  create_and_fill_cloud(second_cloud, 5);
107  create_cloud(expected_cloud, 5);
108  for (size_t i = 0; i < 5; ++i) {
109  for (size_t j = 0; j < DIMS; ++j) {
110  expected_cloud[i * DIMS + j] = first_cloud[i * DIMS + j] + second_cloud[i * DIMS + j];
111  }
112  }
113  first_cloud += second_cloud;
114  EXPECT_THAT(first_cloud, Pointwise(Eq(), expected_cloud));
115 }
116 
117 TEST(OperatorTests, InplaceAddSingleOnCloud)
118 {
119  create_and_fill_cloud(cloud, 5);
120  create_and_fill_single(single, DIMS);
121  create_cloud(expected_cloud, 5);
122  for (size_t i = 0; i < 5; ++i) {
123  for (size_t j = 0; j < DIMS; ++j) {
124  expected_cloud[i * DIMS + j] = cloud[i * DIMS + j] + single[j];
125  }
126  }
127  cloud += single;
128  EXPECT_THAT(cloud, Pointwise(Eq(), expected_cloud));
129 }
130 
131 TEST(OperatorTests, MinusSingleOnSingle)
132 {
133  create_and_fill_single(first_single, DIMS);
134  create_and_fill_single(second_single, DIMS);
135  create_single(expected_single, DIMS);
136  for(size_t i = 0; i < DIMS; ++i) {
137  expected_single[i] = first_single[i] - second_single[i];
138  }
139  ParticleComponent<PRECISION> result_single = first_single - second_single;
140  EXPECT_THAT(result_single, Pointwise(Eq(), expected_single));
141 }
142 
143 TEST(OperatorTests, MinusCloudOnCloud)
144 {
145  create_and_fill_cloud(first_cloud, 5);
146  create_and_fill_cloud(second_cloud, 5);
147  create_cloud(expected_cloud, 5);
148  for (size_t i = 0; i < 5; ++i) {
149  for (size_t j = 0; j < DIMS; ++j) {
150  expected_cloud[i * DIMS + j] = first_cloud[i * DIMS + j] - second_cloud[i * DIMS + j];
151  }
152  }
153  ParticleCloudComponent<PRECISION> result_cloud = first_cloud - second_cloud;
154  EXPECT_THAT(result_cloud, Pointwise(Eq(), expected_cloud));
155 }
156 
157 TEST(OperatorTests, MinusSingleOnCloud)
158 {
159  create_and_fill_cloud(cloud, 5);
160  create_and_fill_single(single, DIMS);
161  create_cloud(expected_cloud, 5);
162  for (size_t i = 0; i < 5; ++i) {
163  for (size_t j = 0; j < DIMS; ++j) {
164  expected_cloud[i * DIMS + j] = cloud[i * DIMS + j] - single[j];
165  }
166  }
167  ParticleCloudComponent<PRECISION> result_cloud = cloud - single;
168  EXPECT_THAT(result_cloud, Pointwise(Eq(), expected_cloud));
169 }
170 
171 TEST(OperatorTests, InplaceMinusSingleOnSingle)
172 {
173  create_and_fill_single(first_single, DIMS);
174  create_and_fill_single(second_single, DIMS);
175  create_single(expected_single, DIMS);
176  for(size_t i = 0; i < DIMS; ++i) {
177  expected_single[i] = first_single[i] - second_single[i];
178  }
179  first_single -= second_single;
180  EXPECT_THAT(first_single, Pointwise(Eq(), expected_single));
181 }
182 
183 TEST(OperatorTests, InplaceMinusCloudOnCloud)
184 {
185  create_and_fill_cloud(first_cloud, 5);
186  create_and_fill_cloud(second_cloud, 5);
187  create_cloud(expected_cloud, 5);
188  for (size_t i = 0; i < 5; ++i) {
189  for (size_t j = 0; j < DIMS; ++j) {
190  expected_cloud[i * DIMS + j] = first_cloud[i * DIMS + j] - second_cloud[i * DIMS + j];
191  }
192  }
193  first_cloud -= second_cloud;
194  EXPECT_THAT(first_cloud, Pointwise(Eq(), expected_cloud));
195 }
196 
197 TEST(OperatorTests, InplaceMinusSingleOnCloud)
198 {
199  create_and_fill_cloud(cloud, 5);
200  create_and_fill_single(single, DIMS);
201  create_cloud(expected_cloud, 5);
202  for (size_t i = 0; i < 5; ++i) {
203  for (size_t j = 0; j < DIMS; ++j) {
204  expected_cloud[i * DIMS + j] = cloud[i * DIMS + j] - single[j];
205  }
206  }
207  cloud -= single;
208  EXPECT_THAT(cloud, Pointwise(Eq(), expected_cloud));
209 }
210 
211 TEST(OperatorTests, MulWithSingle)
212 {
213  create_and_fill_single(single, DIMS);
214  PRECISION value = 2.0;
215  create_single(expected_single, DIMS);
216  for(size_t i = 0; i < DIMS; ++i) {
217  expected_single[i] = single[i] * value;
218  }
219  ParticleComponent<PRECISION> result_single1 = single * value;
220  EXPECT_THAT(result_single1, Pointwise(Eq(), expected_single));
221  ParticleComponent<PRECISION> result_single2 = value * single;
222  EXPECT_THAT(result_single2, Pointwise(Eq(), expected_single));
223 }
224 
225 TEST(OperatorTests, MulWithCloud)
226 {
227  create_and_fill_cloud(cloud, 5);
228  PRECISION value = 2.0;
229  create_cloud(expected_cloud, 5);
230  for (size_t i = 0; i < 5; ++i) {
231  for (size_t j = 0; j < DIMS; ++j) {
232  expected_cloud[i * DIMS + j] = cloud[i * DIMS + j] * value;
233  }
234  }
235  ParticleCloudComponent<PRECISION> result_cloud1 = cloud * value;
236  EXPECT_THAT(result_cloud1, Pointwise(Eq(), expected_cloud));
237  ParticleCloudComponent<PRECISION> result_cloud2 = value * cloud;
238  EXPECT_THAT(result_cloud2, Pointwise(Eq(), expected_cloud));
239 }
240 
241 TEST(OperatorTests, InplaceMulWithSingle)
242 {
243  create_and_fill_single(single, DIMS);
244  PRECISION value = 2.0;
245  create_single(expected_single, DIMS);
246  for(size_t i = 0; i < DIMS; ++i) {
247  expected_single[i] = single[i] * value;
248  }
249  single *= value;
250  EXPECT_THAT(single, Pointwise(Eq(), expected_single));
251 }
252 
253 TEST(OperatorTests, InplaceMulWithCloud)
254 {
255  create_and_fill_cloud(cloud, 5);
256  PRECISION value = 2.0;
257  create_cloud(expected_cloud, 5);
258  for (size_t i = 0; i < 5; ++i) {
259  for (size_t j = 0; j < DIMS; ++j) {
260  expected_cloud[i * DIMS + j] = cloud[i * DIMS + j] * value;
261  }
262  }
263  cloud *= value;
264  EXPECT_THAT(cloud, Pointwise(Eq(), expected_cloud));
265 }
266 
267 TEST(OperatorTests, DivWithSingle)
268 {
269  create_and_fill_single(single, DIMS);
270  PRECISION value = 2.0;
271  create_single(expected_single, DIMS);
272  for(size_t i = 0; i < DIMS; ++i) {
273  expected_single[i] = single[i] / value;
274  }
275  ParticleComponent<PRECISION> result_single = single / value;
276  EXPECT_THAT(result_single, Pointwise(Eq(), expected_single));
277 }
278 
279 TEST(OperatorTests, DivWithCloud)
280 {
281  create_and_fill_cloud(cloud, 5);
282  PRECISION value = 2.0;
283  create_cloud(expected_cloud, 5);
284  for (size_t i = 0; i < 5; ++i) {
285  for (size_t j = 0; j < DIMS; ++j) {
286  expected_cloud[i * DIMS + j] = cloud[i * DIMS + j] / value;
287  }
288  }
289  ParticleCloudComponent<PRECISION> result_cloud = cloud / value;
290  EXPECT_THAT(result_cloud, Pointwise(Eq(), expected_cloud));
291 }
292 
293 TEST(OperatorTests, InplaceDivWithSingle)
294 {
295  create_and_fill_single(single, DIMS);
296  PRECISION value = 2.0;
297  create_single(expected_single, DIMS);
298  for(size_t i = 0; i < DIMS; ++i) {
299  expected_single[i] = single[i] / value;
300  }
301  single /= value;
302  EXPECT_THAT(single, Pointwise(Eq(), expected_single));
303 }
304 
305 TEST(OperatorTests, InplaceDivWithCloud)
306 {
307  create_and_fill_cloud(cloud, 5);
308  PRECISION value = 2.0;
309  create_cloud(expected_cloud, 5);
310  for (size_t i = 0; i < 5; ++i) {
311  for (size_t j = 0; j < DIMS; ++j) {
312  expected_cloud[i * DIMS + j] = cloud[i * DIMS + j] / value;
313  }
314  }
315  cloud /= value;
316  EXPECT_THAT(cloud, Pointwise(Eq(), expected_cloud));
317 }
318 
319 TEST(OperatorTests, CrossProdSingleOnSingle)
320 {
321  create_and_fill_single(first_single, DIMS);
322  create_and_fill_single(second_single, DIMS);
323  create_single(expected_single, DIMS);
324  expected_single[0] = first_single[1] * second_single[2] - first_single[2] * second_single[1];
325  expected_single[1] = first_single[2] * second_single[0] - first_single[0] * second_single[2];
326  expected_single[2] = first_single[0] * second_single[1] - first_single[1] * second_single[0];
327 
328  ParticleComponent<PRECISION> result_single = cross_prod(first_single, second_single);
329  EXPECT_THAT(result_single, Pointwise(Eq(), expected_single));
330 }
331 
332 TEST(OperatorTests, CrossProdCloudOnCloud)
333 {
334  create_and_fill_cloud(first_cloud, 5);
335  create_and_fill_cloud(second_cloud, 5);
336  create_cloud(expected_cloud, 5);
337  for (size_t i = 0; i < 5; ++i) {
338  expected_cloud[i * DIMS] = first_cloud[i * DIMS + 1] * second_cloud[i * DIMS + 2] - first_cloud[i * DIMS + 2] * second_cloud[i * DIMS + 1];
339  expected_cloud[i * DIMS + 1] = first_cloud[i * DIMS + 2] * second_cloud[i * DIMS] - first_cloud[i * DIMS] * second_cloud[i * DIMS + 2];
340  expected_cloud[i * DIMS + 2] = first_cloud[i * DIMS] * second_cloud[i * DIMS + 1] - first_cloud[i * DIMS + 1] * second_cloud[i * DIMS];
341  }
342  ParticleCloudComponent<PRECISION> result_cloud = cross_prod(first_cloud, second_cloud);
343  EXPECT_THAT(result_cloud, Pointwise(Eq(), expected_cloud));
344 }
345 
346 TEST(OperatorTests, CrossProdSingleOnCloud)
347 {
348  create_and_fill_cloud(cloud, 5);
349  create_and_fill_single(single, DIMS);
350  create_cloud(expected_cloud, 5);
351  for (size_t i = 0; i < 5; ++i) {
352  expected_cloud[i * DIMS] = cloud[i * DIMS + 1] * single[2] - cloud[i * DIMS + 2] * single[1];
353  expected_cloud[i * DIMS + 1] = cloud[i * DIMS + 2] * single[0] - cloud[i * DIMS] * single[2];
354  expected_cloud[i * DIMS + 2] = cloud[i * DIMS] * single[1] - cloud[i * DIMS + 1] * single[0];
355  }
356  ParticleCloudComponent<PRECISION> result_cloud = cross_prod(cloud, single);
357  EXPECT_THAT(result_cloud, Pointwise(Eq(), expected_cloud));
358 }
359 
360 
361 TEST(UtilitiesTests, DistanceBetweenTwoParticles)
362 {
363  Particle<PRECISION> first_particle(DIMS);
364  create_and_fill_single(first_single, DIMS);
365  first_particle.pos() = first_single;
366  Particle<PRECISION> second_particle(DIMS);
367  create_and_fill_single(second_single, DIMS);
368  second_particle.pos() = second_single;
369  PRECISION expected_distance = 0.0;
370  for (size_t i = 0; i < DIMS; ++i) {
371  expected_distance += (first_single[i] - second_single[i]) * (first_single[i] - second_single[i]);
372  }
373  expected_distance = sqrt(expected_distance);
374  PRECISION dist = distance(first_particle, second_particle);
375  EXPECT_THAT(dist, DoubleEq(expected_distance));
376 }
377 
378 TEST(UtilitiesTests, DistanceOfCloudToReference)
379 {
380  Particle<PRECISION> particle(DIMS);
381  create_and_fill_single(single, DIMS);
382  particle.pos() = single;
383  ParticleCloud<PRECISION> cloud(5, DIMS);
384  create_and_fill_cloud(temp, 5);
385  cloud.positions() = temp;
386  vector<PRECISION> expected_distance(5, 0.0);
387  for (size_t j = 0; j < 5; ++j) {
388  for (size_t i = 0; i < DIMS; ++i) {
389  expected_distance[j] += (cloud.positions()[j * DIMS + i] - particle.pos()[i]) * (cloud.positions()[j * DIMS + i] - particle.pos()[i]);
390  }
391  expected_distance[j] = sqrt(expected_distance[j]);
392  }
393  vector<PRECISION> dist = distance_to_reference(cloud, particle);
394  EXPECT_THAT(dist, Pointwise(Eq(), expected_distance));
395 }
396 
397 
398 int main(int argc, char** argv)
399 {
400  testing::InitGoogleTest(&argc, argv);
401  return RUN_ALL_TESTS();
402 }
TEST(OperatorTests, AddSingleOnSingle)
static vector< precision > distance_to_reference(const ParticleCloud< precision > &cloud, const Particle< precision > &reference)
ParticleComponent< precision > & pos()
int main(int argc, char **argv)
#define create_cloud(name, num)
static PRECISION roll()
#define create_single(name, num)
STL namespace.
static uniform_real_distribution< PRECISION > dist
void cross_prod(const double first[DIM], const double second[DIM], double cross_prod[DIM])
static default_random_engine rd_gen
def distance(a, b)
ParticleCloudComponent< precision > & positions()
vector< precision > ParticleCloudComponent
vector< precision > ParticleComponent
Definition: particle.hpp:27
#define DIMS
#define create_and_fill_single(name, num)
void fill_single(ParticleComponent< PRECISION > &vec)
#define create_and_fill_cloud(name, num)
#define PRECISION