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