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