1   package org.orekit.propagation.sampling;
2   
3   import org.hipparchus.Field;
4   import org.hipparchus.ode.events.Action;
5   import org.hipparchus.util.Decimal64;
6   import org.hipparchus.util.Decimal64Field;
7   import org.junit.After;
8   import org.junit.Assert;
9   import org.junit.Before;
10  import org.junit.Test;
11  import org.orekit.Utils;
12  import org.orekit.frames.FramesFactory;
13  import org.orekit.orbits.FieldKeplerianOrbit;
14  import org.orekit.orbits.FieldOrbit;
15  import org.orekit.orbits.PositionAngle;
16  import org.orekit.propagation.FieldPropagator;
17  import org.orekit.propagation.FieldSpacecraftState;
18  import org.orekit.propagation.analytical.FieldKeplerianPropagator;
19  import org.orekit.propagation.events.FieldDateDetector;
20  import org.orekit.time.FieldAbsoluteDate;
21  import org.orekit.time.TimeScalesFactory;
22  import org.orekit.utils.Constants;
23  
24  public class FieldStepHandlerMultiplexerTest {
25  
26      FieldAbsoluteDate<Decimal64> initDate;
27      FieldPropagator<Decimal64> propagator;
28  
29      @Before
30      public void setUp() {
31          Utils.setDataRoot("regular-data");
32          Field<Decimal64> field = Decimal64Field.getInstance();
33          Decimal64        zero  = field.getZero();
34          initDate = new FieldAbsoluteDate<>(field, 2020, 2, 28, 16, 15, 0.0, TimeScalesFactory.getUTC());
35          FieldOrbit<Decimal64> ic = new FieldKeplerianOrbit<>(zero.add(6378137 + 500e3), zero.add(1e-3), zero, zero, zero, zero,
36                                                               PositionAngle.TRUE, FramesFactory.getGCRF(), initDate,
37                                                               zero.add(Constants.WGS84_EARTH_MU));
38          propagator = new FieldKeplerianPropagator<>(ic);
39      }
40  
41      @After
42      public void tearDown() {
43          initDate   = null;
44          propagator = null;
45      }
46  
47      @Test
48      public void testMixedSteps() {
49  
50          Field<Decimal64> field = Decimal64Field.getInstance();
51          Decimal64        zero  = field.getZero();
52  
53          FieldStepHandlerMultiplexer<Decimal64> multiplexer = propagator.getMultiplexer();
54  
55          FieldInitCheckerHandler initHandler = new FieldInitCheckerHandler(1.0);
56          FieldFixedCounter    counter60  = new FieldFixedCounter();
57          FieldVariableCounter counterVar = new FieldVariableCounter();
58          FieldFixedCounter    counter10  = new FieldFixedCounter();
59  
60          multiplexer.add(zero.newInstance(60.0), initHandler);
61          multiplexer.add(zero.newInstance(60.0), counter60);
62          multiplexer.add(counterVar);
63          multiplexer.add(zero.newInstance(10.0), counter10);
64          Assert.assertEquals(4, multiplexer.getHandlers().size());
65  
66          Assert.assertFalse(initHandler.isInitialized());
67          Assert.assertEquals(1.0, initHandler.getExpected(), Double.MIN_VALUE);
68  
69          propagator.propagate(initDate.shiftedBy(90.0));
70  
71          // verify
72          Assert.assertTrue(initHandler.isInitialized());
73          Assert.assertEquals(2.0, initHandler.getExpected(), Double.MIN_VALUE);
74  
75          Assert.assertEquals( 1,  counter60.initCount);
76          Assert.assertEquals( 2,  counter60.handleCount);
77          Assert.assertEquals( 1,  counter60.finishCount);
78  
79          Assert.assertEquals( 1,  counterVar.initCount);
80          Assert.assertEquals( 1,  counterVar.handleCount);
81          Assert.assertEquals( 1,  counterVar.finishCount);
82  
83          Assert.assertEquals( 1,  counter10.initCount);
84          Assert.assertEquals(10,  counter10.handleCount);
85          Assert.assertEquals( 1,  counter10.finishCount);
86  
87      }
88  
89      @Test
90      public void testRemove() {
91  
92          FieldStepHandlerMultiplexer<Decimal64> multiplexer = propagator.getMultiplexer();
93  
94          Field<Decimal64> field = Decimal64Field.getInstance();
95          Decimal64        zero  = field.getZero();
96  
97          FieldFixedCounter    counter60  = new FieldFixedCounter();
98          FieldVariableCounter counterVar = new FieldVariableCounter();
99          FieldFixedCounter    counter10  = new FieldFixedCounter();
100 
101         multiplexer.add(zero.newInstance(60.0), counter60);
102         multiplexer.add(counterVar);
103         multiplexer.add(zero.newInstance(10.0), counter10);
104         Assert.assertEquals(3, multiplexer.getHandlers().size());
105         Assert.assertTrue(((FieldOrekitStepNormalizer<Decimal64>) multiplexer.getHandlers().get(0)).getFixedStepHandler() instanceof FieldFixedCounter);
106         Assert.assertEquals(60.0, ((FieldOrekitStepNormalizer<Decimal64>) multiplexer.getHandlers().get(0)).getFixedTimeStep().getReal(), 1.0e-15);
107         Assert.assertTrue(((FieldOrekitStepNormalizer<Decimal64>) multiplexer.getHandlers().get(2)).getFixedStepHandler() instanceof FieldFixedCounter);
108         Assert.assertEquals(10.0, ((FieldOrekitStepNormalizer<Decimal64>) multiplexer.getHandlers().get(2)).getFixedTimeStep().getReal(), 1.0e-15);
109 
110         // first run with all handlers
111         propagator.propagate(initDate.shiftedBy(90.0));
112         Assert.assertEquals( 1,    counter60.initCount);
113         Assert.assertEquals( 2,    counter60.handleCount);
114         Assert.assertEquals( 1,    counter60.finishCount);
115         Assert.assertEquals(  0.0, counter60.start, 1.0e-15);
116         Assert.assertEquals( 90.0, counter60.stop, 1.0e-15);
117         Assert.assertEquals( 1,    counterVar.initCount);
118         Assert.assertEquals( 1,    counterVar.handleCount);
119         Assert.assertEquals( 1,    counterVar.finishCount);
120         Assert.assertEquals(  0.0, counterVar.start, 1.0e-15);
121         Assert.assertEquals( 90.0, counterVar.stop, 1.0e-15);
122         Assert.assertEquals( 1,    counter10.initCount);
123         Assert.assertEquals(10,    counter10.handleCount);
124         Assert.assertEquals( 1,    counter10.finishCount);
125         Assert.assertEquals(  0.0, counter10.start, 1.0e-15);
126         Assert.assertEquals( 90.0, counter10.stop, 1.0e-15);
127 
128         // removing the handler at 10 seconds
129         multiplexer.remove(counter10);
130         Assert.assertEquals(2, multiplexer.getHandlers().size());
131         propagator.propagate(initDate.shiftedBy(100.0), initDate.shiftedBy(190.0));
132         Assert.assertEquals( 2,    counter60.initCount);
133         Assert.assertEquals( 4,    counter60.handleCount);
134         Assert.assertEquals( 2,    counter60.initCount);
135         Assert.assertEquals(100.0, counter60.start, 1.0e-15);
136         Assert.assertEquals(190.0, counter60.stop, 1.0e-15);
137         Assert.assertEquals( 2,    counterVar.initCount);
138         Assert.assertEquals( 2,    counterVar.handleCount);
139         Assert.assertEquals( 2,    counterVar.finishCount);
140         Assert.assertEquals(100.0, counterVar.start, 1.0e-15);
141         Assert.assertEquals(190.0, counterVar.stop, 1.0e-15);
142         Assert.assertEquals( 1,    counter10.initCount);
143         Assert.assertEquals(10,    counter10.handleCount);
144         Assert.assertEquals( 1,    counter10.initCount);
145         Assert.assertEquals(  0.0, counter10.start, 1.0e-15);
146         Assert.assertEquals( 90.0, counter10.stop, 1.0e-15);
147 
148         // attempting to remove a handler already removed
149         multiplexer.remove(counter10);
150         Assert.assertEquals(2, multiplexer.getHandlers().size());
151         propagator.propagate(initDate.shiftedBy(200.0), initDate.shiftedBy(290.0));
152         Assert.assertEquals( 3,    counter60.initCount);
153         Assert.assertEquals( 6,    counter60.handleCount);
154         Assert.assertEquals( 3,    counter60.finishCount);
155         Assert.assertEquals(200.0, counter60.start, 1.0e-15);
156         Assert.assertEquals(290.0, counter60.stop, 1.0e-15);
157         Assert.assertEquals( 3,    counterVar.initCount);
158         Assert.assertEquals( 3,    counterVar.handleCount);
159         Assert.assertEquals( 3,    counterVar.finishCount);
160         Assert.assertEquals(200.0, counterVar.start, 1.0e-15);
161         Assert.assertEquals(290.0, counterVar.stop, 1.0e-15);
162         Assert.assertEquals( 1,    counter10.initCount);
163         Assert.assertEquals(10,    counter10.handleCount);
164         Assert.assertEquals( 1,    counter10.finishCount);
165         Assert.assertEquals(  0.0, counter10.start, 1.0e-15);
166         Assert.assertEquals( 90.0, counter10.stop, 1.0e-15);
167         
168         // removing the handler with variable stepsize
169         multiplexer.remove(counterVar);
170         Assert.assertEquals(1, multiplexer.getHandlers().size());
171         propagator.propagate(initDate.shiftedBy(300.0), initDate.shiftedBy(390.0));
172         Assert.assertEquals( 4,    counter60.initCount);
173         Assert.assertEquals( 8,    counter60.handleCount);
174         Assert.assertEquals( 4,    counter60.initCount);
175         Assert.assertEquals(300.0, counter60.start, 1.0e-15);
176         Assert.assertEquals(390.0, counter60.stop, 1.0e-15);
177         Assert.assertEquals( 3,    counterVar.initCount);
178         Assert.assertEquals( 3,    counterVar.handleCount);
179         Assert.assertEquals( 3,    counterVar.finishCount);
180         Assert.assertEquals(200.0, counterVar.start, 1.0e-15);
181         Assert.assertEquals(290.0, counterVar.stop, 1.0e-15);
182         Assert.assertEquals( 1,    counter10.initCount);
183         Assert.assertEquals(10,    counter10.handleCount);
184         Assert.assertEquals( 1,    counter10.initCount);
185         Assert.assertEquals(  0.0, counter10.start, 1.0e-15);
186         Assert.assertEquals( 90.0, counter10.stop, 1.0e-15);
187 
188         // attempting to remove a handler already removed
189         multiplexer.remove(counterVar);
190         Assert.assertEquals(1, multiplexer.getHandlers().size());
191         propagator.propagate(initDate.shiftedBy(400.0), initDate.shiftedBy(490.0));
192         Assert.assertEquals( 5,    counter60.initCount);
193         Assert.assertEquals(10,    counter60.handleCount);
194         Assert.assertEquals( 5,    counter60.finishCount);
195         Assert.assertEquals(400.0, counter60.start, 1.0e-15);
196         Assert.assertEquals(490.0, counter60.stop, 1.0e-15);
197         Assert.assertEquals( 3,    counterVar.initCount);
198         Assert.assertEquals( 3,    counterVar.handleCount);
199         Assert.assertEquals( 3,    counterVar.finishCount);
200         Assert.assertEquals(200.0, counterVar.start, 1.0e-15);
201         Assert.assertEquals(290.0, counterVar.stop, 1.0e-15);
202         Assert.assertEquals( 1,    counter10.initCount);
203         Assert.assertEquals(10,    counter10.handleCount);
204         Assert.assertEquals( 1,    counter10.finishCount);
205         Assert.assertEquals(  0.0, counter10.start, 1.0e-15);
206         Assert.assertEquals( 90.0, counter10.stop, 1.0e-15);
207         
208         // removing everything
209         multiplexer.clear();
210         Assert.assertEquals(0, multiplexer.getHandlers().size());
211         propagator.propagate(initDate.shiftedBy(500.0), initDate.shiftedBy(590.0));
212         Assert.assertEquals( 5,    counter60.initCount);
213         Assert.assertEquals(10,    counter60.handleCount);
214         Assert.assertEquals( 5,    counter60.finishCount);
215         Assert.assertEquals(400.0, counter60.start, 1.0e-15);
216         Assert.assertEquals(490.0, counter60.stop, 1.0e-15);
217         Assert.assertEquals( 3,    counterVar.initCount);
218         Assert.assertEquals( 3,    counterVar.handleCount);
219         Assert.assertEquals( 3,    counterVar.finishCount);
220         Assert.assertEquals(200.0, counterVar.start, 1.0e-15);
221         Assert.assertEquals(290.0, counterVar.stop, 1.0e-15);
222         Assert.assertEquals( 1,    counter10.initCount);
223         Assert.assertEquals(10,    counter10.handleCount);
224         Assert.assertEquals( 1,    counter10.finishCount);
225         Assert.assertEquals(  0.0, counter10.start, 1.0e-15);
226         Assert.assertEquals( 90.0, counter10.stop, 1.0e-15);
227                 
228     }
229 
230     @Test
231     public void testOnTheFlyChanges() {
232 
233         final FieldStepHandlerMultiplexer<Decimal64> multiplexer = propagator.getMultiplexer();
234 
235         Field<Decimal64> field = Decimal64Field.getInstance();
236         Decimal64        zero  = field.getZero();
237 
238         double               add60      =  3.0;
239         double               rem60      = 78.0;
240         FieldFixedCounter    counter60  = new FieldFixedCounter();
241         propagator.addEventDetector(new FieldDateDetector<>(initDate.shiftedBy(add60)).
242                                     withHandler((FieldSpacecraftState<Decimal64> s, FieldDateDetector<Decimal64> d, boolean i) -> {
243                                         multiplexer.add(zero.newInstance(60.0), counter60);
244                                         return Action.CONTINUE;
245                                     }));
246         propagator.addEventDetector(new FieldDateDetector<>(initDate.shiftedBy(rem60)).
247                                     withHandler((FieldSpacecraftState<Decimal64> s, FieldDateDetector<Decimal64> d, boolean i) -> {
248                                         multiplexer.remove(counter60);
249                                         return Action.CONTINUE;
250                                     }));
251 
252         double               addVar     =  5.0;
253         double               remVar     =  7.0;
254         FieldVariableCounter counterVar = new FieldVariableCounter();
255         propagator.addEventDetector(new FieldDateDetector<>(initDate.shiftedBy(addVar)).
256                                     withHandler((FieldSpacecraftState<Decimal64> s, FieldDateDetector<Decimal64> d, boolean i) -> {
257                                         multiplexer.add(counterVar);
258                                         return Action.CONTINUE;
259                                     }));
260         propagator.addEventDetector(new FieldDateDetector<>(initDate.shiftedBy(remVar)).
261                                     withHandler((FieldSpacecraftState<Decimal64> s, FieldDateDetector<Decimal64> d, boolean i) -> {
262                                         multiplexer.remove(counterVar);
263                                         return Action.CONTINUE;
264                                     }));
265 
266         double               add10      =  6.0;
267         double               rem10      = 82.0;
268         FieldFixedCounter    counter10  = new FieldFixedCounter();
269         propagator.addEventDetector(new FieldDateDetector<>(initDate.shiftedBy(add10)).
270                                     withHandler((FieldSpacecraftState<Decimal64> s, FieldDateDetector<Decimal64> d, boolean i) -> {
271                                         multiplexer.add(zero.newInstance(10.0), counter10);
272                                         return Action.CONTINUE;
273                                     }));
274         propagator.addEventDetector(new FieldDateDetector<>(initDate.shiftedBy(rem10)).
275                                     withHandler((FieldSpacecraftState<Decimal64> s, FieldDateDetector<Decimal64> d, boolean i) -> {
276                                         multiplexer.clear();
277                                         return Action.CONTINUE;
278                                     }));
279 
280         // full run, which will add and remove step handlers on the fly
281         propagator.propagate(initDate.shiftedBy(90.0));
282         Assert.assertEquals( 1,     counter60.initCount);
283         Assert.assertEquals( 2,     counter60.handleCount);
284         Assert.assertEquals( 1,     counter60.finishCount);
285         Assert.assertEquals(add60,  counter60.start, 1.0e-15);
286         Assert.assertEquals(rem60,  counter60.stop, 1.0e-15);
287         Assert.assertEquals( 1,     counterVar.initCount);
288         Assert.assertEquals( 2,     counterVar.handleCount); // event at add10 splits the variable step in two parts
289         Assert.assertEquals( 1,     counterVar.finishCount);
290         Assert.assertEquals(addVar, counterVar.start, 1.0e-15);
291         Assert.assertEquals(remVar, counterVar.stop, 1.0e-15);
292         Assert.assertEquals( 1,     counter10.initCount);
293         Assert.assertEquals( 8,     counter10.handleCount);
294         Assert.assertEquals( 1,     counter10.finishCount);
295         Assert.assertEquals(add10,  counter10.start, 1.0e-15);
296         Assert.assertEquals(rem10,  counter10.stop, 1.0e-15);
297 
298     }
299 
300     private class FieldInitCheckerHandler implements FieldOrekitFixedStepHandler<Decimal64> {
301 
302         private double expected;
303         private boolean initialized;
304 
305         public FieldInitCheckerHandler(final double expected) {
306             this.expected    = expected;
307             this.initialized = false;
308         }
309 
310         @Override
311         public void init(FieldSpacecraftState<Decimal64> s0, FieldAbsoluteDate<Decimal64> t, Decimal64 step) {
312             initialized = true;
313         }
314 
315         @Override
316         public void handleStep(FieldSpacecraftState<Decimal64> currentState) {
317             this.expected = 2.0;
318         }
319 
320         boolean isInitialized() {
321             return initialized;
322         }
323 
324         double getExpected() {
325             return expected;
326         }
327 
328     }
329 
330     private class FieldFixedCounter implements FieldOrekitFixedStepHandler<Decimal64> {
331 
332         private int    initCount;
333         private int    handleCount;
334         private int    finishCount;
335         private double start;
336         private double stop;
337 
338         @Override
339         public void init(FieldSpacecraftState<Decimal64> s0, FieldAbsoluteDate<Decimal64> t, Decimal64 step) {
340             ++initCount;
341             start = s0.getDate().durationFrom(initDate).getReal();
342         }
343 
344         @Override
345         public void handleStep(FieldSpacecraftState<Decimal64> currentState) {
346             ++handleCount;
347         }
348 
349         @Override
350         public void finish(FieldSpacecraftState<Decimal64> finalState) {
351             ++finishCount;
352             stop = finalState.getDate().durationFrom(initDate).getReal();
353         }
354 
355     }
356 
357     private class FieldVariableCounter implements FieldOrekitStepHandler<Decimal64> {
358 
359         private int    initCount;
360         private int    handleCount;
361         private int    finishCount;
362         private double start;
363         private double stop;
364 
365         @Override
366         public void init(FieldSpacecraftState<Decimal64> s0, FieldAbsoluteDate<Decimal64> t) {
367             ++initCount;
368             start = s0.getDate().durationFrom(initDate).getReal();
369         }
370 
371         @Override
372         public void handleStep(FieldOrekitStepInterpolator<Decimal64> interpolator) {
373             ++handleCount;
374         }
375 
376         @Override
377         public void finish(FieldSpacecraftState<Decimal64> finalState) {
378             ++finishCount;
379             stop = finalState.getDate().durationFrom(initDate).getReal();
380         }
381 
382     }
383 
384 }