1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.orekit.time;
19
20 import org.junit.jupiter.api.Assertions;
21 import org.junit.jupiter.api.DisplayName;
22 import org.junit.jupiter.api.RepeatedTest;
23 import org.junit.jupiter.api.Test;
24
25 import java.util.ArrayList;
26 import java.util.List;
27 import java.util.concurrent.Callable;
28 import java.util.concurrent.ExecutorService;
29 import java.util.concurrent.Executors;
30 import java.util.concurrent.TimeUnit;
31 import java.util.concurrent.atomic.DoubleAccumulator;
32
33 class TimeStampedDoubleAndDerivativeHermiteInterpolatorTest {
34
35 @Test
36 @DisplayName("Test default constructor")
37 void testDefaultConstructor() {
38
39 final TimeStampedDoubleAndDerivativeHermiteInterpolator interpolator = new TimeStampedDoubleAndDerivativeHermiteInterpolator();
40
41
42 Assertions.assertEquals(AbstractTimeInterpolator.DEFAULT_INTERPOLATION_POINTS,
43 interpolator.getNbInterpolationPoints());
44 Assertions.assertEquals(AbstractTimeInterpolator.DEFAULT_EXTRAPOLATION_THRESHOLD_SEC,
45 interpolator.getExtrapolationThreshold());
46 }
47
48 @RepeatedTest(10)
49 @DisplayName("test interpolator in multi-threaded environment")
50 void testIssue1164() throws InterruptedException {
51
52
53 final TimeInterpolator<TimeStampedDoubleAndDerivative> interpolator = new TimeStampedDoubleAndDerivativeHermiteInterpolator();
54
55
56 final int sampleSize = 100;
57 final AbsoluteDate initialDate = new AbsoluteDate();
58 final List<TimeStampedDoubleAndDerivative> sample = new ArrayList<>();
59 final List<AbsoluteDate> dates = new ArrayList<>();
60 for (int i = 1; i < sampleSize + 1; i++) {
61 sample.add(new TimeStampedDoubleAndDerivative(i * i, i / 30.0,
62 initialDate.shiftedBy(i * 60)));
63 dates.add(initialDate.shiftedBy(i * 60));
64 }
65
66
67 ExecutorService service = Executors.newFixedThreadPool(sampleSize);
68
69 final DoubleAccumulator sum0 = new DoubleAccumulator(Double::sum, 0.0);
70 final DoubleAccumulator sum1 = new DoubleAccumulator(Double::sum, 0.0);
71 final List<Callable<Integer>> tasks = new ArrayList<>();
72 for (final AbsoluteDate date : dates) {
73 tasks.add(new ParallelTask(interpolator, sum0, sum1, sample, date));
74 }
75
76
77 service.invokeAll(tasks);
78
79
80
81
82 final double expectedSum0 = sampleSize * (sampleSize + 1) * (2 * sampleSize + 1) / 6.0;
83 final double expectedSum1 = sampleSize * (sampleSize + 1) / 60.0;
84 try {
85
86 service.shutdown();
87 Assertions.assertTrue(service.awaitTermination(5, TimeUnit.SECONDS));
88 } catch (InterruptedException ie) {
89
90 Thread.currentThread().interrupt();
91 }
92 Assertions.assertEquals(expectedSum0, sum0.get(), 1.0e-12);
93 Assertions.assertEquals(expectedSum1, sum1.get(), 1.0e-12);
94 }
95
96
97 private static class ParallelTask implements Callable<Integer> {
98
99 private final TimeInterpolator<TimeStampedDoubleAndDerivative> interpolator;
100
101 private final List<TimeStampedDoubleAndDerivative> sample;
102
103 private final DoubleAccumulator sum0;
104
105 private final DoubleAccumulator sum1;
106
107 private final AbsoluteDate interpolationDate;
108
109 private ParallelTask(final TimeInterpolator<TimeStampedDoubleAndDerivative> interpolator,
110 final DoubleAccumulator sum0, final DoubleAccumulator sum1,
111 final List<TimeStampedDoubleAndDerivative> sample,
112 final AbsoluteDate interpolationDate) {
113
114 this.interpolator = interpolator;
115 this.sum0 = sum0;
116 this.sum1 = sum1;
117 this.interpolationDate = interpolationDate;
118 this.sample = sample;
119 }
120
121 @Override
122 public Integer call() {
123
124 final TimeStampedDoubleAndDerivative interpolated = interpolator.interpolate(interpolationDate, sample);
125 sum0.accumulate(interpolated.getValue());
126 sum1.accumulate(interpolated.getDerivative());
127 return 1;
128 }
129 }
130 }