1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.models.earth.weather;
18
19 import java.io.BufferedInputStream;
20 import java.io.IOException;
21 import java.io.InputStream;
22
23 import org.hipparchus.CalculusFieldElement;
24 import org.hipparchus.util.FastMath;
25 import org.orekit.bodies.FieldGeodeticPoint;
26 import org.orekit.bodies.GeodeticPoint;
27 import org.orekit.data.DataSource;
28 import org.orekit.models.earth.troposphere.AzimuthalGradientCoefficients;
29 import org.orekit.models.earth.troposphere.AzimuthalGradientProvider;
30 import org.orekit.models.earth.troposphere.FieldAzimuthalGradientCoefficients;
31 import org.orekit.models.earth.troposphere.FieldViennaACoefficients;
32 import org.orekit.models.earth.troposphere.TroposphericModelUtils;
33 import org.orekit.models.earth.troposphere.ViennaACoefficients;
34 import org.orekit.models.earth.troposphere.ViennaAProvider;
35 import org.orekit.time.AbsoluteDate;
36 import org.orekit.time.FieldAbsoluteDate;
37 import org.orekit.time.TimeScale;
38 import org.orekit.utils.Constants;
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78 public class AbstractGlobalPressureTemperature
79 implements ViennaAProvider, AzimuthalGradientProvider, PressureTemperatureHumidityProvider {
80
81
82 private static final double G = Constants.G0_STANDARD_GRAVITY;
83
84
85 private static final double R = 287.0;
86
87
88 private final Grid grid;
89
90
91 private final TimeScale utc;
92
93
94
95
96
97
98
99
100
101 protected AbstractGlobalPressureTemperature(final DataSource source, final TimeScale utc,
102 final SeasonalModelType... expected)
103 throws IOException {
104 this.utc = utc;
105
106
107 try (InputStream is = source.getOpener().openStreamOnce();
108 BufferedInputStream bis = new BufferedInputStream(is)) {
109 final GptNParser parser = new GptNParser(expected);
110 parser.loadData(bis, source.getName());
111 grid = parser.getGrid();
112 }
113
114 }
115
116
117
118
119
120
121
122
123 @Deprecated
124 protected AbstractGlobalPressureTemperature(final Grid grid, final TimeScale utc) {
125 this.grid = grid;
126 this.utc = utc;
127 }
128
129
130 @Override
131 public ViennaACoefficients getA(final GeodeticPoint location, final AbsoluteDate date) {
132
133
134 final CellInterpolator interpolator = grid.getInterpolator(location.getLatitude(), location.getLongitude());
135 final int dayOfYear = date.getComponents(utc).getDate().getDayOfYear();
136
137
138 return new ViennaACoefficients(interpolator.interpolate(e -> e.getModel(SeasonalModelType.AH).evaluate(dayOfYear)) * 0.001,
139 interpolator.interpolate(e -> e.getModel(SeasonalModelType.AW).evaluate(dayOfYear)) * 0.001);
140
141 }
142
143
144 @Override
145 public PressureTemperatureHumidity getWeatherParamerers(final GeodeticPoint location, final AbsoluteDate date) {
146
147
148 final CellInterpolator interpolator = grid.getInterpolator(location.getLatitude(), location.getLongitude());
149 final int dayOfYear = date.getComponents(utc).getDate().getDayOfYear();
150
151
152 final double undu = interpolator.interpolate(e -> e.getUndulation());
153 final double correctedheight = location.getAltitude() - undu - interpolator.interpolate(e -> e.getHs());
154
155
156 final double dTdH = interpolator.interpolate(e -> e.getModel(SeasonalModelType.DT).evaluate(dayOfYear)) * 0.001;
157
158
159 final double qv = interpolator.interpolate(e -> e.getModel(SeasonalModelType.QV).evaluate(dayOfYear)) * 0.001;
160
161
162
163
164
165 final double t0 = interpolator.interpolate(e -> e.getModel(SeasonalModelType.TEMPERATURE).evaluate(dayOfYear));
166 final double temperature = t0 + dTdH * correctedheight;
167
168
169 final double p0 = interpolator.interpolate(e -> e.getModel(SeasonalModelType.PRESSURE).evaluate(dayOfYear));
170 final double exponent = G / (dTdH * R);
171 final double pressure = p0 * FastMath.pow(1 - (dTdH / t0) * correctedheight, exponent) * 0.01;
172
173
174 final double e0 = qv * pressure / (0.622 + 0.378 * qv);
175
176
177 final double tm = grid.hasModels(SeasonalModelType.TM) ?
178 interpolator.interpolate(e -> e.getModel(SeasonalModelType.TM).evaluate(dayOfYear)) :
179 Double.NaN;
180
181
182 final double lambda = grid.hasModels(SeasonalModelType.LAMBDA) ?
183 interpolator.interpolate(e -> e.getModel(SeasonalModelType.LAMBDA).evaluate(dayOfYear)) :
184 Double.NaN;
185
186 return new PressureTemperatureHumidity(location.getAltitude(),
187 TroposphericModelUtils.HECTO_PASCAL.toSI(pressure),
188 temperature,
189 TroposphericModelUtils.HECTO_PASCAL.toSI(e0),
190 tm,
191 lambda);
192
193 }
194
195
196 @Override
197 public AzimuthalGradientCoefficients getGradientCoefficients(final GeodeticPoint location, final AbsoluteDate date) {
198
199 if (grid.hasModels(SeasonalModelType.GN_H, SeasonalModelType.GE_H, SeasonalModelType.GN_W, SeasonalModelType.GE_W)) {
200
201 final CellInterpolator interpolator = grid.getInterpolator(location.getLatitude(), location.getLongitude());
202 final int dayOfYear = date.getComponents(utc).getDate().getDayOfYear();
203
204 return new AzimuthalGradientCoefficients(interpolator.interpolate(e -> e.getModel(SeasonalModelType.GN_H).evaluate(dayOfYear)),
205 interpolator.interpolate(e -> e.getModel(SeasonalModelType.GE_H).evaluate(dayOfYear)),
206 interpolator.interpolate(e -> e.getModel(SeasonalModelType.GN_W).evaluate(dayOfYear)),
207 interpolator.interpolate(e -> e.getModel(SeasonalModelType.GE_W).evaluate(dayOfYear)));
208 } else {
209 return null;
210 }
211
212 }
213
214
215 @Override
216 public <T extends CalculusFieldElement<T>> FieldViennaACoefficients<T> getA(final FieldGeodeticPoint<T> location,
217 final FieldAbsoluteDate<T> date) {
218
219
220 final FieldCellInterpolator<T> interpolator = grid.getInterpolator(location.getLatitude(), location.getLongitude());
221 final int dayOfYear = date.getComponents(utc).getDate().getDayOfYear();
222
223
224 return new FieldViennaACoefficients<>(interpolator.interpolate(e -> e.getModel(SeasonalModelType.AH).evaluate(dayOfYear)).multiply(0.001),
225 interpolator.interpolate(e -> e.getModel(SeasonalModelType.AW).evaluate(dayOfYear)).multiply(0.001));
226
227 }
228
229
230 @Override
231 public <T extends CalculusFieldElement<T>> FieldPressureTemperatureHumidity<T> getWeatherParamerers(final FieldGeodeticPoint<T> location,
232 final FieldAbsoluteDate<T> date) {
233
234
235 final FieldCellInterpolator<T> interpolator = grid.getInterpolator(location.getLatitude(), location.getLongitude());
236 final int dayOfYear = date.getComponents(utc).getDate().getDayOfYear();
237
238
239 final T undu = interpolator.interpolate(e -> e.getUndulation());
240 final T correctedheight = location.getAltitude().subtract(undu).subtract(interpolator.interpolate(e -> e.getHs()));
241
242
243 final T dTdH = interpolator.interpolate(e -> e.getModel(SeasonalModelType.DT).evaluate(dayOfYear)).multiply(0.001);
244
245
246 final T qv = interpolator.interpolate(e -> e.getModel(SeasonalModelType.QV).evaluate(dayOfYear)).multiply(0.001);
247
248
249
250
251
252 final T t0 = interpolator.interpolate(e -> e.getModel(SeasonalModelType.TEMPERATURE).evaluate(dayOfYear));
253 final T temperature = correctedheight.multiply(dTdH).add(t0);
254
255
256 final T p0 = interpolator.interpolate(e -> e.getModel(SeasonalModelType.PRESSURE).evaluate(dayOfYear));
257 final T exponent = dTdH.multiply(R).reciprocal().multiply(G);
258 final T pressure = FastMath.pow(correctedheight.multiply(dTdH.negate().divide(t0)).add(1), exponent).multiply(p0.multiply(0.01));
259
260
261 final T e0 = pressure.multiply(qv.divide(qv.multiply(0.378).add(0.622 )));
262
263
264 final T tm = grid.hasModels(SeasonalModelType.TM) ?
265 interpolator.interpolate(e -> e.getModel(SeasonalModelType.TM).evaluate(dayOfYear)) :
266 date.getField().getZero().newInstance(Double.NaN);
267
268
269 final T lambda = grid.hasModels(SeasonalModelType.LAMBDA) ?
270 interpolator.interpolate(e -> e.getModel(SeasonalModelType.LAMBDA).evaluate(dayOfYear)) :
271 date.getField().getZero().newInstance(Double.NaN);
272
273 return new FieldPressureTemperatureHumidity<>(location.getAltitude(),
274 TroposphericModelUtils.HECTO_PASCAL.toSI(pressure),
275 temperature,
276 TroposphericModelUtils.HECTO_PASCAL.toSI(e0),
277 tm,
278 lambda);
279
280 }
281
282
283 @Override
284 public <T extends CalculusFieldElement<T>> FieldAzimuthalGradientCoefficients<T> getGradientCoefficients(final FieldGeodeticPoint<T> location,
285 final FieldAbsoluteDate<T> date) {
286
287 if (grid.hasModels(SeasonalModelType.GN_H, SeasonalModelType.GE_H, SeasonalModelType.GN_W, SeasonalModelType.GE_W)) {
288
289 final FieldCellInterpolator<T> interpolator = grid.getInterpolator(location.getLatitude(), location.getLongitude());
290 final int dayOfYear = date.getComponents(utc).getDate().getDayOfYear();
291
292 return new FieldAzimuthalGradientCoefficients<>(interpolator.interpolate(e -> e.getModel(SeasonalModelType.GN_H).evaluate(dayOfYear)),
293 interpolator.interpolate(e -> e.getModel(SeasonalModelType.GE_H).evaluate(dayOfYear)),
294 interpolator.interpolate(e -> e.getModel(SeasonalModelType.GN_W).evaluate(dayOfYear)),
295 interpolator.interpolate(e -> e.getModel(SeasonalModelType.GE_W).evaluate(dayOfYear)));
296 } else {
297 return null;
298 }
299
300 }
301
302 }