1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.data;
18
19 import java.util.Arrays;
20
21 import org.hipparchus.RealFieldElement;
22 import org.hipparchus.util.FastMath;
23 import org.hipparchus.util.MathArrays;
24 import org.orekit.errors.OrekitInternalError;
25 import org.orekit.utils.Constants;
26
27
28
29
30
31 abstract class SeriesTerm {
32
33
34 private double[][] sinCoeff;
35
36
37 private double[][] cosCoeff;
38
39
40
41 protected SeriesTerm() {
42 this.sinCoeff = new double[0][0];
43 this.cosCoeff = new double[0][0];
44 }
45
46
47
48
49
50 public int getDegree(final int index) {
51 return sinCoeff[index].length - 1;
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 public void add(final int index, final int degree,
78 final double sinID, final double cosID) {
79 sinCoeff = extendArray(index, degree, sinCoeff);
80 cosCoeff = extendArray(index, degree, cosCoeff);
81 if (degree >= 0) {
82 sinCoeff[index][degree] += sinID;
83 cosCoeff[index][degree] += cosID;
84 }
85 }
86
87
88
89
90
91
92
93 public double getSinCoeff(final int index, final int degree) {
94 return sinCoeff[index][degree];
95 }
96
97
98
99
100
101
102
103 public double getCosCoeff(final int index, final int degree) {
104 return cosCoeff[index][degree];
105 }
106
107
108
109
110
111 public double[] value(final BodiesElements elements) {
112
113
114 final double tc = elements.getTC();
115 final double a = argument(elements);
116 final double sin = FastMath.sin(a);
117 final double cos = FastMath.cos(a);
118
119
120 final double[] values = new double[sinCoeff.length];
121 for (int i = 0; i < values.length; ++i) {
122 double s = 0;
123 double c = 0;
124 for (int j = sinCoeff[i].length - 1; j >= 0; --j) {
125 s = s * tc + sinCoeff[i][j];
126 c = c * tc + cosCoeff[i][j];
127 }
128 values[i] = s * sin + c * cos;
129 }
130
131 return values;
132
133 }
134
135
136
137
138
139 public double[] derivative(final BodiesElements elements) {
140
141
142 final double tc = elements.getTC();
143 final double a = argument(elements);
144 final double aDot = argumentDerivative(elements);
145 final double sin = FastMath.sin(a);
146 final double cos = FastMath.cos(a);
147
148
149 final double[] derivatives = new double[sinCoeff.length];
150 for (int i = 0; i < derivatives.length; ++i) {
151 double s = 0;
152 double c = 0;
153 double sDot = 0;
154 double cDot = 0;
155 if (sinCoeff[i].length > 0) {
156 for (int j = sinCoeff[i].length - 1; j > 0; --j) {
157 s = s * tc + sinCoeff[i][j];
158 c = c * tc + cosCoeff[i][j];
159 sDot = sDot * tc + j * sinCoeff[i][j];
160 cDot = cDot * tc + j * cosCoeff[i][j];
161 }
162 s = s * tc + sinCoeff[i][0];
163 c = c * tc + cosCoeff[i][0];
164 sDot /= Constants.JULIAN_CENTURY;
165 cDot /= Constants.JULIAN_CENTURY;
166 }
167 derivatives[i] = (sDot - c * aDot) * sin + (cDot + s * aDot) * cos;
168 }
169
170 return derivatives;
171
172 }
173
174
175
176
177
178 protected abstract double argument(BodiesElements elements);
179
180
181
182
183
184 protected abstract double argumentDerivative(BodiesElements elements);
185
186
187
188
189
190
191 public <T extends RealFieldElement<T>> T[] value(final FieldBodiesElements<T> elements) {
192
193
194 final T tc = elements.getTC();
195 final T a = argument(elements);
196 final T sin = a.sin();
197 final T cos = a.cos();
198
199
200 final T[] values = MathArrays.buildArray(tc.getField(), sinCoeff.length);
201 for (int i = 0; i < values.length; ++i) {
202 T s = tc.getField().getZero();
203 T c = tc.getField().getZero();
204 for (int j = sinCoeff[i].length - 1; j >= 0; --j) {
205 s = s.multiply(tc).add(sinCoeff[i][j]);
206 c = c.multiply(tc).add(cosCoeff[i][j]);
207 }
208 values[i] = s.multiply(sin).add(c.multiply(cos));
209 }
210
211 return values;
212
213 }
214
215
216
217
218
219
220 public <T extends RealFieldElement<T>> T[] derivative(final FieldBodiesElements<T> elements) {
221
222
223 final T tc = elements.getTC();
224 final T a = argument(elements);
225 final T aDot = argumentDerivative(elements);
226 final T sin = a.sin();
227 final T cos = a.cos();
228
229
230 final T[] derivatives = MathArrays.buildArray(tc.getField(), sinCoeff.length);
231 for (int i = 0; i < derivatives.length; ++i) {
232 T s = tc.getField().getZero();
233 T c = tc.getField().getZero();
234 T sDot = tc.getField().getZero();
235 T cDot = tc.getField().getZero();
236 if (sinCoeff[i].length > 0) {
237 for (int j = sinCoeff[i].length - 1; j > 0; --j) {
238 s = s.multiply(tc).add(sinCoeff[i][j]);
239 c = c.multiply(tc).add(cosCoeff[i][j]);
240 sDot = sDot.multiply(tc).add(j * sinCoeff[i][j]);
241 cDot = cDot.multiply(tc).add(j * cosCoeff[i][j]);
242 }
243 s = s.multiply(tc).add(sinCoeff[i][0]);
244 c = c.multiply(tc).add(cosCoeff[i][0]);
245 sDot = sDot.divide(Constants.JULIAN_CENTURY);
246 cDot = cDot.divide(Constants.JULIAN_CENTURY);
247 }
248 derivatives[i] = sDot.subtract(c.multiply(aDot)).multiply(sin).
249 add(cDot.add(s.multiply(aDot)).multiply(cos));
250 }
251
252 return derivatives;
253
254 }
255
256
257
258
259
260
261 protected abstract <T extends RealFieldElement<T>> T argument(FieldBodiesElements<T> elements);
262
263
264
265
266
267
268 protected abstract <T extends RealFieldElement<T>> T argumentDerivative(FieldBodiesElements<T> elements);
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291 public static SeriesTerm buildTerm(final int cGamma,
292 final int cL, final int cLPrime, final int cF,
293 final int cD, final int cOmega,
294 final int cMe, final int cVe, final int cE,
295 final int cMa, final int cJu, final int cSa,
296 final int cUr, final int cNe, final int cPa) {
297 if (cGamma == 0 && cL == 0 && cLPrime == 0 && cF == 0 && cD == 0 && cOmega == 0) {
298 return new PlanetaryTerm(cMe, cVe, cE, cMa, cJu, cSa, cUr, cNe, cPa);
299 } else if (cGamma == 0 &&
300 cMe == 0 && cVe == 0 && cE == 0 && cMa == 0 && cJu == 0 &&
301 cSa == 0 && cUr == 0 && cNe == 0 && cPa == 0) {
302 return new LuniSolarTerm(cL, cLPrime, cF, cD, cOmega);
303 } else if (cGamma != 0 &&
304 cMe == 0 && cVe == 0 && cE == 0 && cMa == 0 && cJu == 0 &&
305 cSa == 0 && cUr == 0 && cNe == 0 && cPa == 0) {
306 return new TideTerm(cGamma, cL, cLPrime, cF, cD, cOmega);
307 } else if (cGamma == 0 && cLPrime == 0 && cUr == 0 && cNe == 0 && cPa == 0) {
308 return new NoFarPlanetsTerm(cL, cF, cD, cOmega,
309 cMe, cVe, cE, cMa, cJu, cSa);
310 } else if (cGamma == 0) {
311 return new GeneralTerm(cL, cLPrime, cF, cD, cOmega,
312 cMe, cVe, cE, cMa, cJu, cSa, cUr, cNe, cPa);
313 } else {
314 throw new OrekitInternalError(null);
315 }
316
317 }
318
319
320
321
322
323
324
325 private static double[][] extendArray(final int index, final int degree,
326 final double[][] array) {
327
328
329 final double[][] extended;
330 if (array.length > index) {
331 extended = array;
332 } else {
333 final int rows = index + 1;
334 extended = new double[rows][];
335 System.arraycopy(array, 0, extended, 0, array.length);
336 Arrays.fill(extended, array.length, index + 1, new double[0]);
337 }
338
339
340 extended[index] = extendArray(degree, extended[index]);
341
342 return extended;
343
344 }
345
346
347
348
349
350
351 private static double[] extendArray(final int degree, final double[] array) {
352
353 if (array.length > degree) {
354 return array;
355 } else {
356 final double[] extended = new double[degree + 1];
357 System.arraycopy(array, 0, extended, 0, array.length);
358 return extended;
359 }
360 }
361
362 }