1   /* Copyright 2002-2025 CS GROUP
2    * Licensed to CS GROUP (CS) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * CS licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *   http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.orekit.propagation.events;
18  
19  import org.hipparchus.CalculusFieldElement;
20  import org.hipparchus.Field;
21  import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
22  import org.hipparchus.util.Binary64;
23  import org.hipparchus.util.Binary64Field;
24  import org.junit.jupiter.api.Assertions;
25  import org.junit.jupiter.api.BeforeEach;
26  import org.junit.jupiter.api.Test;
27  import org.orekit.Utils;
28  import org.orekit.frames.FramesFactory;
29  import org.orekit.orbits.FieldCartesianOrbit;
30  import org.orekit.orbits.FieldOrbit;
31  import org.orekit.propagation.analytical.FieldEcksteinHechlerPropagator;
32  import org.orekit.propagation.events.handlers.FieldContinueOnEvent;
33  import org.orekit.time.AbsoluteDate;
34  import org.orekit.time.FieldAbsoluteDate;
35  import org.orekit.time.TimeScale;
36  import org.orekit.time.TimeScalesFactory;
37  import org.orekit.utils.Constants;
38  import org.orekit.utils.FieldPVCoordinates;
39  
40  class FieldParameterDrivenDateIntervalDetectorTest {
41  
42      @Test
43      void testDependsOnlyOnTime() {
44          // GIVEN
45          final FieldAbsoluteDate<Binary64> fieldDate = FieldAbsoluteDate.getArbitraryEpoch(Binary64Field.getInstance());
46          final FieldParameterDrivenDateIntervalDetector<Binary64> detector = new FieldParameterDrivenDateIntervalDetector<>(fieldDate.getField(),
47                  "e", fieldDate.toAbsoluteDate(), fieldDate.toAbsoluteDate());
48          // WHEN
49          final boolean value = detector.dependsOnTimeOnly();
50          // THEN
51          Assertions.assertTrue(value);
52      }
53      
54      @Test
55      void testNoShift() {
56          doTestNoShift(Binary64Field.getInstance());
57      }
58  
59      @Test
60      void testSmallShift() {
61          doTestSmallShift(Binary64Field.getInstance());
62      }
63  
64      @Test
65      void testLargeShift() {
66          doTestLargeShift(Binary64Field.getInstance());
67      }
68  
69      private <T extends CalculusFieldElement<T>> void doTestNoShift(Field<T> field) {
70          final T zero = field.getZero();
71  
72          final TimeScale utc = TimeScalesFactory.getUTC();
73          final FieldVector3D<T> position = new FieldVector3D<>(zero.add(-6142438.668), zero.add(3492467.56), zero.add(-25767.257));
74          final FieldVector3D<T> velocity = new FieldVector3D<>(zero.add(506.0), zero.add(943.0), zero.add(7450));
75          final FieldAbsoluteDate<T> date = new FieldAbsoluteDate<>(field, 2003, 9, 16, utc);
76          final FieldOrbit<T> orbit = new FieldCartesianOrbit<>(new FieldPVCoordinates<>(position,  velocity),
77                                                                FramesFactory.getEME2000(), date,
78                                                                zero.add(Constants.EIGEN5C_EARTH_MU));
79          FieldEcksteinHechlerPropagator<T> propagator =
80                          new FieldEcksteinHechlerPropagator<>(orbit,
81                                                               Constants.EIGEN5C_EARTH_EQUATORIAL_RADIUS,
82                                                               zero.add(Constants.EIGEN5C_EARTH_MU),
83                                                               Constants.EIGEN5C_EARTH_C20,
84                                                               Constants.EIGEN5C_EARTH_C30,
85                                                               Constants.EIGEN5C_EARTH_C40,
86                                                               Constants.EIGEN5C_EARTH_C50,
87                                                               Constants.EIGEN5C_EARTH_C60);
88  
89          final AbsoluteDate t0    = propagator.getInitialState().getDate().toAbsoluteDate();
90          final AbsoluteDate start = t0.shiftedBy( 120);
91          final AbsoluteDate stop  = t0.shiftedBy(1120);
92          FieldParameterDrivenDateIntervalDetector<T> detector =
93                          new FieldParameterDrivenDateIntervalDetector<>(field, "no-shift", start, stop).
94                          withMaxCheck(10.0).
95                          withThreshold(zero.newInstance(1.0e-12)).
96                          withHandler(new FieldContinueOnEvent<>());
97  
98          Assertions.assertEquals(10.0, detector.getMaxCheckInterval().currentInterval(null, true), 1.0e-15);
99          Assertions.assertEquals(1.0e-12, detector.getThreshold().getReal(), 1.0e-15);
100         Assertions.assertEquals(AbstractDetector.DEFAULT_MAX_ITER, detector.getMaxIterationCount());
101         Assertions.assertEquals("no-shift_START", detector.getStartDriver().getName());
102         Assertions.assertEquals("no-shift_STOP", detector.getStopDriver().getName());
103 
104         FieldEventsLogger<T> logger = new FieldEventsLogger<>();
105         propagator.addEventDetector(logger.monitorDetector(detector));
106 
107         propagator.propagate(propagator.getInitialState().getOrbit().getDate().shiftedBy(Constants.JULIAN_DAY));
108 
109         Assertions.assertEquals(2, logger.getLoggedEvents().size());
110         Assertions.assertEquals(0.0, logger.getLoggedEvents().get(0).getState().getDate().durationFrom(start).getReal(), 1.0e-10);
111         Assertions.assertEquals(0.0, logger.getLoggedEvents().get(1).getState().getDate().durationFrom(stop).getReal(), 1.0e-10);
112 
113     }
114 
115     private <T extends CalculusFieldElement<T>> void doTestSmallShift(Field<T> field) {
116         final T zero = field.getZero();
117 
118         final TimeScale utc = TimeScalesFactory.getUTC();
119         final FieldVector3D<T> position = new FieldVector3D<>(zero.add(-6142438.668), zero.add(3492467.56), zero.add(-25767.257));
120         final FieldVector3D<T> velocity = new FieldVector3D<>(zero.add(506.0), zero.add(943.0), zero.add(7450));
121         final FieldAbsoluteDate<T> date = new FieldAbsoluteDate<>(field, 2003, 9, 16, utc);
122         final FieldOrbit<T> orbit = new FieldCartesianOrbit<>(new FieldPVCoordinates<>(position,  velocity),
123                                                               FramesFactory.getEME2000(), date,
124                                                               zero.add(Constants.EIGEN5C_EARTH_MU));
125         FieldEcksteinHechlerPropagator<T> propagator =
126                         new FieldEcksteinHechlerPropagator<>(orbit,
127                                                              Constants.EIGEN5C_EARTH_EQUATORIAL_RADIUS,
128                                                              zero.add(Constants.EIGEN5C_EARTH_MU),
129                                                              Constants.EIGEN5C_EARTH_C20,
130                                                              Constants.EIGEN5C_EARTH_C30,
131                                                              Constants.EIGEN5C_EARTH_C40,
132                                                              Constants.EIGEN5C_EARTH_C50,
133                                                              Constants.EIGEN5C_EARTH_C60);
134 
135         final AbsoluteDate t0    = propagator.getInitialState().getDate().toAbsoluteDate();
136         final AbsoluteDate start = t0.shiftedBy( 120);
137         final AbsoluteDate stop  = t0.shiftedBy(1120);
138         FieldParameterDrivenDateIntervalDetector<T> detector =
139                         new FieldParameterDrivenDateIntervalDetector<>(field, "no-shift", start, stop).
140                         withMaxCheck(10.0).
141                         withThreshold(zero.newInstance(1.0e-12)).
142                         withHandler(new FieldContinueOnEvent<>());
143 
144         Assertions.assertEquals(10.0, detector.getMaxCheckInterval().currentInterval(null, true), 1.0e-15);
145         Assertions.assertEquals(1.0e-12, detector.getThreshold().getReal(), 1.0e-15);
146         Assertions.assertEquals(AbstractDetector.DEFAULT_MAX_ITER, detector.getMaxIterationCount());
147         Assertions.assertEquals("no-shift_START", detector.getStartDriver().getName());
148         Assertions.assertEquals("no-shift_STOP", detector.getStopDriver().getName());
149 
150         FieldEventsLogger<T> logger = new FieldEventsLogger<>();
151         propagator.addEventDetector(logger.monitorDetector(detector));
152 
153         final double startShift = 5.5;
154         detector.getStartDriver().setValue(startShift);
155         final double stopShift  = -0.5;
156         detector.getStopDriver().setValue(stopShift, null);
157         propagator.propagate(propagator.getInitialState().getOrbit().getDate().shiftedBy(Constants.JULIAN_DAY));
158 
159         Assertions.assertEquals(2, logger.getLoggedEvents().size());
160         Assertions.assertEquals(startShift, logger.getLoggedEvents().get(0).getState().getDate().durationFrom(start).getReal(), 1.0e-10);
161         Assertions.assertEquals(stopShift,  logger.getLoggedEvents().get(1).getState().getDate().durationFrom(stop).getReal(),  1.0e-10);
162 
163     }
164 
165     private <T extends CalculusFieldElement<T>> void doTestLargeShift(Field<T> field) {
166         final T zero = field.getZero();
167 
168         final TimeScale utc = TimeScalesFactory.getUTC();
169         final FieldVector3D<T> position = new FieldVector3D<>(zero.add(-6142438.668), zero.add(3492467.56), zero.add(-25767.257));
170         final FieldVector3D<T> velocity = new FieldVector3D<>(zero.add(506.0), zero.add(943.0), zero.add(7450));
171         final FieldAbsoluteDate<T> date = new FieldAbsoluteDate<>(field, 2003, 9, 16, utc);
172         final FieldOrbit<T> orbit = new FieldCartesianOrbit<>(new FieldPVCoordinates<>(position,  velocity),
173                                                               FramesFactory.getEME2000(), date,
174                                                               zero.add(Constants.EIGEN5C_EARTH_MU));
175         FieldEcksteinHechlerPropagator<T> propagator =
176                         new FieldEcksteinHechlerPropagator<>(orbit,
177                                                              Constants.EIGEN5C_EARTH_EQUATORIAL_RADIUS,
178                                                              zero.add(Constants.EIGEN5C_EARTH_MU),
179                                                              Constants.EIGEN5C_EARTH_C20,
180                                                              Constants.EIGEN5C_EARTH_C30,
181                                                              Constants.EIGEN5C_EARTH_C40,
182                                                              Constants.EIGEN5C_EARTH_C50,
183                                                              Constants.EIGEN5C_EARTH_C60);
184 
185         final AbsoluteDate t0    = propagator.getInitialState().getDate().toAbsoluteDate();
186         final AbsoluteDate start = t0.shiftedBy( 120);
187         final AbsoluteDate stop  = t0.shiftedBy(1120);
188         FieldParameterDrivenDateIntervalDetector<T> detector =
189                         new FieldParameterDrivenDateIntervalDetector<>(field, "no-shift", start, stop).
190                         withMaxCheck(10.0).
191                         withThreshold(zero.newInstance(1.0e-12)).
192                         withHandler(new FieldContinueOnEvent<>());
193 
194         Assertions.assertEquals(10.0, detector.getMaxCheckInterval().currentInterval(null, true), 1.0e-15);
195         Assertions.assertEquals(1.0e-12, detector.getThreshold().getReal(), 1.0e-15);
196         Assertions.assertEquals(AbstractDetector.DEFAULT_MAX_ITER, detector.getMaxIterationCount());
197         Assertions.assertEquals("no-shift_START", detector.getStartDriver().getName());
198         Assertions.assertEquals("no-shift_STOP", detector.getStopDriver().getName());
199 
200         FieldEventsLogger<T> logger = new FieldEventsLogger<>();
201         propagator.addEventDetector(logger.monitorDetector(detector));
202 
203         final double startShift = 500.5;
204         detector.getStartDriver().setValue(startShift);
205         final double stopShift  = -500.5;
206         detector.getStopDriver().setValue(stopShift);
207         propagator.propagate(propagator.getInitialState().getOrbit().getDate().shiftedBy(Constants.JULIAN_DAY));
208 
209         Assertions.assertEquals(0, logger.getLoggedEvents().size());
210 
211     }
212 
213     @BeforeEach
214     public void setUp() {
215         Utils.setDataRoot("regular-data");
216     }
217 
218 }
219