1   /* Copyright 2002-2024 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.forces.gravity.potential;
18  
19  import org.hipparchus.util.CombinatoricsUtils;
20  import org.hipparchus.util.FastMath;
21  import org.hipparchus.util.Precision;
22  import org.junit.jupiter.api.Assertions;
23  import org.junit.jupiter.api.Test;
24  import org.orekit.Utils;
25  import org.orekit.data.DataContext;
26  import org.orekit.errors.OrekitException;
27  import org.orekit.errors.OrekitMessages;
28  import org.orekit.forces.gravity.potential.NormalizedSphericalHarmonicsProvider.NormalizedSphericalHarmonics;
29  import org.orekit.forces.gravity.potential.UnnormalizedSphericalHarmonicsProvider.UnnormalizedSphericalHarmonics;
30  import org.orekit.time.AbsoluteDate;
31  import org.orekit.time.TimeScalesFactory;
32  
33  import java.io.File;
34  import java.util.Set;
35  
36  public class GravityFieldFactoryTest {
37  
38      @Test
39      public void testDefaultEGMMissingCoefficients() {
40          Utils.setDataRoot("potential/egm-format");
41          // we explicitly DON'T call GravityFieldFactory.addPotentialCoefficientsReader
42          // to make sure we use only the default readers
43          try {
44              GravityFieldFactory.getUnnormalizedProvider(5, 3);
45              Assertions.fail("an exception should have been thrown");
46          } catch (OrekitException oe) {
47              Assertions.assertEquals(OrekitMessages.MISSING_GRAVITY_FIELD_COEFFICIENT_IN_FILE, oe.getSpecifier());
48              Assertions.assertEquals("egm96_to5.ascii.gz", new File((String) oe.getParts()[3]).getName());
49          }
50      }
51  
52      @Test
53      public void testDefaultGRGSMissingCoefficients() {
54          Utils.setDataRoot("potential/grgs-format");
55          // we explicitly DON'T call GravityFieldFactory.addPotentialCoefficientsReader
56          // to make sure we use only the default readers
57          try {
58              GravityFieldFactory.getUnnormalizedProvider(5, 3);
59              Assertions.fail("an exception should have been thrown");
60          } catch (OrekitException oe) {
61              Assertions.assertEquals(OrekitMessages.MISSING_GRAVITY_FIELD_COEFFICIENT_IN_FILE, oe.getSpecifier());
62              Assertions.assertEquals("grim5_C1.dat", new File((String) oe.getParts()[3]).getName());
63          }
64      }
65  
66      @Test
67      public void testDefaultIncludesICGEM() {
68          Utils.setDataRoot("potential/icgem-format");
69          // we explicitly DON'T call GravityFieldFactory.addPotentialCoefficientsReader
70          // to make sure we use only the default readers
71          UnnormalizedSphericalHarmonicsProvider provider = GravityFieldFactory.getUnnormalizedProvider(5, 3);
72          Assertions.assertEquals(5, provider.getMaxDegree());
73          Assertions.assertEquals(3, provider.getMaxOrder());
74          Set<String> loaded = DataContext.getDefault().getDataProvidersManager().getLoadedDataNames();
75          Assertions.assertEquals(1, loaded.size());
76          Assertions.assertEquals("g007_eigen_05c_coef", new File(loaded.iterator().next()).getName());
77      }
78  
79      @Test
80      public void testDefaultIncludesSHM() {
81          Utils.setDataRoot("potential/shm-format");
82          // we explicitly DON'T call GravityFieldFactory.addPotentialCoefficientsReader
83          // to make sure we use only the default readers
84          UnnormalizedSphericalHarmonicsProvider provider = GravityFieldFactory.getUnnormalizedProvider(5, 3);
85          Assertions.assertEquals(5, provider.getMaxDegree());
86          Assertions.assertEquals(3, provider.getMaxOrder());
87          Set<String> loaded = DataContext.getDefault().getDataProvidersManager().getLoadedDataNames();
88          Assertions.assertEquals(1, loaded.size());
89          Assertions.assertEquals("eigen_cg03c_coef", new File(loaded.iterator().next()).getName());
90      }
91  
92      @Test
93      public void testNormalizationFirstElements() {
94          int max = 50;
95          double[][] factors = GravityFieldFactory.getUnnormalizationFactors(max, max);
96          Assertions.assertEquals(max + 1, factors.length);
97          for (int i = 0; i <= max; ++i) {
98              Assertions.assertEquals(i + 1, factors[i].length);
99              for (int j = 0; j <= i; ++j) {
100                 double ref = FastMath.sqrt((2 * i + 1) *
101                                            CombinatoricsUtils.factorialDouble(i - j) /
102                                            CombinatoricsUtils.factorialDouble(i + j));
103                 if (j > 0) {
104                     ref *= FastMath.sqrt(2);
105                 }
106                 Assertions.assertEquals(ref, factors[i][j], 8.0e-15);
107             }
108         }
109     }
110 
111     @Test
112     public void testNormalizationSquareField() {
113         int max = 89;
114         double[][] factors = GravityFieldFactory.getUnnormalizationFactors(max, max);
115         Assertions.assertEquals(max + 1, factors.length);
116         for (int i = 0; i <= max; ++i) {
117             Assertions.assertEquals(i + 1, factors[i].length);
118             for (int j = 0; j <= i; ++j) {
119                 Assertions.assertTrue(factors[i][j] > Precision.SAFE_MIN);
120             }
121         }
122     }
123 
124     @Test
125     public void testNormalizationLowOrder() {
126         int maxDegree = 393;
127         int maxOrder  = 63;
128         double[][] factors = GravityFieldFactory.getUnnormalizationFactors(maxDegree, maxOrder);
129         Assertions.assertEquals(maxDegree + 1, factors.length);
130         for (int i = 0; i <= maxDegree; ++i) {
131             Assertions.assertEquals(FastMath.min(i, maxOrder) + 1, factors[i].length);
132             for (int j = 0; j <= FastMath.min(i, maxOrder); ++j) {
133                 Assertions.assertTrue(factors[i][j] > Precision.SAFE_MIN);
134             }
135         }
136     }
137 
138     @Test
139     public void testNormalizationUnderflowSquareField() {
140         Assertions.assertThrows(OrekitException.class, () -> {
141             GravityFieldFactory.getUnnormalizationFactors(90, 90);
142         });
143     }
144 
145     @Test
146     public void testNormalizationUnderflowLowOrder1() {
147         Assertions.assertThrows(OrekitException.class, () -> {
148             GravityFieldFactory.getUnnormalizationFactors(394, 63);
149         });
150     }
151 
152     @Test
153     public void testNormalizationUnderflowLowOrde2() {
154         Assertions.assertThrows(OrekitException.class, () -> {
155             GravityFieldFactory.getUnnormalizationFactors(393, 64);
156         });
157     }
158 
159     @Test
160     public void testUnnormalizer() throws OrekitException {
161         Utils.setDataRoot("potential/icgem-format");
162         final AbsoluteDate refDate = new AbsoluteDate(2004, 10, 1, 12, 0, 0.0, TimeScalesFactory.getTT());
163         final double shift = 1.23456e8;
164         UnnormalizedSphericalHarmonicsProvider ref =
165                 GravityFieldFactory.getUnnormalizedProvider(5, 5);
166         UnnormalizedSphericalHarmonics refHarmonics = ref.onDate(refDate.shiftedBy(shift));
167         NormalizedSphericalHarmonicsProvider normalized =
168                 GravityFieldFactory.getNormalizedProvider(5, 5);
169         UnnormalizedSphericalHarmonicsProvider unnormalized =
170                 GravityFieldFactory.getUnnormalizedProvider(normalized);
171         UnnormalizedSphericalHarmonics unnormalizedHarmonics = unnormalized.onDate(refDate.shiftedBy(shift));
172         Assertions.assertEquals(ref.getMaxDegree(), unnormalized.getMaxDegree());
173         Assertions.assertEquals(ref.getMaxOrder(), unnormalized.getMaxOrder());
174         Assertions.assertEquals(ref.getAe(), unnormalized.getAe(), FastMath.ulp(ref.getAe()));
175         Assertions.assertEquals(ref.getMu(), unnormalized.getMu(), FastMath.ulp(ref.getMu()));
176         for (int i = 0; i <= 5; ++i) {
177             for (int j = 0; j <= i; ++j) {
178                 double cRef  = refHarmonics.getUnnormalizedCnm(i, j);
179                 double cTest = unnormalizedHarmonics.getUnnormalizedCnm(i, j);
180                 Assertions.assertEquals(cRef, cTest, FastMath.ulp(cRef));
181                 double sRef  = refHarmonics.getUnnormalizedSnm(i, j);
182                 double sTest = unnormalizedHarmonics.getUnnormalizedSnm(i, j);
183                 Assertions.assertEquals(sRef, sTest, FastMath.ulp(sRef));
184             }
185         }
186     }
187 
188     @Test
189     public void testNormalizer() {
190         Utils.setDataRoot("potential/icgem-format");
191         final AbsoluteDate refDate = new AbsoluteDate(2004, 10, 1, 12, 0, 0.0, TimeScalesFactory.getTT());
192         final double shift = 1.23456e8;
193         NormalizedSphericalHarmonicsProvider ref =
194                 GravityFieldFactory.getNormalizedProvider(5, 5);
195         NormalizedSphericalHarmonics refHarmonics = ref.onDate(refDate.shiftedBy(shift));
196         UnnormalizedSphericalHarmonicsProvider unnormalized =
197                 GravityFieldFactory.getUnnormalizedProvider(5, 5);
198         NormalizedSphericalHarmonicsProvider normalized =
199                 GravityFieldFactory.getNormalizedProvider(unnormalized);
200         NormalizedSphericalHarmonics normalizedHarmonics = normalized.onDate(refDate.shiftedBy(shift));
201         Assertions.assertEquals(ref.getMaxDegree(), normalized.getMaxDegree());
202         Assertions.assertEquals(ref.getMaxOrder(), normalized.getMaxOrder());
203         Assertions.assertEquals(ref.getAe(), normalized.getAe(), FastMath.ulp(ref.getAe()));
204         Assertions.assertEquals(ref.getMu(), normalized.getMu(), FastMath.ulp(ref.getMu()));
205         for (int i = 0; i <= 5; ++i) {
206             for (int j = 0; j <= i; ++j) {
207                 double cRef  = refHarmonics.getNormalizedCnm(i, j);
208                 double cTest = normalizedHarmonics.getNormalizedCnm(i, j);
209                 Assertions.assertEquals(cRef, cTest, FastMath.ulp(cRef));
210                 double sRef  = refHarmonics.getNormalizedSnm(i, j);
211                 double sTest = normalizedHarmonics.getNormalizedSnm(i, j);
212                 Assertions.assertEquals(sRef, sTest, FastMath.ulp(sRef));
213             }
214         }
215     }
216 
217 }