1   /* Copyright 2022-2025 Romain Serra
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.orbits;
18  
19  import org.hipparchus.complex.Complex;
20  import org.hipparchus.util.Binary64;
21  import org.junit.jupiter.api.Assertions;
22  import org.junit.jupiter.api.Test;
23  import org.junit.jupiter.params.ParameterizedTest;
24  import org.junit.jupiter.params.provider.EnumSource;
25  import org.junit.jupiter.params.provider.ValueSource;
26  import org.orekit.errors.OrekitException;
27  import org.orekit.errors.OrekitMessages;
28  
29  class FieldEquinoctialLongitudeArgumentUtilityTest {
30  
31      private static final Complex EX = new Complex(0.1, 0.);
32      private static final Complex EY = new Complex(0.66, 0.);
33      private static final double TOLERANCE = 1e-10;
34  
35      @Test
36      void testMeanToTrueAndBack() {
37          // GIVEN
38          final Complex expectedLatitudeArgument = new Complex(3., 0.);
39          // WHEN
40          final Complex intermediateLatitudeArgument = FieldEquinoctialLongitudeArgumentUtility.meanToTrue(
41                  EX, EY, expectedLatitudeArgument);
42          final Complex actualLatitudeArgument = FieldEquinoctialLongitudeArgumentUtility.trueToMean(
43                  EX, EY, intermediateLatitudeArgument);
44          // THEN
45          Assertions.assertEquals(expectedLatitudeArgument.getReal(), actualLatitudeArgument.getReal(), TOLERANCE);
46      }
47  
48      @Test
49      void testEccentricToTrueAndBack() {
50          // GIVEN
51          final Complex expectedLatitudeArgument = new Complex(3., 0.);
52          // WHEN
53          final Complex intermediateLatitudeArgument = FieldEquinoctialLongitudeArgumentUtility
54                  .eccentricToTrue(EX, EY, expectedLatitudeArgument);
55          final Complex actualLatitudeArgument = FieldEquinoctialLongitudeArgumentUtility
56                  .trueToEccentric(EX, EY, intermediateLatitudeArgument);
57          // THEN
58          Assertions.assertEquals(expectedLatitudeArgument.getReal(), actualLatitudeArgument.getReal(), TOLERANCE);
59      }
60  
61      @Test
62      void testEccentricToMeanAndBack() {
63          // GIVEN
64          final Complex expectedLatitudeArgument = new Complex(3., 0.);
65          // WHEN
66          final Complex intermediateLatitudeArgument = FieldEquinoctialLongitudeArgumentUtility
67                  .eccentricToMean(EX, EY, expectedLatitudeArgument);
68          final Complex actualLatitudeArgument = FieldEquinoctialLongitudeArgumentUtility
69                  .meanToEccentric(EX, EY, intermediateLatitudeArgument);
70          // THEN
71          Assertions.assertEquals(expectedLatitudeArgument.getReal(), actualLatitudeArgument.getReal(), TOLERANCE);
72      }
73  
74      @Test
75      void testMeanToTrueVersusDouble() {
76          // GIVEN
77          final Complex fieldOriginalPositionAngle = new Complex(3., 0.);
78          // WHEN
79          final double actualConvertedPositionAngle = FieldEquinoctialLongitudeArgumentUtility.meanToTrue(
80                  EX, EY, fieldOriginalPositionAngle).getReal();
81          // THEN
82          final double expectedPositionAngle = CircularLatitudeArgumentUtility.meanToTrue(
83                  EX.getReal(), EY.getReal(), fieldOriginalPositionAngle.getReal());
84          Assertions.assertEquals(expectedPositionAngle, actualConvertedPositionAngle, TOLERANCE);
85      }
86  
87      @Test
88      void testMeanToEccentricVersusDouble() {
89          // GIVEN
90          final Complex fieldOriginalPositionAngle = new Complex(3., 0.);
91          // WHEN
92          final double actualConvertedPositionAngle = FieldEquinoctialLongitudeArgumentUtility.meanToEccentric(
93                  EX, EY, fieldOriginalPositionAngle).getReal();
94          // THEN
95          final double expectedPositionAngle = CircularLatitudeArgumentUtility.meanToEccentric(
96                  EX.getReal(), EY.getReal(), fieldOriginalPositionAngle.getReal());
97          Assertions.assertEquals(expectedPositionAngle, actualConvertedPositionAngle, TOLERANCE);
98      }
99  
100     @Test
101     void testTrueToEccentricVersusDouble() {
102         // GIVEN
103         final Complex fieldOriginalPositionAngle = new Complex(3., 0.);
104         // WHEN
105         final double actualConvertedPositionAngle = FieldEquinoctialLongitudeArgumentUtility.trueToEccentric(
106                 EX, EY, fieldOriginalPositionAngle).getReal();
107         // THEN
108         final double expectedPositionAngle = CircularLatitudeArgumentUtility.trueToEccentric(
109                 EX.getReal(), EY.getReal(), fieldOriginalPositionAngle.getReal());
110         Assertions.assertEquals(expectedPositionAngle, actualConvertedPositionAngle, TOLERANCE);
111     }
112 
113     @Test
114     void testTrueToMeanVersusDouble() {
115         // GIVEN
116         final Complex fieldOriginalPositionAngle = new Complex(3., 0.);
117         // WHEN
118         final double actualConvertedPositionAngle = FieldEquinoctialLongitudeArgumentUtility.trueToMean(
119                 EX, EY, fieldOriginalPositionAngle).getReal();
120         // THEN
121         final double expectedPositionAngle = CircularLatitudeArgumentUtility.trueToMean(
122                 EX.getReal(), EY.getReal(), fieldOriginalPositionAngle.getReal());
123         Assertions.assertEquals(expectedPositionAngle, actualConvertedPositionAngle, TOLERANCE);
124     }
125 
126     @Test
127     void testEccentricToMeanVersusDouble() {
128         // GIVEN
129         final Complex fieldOriginalPositionAngle = new Complex(3., 0.);
130         // WHEN
131         final double actualConvertedPositionAngle = FieldEquinoctialLongitudeArgumentUtility.eccentricToMean(
132                 EX, EY, fieldOriginalPositionAngle).getReal();
133         // THEN
134         final double expectedPositionAngle = CircularLatitudeArgumentUtility.eccentricToMean(
135                 EX.getReal(), EY.getReal(), fieldOriginalPositionAngle.getReal());
136         Assertions.assertEquals(expectedPositionAngle, actualConvertedPositionAngle, TOLERANCE);
137     }
138 
139     @Test
140     void testEccentricToTrueVersusDouble() {
141         // GIVEN
142         final Complex fieldOriginalPositionAngle = new Complex(3., 0.);
143         // WHEN
144         final double actualConvertedPositionAngle = FieldEquinoctialLongitudeArgumentUtility.eccentricToTrue(
145                 EX, EY, fieldOriginalPositionAngle).getReal();
146         // THEN
147         final double expectedPositionAngle = CircularLatitudeArgumentUtility.eccentricToTrue(
148                 EX.getReal(), EY.getReal(), fieldOriginalPositionAngle.getReal());
149         Assertions.assertEquals(expectedPositionAngle, actualConvertedPositionAngle, TOLERANCE);
150     }
151 
152     @Test
153     void testMeanToEccentricException() {
154         // GIVEN
155         final Complex fieldNaNPositionAngle = Complex.NaN;
156         // WHEN & THEN
157         Assertions.assertThrows(OrekitException.class, () -> FieldEquinoctialLongitudeArgumentUtility.meanToEccentric(EX,
158                 EY, fieldNaNPositionAngle), OrekitMessages.UNABLE_TO_COMPUTE_ECCENTRIC_LONGITUDE_ARGUMENT.toString());
159     }
160 
161     @ParameterizedTest
162     @EnumSource(PositionAngleType.class)
163     void testConvertLVersusDouble(final PositionAngleType positionAngleType) {
164         // GIVEN
165         final Complex fieldOriginalPositionAngle = new Complex(3., 0.);
166         final PositionAngleType outputType = PositionAngleType.ECCENTRIC;
167         // WHEN
168         final double actualConvertedPositionAngle = FieldEquinoctialLongitudeArgumentUtility.convertL(positionAngleType,
169                 fieldOriginalPositionAngle, EX, EY, outputType).getReal();
170         // THEN
171         final double expectedPositionAngle = EquinoctialLongitudeArgumentUtility.convertL(positionAngleType,
172                 fieldOriginalPositionAngle.getReal(), EX.getReal(), EY.getReal(), outputType);
173         Assertions.assertEquals(expectedPositionAngle, actualConvertedPositionAngle, TOLERANCE);
174     }
175 
176     @ParameterizedTest
177     @ValueSource(doubles = {1e3, 5e3, 1e4, 1e5, 5e5})
178     void testIssue1525(final double alphaM) {
179         final double ex = 0.44940492906694396;
180         final double ey = 0.56419162961687;
181         final Binary64 zero = Binary64.ZERO;
182         Assertions.assertDoesNotThrow(() -> FieldEquinoctialLongitudeArgumentUtility
183                 .meanToEccentric(zero.newInstance(ex), zero.newInstance(ey), zero.newInstance(alphaM)));
184     }
185 
186 }