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 org.hipparchus.util.FastMath;
20 import org.hipparchus.util.SinCos;
21 import org.orekit.annotation.DefaultDataContext;
22 import org.orekit.bodies.GeodeticPoint;
23 import org.orekit.data.DataContext;
24 import org.orekit.models.earth.Geoid;
25 import org.orekit.models.earth.troposphere.TroposphericModelUtils;
26 import org.orekit.time.AbsoluteDate;
27 import org.orekit.time.DateTimeComponents;
28 import org.orekit.time.TimeScale;
29 import org.orekit.utils.LegendrePolynomials;
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49 public class GlobalPressureTemperature {
50
51
52 private static final double TEMPERATURE_GRADIENT = -6.5e-3;
53
54
55 private static final int DEGREE = 9;
56
57
58 private static final int ORDER = 9;
59
60
61 private final Geoid geoid;
62
63
64 private final TimeScale utc;
65
66
67
68
69
70
71
72
73 @DefaultDataContext
74 public GlobalPressureTemperature(final Geoid geoid) {
75 this(geoid, DataContext.getDefault().getTimeScales().getUTC());
76 }
77
78
79
80
81
82 public GlobalPressureTemperature(final Geoid geoid, final TimeScale utc) {
83 this.geoid = geoid;
84 this.utc = utc;
85 }
86
87
88
89
90
91
92 public PressureTemperature getWeatherParameters(final GeodeticPoint location, final AbsoluteDate date) {
93
94
95 final DateTimeComponents dtc = date.getComponents(utc);
96 final int dofyear = dtc.getDate().getDayOfYear();
97
98
99 final int t0 = 28;
100 final double coef = ((dofyear + 1 - t0) / 365.25) * 2 * FastMath.PI;
101 final double cosCoef = FastMath.cos(coef);
102
103
104 final LegendrePolynomials p = new LegendrePolynomials(DEGREE, ORDER,
105 FastMath.sin(location.getLatitude()));
106
107
108 final double correctedheight = FastMath.max(0.0,
109 location.getAltitude() - geoid.getUndulation(location.getLatitude(),
110 location.getLongitude(),
111 date));
112
113
114 double meanT0 = 0.0;
115 double amplitudeT0 = 0.0;
116 double meanP0 = 0.0;
117 double amplitudeP0 = 0.0;
118 final ABCoefficients abCoef = new ABCoefficients();
119 int j = 0;
120 for (int n = 0; n <= DEGREE; n++) {
121 for (int m = 0; m <= n; m++) {
122 final SinCos sc = FastMath.sinCos(m * location.getLongitude());
123 final double pCosmLambda = p.getPnm(n, m) * sc.cos();
124 final double pSinmLambda = p.getPnm(n, m) * sc.sin();
125
126 meanT0 = meanT0 +
127 (abCoef.getAnmTemperatureMean(j) * pCosmLambda + abCoef.getBnmTemperatureMean(j) * pSinmLambda);
128 amplitudeT0 = amplitudeT0 +
129 (abCoef.getAnmTemperatureAmpl(j) * pCosmLambda + abCoef.getBnmTemperatureAmpl(j) * pSinmLambda);
130 meanP0 = meanP0 +
131 (abCoef.getAnmPressureMean(j) * pCosmLambda + abCoef.getBnmPressureMean(j) * pSinmLambda);
132 amplitudeP0 = amplitudeP0 +
133 (abCoef.getAnmPressureAmpl(j) * pCosmLambda + abCoef.getBnmPressureAmpl(j) * pSinmLambda);
134
135 j = j + 1;
136 }
137 }
138
139
140 final double temp0 = meanT0 + amplitudeT0 * cosCoef;
141 final double pres0 = meanP0 + amplitudeP0 * cosCoef;
142
143
144 final double degrees = temp0 + TEMPERATURE_GRADIENT * correctedheight;
145 final double temperature = degrees + 273.15;
146 final double pressure = pres0 * FastMath.pow(1.0 - correctedheight * 0.0000226, 5.225);
147
148 return new PressureTemperature(location.getAltitude(),
149 TroposphericModelUtils.HECTO_PASCAL.toSI(pressure),
150 temperature);
151
152 }
153
154 private static class ABCoefficients {
155
156
157 private static final double[] A_PRESSURE_MEAN = {
158 1.0108e+03,
159 8.4886e+00,
160 1.4799e+00,
161 -1.3897e+01,
162 3.7516e-03,
163 -1.4936e-01,
164 1.2232e+01,
165 -7.6615e-01,
166 -6.7699e-02,
167 8.1002e-03,
168 -1.5874e+01,
169 3.6614e-01,
170 -6.7807e-02,
171 -3.6309e-03,
172 5.9966e-04,
173 4.8163e+00,
174 -3.7363e-01,
175 -7.2071e-02,
176 1.9998e-03,
177 -6.2385e-04,
178 -3.7916e-04,
179 4.7609e+00,
180 -3.9534e-01,
181 8.6667e-03,
182 1.1569e-02,
183 1.1441e-03,
184 -1.4193e-04,
185 -8.5723e-05,
186 6.5008e-01,
187 -5.0889e-01,
188 -1.5754e-02,
189 -2.8305e-03,
190 5.7458e-04,
191 3.2577e-05,
192 -9.6052e-06,
193 -2.7974e-06,
194 1.3530e+00,
195 -2.7271e-01,
196 -3.0276e-04,
197 3.6286e-03,
198 -2.0398e-04,
199 1.5846e-05,
200 -7.7787e-06,
201 1.1210e-06,
202 9.9020e-08,
203 5.5046e-01,
204 -2.7312e-01,
205 3.2532e-03,
206 -2.4277e-03,
207 1.1596e-04,
208 2.6421e-07,
209 -1.3263e-06,
210 2.7322e-07,
211 1.4058e-07,
212 4.9414e-09
213 };
214
215
216 private static final double[] B_PRESSURE_MEAN = {
217 0.0000e+00,
218 0.0000e+00,
219 -1.2878e+00,
220 0.0000e+00,
221 7.0444e-01,
222 3.3222e-01,
223 0.0000e+00,
224 -2.9636e-01,
225 7.2248e-03,
226 7.9655e-03,
227 0.0000e+00,
228 1.0854e+00,
229 1.1145e-02,
230 -3.6513e-02,
231 3.1527e-03,
232 0.0000e+00,
233 -4.8434e-01,
234 5.2023e-02,
235 -1.3091e-02,
236 1.8515e-03,
237 1.5422e-04,
238 0.0000e+00,
239 6.8298e-01,
240 2.5261e-03,
241 -9.9703e-04,
242 -1.0829e-03,
243 +1.7688e-04,
244 -3.1418e-05,
245 +0.0000e+00,
246 -3.7018e-01,
247 4.3234e-02,
248 7.2559e-03,
249 3.1516e-04,
250 2.0024e-05,
251 -8.0581e-06,
252 -2.3653e-06,
253 0.0000e+00,
254 1.0298e-01,
255 -1.5086e-02,
256 5.6186e-03,
257 3.2613e-05,
258 4.0567e-05,
259 -1.3925e-06,
260 -3.6219e-07,
261 -2.0176e-08,
262 0.0000e+00,
263 -1.8364e-01,
264 1.8508e-02,
265 7.5016e-04,
266 -9.6139e-05,
267 -3.1995e-06,
268 1.3868e-07,
269 -1.9486e-07,
270 3.0165e-10,
271 -6.4376e-10
272 };
273
274
275 private static final double[] A_PRESSURE_AMPLITUDE = {
276 -1.0444e-01,
277 1.6618e-01,
278 -6.3974e-02,
279 1.0922e+00,
280 5.7472e-01,
281 -3.0277e-01,
282 -3.5087e+00,
283 7.1264e-03,
284 -1.4030e-01,
285 3.7050e-02,
286 4.0208e-01,
287 -3.0431e-01,
288 -1.3292e-01,
289 4.6746e-03,
290 -1.5902e-04,
291 2.8624e+00,
292 -3.9315e-01,
293 -6.4371e-02,
294 1.6444e-02,
295 -2.3403e-03,
296 4.2127e-05,
297 1.9945e+00,
298 -6.0907e-01,
299 -3.5386e-02,
300 -1.0910e-03,
301 -1.2799e-04,
302 4.0970e-05,
303 2.2131e-05,
304 -5.3292e-01,
305 -2.9765e-01,
306 -3.2877e-02,
307 1.7691e-03,
308 5.9692e-05,
309 3.1725e-05,
310 2.0741e-05,
311 -3.7622e-07,
312 2.6372e+00,
313 -3.1165e-01,
314 1.6439e-02,
315 2.1633e-04,
316 1.7485e-04,
317 2.1587e-05,
318 6.1064e-06,
319 -1.3755e-08,
320 -7.8748e-08,
321 -5.9152e-01,
322 -1.7676e-01,
323 8.1807e-03,
324 1.0445e-03,
325 2.3432e-04,
326 9.3421e-06,
327 2.8104e-06,
328 -1.5788e-07,
329 -3.0648e-08,
330 2.6421e-10
331 };
332
333
334 private static final double[] B_PRESSURE_AMPLITUDE = {
335 0.0000e+00,
336 0.0000e+00,
337 9.3340e-01,
338 0.0000e+00,
339 8.2346e-01,
340 2.2082e-01,
341 0.0000e+00,
342 9.6177e-01,
343 -1.5650e-02,
344 1.2708e-03,
345 0.0000e+00,
346 -3.9913e-01,
347 2.8020e-02,
348 2.8334e-02,
349 8.5980e-04,
350 0.0000e+00,
351 3.0545e-01,
352 -2.1691e-02,
353 6.4067e-04,
354 -3.6528e-05,
355 -1.1166e-04,
356 0.0000e+00,
357 -7.6974e-02,
358 -1.8986e-02,
359 +5.6896e-03,
360 -2.4159e-04,
361 -2.3033e-04,
362 -9.6783e-06,
363 0.0000e+00,
364 -1.0218e-01,
365 -1.3916e-02,
366 -4.1025e-03,
367 -5.1340e-05,
368 -7.0114e-05,
369 -3.3152e-07,
370 1.6901e-06,
371 0.0000e+00,
372 -1.2422e-02,
373 +2.5072e-03,
374 +1.1205e-03,
375 -1.3034e-04,
376 -2.3971e-05,
377 -2.6622e-06,
378 5.7852e-07,
379 4.5847e-08,
380 0.0000e+00,
381 4.4777e-02,
382 -3.0421e-03,
383 2.6062e-05,
384 -7.2421e-05,
385 1.9119e-06,
386 3.9236e-07,
387 2.2390e-07,
388 2.9765e-09,
389 -4.6452e-09
390 };
391
392
393 private static final double[] A_TEMPERATURE_MEAN = {
394 1.6257e+01,
395 2.1224e+00,
396 9.2569e-01,
397 -2.5974e+01,
398 1.4510e+00,
399 9.2468e-02,
400 -5.3192e-01,
401 2.1094e-01,
402 -6.9210e-02,
403 -3.4060e-02,
404 -4.6569e+00,
405 2.6385e-01,
406 -3.6093e-02,
407 1.0198e-02,
408 -1.8783e-03,
409 7.4983e-01,
410 1.1741e-01,
411 3.9940e-02,
412 5.1348e-03,
413 5.9111e-03,
414 8.6133e-06,
415 6.3057e-01,
416 1.5203e-01,
417 3.9702e-02,
418 4.6334e-03,
419 2.4406e-04,
420 1.5189e-04,
421 1.9581e-07,
422 5.4414e-01,
423 3.5722e-01,
424 5.2763e-02,
425 4.1147e-03,
426 -2.7239e-04,
427 -5.9957e-05,
428 1.6394e-06,
429 -7.3045e-07,
430 -2.9394e+00,
431 5.5579e-02,
432 1.8852e-02,
433 3.4272e-03,
434 -2.3193e-05,
435 -2.9349e-05,
436 3.6397e-07,
437 2.0490e-06,
438 -6.4719e-08,
439 -5.2225e-01,
440 2.0799e-01,
441 1.3477e-03,
442 3.1613e-04,
443 -2.2285e-04,
444 -1.8137e-05,
445 -1.5177e-07,
446 6.1343e-07,
447 7.8566e-08,
448 1.0749e-09
449 };
450
451
452 private static final double[] B_TEMPERATURE_MEAN = {
453 0.0000e+00,
454 0.0000e+00,
455 1.0210e+00,
456 0.0000e+00,
457 6.0194e-01,
458 1.2292e-01,
459 0.0000e+00,
460 -4.2184e-01,
461 1.8230e-01,
462 4.2329e-02,
463 0.0000e+00,
464 9.3312e-02,
465 9.5346e-02,
466 -1.9724e-03,
467 5.8776e-03,
468 0.0000e+00,
469 -2.0940e-01,
470 3.4199e-02,
471 -5.7672e-03,
472 -2.1590e-03,
473 5.6815e-04,
474 0.0000e+00,
475 2.2858e-01,
476 1.2283e-02,
477 -9.3679e-03,
478 -1.4233e-03,
479 -1.5962e-04,
480 4.0160e-05,
481 0.0000e+00,
482 3.6353e-02,
483 -9.4263e-04,
484 -3.6762e-03,
485 5.8608e-05,
486 -2.6391e-05,
487 3.2095e-06,
488 -1.1605e-06,
489 0.0000e+00,
490 1.6306e-01,
491 1.3293e-02,
492 -1.1395e-03,
493 5.1097e-05,
494 3.3977e-05,
495 7.6449e-06,
496 -1.7602e-07,
497 -7.6558e-08,
498 0.0000e+00,
499 -4.5415e-02,
500 -1.8027e-02,
501 3.6561e-04,
502 -1.1274e-04,
503 1.3047e-05,
504 2.0001e-06,
505 -1.5152e-07,
506 -2.7807e-08,
507 7.7491e-09
508 };
509
510
511 private static final double[] A_TEMPERATURE_AMPLITUDE = {
512 -1.8654e+00,
513 -9.0041e+00,
514 -1.2974e-01,
515 -3.6053e+00,
516 2.0284e-02,
517 2.1872e-01,
518 -1.3015e+00,
519 4.0355e-01,
520 2.2216e-01,
521 -4.0605e-03,
522 1.9623e+00,
523 4.2887e-01,
524 2.1437e-01,
525 -1.0061e-02,
526 -1.1368e-03,
527 -6.9235e-02,
528 5.6758e-01,
529 1.1917e-01,
530 -7.0765e-03,
531 3.0017e-04,
532 3.0601e-04,
533 1.6559e+00,
534 2.0722e-01,
535 6.0013e-02,
536 1.7023e-04,
537 -9.2424e-04,
538 1.1269e-05,
539 -6.9911e-06,
540 -2.0886e+00,
541 -6.7879e-02,
542 -8.5922e-04,
543 -1.6087e-03,
544 -4.5549e-05,
545 3.3178e-05,
546 -6.1715e-06,
547 -1.4446e-06,
548 -3.7210e-01,
549 1.5775e-01,
550 -1.7827e-03,
551 -4.4396e-04,
552 2.2844e-04,
553 -1.1215e-05,
554 -2.1120e-06,
555 -9.6421e-07,
556 -1.4170e-08,
557 7.8720e-01,
558 -4.4238e-02,
559 -1.5120e-03,
560 -9.4119e-04,
561 4.0645e-06,
562 -4.9253e-06,
563 -1.8656e-06,
564 -4.0736e-07,
565 -4.9594e-08,
566 1.6134e-09
567 };
568
569
570 private static final double[] B_TEMPERATURE_AMPLITUDE = {
571 0.0000e+00,
572 0.0000e+00,
573 -8.9895e-01,
574 0.0000e+00,
575 -1.0790e+00,
576 -1.2699e-01,
577 0.0000e+00,
578 -5.9033e-01,
579 3.4865e-02,
580 -3.2614e-02,
581 0.0000e+00,
582 -2.4310e-02,
583 1.5607e-02,
584 -2.9833e-02,
585 -5.9048e-03,
586 0.0000e+00,
587 2.8383e-01,
588 4.0509e-02,
589 -1.8834e-02,
590 -1.2654e-03,
591 -1.3794e-04,
592 0.0000e+00,
593 1.3306e-01,
594 3.4960e-02,
595 -3.6799e-03,
596 -3.5626e-04,
597 1.4814e-04,
598 3.7932e-06,
599 0.0000e+00,
600 2.0801e-01,
601 6.5640e-03,
602 -3.4893e-03,
603 -2.7395e-04,
604 7.4296e-05,
605 -7.9927e-06,
606 -1.0277e-06,
607 0.0000e+00,
608 3.6515e-02,
609 -7.4319e-03,
610 -6.2873e-04,
611 8.2461e-05,
612 3.1095e-05,
613 -5.3860e-07,
614 -1.2055e-07,
615 -1.1517e-07,
616 0.0000e+00,
617 3.1404e-02,
618 1.5580e-02,
619 -1.1428e-03,
620 3.3529e-05,
621 1.0387e-05,
622 -1.9378e-06,
623 -2.7327e-07,
624 7.5833e-09,
625 -9.2323e-09
626 };
627
628
629 ABCoefficients() {
630
631 }
632
633
634
635
636
637 public double getAnmPressureMean(final int index) {
638 return A_PRESSURE_MEAN[index];
639 }
640
641
642
643
644
645 public double getBnmPressureMean(final int index) {
646 return B_PRESSURE_MEAN[index];
647 }
648
649
650
651
652
653 public double getAnmPressureAmpl(final int index) {
654 return A_PRESSURE_AMPLITUDE[index];
655 }
656
657
658
659
660
661 public double getBnmPressureAmpl(final int index) {
662 return B_PRESSURE_AMPLITUDE[index];
663 }
664
665
666
667
668
669 public double getAnmTemperatureMean(final int index) {
670 return A_TEMPERATURE_MEAN[index];
671 }
672
673
674
675
676
677 public double getBnmTemperatureMean(final int index) {
678 return B_TEMPERATURE_MEAN[index];
679 }
680
681
682
683
684
685 public double getAnmTemperatureAmpl(final int index) {
686 return A_TEMPERATURE_AMPLITUDE[index];
687 }
688
689
690
691
692
693 public double getBnmTemperatureAmpl(final int index) {
694 return B_TEMPERATURE_AMPLITUDE[index];
695 }
696 }
697
698 }