1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.models.earth.atmosphere;
18
19 import org.hipparchus.CalculusFieldElement;
20 import org.hipparchus.Field;
21 import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
22 import org.hipparchus.geometry.euclidean.threed.Rotation;
23 import org.hipparchus.geometry.euclidean.threed.RotationConvention;
24 import org.hipparchus.geometry.euclidean.threed.Vector3D;
25 import org.hipparchus.util.Binary64;
26 import org.hipparchus.util.Binary64Field;
27 import org.hipparchus.util.FastMath;
28 import org.junit.jupiter.api.Assertions;
29 import org.junit.jupiter.api.BeforeEach;
30 import org.junit.jupiter.api.Test;
31 import org.orekit.SolarInputs97to05;
32 import org.orekit.Utils;
33 import org.orekit.bodies.CelestialBody;
34 import org.orekit.bodies.CelestialBodyFactory;
35 import org.orekit.bodies.OneAxisEllipsoid;
36 import org.orekit.frames.Frame;
37 import org.orekit.frames.FramesFactory;
38 import org.orekit.frames.Transform;
39 import org.orekit.models.earth.ReferenceEllipsoid;
40 import org.orekit.time.AbsoluteDate;
41 import org.orekit.time.FieldAbsoluteDate;
42 import org.orekit.time.TimeScale;
43 import org.orekit.time.TimeScalesFactory;
44 import org.orekit.utils.Constants;
45 import org.orekit.utils.IERSConventions;
46 import org.orekit.utils.PVCoordinatesProvider;
47 import org.orekit.utils.TimeStampedFieldPVCoordinates;
48 import org.orekit.utils.TimeStampedPVCoordinates;
49
50 import java.util.TimeZone;
51
52 public class DTM2000Test {
53
54 @Test
55 public void testWithOriginalTestsCases() {
56
57 Frame itrf = FramesFactory.getITRF(IERSConventions.IERS_2010, true);
58 PVCoordinatesProvider sun = CelestialBodyFactory.getSun();
59 OneAxisEllipsoid earth = new OneAxisEllipsoid(6378136.460, 1.0 / 298.257222101, itrf);
60 SolarInputs97to05 in = SolarInputs97to05.getInstance();
61 earth.setAngularThreshold(1e-10);
62 DTM2000 atm = new DTM2000(in, sun, earth);
63 double roTestCase;
64 double myRo;
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82 roTestCase = 1.8710001353820e-17 * 1000;
83
84
85 myRo = atm.getDensity(185, 800*1000, 0, FastMath.toRadians(40), 16*FastMath.PI/12, 150, 150, 0, 0);
86 Assertions.assertEquals(roTestCase, myRo , roTestCase * 1e-14);
87
88
89
90 roTestCase= 2.8524195214905e-17* 1000;
91
92 myRo = atm.getDensity(275, 800*1000, 0, FastMath.toRadians(40), 16*FastMath.PI/12, 150, 150, 0, 0);
93 Assertions.assertEquals(roTestCase, myRo , roTestCase * 1e-14);
94
95
96
97 roTestCase= 1.7343324462212e-17* 1000;
98
99 myRo = atm.getDensity(355, 800*1000, 0, FastMath.toRadians(40), 16*FastMath.PI/12, 150, 150, 0, 0);
100 Assertions.assertEquals(roTestCase, myRo , roTestCase * 2e-14);
101
102
103 roTestCase= 2.9983740796297e-17* 1000;
104
105 myRo = atm.getDensity(85, 800*1000, 0, FastMath.toRadians(40), 16*FastMath.PI/12, 150, 150, 0, 0);
106 Assertions.assertEquals(roTestCase, myRo , roTestCase * 1e-14);
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132 roTestCase = 1.5699108952425600E-016* 1000;
133
134 myRo = atm.getDensity(15, 500*1000, 0, FastMath.toRadians(-70), 16*FastMath.PI/12, 70, 70, 0, 0);
135 Assertions.assertEquals(roTestCase, myRo , roTestCase * 1e-14);
136
137
138
139
140
141
142
143
144
145
146
147
148 roTestCase = 2.4123751406975562E-018* 1000;
149 myRo = atm.getDensity(15, 800*1000, 0, FastMath.toRadians(-70), 16*FastMath.PI/12, 70, 70, 0, 0);
150 Assertions.assertEquals(roTestCase, myRo , roTestCase * 1e-14);
151
152 }
153
154 @Test
155 public void testNonEarthRotationAxisAlignedFrame() {
156
157 AbsoluteDate date = AbsoluteDate.J2000_EPOCH;
158 Frame ecef = FramesFactory.getITRF(IERSConventions.IERS_2010, true);
159 Rotation rotation = new Rotation(Vector3D.PLUS_I, FastMath.PI / 2, RotationConvention.VECTOR_OPERATOR);
160 Frame frame = new Frame(ecef, new Transform(date, rotation), "other");
161 Vector3D pEcef = new Vector3D(6378137 + 300e3, 0, 0);
162 Vector3D pFrame = ecef.getStaticTransformTo(frame, date)
163 .transformPosition(pEcef);
164 PVCoordinatesProvider sun = CelestialBodyFactory.getSun();
165 OneAxisEllipsoid earth = new OneAxisEllipsoid(
166 6378136.460, 1.0 / 298.257222101, ecef);
167 SolarInputs97to05 in = SolarInputs97to05.getInstance();
168 earth.setAngularThreshold(1e-10);
169 DTM2000 atm = new DTM2000(in, sun, earth);
170
171
172 final double actual = atm.getDensity(date, pFrame, frame);
173
174
175 Assertions.assertEquals(atm.getDensity(date, pEcef, ecef), actual, 0.0);
176 }
177
178 @Test
179 public void testField() {
180 Frame itrf = FramesFactory.getITRF(IERSConventions.IERS_2010, true);
181 PVCoordinatesProvider sun = CelestialBodyFactory.getSun();
182 OneAxisEllipsoid earth = new OneAxisEllipsoid(6378136.460, 1.0 / 298.257222101, itrf);
183 SolarInputs97to05 in = SolarInputs97to05.getInstance();
184 earth.setAngularThreshold(1e-10);
185 DTM2000 atm = new DTM2000(in, sun, earth);
186
187
188 for (double alti = 400; alti < 1000; alti += 50) {
189 for (double lon = 0; lon < 6; lon += 0.5) {
190 for (double lat = -1.5; lat < 1.5; lat += 0.5) {
191 for (double hl = 0; hl < 6; hl += 0.5) {
192 double rhoD = atm.getDensity(185, alti*1000, lon, lat, hl, 50, 150, 0, 0);
193 Binary64 rho64 = atm.getDensity(185, new Binary64(alti*1000),
194 new Binary64(lon), new Binary64(lat),
195 new Binary64(hl), 50, 150, 0, 0);
196 Assertions.assertEquals(rhoD, rho64.getReal(), rhoD * 1e-14);
197 }
198 }
199 }
200 }
201
202 }
203
204
205 @Test
206 public void testIssue1365() {
207
208
209
210
211
212 final DTM2000InputParameters ip = new InputParamsIssue1365();
213
214
215 final Field<Binary64> field = Binary64Field.getInstance();
216
217
218 final AbsoluteDate date = new AbsoluteDate("2005-09-08T19:19:10.000", TimeScalesFactory.getUTC());
219 final FieldAbsoluteDate<Binary64> fieldDate = new FieldAbsoluteDate<>(field, date);
220
221
222 final Frame itrf = FramesFactory.getITRF(IERSConventions.IERS_2010, true);
223 final Vector3D sunPositionItrf = new Vector3D(-5.230565928624774E10, -1.4059879929943967E11, 1.4263029155223734E10);
224
225
226 final CelestialBody sunAtDate = new SunPositionIssue1365(sunPositionItrf, itrf);
227
228
229
230 final OneAxisEllipsoid earth = ReferenceEllipsoid.getWgs84(itrf);
231
232 final DTM2000 atm = new DTM2000(ip, sunAtDate, earth);
233
234
235 final Vector3D position = new Vector3D(4355380.654425714, 2296727.21938809, -4575242.76838552);
236 final FieldVector3D<Binary64> fieldPosition = new FieldVector3D<>(field, position);
237 final Frame j2000 = FramesFactory.getEME2000();
238
239
240
241
242 final double density = atm.getDensity(date, position, j2000);
243 final Binary64 fieldDensity = atm.getDensity(fieldDate, fieldPosition, j2000);
244
245
246
247
248
249 Assertions.assertFalse(Double.isNaN(density));
250 Assertions.assertFalse(Double.isNaN(fieldDensity.getReal()));
251 }
252
253
254
255
256 @Test
257 public void testTimeZoneIndependantIssue539() {
258
259
260
261 TimeScale utc = TimeScalesFactory.getUTC();
262 AbsoluteDate date = new AbsoluteDate("2000-04-01T22:30:00.000", utc);
263
264
265 Vector3D position = new Vector3D(-1038893.194, -4654348.144, 5021579.14);
266 Frame gcrf = FramesFactory.getGCRF();
267
268
269 Frame itrf = FramesFactory.getITRF(IERSConventions.IERS_2010, true);
270 PVCoordinatesProvider sun = CelestialBodyFactory.getSun();
271 OneAxisEllipsoid earth = new OneAxisEllipsoid(Constants.GRIM5C1_EARTH_EQUATORIAL_RADIUS,
272 Constants.GRIM5C1_EARTH_FLATTENING, itrf);
273 SolarInputs97to05 in = SolarInputs97to05.getInstance();
274 earth.setAngularThreshold(1e-10);
275 DTM2000 atm = new DTM2000(in, sun, earth);
276
277
278 TimeZone defaultTZ = TimeZone.getDefault();
279
280
281 TimeZone.setDefault(TimeZone.getTimeZone("Etc/UTC"));
282 double rhoUtc = atm.getDensity(date, position, gcrf);
283
284
285 TimeZone.setDefault(TimeZone.getTimeZone("Europe/Paris"));
286 double rhoParis = atm.getDensity(date, position, gcrf);
287
288
289 Assertions.assertEquals(0., rhoUtc - rhoParis, 0.);
290
291
292 TimeZone.setDefault(defaultTZ);
293 }
294
295 @BeforeEach
296 public void setUp() {
297 Utils.setDataRoot("regular-data");
298 }
299
300
301 @SuppressWarnings("serial")
302 private static class InputParamsIssue1365 implements DTM2000InputParameters {
303 @Override
304 public AbsoluteDate getMinDate() { return new AbsoluteDate(2005, 9, 8, TimeScalesFactory.getUTC()); }
305 @Override
306 public AbsoluteDate getMaxDate() { return new AbsoluteDate(2005, 9, 9, TimeScalesFactory.getUTC()); }
307 @Override
308 public double getInstantFlux(AbsoluteDate date) { return 587.9532986111111; }
309 @Override
310 public double getMeanFlux(AbsoluteDate date) { return 99.5; }
311 @Override
312 public double getThreeHourlyKP(AbsoluteDate date) { return 1.7; }
313 @Override
314 public double get24HoursKp(AbsoluteDate date) { return 1.5875; }
315 }
316
317
318 @SuppressWarnings("serial")
319 private static class SunPositionIssue1365 implements CelestialBody {
320
321 private final Vector3D sunPositionItrf;
322 private final Frame itrf;
323
324
325
326
327
328 private SunPositionIssue1365(Vector3D sunPositionItrf,
329 Frame itrf) {
330 this.sunPositionItrf = sunPositionItrf;
331 this.itrf = itrf;
332 }
333
334 @Override
335 public TimeStampedPVCoordinates getPVCoordinates(AbsoluteDate date, Frame frame) {
336 return new TimeStampedPVCoordinates(date, sunPositionItrf, Vector3D.ZERO);
337 }
338 @Override
339 public <T extends CalculusFieldElement<T>> TimeStampedFieldPVCoordinates<T> getPVCoordinates(FieldAbsoluteDate<T> date, Frame frame) {
340 return new TimeStampedFieldPVCoordinates<T>(date, date.getField().getOne(), getPVCoordinates(date.toAbsoluteDate(), frame));
341 }
342 @Override
343 public String getName() { return "SUN"; }
344 @Override
345 public Frame getInertiallyOrientedFrame() { return itrf; }
346 @Override
347 public double getGM() { return Constants.JPL_SSD_SUN_GM; }
348 @Override
349 public Frame getBodyOrientedFrame() { return itrf; }
350 }
351 }