1   package org.orekit.forces.radiation;
2   
3   import org.hipparchus.complex.Complex;
4   import org.hipparchus.complex.ComplexField;
5   import org.hipparchus.geometry.euclidean.threed.Vector3D;
6   import org.junit.jupiter.api.Assertions;
7   import org.junit.jupiter.api.BeforeEach;
8   import org.junit.jupiter.api.Test;
9   import org.orekit.Utils;
10  import org.orekit.bodies.AnalyticalSolarPositionProvider;
11  import org.orekit.bodies.OneAxisEllipsoid;
12  import org.orekit.errors.OrekitException;
13  import org.orekit.frames.Frame;
14  import org.orekit.frames.FramesFactory;
15  import org.orekit.orbits.CartesianOrbit;
16  import org.orekit.propagation.FieldSpacecraftState;
17  import org.orekit.propagation.SpacecraftState;
18  import org.orekit.propagation.events.EventDetectionSettings;
19  import org.orekit.propagation.events.EventDetector;
20  import org.orekit.propagation.events.FieldEventDetector;
21  import org.orekit.propagation.events.handlers.FieldResetDerivativesOnEvent;
22  import org.orekit.propagation.events.handlers.ResetDerivativesOnEvent;
23  import org.orekit.time.AbsoluteDate;
24  import org.orekit.utils.Constants;
25  import org.orekit.utils.ExtendedPositionProvider;
26  import org.orekit.utils.PVCoordinates;
27  
28  import java.util.List;
29  
30  class ConicallyShadowedLightFluxModelTest {
31  
32      @BeforeEach
33      public void setUp() throws OrekitException {
34          Utils.setDataRoot("potential/shm-format:regular-data");
35      }
36  
37      @Test
38      void testConstructor() {
39          // GIVEN
40          final ExtendedPositionProvider positionProvider = new AnalyticalSolarPositionProvider();
41          final ConicallyShadowedLightFluxModel fluxModel = new ConicallyShadowedLightFluxModel(1., 1.,
42                  positionProvider, 1.);
43          // WHEN
44          final List<EventDetector> detectors = fluxModel.getEclipseConditionsDetector();
45          // THEN
46          final EventDetectionSettings detectionSettings = ConicallyShadowedLightFluxModel.getDefaultEclipseDetectionSettings();
47          Assertions.assertEquals(detectionSettings.getMaxIterationCount(), detectors.get(0).getMaxIterationCount());
48          Assertions.assertEquals(detectionSettings.getThreshold(), detectors.get(0).getThreshold());
49      }
50  
51      @Test
52      void testGetEclipseConditionsDetector() {
53          // GIVEN
54          final ExtendedPositionProvider positionProvider = new AnalyticalSolarPositionProvider();
55          final ConicallyShadowedLightFluxModel fluxModel = new ConicallyShadowedLightFluxModel(1., positionProvider,
56                  1.);
57          // WHEN
58          final List<EventDetector> detectors = fluxModel.getEclipseConditionsDetector();
59          // THEN
60          Assertions.assertEquals(2, detectors.size());
61          for (EventDetector detector : detectors) {
62              Assertions.assertInstanceOf(ResetDerivativesOnEvent.class, detector.getHandler());
63          }
64      }
65  
66      @Test
67      void testGetFieldEclipseConditionsDetector() {
68          // GIVEN
69          final ExtendedPositionProvider positionProvider = new AnalyticalSolarPositionProvider();
70          final ConicallyShadowedLightFluxModel fluxModel = new ConicallyShadowedLightFluxModel(1., positionProvider,
71                  1.);
72          final ComplexField field = ComplexField.getInstance();
73          // WHEN
74          final List<FieldEventDetector<Complex>> fieldDetectors = fluxModel.getFieldEclipseConditionsDetector(field);
75          // THEN
76          final List<EventDetector> detectors = fluxModel.getEclipseConditionsDetector();
77          Assertions.assertEquals(detectors.size(), fieldDetectors.size());
78          for (int i = 0; i < detectors.size(); i++) {
79              Assertions.assertInstanceOf(FieldResetDerivativesOnEvent.class, fieldDetectors.get(i).getHandler());
80              Assertions.assertEquals(detectors.get(i).getThreshold(), fieldDetectors.get(i).getThreshold().getReal());
81              Assertions.assertEquals(detectors.get(i).getMaxIterationCount(), fieldDetectors.get(i).getMaxIterationCount());
82          }
83          final SpacecraftState state = new SpacecraftState(new CartesianOrbit(new PVCoordinates(Vector3D.PLUS_I, Vector3D.MINUS_J),
84                  FramesFactory.getEME2000(), AbsoluteDate.ARBITRARY_EPOCH, 1.));
85          final FieldSpacecraftState<Complex> fieldState = new FieldSpacecraftState<>(field, state);
86          fluxModel.init(fieldState, null);
87          for (int i = 0; i < detectors.size(); i++) {
88              Assertions.assertEquals(detectors.get(i).g(state), fieldDetectors.get(i).g(fieldState).getReal(), 1e-8);
89              Assertions.assertEquals(detectors.get(i).getMaxCheckInterval().currentInterval(state, true),
90                      fieldDetectors.get(i).getMaxCheckInterval().currentInterval(fieldState, true), 1e-14);
91          }
92      }
93  
94      @Test
95      void testFieldGetLightingRatio() {
96          // GIVEN
97          final ExtendedPositionProvider positionProvider = new AnalyticalSolarPositionProvider();
98          final ConicallyShadowedLightFluxModel fluxModel = new ConicallyShadowedLightFluxModel(Constants.SUN_RADIUS, positionProvider,
99                  Constants.EGM96_EARTH_EQUATORIAL_RADIUS);
100         final ComplexField field = ComplexField.getInstance();
101         // WHEN & THEN
102         for (int i = 0; i < 100000; i++) {
103             final SpacecraftState state = new SpacecraftState(new CartesianOrbit(
104                     new PVCoordinates(new Vector3D(fluxModel.getOccultingBodyRadius() + 500e3, 0., 1e3), new Vector3D(1e1, 7e3, 1e2)),
105                     FramesFactory.getEME2000(), AbsoluteDate.ARBITRARY_EPOCH.shiftedBy(i * 3600.), Constants.EGM96_EARTH_MU));
106             final FieldSpacecraftState<Complex> fieldState = new FieldSpacecraftState<>(field, state);
107             final double expectedRatio = fluxModel.getLightingRatio(state);
108             Assertions.assertEquals(expectedRatio, fluxModel.getLightingRatio(fieldState).getReal(), 1e-8);
109         }
110     }
111 
112     @Test
113     void testGetLightingRatio() {
114         // GIVEN
115         final ExtendedPositionProvider positionProvider = new AnalyticalSolarPositionProvider();
116         final ConicallyShadowedLightFluxModel fluxModel = new ConicallyShadowedLightFluxModel(Constants.SUN_RADIUS, positionProvider,
117                 Constants.EGM96_EARTH_EQUATORIAL_RADIUS);
118         final Frame frame = FramesFactory.getGCRF();
119         final SolarRadiationPressure radiationPressure = new SolarRadiationPressure(positionProvider,
120                 new OneAxisEllipsoid(fluxModel.getOccultingBodyRadius(), 0., FramesFactory.getGCRF()), null);
121         // WHEN & THEN
122         for (int i = 0; i < 10000; i++) {
123             final SpacecraftState state = new SpacecraftState(new CartesianOrbit(
124                     new PVCoordinates(new Vector3D(fluxModel.getOccultingBodyRadius() + 500e3, 0., 1e3), new Vector3D(1e1, 7e3, 1e2)),
125                     frame, AbsoluteDate.ARBITRARY_EPOCH.shiftedBy(i * 3600.), Constants.EGM96_EARTH_MU));
126             final double expectedRatio = radiationPressure.getLightingRatio(state);
127             Assertions.assertEquals(expectedRatio, fluxModel.getLightingRatio(state), 1e-6);
128         }
129     }
130 
131 }