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