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.orbits;
18  
19  import org.hipparchus.CalculusFieldElement;
20  import org.hipparchus.Field;
21  import org.hipparchus.complex.Complex;
22  import org.hipparchus.util.Binary64Field;
23  import org.junit.jupiter.api.Assertions;
24  import org.junit.jupiter.api.Test;
25  import org.junit.jupiter.params.ParameterizedTest;
26  import org.junit.jupiter.params.provider.EnumSource;
27  
28  public class FieldKeplerianAnomalyUtilityTest {
29  
30      @Test
31      public void testEllipticMeanToTrue() {
32          doTestEllipticMeanToTrue(Binary64Field.getInstance());
33      }
34  
35      @Test
36      public void testEllipticTrueToMean() {
37          doTestEllipticTrueToMean(Binary64Field.getInstance());
38      }
39  
40      @Test
41      public void testEllipticEccentricToTrue() {
42          doTestEllipticEccentricToTrue(Binary64Field.getInstance());
43      }
44  
45      @Test
46      public void testEllipticTrueToEccentric() {
47          doTestEllipticTrueToEccentric(Binary64Field.getInstance());
48      }
49  
50      @Test
51      public void testEllipticMeanToEccentric() {
52          doTestEllipticMeanToEccentric(Binary64Field.getInstance());
53      }
54  
55      @Test
56      public void testEllipticEccentricToMean() {
57          doTestEllipticEccentricToMean(Binary64Field.getInstance());
58      }
59  
60      @Test
61      public void testHyperbolicMeanToTrue() {
62          doTestHyperbolicMeanToTrue(Binary64Field.getInstance());
63      }
64  
65      @Test
66      public void testHyperbolicTrueToMean() {
67          doTestHyperbolicTrueToMean(Binary64Field.getInstance());
68      }
69  
70      @Test
71      public void testHyperbolicEccentricToTrue() {
72          doTestHyperbolicEccentricToTrue(Binary64Field.getInstance());
73      }
74  
75      @Test
76      public void testHyperbolicTrueToEccentric() {
77          doTestHyperbolicTrueToEccentric(Binary64Field.getInstance());
78      }
79  
80      @Test
81      public void testHyperbolicMeanToEccentric() {
82          doTestHyperbolicMeanToEccentric(Binary64Field.getInstance());
83      }
84  
85      @Test
86      public void testHyperbolicEccentricToMean() {
87          doTestHyperbolicEccentricToMean(Binary64Field.getInstance());
88      }
89  
90      @Test
91      public void testIssue544() {
92          doTestIssue544(Binary64Field.getInstance());
93      }
94  
95      private <T extends CalculusFieldElement<T>> void doTestEllipticMeanToTrue(final Field<T> field) {
96          final T e = field.getZero().add(0.231);
97          final T M = field.getZero().add(2.045);
98          final T v = FieldKeplerianAnomalyUtility.ellipticMeanToTrue(e, M);
99          Assertions.assertEquals(2.4004986679372027, v.getReal(), 1e-14);
100     }
101 
102     private <T extends CalculusFieldElement<T>> void doTestEllipticTrueToMean(final Field<T> field) {
103         final T e = field.getZero().add(0.487);
104         final T v = field.getZero().add(1.386);
105         final T M = FieldKeplerianAnomalyUtility.ellipticTrueToMean(e, v);
106         Assertions.assertEquals(0.5238159114936672, M.getReal(), 1e-14);
107     }
108 
109     private <T extends CalculusFieldElement<T>> void doTestEllipticEccentricToTrue(final Field<T> field) {
110         final T e = field.getZero().add(0.687);
111         final T E = field.getZero().add(4.639);
112         final T v = FieldKeplerianAnomalyUtility.ellipticEccentricToTrue(e, E);
113         Assertions.assertEquals(3.903008140176819, v.getReal(), 1e-14);
114     }
115 
116     private <T extends CalculusFieldElement<T>> void doTestEllipticTrueToEccentric(final Field<T> field) {
117         final T e = field.getZero().add(0.527);
118         final T v = field.getZero().add(0.768);
119         final T E = FieldKeplerianAnomalyUtility.ellipticTrueToEccentric(e, v);
120         Assertions.assertEquals(0.44240462411915754, E.getReal(), 1e-14);
121     }
122 
123     private <T extends CalculusFieldElement<T>> void doTestEllipticMeanToEccentric(final Field<T> field) {
124         final T e1 = field.getZero().add(0.726);
125         final T M1 = field.getZero().add(0.);
126         final T E1 = FieldKeplerianAnomalyUtility.ellipticMeanToEccentric(e1, M1);
127         Assertions.assertEquals(0.0, E1.getReal(), 1e-14);
128 
129         final T e2 = field.getZero().add(0.065);
130         final T M2 = field.getZero().add(4.586);
131         final T E2 = FieldKeplerianAnomalyUtility.ellipticMeanToEccentric(e2, M2);
132         Assertions.assertEquals(4.522172385101093, E2.getReal(), 1e-14);
133 
134         final T e3 = field.getZero().add(0.403);
135         final T M3 = field.getZero().add(0.121);
136         final T E3 = FieldKeplerianAnomalyUtility.ellipticMeanToEccentric(e3, M3);
137         Assertions.assertEquals(0.20175794699115656, E3.getReal(), 1e-14);
138 
139         final T e4 = field.getZero().add(0.999);
140         final T M4 = field.getZero().add(0.028);
141         final T E4 = FieldKeplerianAnomalyUtility.ellipticMeanToEccentric(e4, M4);
142         Assertions.assertEquals(0.5511071508829587, E4.getReal(), 1e-14);
143     }
144 
145     private <T extends CalculusFieldElement<T>> void doTestEllipticEccentricToMean(final Field<T> field) {
146         final T e = field.getZero().add(0.192);
147         final T E = field.getZero().add(2.052);
148         final T M = FieldKeplerianAnomalyUtility.ellipticEccentricToMean(e, E);
149         Assertions.assertEquals(1.881803817764882, M.getReal(), 1e-14);
150     }
151 
152     private <T extends CalculusFieldElement<T>> void doTestHyperbolicMeanToTrue(final Field<T> field) {
153         final T e = field.getZero().add(1.027);
154         final T M = field.getZero().add(1.293);
155         final T v = FieldKeplerianAnomalyUtility.hyperbolicMeanToTrue(e, M);
156         Assertions.assertEquals(2.8254185280004855, v.getReal(), 1e-14);
157     }
158 
159     private <T extends CalculusFieldElement<T>> void doTestHyperbolicTrueToMean(final Field<T> field) {
160         final T e = field.getZero().add(1.161);
161         final T v = field.getZero().add(-2.469);
162         final T M = FieldKeplerianAnomalyUtility.hyperbolicTrueToMean(e, v);
163         Assertions.assertEquals(-2.5499244818919915, M.getReal(), 1e-14);
164     }
165 
166     private <T extends CalculusFieldElement<T>> void doTestHyperbolicEccentricToTrue(final Field<T> field) {
167         final T e = field.getZero().add(2.161);
168         final T E = field.getZero().add(-1.204);
169         final T v = FieldKeplerianAnomalyUtility.hyperbolicEccentricToTrue(e, E);
170         Assertions.assertEquals(-1.4528528149658333, v.getReal(), 1e-14);
171     }
172 
173     private <T extends CalculusFieldElement<T>> void doTestHyperbolicTrueToEccentric(final Field<T> field) {
174         final T e = field.getZero().add(1.595);
175         final T v = field.getZero().add(0.298);
176         final T E = FieldKeplerianAnomalyUtility.hyperbolicTrueToEccentric(e, v);
177         Assertions.assertEquals(0.1440079208139455, E.getReal(), 1e-14);
178     }
179 
180     private <T extends CalculusFieldElement<T>> void doTestHyperbolicMeanToEccentric(final Field<T> field) {
181         final T e1 = field.getZero().add(1.201);
182         final T M1 = field.getZero();
183         final T E1 = FieldKeplerianAnomalyUtility.hyperbolicMeanToEccentric(e1, M1);
184         Assertions.assertEquals(0.0, E1.getReal(), 1e-14);
185 
186         final T e2 = field.getZero().add(1.127);
187         final T M2 = field.getZero().add(-3.624);
188         final T E2 = FieldKeplerianAnomalyUtility.hyperbolicMeanToEccentric(e2, M2);
189         Assertions.assertEquals(-2.3736718687722265, E2.getReal(), 1e-14);
190 
191         final T e3 = field.getZero().add(1.338);
192         final T M3 = field.getZero().add(-0.290);
193         final T E3 = FieldKeplerianAnomalyUtility.hyperbolicMeanToEccentric(e3, M3);
194         Assertions.assertEquals(-0.6621795141831807, E3.getReal(), 1e-14);
195 
196         final T e4 = field.getZero().add(1.044);
197         final T M4 = field.getZero().add(3.996);
198         final T E4 = FieldKeplerianAnomalyUtility.hyperbolicMeanToEccentric(e4, M4);
199         Assertions.assertEquals(2.532614977388778, E4.getReal(), 1e-14);
200 
201         final T e5 = field.getZero().add(2.052);
202         final T M5 = field.getZero().add(4.329);
203         final T E5 = FieldKeplerianAnomalyUtility.hyperbolicMeanToEccentric(e5, M5);
204         Assertions.assertEquals(1.816886788278918, E5.getReal(), 1e-14);
205 
206         final T e6 = field.getZero().add(2.963);
207         final T M6 = field.getZero().add(-1.642);
208         final T E6 = FieldKeplerianAnomalyUtility.hyperbolicMeanToEccentric(e6, M6);
209         Assertions.assertEquals(-0.7341946491456494, E6.getReal(), 1e-14);
210 
211         final T e7 = field.getZero().add(4.117);
212         final T M7 = field.getZero().add(-0.286);
213         final T E7 = FieldKeplerianAnomalyUtility.hyperbolicMeanToEccentric(e7, M7);
214         Assertions.assertEquals(-0.09158570899196887, E7.getReal(), 1e-14);
215 
216         // Issue 951.
217         final T e8 = field.getZero().add(1.251844925917281);
218         final T M8 = field.getZero().add(54.70111712786907);
219         final T E8 = FieldKeplerianAnomalyUtility.hyperbolicMeanToEccentric(e8, M8);
220         Assertions.assertEquals(4.550432282228856, E8.getReal(), 1e-14);
221     }
222 
223     private <T extends CalculusFieldElement<T>> void doTestHyperbolicEccentricToMean(final Field<T> field) {
224         final T e = field.getZero().add(1.801);
225         final T E = field.getZero().add(3.287);
226         final T M = FieldKeplerianAnomalyUtility.hyperbolicEccentricToMean(e, E);
227         Assertions.assertEquals(20.77894350750361, M.getReal(), 1e-14);
228     }
229 
230     private <T extends CalculusFieldElement<T>> void doTestIssue544(final Field<T> field) {
231         // Initial parameters
232         // In order to test the issue, we voluntarily set the anomaly at T.NaN.
233         T e = field.getZero().add(0.7311);
234         T anomaly = field.getZero().add(Double.NaN);
235         // Computes the elliptic eccentric anomaly
236         T E = FieldKeplerianAnomalyUtility.ellipticMeanToEccentric(e, anomaly);
237         // Verify that an infinite loop did not occur
238         Assertions.assertTrue(Double.isNaN(E.getReal()));
239     }
240 
241     @ParameterizedTest
242     @EnumSource(PositionAngleType.class)
243     void testConvertAnomalyEllipticVersusDouble(final PositionAngleType positionAngleType) {
244         // GIVEN
245         final Complex fieldOriginalPositionAngle = new Complex(3., 0.);
246         final PositionAngleType outputType = PositionAngleType.TRUE;
247         final Complex eccentricity = new Complex(0.5, 0.);
248         // WHEN
249         final double actualConvertedPositionAngle = FieldKeplerianAnomalyUtility.convertAnomaly(positionAngleType,
250                 fieldOriginalPositionAngle, eccentricity, outputType).getReal();
251         // THEN
252         final double expectedPositionAngle = KeplerianAnomalyUtility.convertAnomaly(positionAngleType,
253                 fieldOriginalPositionAngle.getReal(), eccentricity.getReal(), outputType);
254         Assertions.assertEquals(expectedPositionAngle, actualConvertedPositionAngle, 1e-12);
255     }
256 
257     @ParameterizedTest
258     @EnumSource(PositionAngleType.class)
259     void testConvertAnomalyHyperbolicVersusDouble(final PositionAngleType positionAngleType) {
260         // GIVEN
261         final Complex fieldOriginalPositionAngle = new Complex(3., 0.);
262         final PositionAngleType outputType = PositionAngleType.MEAN;
263         final Complex eccentricity = new Complex(2., 0.);
264         // WHEN
265         final double actualConvertedPositionAngle = FieldKeplerianAnomalyUtility.convertAnomaly(positionAngleType,
266                 fieldOriginalPositionAngle, eccentricity, outputType).getReal();
267         // THEN
268         final double expectedPositionAngle = KeplerianAnomalyUtility.convertAnomaly(positionAngleType,
269                 fieldOriginalPositionAngle.getReal(), eccentricity.getReal(), outputType);
270         Assertions.assertEquals(expectedPositionAngle, actualConvertedPositionAngle, 1e-12);
271     }
272 }