1 /* Copyright 2022-2025 Thales Alenia Space
2 * Licensed to CS GROUP (CS) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * CS licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.orekit.models.earth.weather;
18
19 import java.util.HashMap;
20 import java.util.Map;
21
22 import org.hipparchus.CalculusFieldElement;
23 import org.hipparchus.util.FieldSinCos;
24 import org.hipparchus.util.MathUtils;
25 import org.hipparchus.util.SinCos;
26
27 /** Grid entry in Global Pressure Temperature models.
28 * @author Luc Maisonobe
29 * @since 12.1
30 */
31 class GridEntry {
32
33 /** Conversion factor from degrees to mill arcseconds. */
34 public static final int DEG_TO_MAS = 3600000;
35
36 /** Latitude (radian). */
37 private final double latitude;
38
39 /** Latitude key (mas). */
40 private final int latKey;
41
42 /** Longitude (radian). */
43 private final double longitude;
44
45 /** Longitude key (mas). */
46 private final int lonKey;
47
48 /** Undulation. */
49 private final double undulation;
50
51 /** Height correction. */
52 private final double hS;
53
54 /** Seasonal models. */
55 private final Map<SeasonalModelType, SeasonalModel> models;
56
57 /** Build an entry from its components.
58 * @param latitude latitude (radian)
59 * @param latKey latitude key (mas)
60 * @param longitude longitude (radian)
61 * @param lonKey longitude key (mas)
62 * @param undulation undulation (m)
63 * @param hS height correction
64 * @param models seasonal models
65 */
66 GridEntry(final double latitude, final int latKey, final double longitude, final int lonKey,
67 final double undulation, final double hS, final Map<SeasonalModelType, SeasonalModel> models) {
68
69 this.latitude = latitude;
70 this.latKey = latKey;
71 this.longitude = longitude;
72 this.lonKey = lonKey;
73 this.undulation = undulation;
74 this.hS = hS;
75 this.models = models;
76 }
77
78 /** Build a new entry 360° to the East of instance.
79 * @return new wrapping entry (always same type as instance)
80 */
81 public GridEntry buildWrappedEntry() {
82 return new GridEntry(latitude, latKey,
83 longitude + MathUtils.TWO_PI,
84 lonKey + DEG_TO_MAS * 360,
85 undulation, hS,
86 models);
87 }
88
89 /** Get latitude (radian).
90 * @return latitude (radian)
91 */
92 public double getLatitude() {
93 return latitude;
94 }
95
96 /** Get latitude key (mas).
97 * @return latitude key (mas)
98 */
99 public int getLatKey() {
100 return latKey;
101 }
102
103 /** Get longitude (radian).
104 * @return longitude (radian)
105 */
106 public double getLongitude() {
107 return longitude;
108 }
109
110 /** Get longitude key (mas).
111 * @return longitude key (mas)
112 */
113 public int getLonKey() {
114 return lonKey;
115 }
116
117 /** Get undulation.
118 * @return undulation
119 */
120 public double getUndulation() {
121 return undulation;
122 }
123
124 /** Get height correction.
125 * @return height correction
126 */
127 public double getHs() {
128 return hS;
129 }
130
131 /** Check if an entry has a model.
132 * @param type model type
133 * @return true if the entry has the model
134 * @since 13.0
135 */
136 public boolean hasModel(final SeasonalModelType type) {
137 return models.containsKey(type);
138 }
139
140 /** Evaluate the entry at one date.
141 * @param sc1 sine and cosine of yearly harmonic term
142 * @param sc2 sine and cosine of bi-yearly harmonic term
143 * @param altitude altitude
144 * @return evaluated entry
145 */
146 public EvaluatedGridEntry evaluate(final SinCos sc1, final SinCos sc2, final double altitude) {
147
148 // evaluate all models
149 final Map<SeasonalModelType, Double> evaluatedModels = new HashMap<>(models.size());
150 for (final Map.Entry<SeasonalModelType, SeasonalModel> entry : models.entrySet()) {
151 evaluatedModels.put(entry.getKey(), entry.getValue().evaluate(sc1, sc2));
152 }
153
154 // build the evaluated grid entry
155 return new EvaluatedGridEntry(this, altitude, evaluatedModels);
156
157 }
158
159 /** Evaluate the entry at one date.
160 * @param <T> type of the field elements
161 * @param sc1 sine and cosine of yearly harmonic term
162 * @param sc2 sine and cosine of bi-yearly harmonic term
163 * @param altitude altitude
164 * @return evaluated entry
165 */
166 public <T extends CalculusFieldElement<T>> FieldEvaluatedGridEntry<T> evaluate(final FieldSinCos<T> sc1,
167 final FieldSinCos<T> sc2,
168 final T altitude) {
169
170 // evaluate all models
171 final Map<SeasonalModelType, T> evaluatedModels = new HashMap<>(models.size());
172 for (final Map.Entry<SeasonalModelType, SeasonalModel> entry : models.entrySet()) {
173 evaluatedModels.put(entry.getKey(), entry.getValue().evaluate(sc1, sc2));
174 }
175
176 // build the evaluated grid entry
177 return new FieldEvaluatedGridEntry<>(this, altitude, evaluatedModels);
178
179 }
180
181 }