Line data Source code
1 : #include "crpropa/Candidate.h"
2 : #include "crpropa/ParticleID.h"
3 : #include "crpropa/module/SimplePropagation.h"
4 : #include "crpropa/module/PropagationBP.h"
5 : #include "crpropa/module/PropagationCK.h"
6 : #include "crpropa/magneticField/turbulentField/PlaneWaveTurbulence.h"
7 :
8 : #include "gtest/gtest.h"
9 :
10 : #include <string>
11 : #include <iostream>
12 :
13 : namespace crpropa {
14 :
15 1 : TEST(testSimplePropagation, step) {
16 1 : double minStep = 20;
17 1 : double maxStep = 100;
18 1 : SimplePropagation propa(minStep, maxStep);
19 :
20 1 : ParticleState p;
21 1 : p.setPosition(Vector3d(0, 0, 0));
22 1 : p.setDirection(Vector3d(0, 1, 0));
23 :
24 1 : Candidate c(p);
25 1 : c.setNextStep(10);
26 :
27 1 : propa.process(&c);
28 :
29 1 : EXPECT_EQ(minStep, c.getCurrentStep());
30 1 : EXPECT_EQ(maxStep, c.getNextStep());
31 2 : EXPECT_EQ(Vector3d(0, 0, 0), c.created.getPosition());
32 2 : EXPECT_EQ(Vector3d(0, 1, 0), c.created.getDirection());
33 2 : EXPECT_EQ(Vector3d(0, 0, 0), c.previous.getPosition());
34 2 : EXPECT_EQ(Vector3d(0, 1, 0), c.previous.getDirection());
35 2 : EXPECT_EQ(Vector3d(0, 20, 0), c.current.getPosition());
36 2 : EXPECT_EQ(Vector3d(0, 1, 0), c.current.getDirection());
37 2 : }
38 :
39 :
40 1 : TEST(testPropagationCK, zeroField) {
41 1 : PropagationCK propa(new UniformMagneticField(Vector3d(0, 0, 0)));
42 :
43 : double minStep = 0.1 * kpc;
44 1 : propa.setMinimumStep(minStep);
45 :
46 1 : ParticleState p;
47 1 : p.setId(nucleusId(1, 1));
48 1 : p.setEnergy(100 * EeV);
49 1 : p.setPosition(Vector3d(0, 0, 0));
50 1 : p.setDirection(Vector3d(0, 1, 0));
51 1 : Candidate c(p);
52 1 : c.setNextStep(0);
53 :
54 1 : propa.process(&c);
55 :
56 1 : EXPECT_DOUBLE_EQ(minStep, c.getCurrentStep()); // perform minimum step
57 1 : EXPECT_DOUBLE_EQ(5 * minStep, c.getNextStep()); // acceleration by factor 5
58 1 : }
59 :
60 : #ifndef CRPROPA_TESTS_SKIP_EXCEPTIONS
61 1 : TEST(testPropagationCK, exceptions) {
62 : // minStep should be smaller than maxStep
63 2 : EXPECT_THROW(PropagationCK propa(new UniformMagneticField(Vector3d(0, 0, 1 * nG)), 0.42, 10 , 0), std::runtime_error);
64 : // Too large tolerance: tolerance should be between 0 and 1
65 2 : EXPECT_THROW(PropagationCK propa(new UniformMagneticField(Vector3d(0, 0, 1 * nG)), 42., 10 * kpc , 20 * kpc), std::runtime_error);
66 :
67 2 : PropagationCK propa(new UniformMagneticField(Vector3d(0, 0, 1 * nG)));
68 :
69 : // set maximum step, so that it can be tested what happens if a larger minStep is set.
70 1 : propa.setMaximumStep(1 * Mpc);
71 :
72 : // this tests _that_ the expected exception is thrown
73 1 : EXPECT_THROW(propa.setTolerance(2.), std::runtime_error);
74 1 : EXPECT_THROW(propa.setMinimumStep(-1.), std::runtime_error);
75 1 : EXPECT_THROW(propa.setMinimumStep(2 * Mpc), std::runtime_error);
76 :
77 : // set minimum step, so that it can be tested what happens if a smaller maxStep is set.
78 1 : propa.setMinimumStep(0.5 * Mpc);
79 :
80 1 : EXPECT_THROW(propa.setMaximumStep(0.1 * Mpc), std::runtime_error);
81 1 : }
82 : #endif
83 :
84 1 : TEST(testPropagationCK, constructor) {
85 : // Test construction and parameters
86 1 : ref_ptr<MagneticField> bField = new UniformMagneticField(Vector3d(0, 0, 1 * nG));
87 :
88 1 : double minStep = 1.;
89 1 : double maxStep = 100.;
90 1 : double tolerance = 0.01;
91 :
92 1 : PropagationCK propa(bField, tolerance, minStep, maxStep);
93 :
94 1 : EXPECT_EQ(minStep, propa.getMinimumStep());
95 1 : EXPECT_EQ(maxStep, propa.getMaximumStep());
96 1 : EXPECT_EQ(tolerance, propa.getTolerance());
97 2 : EXPECT_EQ(bField, propa.getField());
98 :
99 : // Update parameters
100 1 : minStep = 10.;
101 1 : maxStep = 10.;
102 1 : propa.setTolerance(0.0001);
103 1 : bField = new UniformMagneticField(Vector3d(10 * nG, 0, 1 * nG));
104 :
105 1 : propa.setTolerance(tolerance);
106 1 : propa.setMinimumStep(minStep);
107 1 : propa.setMaximumStep(maxStep);
108 1 : propa.setField(bField);
109 :
110 1 : EXPECT_EQ(minStep, propa.getMinimumStep());
111 1 : EXPECT_EQ(maxStep, propa.getMaximumStep());
112 1 : EXPECT_EQ(tolerance, propa.getTolerance());
113 2 : EXPECT_EQ(bField, propa.getField());
114 :
115 : // The propagation should be initialized with the default constructor
116 2 : PropagationCK propaCKField(bField);
117 1 : EXPECT_EQ(propaCKField.getMaximumStep(), 1 * Gpc);
118 2 : }
119 :
120 :
121 : // Test if the step size is reduced correctly if the error is too large with respect to the tolerance: r > 1
122 1 : TEST(testPropagationCK, reduceStep) {
123 1 : PropagationCK propa(new UniformMagneticField(Vector3d(0, 0, 100 * nG)));
124 :
125 : double minStep = 0.1 * kpc;
126 : double maxStep = 1 * Gpc;
127 1 : propa.setMinimumStep(minStep);
128 1 : propa.setMaximumStep(maxStep);
129 : // small tolerance leads to large values of r
130 1 : propa.setTolerance(1e-15);
131 :
132 1 : ParticleState p;
133 1 : p.setId(nucleusId(1, 1));
134 1 : p.setEnergy(100 * TeV);
135 1 : p.setPosition(Vector3d(0, 0, 0));
136 1 : p.setDirection(Vector3d(0, 1, 0));
137 1 : Candidate c(p);
138 : // large step leads to large errors and thus in combination with the low tolerance to high values of r
139 1 : c.setNextStep(maxStep);
140 :
141 1 : propa.process(&c);
142 :
143 : // adaptive algorithm should propagate particle with minimum step size due to the low value for the tolerance
144 1 : EXPECT_DOUBLE_EQ(minStep, c.getCurrentStep()); // perform minimum step because of large r due to small tolerance
145 1 : EXPECT_DOUBLE_EQ(minStep, c.getNextStep()); // stay at minimum step because of large r due to small tolerance
146 1 : }
147 :
148 :
149 : // Test if the step size is increased correctly if the error is small with respect to the tolerance: r < 1
150 1 : TEST(testPropagationCK, increaseStep) {
151 1 : PropagationCK propa(new UniformMagneticField(Vector3d(0, 0, 1 * nG)));
152 :
153 : double minStep = 0.001 * pc;
154 : double maxStep = 3.125 * pc;
155 1 : propa.setMinimumStep(minStep);
156 1 : propa.setMaximumStep(maxStep);
157 : // large tolerance leads to small values of r. Consequently, the step size can be increased.
158 1 : propa.setTolerance(0.9);
159 :
160 1 : ParticleState p;
161 1 : p.setId(nucleusId(1, 1));
162 1 : p.setEnergy(100 * EeV);
163 1 : p.setPosition(Vector3d(0, 0, 0));
164 1 : p.setDirection(Vector3d(0, 1, 0));
165 1 : Candidate c(p);
166 :
167 : // each step the step size can be increased by a factor of 5.
168 6 : for (int i = 1; i < 6; i++){
169 5 : propa.process(&c);
170 5 : EXPECT_DOUBLE_EQ(minStep*pow(5, i) / pc, c.getNextStep()/pc);
171 : }
172 : // after 5 steps the maxStep is reached. The current step is, however, less.
173 1 : EXPECT_DOUBLE_EQ(maxStep/pc/5., c.getCurrentStep()/pc);
174 1 : EXPECT_DOUBLE_EQ(maxStep/pc, c.getNextStep()/pc);
175 1 : }
176 :
177 :
178 1 : TEST(testPropagationCK, proton) {
179 1 : PropagationCK propa(new UniformMagneticField(Vector3d(0, 0, 1 * nG)));
180 :
181 : double minStep = 0.1 * kpc;
182 1 : propa.setMinimumStep(minStep);
183 :
184 1 : ParticleState p;
185 1 : p.setId(nucleusId(1, 1));
186 1 : p.setEnergy(100 * EeV);
187 1 : p.setPosition(Vector3d(0, 0, 0));
188 1 : p.setDirection(Vector3d(0, 1, 0));
189 1 : Candidate c(p);
190 1 : c.setNextStep(0);
191 :
192 1 : propa.process(&c);
193 :
194 1 : EXPECT_DOUBLE_EQ(minStep, c.getCurrentStep()); // perform minimum step
195 1 : EXPECT_DOUBLE_EQ(5 * minStep, c.getNextStep()); // acceleration by factor 5
196 1 : }
197 :
198 :
199 : // Test the numerical results for parallel magnetic field lines along the z-axis
200 1 : TEST(testPropagationCK, gyration) {
201 1 : PropagationCK propa(new UniformMagneticField(Vector3d(0, 0, 1 * nG)));
202 :
203 : double step = 10. * Mpc; // gyroradius is 108.1 Mpc
204 1 : propa.setMaximumStep(step);
205 1 : propa.setMinimumStep(step);
206 :
207 :
208 1 : ParticleState p;
209 1 : p.setId(nucleusId(1, 1));
210 1 : p.setEnergy(100 * EeV);
211 1 : p.setPosition(Vector3d(0, 0, 0));
212 1 : p.setDirection(Vector3d(1, 1, 1));
213 1 : Candidate c(p);
214 1 : c.setNextStep(0);
215 1 : propa.process(&c);
216 :
217 1 : double dirX = c.current.getDirection().x;
218 1 : double dirY = c.current.getDirection().y;
219 1 : double dirZ = c.current.getDirection().z;
220 1 : double posZ = c.current.getPosition().z;
221 :
222 : // Test if the analytical solution is achieved for the components of the momentum with the CK method as expected in
223 : // the background magnetic field.
224 : double precision = 1e-7;
225 : double expected = 2 / 3.;
226 1 : EXPECT_NEAR(expected, dirX * dirX + dirY * dirY, expected * precision); // constant momentum in the plane perpendicular to background magnetic field field
227 : expected = 1 / 3.;
228 1 : EXPECT_NEAR(expected, dirZ * dirZ, expected * precision); // constant momentum parallel to the background magnetic field
229 : expected = step * step / 3.;
230 1 : EXPECT_NEAR(expected, posZ * posZ, expected * precision); // constant velocity parallel to the background magnetic field
231 :
232 : // Nine new steps to have finally propagated the particle ten times
233 10 : for (int i = 0; i < 9; i++){
234 9 : propa.process(&c);
235 : }
236 :
237 1 : dirX = c.current.getDirection().x;
238 1 : dirY = c.current.getDirection().y;
239 1 : dirZ = c.current.getDirection().z;
240 1 : posZ = c.current.getPosition().z;
241 :
242 : // Compare the numerical solutions after ten steps with the analytical solution of the trajectories
243 : expected = 2 / 3.;
244 1 : EXPECT_NEAR(expected, dirX * dirX + dirY * dirY, expected * precision); // constant momentum in the plane perpendicular to background magnetic field field
245 : expected = 1 / 3.;
246 1 : EXPECT_NEAR(expected, dirZ * dirZ, expected * precision); // constant momentum parallel to the background magnetic field
247 : expected = 100 * step * step / 3.;
248 1 : EXPECT_NEAR(expected, posZ * posZ, expected * precision); // constant velocity parallel to the background magnetic field
249 1 : }
250 :
251 :
252 1 : TEST(testPropagationCK, neutron) {
253 1 : PropagationCK propa(new UniformMagneticField(Vector3d(0, 0, 1 * nG)));
254 1 : propa.setMinimumStep(1 * kpc);
255 1 : propa.setMaximumStep(42 * Mpc);
256 :
257 1 : ParticleState p;
258 1 : p.setId(nucleusId(1, 0));
259 1 : p.setEnergy(100 * EeV);
260 1 : p.setPosition(Vector3d(0, 0, 0));
261 1 : p.setDirection(Vector3d(0, 1, 0));
262 1 : Candidate c(p);
263 :
264 1 : propa.process(&c);
265 :
266 1 : EXPECT_DOUBLE_EQ(1 * kpc, c.getCurrentStep());
267 1 : EXPECT_DOUBLE_EQ(42 * Mpc, c.getNextStep());
268 2 : EXPECT_EQ(Vector3d(0, 1 * kpc, 0), c.current.getPosition());
269 2 : EXPECT_EQ(Vector3d(0, 1, 0), c.current.getDirection());
270 1 : }
271 :
272 :
273 1 : TEST(testPropagationBP, zeroField) {
274 1 : PropagationBP propa(new UniformMagneticField(Vector3d(0, 0, 0)), 1 * kpc);
275 :
276 : double minStep = 0.1 * kpc;
277 1 : propa.setMinimumStep(minStep);
278 1 : propa.setTolerance(0.42);
279 :
280 1 : ParticleState p;
281 1 : p.setId(nucleusId(1, 1));
282 1 : p.setEnergy(100 * EeV);
283 1 : p.setPosition(Vector3d(0, 0, 0));
284 1 : p.setDirection(Vector3d(0, 1, 0));
285 1 : Candidate c(p);
286 1 : c.setNextStep(0);
287 :
288 1 : propa.process(&c);
289 :
290 1 : EXPECT_DOUBLE_EQ(minStep, c.getCurrentStep()); // perform minimum step
291 1 : EXPECT_DOUBLE_EQ(5 * minStep, c.getNextStep()); // acceleration by factor 5
292 1 : }
293 :
294 : #ifndef CRPROPA_TESTS_SKIP_EXCEPTIONS
295 1 : TEST(testPropagationBP, exceptions) {
296 : // minStep should be smaller than maxStep
297 2 : EXPECT_THROW(PropagationBP propa(new UniformMagneticField(Vector3d(0, 0, 1 * nG)), 0.42, 10 , 0), std::runtime_error);
298 : // Too large tolerance: tolerance should be between 0 and 1
299 2 : EXPECT_THROW(PropagationBP propa(new UniformMagneticField(Vector3d(0, 0, 1 * nG)), 42., 10 * kpc , 20 * kpc), std::runtime_error);
300 :
301 2 : PropagationBP propa(new UniformMagneticField(Vector3d(0, 0, 1 * nG)));
302 :
303 : // set maximum step, so that it can be tested what happens if a larger minStep is set.
304 1 : propa.setMaximumStep(1 * Mpc);
305 :
306 : // this tests _that_ the expected exception is thrown
307 1 : EXPECT_THROW(propa.setTolerance(2.), std::runtime_error);
308 1 : EXPECT_THROW(propa.setMinimumStep(-1.), std::runtime_error);
309 1 : EXPECT_THROW(propa.setMinimumStep(2 * Mpc), std::runtime_error);
310 :
311 : // set minimum step, so that it can be tested what happens if a smaller maxStep is set.
312 1 : propa.setMinimumStep(0.5 * Mpc);
313 :
314 1 : EXPECT_THROW(propa.setMaximumStep(0.1 * Mpc), std::runtime_error);
315 1 : }
316 : #endif
317 :
318 :
319 1 : TEST(testPropagationBP, constructor) {
320 : // Test construction and parameters
321 1 : ref_ptr<MagneticField> bField = new UniformMagneticField(Vector3d(0, 0, 1 * nG));
322 :
323 1 : double minStep = 1.;
324 1 : double maxStep = 100.;
325 1 : double tolerance = 0.01;
326 :
327 1 : PropagationBP propa(bField, tolerance, minStep, maxStep);
328 :
329 1 : EXPECT_EQ(minStep, propa.getMinimumStep());
330 1 : EXPECT_EQ(maxStep, propa.getMaximumStep());
331 1 : EXPECT_EQ(tolerance, propa.getTolerance());
332 2 : EXPECT_EQ(bField, propa.getField());
333 :
334 : // Update parameters
335 1 : minStep = 10.;
336 1 : maxStep = 10.;
337 1 : propa.setTolerance(0.0001);
338 1 : bField = new UniformMagneticField(Vector3d(10 * nG, 0, 1 * nG));
339 :
340 1 : propa.setTolerance(tolerance);
341 1 : propa.setMinimumStep(minStep);
342 1 : propa.setMaximumStep(maxStep);
343 1 : propa.setField(bField);
344 :
345 1 : EXPECT_EQ(minStep, propa.getMinimumStep());
346 1 : EXPECT_EQ(maxStep, propa.getMaximumStep());
347 1 : EXPECT_EQ(tolerance, propa.getTolerance());
348 2 : EXPECT_EQ(bField, propa.getField());
349 :
350 : // Test the fixed step size version of the Boris push
351 1 : minStep = 10. * kpc;
352 2 : PropagationBP propaBP(bField, minStep);
353 1 : EXPECT_EQ(propaBP.getMaximumStep(), propaBP.getMaximumStep());
354 :
355 : // The propagation should be initialized with the default constructor
356 2 : PropagationBP propaBPField(bField);
357 1 : EXPECT_EQ(propaBPField.getMaximumStep(), 1 * kpc);
358 2 : }
359 :
360 :
361 : // Test if the step size is reduced correctly if the error is too large with respect to the tolerance: r > 1
362 1 : TEST(testPropagationBP, reduceStep) {
363 1 : PropagationBP propa(new UniformMagneticField(Vector3d(0, 0, 100 * nG)), 1 * kpc);
364 :
365 : double minStep = 0.1 * kpc;
366 : double maxStep = 1 * Gpc;
367 1 : propa.setMinimumStep(minStep);
368 1 : propa.setMaximumStep(maxStep);
369 : // small tolerance leads to large values of r
370 1 : propa.setTolerance(1e-15);
371 :
372 1 : ParticleState p;
373 1 : p.setId(nucleusId(1, 1));
374 1 : p.setEnergy(100 * TeV);
375 1 : p.setPosition(Vector3d(0, 0, 0));
376 1 : p.setDirection(Vector3d(0, 1, 0));
377 1 : Candidate c(p);
378 : // large step leads to large errors and thus in combination with the low tolerance to high values of r
379 1 : c.setNextStep(maxStep);
380 :
381 1 : propa.process(&c);
382 :
383 : // adaptive algorithm should propagate particle with minimum step size due to the low value for the tolerance
384 1 : EXPECT_DOUBLE_EQ(minStep, c.getCurrentStep()); // perform minimum step because of large r due to small tolerance
385 1 : EXPECT_DOUBLE_EQ(minStep, c.getNextStep()); // stay at minimum step because of large r due to small tolerance
386 1 : }
387 :
388 :
389 : // Test if the step size is increased correctly if the error is small with respect to the tolerance: r < 1
390 1 : TEST(testPropagationBP, increaseStep) {
391 1 : PropagationBP propa(new UniformMagneticField(Vector3d(0, 0, 1 * nG)), 1 * kpc);
392 :
393 : double minStep = 0.001 * pc;
394 : double maxStep = 3.125 * pc;
395 1 : propa.setMinimumStep(minStep);
396 1 : propa.setMaximumStep(maxStep);
397 : // large tolerance leads to small values of r. Consequently, the step size can be increased.
398 1 : propa.setTolerance(0.9);
399 :
400 1 : ParticleState p;
401 1 : p.setId(nucleusId(1, 1));
402 1 : p.setEnergy(100 * EeV);
403 1 : p.setPosition(Vector3d(0, 0, 0));
404 1 : p.setDirection(Vector3d(0, 1, 0));
405 1 : Candidate c(p);
406 :
407 : // each step the step size can be increased by a factor of 5.
408 6 : for (int i = 1; i < 6; i++){
409 5 : propa.process(&c);
410 5 : EXPECT_DOUBLE_EQ(minStep*pow(5, i) / pc, c.getNextStep()/pc);
411 : }
412 : // after 5 steps the maxStep is reached. The current step is, however, less.
413 1 : EXPECT_DOUBLE_EQ(maxStep/pc/5., c.getCurrentStep()/pc);
414 1 : EXPECT_DOUBLE_EQ(maxStep/pc, c.getNextStep()/pc);
415 1 : }
416 :
417 :
418 1 : TEST(testPropagationBP, proton) {
419 1 : PropagationBP propa(new UniformMagneticField(Vector3d(0, 0, 1 * nG)));
420 :
421 : double step = 0.01 * kpc;
422 1 : propa.setMinimumStep(step);
423 1 : propa.setMaximumStep(10*step);
424 1 : propa.setTolerance(0.00001);
425 :
426 1 : ParticleState p;
427 1 : p.setId(nucleusId(1, 1));
428 1 : p.setEnergy(100 * EeV);
429 1 : p.setPosition(Vector3d(0, 0, 0));
430 1 : p.setDirection(Vector3d(0, 1, 0));
431 1 : Candidate c(p);
432 1 : c.setNextStep(0);
433 :
434 1 : propa.process(&c);
435 :
436 1 : EXPECT_DOUBLE_EQ(step, c.getCurrentStep()); // perform step
437 1 : EXPECT_DOUBLE_EQ(5 * step, c.getNextStep()); // acceleration by factor 5
438 1 : }
439 :
440 :
441 : // Test the numerical results for parallel magnetic field lines along the z-axis
442 1 : TEST(testPropagationBP, gyration) {
443 1 : PropagationBP propa(new UniformMagneticField(Vector3d(0, 0, 1 * nG)));
444 :
445 : double step = 10. * Mpc; // gyroradius is 108.1 Mpc
446 1 : propa.setMaximumStep(step);
447 1 : propa.setMinimumStep(step);
448 :
449 :
450 1 : ParticleState p;
451 1 : p.setId(nucleusId(1, 1));
452 1 : p.setEnergy(100 * EeV);
453 1 : p.setPosition(Vector3d(0, 0, 0));
454 1 : p.setDirection(Vector3d(1, 1, 1));
455 1 : Candidate c(p);
456 1 : c.setNextStep(0);
457 1 : propa.process(&c);
458 :
459 1 : double dirX = c.current.getDirection().x;
460 1 : double dirY = c.current.getDirection().y;
461 1 : double dirZ = c.current.getDirection().z;
462 1 : double posZ = c.current.getPosition().z;
463 :
464 : // Test if the analytical solution is achieved for the components of the momentum with the Boris push as expected in
465 : // the background magnetic field.
466 1 : EXPECT_DOUBLE_EQ(2 / 3., dirX * dirX + dirY * dirY); // constant momentum in the perpendicular plane to background magnetic field field
467 1 : EXPECT_DOUBLE_EQ(1 / 3., dirZ * dirZ); // constant momentum parallel to the background magnetic field
468 1 : EXPECT_DOUBLE_EQ( step * step / 3., posZ * posZ); // constant velocity parallel to the background magnetic field
469 :
470 : // Nine new steps to have finally propagated the particle ten times
471 10 : for (int i = 0; i < 9; i++){
472 9 : propa.process(&c);
473 : }
474 :
475 1 : dirX = c.current.getDirection().x;
476 1 : dirY = c.current.getDirection().y;
477 1 : dirZ = c.current.getDirection().z;
478 1 : posZ = c.current.getPosition().z;
479 :
480 : // Compare the numerical solutions after ten steps with the analytical solution of the trajectories
481 1 : EXPECT_DOUBLE_EQ(2 / 3., dirX * dirX + dirY * dirY); // constant momentum in the perpendicular plane to background magnetic field field
482 1 : EXPECT_DOUBLE_EQ(1 / 3., dirZ * dirZ); // constant momentum parallel to the background magnetic field
483 1 : EXPECT_DOUBLE_EQ(100 * step * step / 3., posZ * posZ); // constant velocity parallel to the background magnetic field
484 1 : }
485 :
486 :
487 : // Test the that the optimization for fixed step sizes works
488 1 : TEST(testPropagationBP, fixedStepOptimization) {
489 : // particle 1 with fixed step sizes
490 : double fixed_step = pc;
491 2 : PropagationBP propa1(new PlaneWaveTurbulence(TurbulenceSpectrum(gauss, pc, 100*pc), 10, 1), fixed_step);
492 1 : ParticleState p1;
493 1 : p1.setId(nucleusId(1, 1));
494 1 : p1.setEnergy(100 * EeV);
495 1 : p1.setPosition(Vector3d(0, 0, 0));
496 1 : p1.setDirection(Vector3d(1, 1, 1));
497 1 : Candidate c1(p1);
498 1 : c1.setNextStep(0);
499 : // Nine new steps to have finally propagated the particle ten times
500 10 : for (int i = 0; i < 9; i++){
501 9 : propa1.process(&c1);
502 : }
503 :
504 : // particle 2 with different min and max steps. The tolerance is chosen such that particle 2 will be
505 : // propagated with the same step as particle 1, however not using the optimization for fixed step sizes
506 : double tolerance = 1;
507 2 : PropagationBP propa2(new PlaneWaveTurbulence(TurbulenceSpectrum(gauss, pc, 100*pc), 10, 1), tolerance, fixed_step, 1.1*fixed_step);
508 1 : ParticleState p2;
509 1 : p2.setId(nucleusId(1, 1));
510 1 : p2.setEnergy(100 * EeV);
511 1 : p2.setPosition(Vector3d(0, 0, 0));
512 1 : p2.setDirection(Vector3d(1, 1, 1));
513 1 : Candidate c2(p2);
514 1 : c1.setNextStep(0);
515 : // Nine new steps to have finally propagated the particle ten times
516 10 : for (int i = 0; i < 9; i++){
517 9 : propa2.process(&c2);
518 : }
519 :
520 1 : EXPECT_DOUBLE_EQ(c1.current.getDirection().x, c2.current.getDirection().x);
521 1 : EXPECT_DOUBLE_EQ(c1.current.getDirection().y, c2.current.getDirection().y);
522 1 : EXPECT_DOUBLE_EQ(c1.current.getDirection().z, c2.current.getDirection().z);
523 1 : EXPECT_DOUBLE_EQ(c1.current.getPosition().x, c2.current.getPosition().x);
524 1 : EXPECT_DOUBLE_EQ(c1.current.getPosition().y, c2.current.getPosition().y);
525 1 : EXPECT_DOUBLE_EQ(c1.current.getPosition().z, c2.current.getPosition().z);
526 1 : }
527 :
528 :
529 1 : TEST(testPropagationBP, neutron) {
530 1 : PropagationBP propa(new UniformMagneticField(Vector3d(0, 0, 1 * nG)));
531 :
532 1 : propa.setMinimumStep(1 * kpc);
533 1 : propa.setMaximumStep(1 * kpc);
534 :
535 1 : ParticleState p;
536 1 : p.setId(nucleusId(1, 0));
537 1 : p.setEnergy(100 * EeV);
538 1 : p.setPosition(Vector3d(0, 0, 0));
539 1 : p.setDirection(Vector3d(0, 1, 0));
540 1 : Candidate c(p);
541 :
542 1 : propa.process(&c);
543 :
544 1 : EXPECT_DOUBLE_EQ(1 * kpc, c.getCurrentStep());
545 1 : EXPECT_DOUBLE_EQ(1 * kpc, c.getNextStep());
546 2 : EXPECT_EQ(Vector3d(0, 1 * kpc, 0), c.current.getPosition());
547 2 : EXPECT_EQ(Vector3d(0, 1, 0), c.current.getDirection());
548 1 : }
549 :
550 :
551 0 : int main(int argc, char **argv) {
552 0 : ::testing::InitGoogleTest(&argc, argv);
553 0 : return RUN_ALL_TESTS();
554 : }
555 :
556 : } // namespace crpropa
|