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.CalculusFieldElement;
22 import org.hipparchus.util.FastMath;
23 import org.hipparchus.util.FieldSinCos;
24 import org.hipparchus.util.MathArrays;
25 import org.hipparchus.util.SinCos;
26 import org.orekit.errors.OrekitInternalError;
27 import org.orekit.utils.Constants;
28
29
30
31
32
33 abstract class SeriesTerm {
34
35
36 private double[][] sinCoeff;
37
38
39 private double[][] cosCoeff;
40
41
42
43 protected SeriesTerm() {
44 this.sinCoeff = new double[0][0];
45 this.cosCoeff = new double[0][0];
46 }
47
48
49
50
51
52 public int getDegree(final int index) {
53 return sinCoeff[index].length - 1;
54 }
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79 public void add(final int index, final int degree,
80 final double sinID, final double cosID) {
81 sinCoeff = extendArray(index, degree, sinCoeff);
82 cosCoeff = extendArray(index, degree, cosCoeff);
83 if (degree >= 0) {
84 sinCoeff[index][degree] += sinID;
85 cosCoeff[index][degree] += cosID;
86 }
87 }
88
89
90
91
92
93
94
95 public double getSinCoeff(final int index, final int degree) {
96 return sinCoeff[index][degree];
97 }
98
99
100
101
102
103
104
105 public double getCosCoeff(final int index, final int degree) {
106 return cosCoeff[index][degree];
107 }
108
109
110
111
112
113 public double[] value(final BodiesElements elements) {
114
115
116 final double tc = elements.getTC();
117 final double a = argument(elements);
118 final SinCos sc = FastMath.sinCos(a);
119
120
121 final double[] values = new double[sinCoeff.length];
122 for (int i = 0; i < values.length; ++i) {
123 double s = 0;
124 double c = 0;
125 for (int j = sinCoeff[i].length - 1; j >= 0; --j) {
126 s = s * tc + sinCoeff[i][j];
127 c = c * tc + cosCoeff[i][j];
128 }
129 values[i] = s * sc.sin() + c * sc.cos();
130 }
131
132 return values;
133
134 }
135
136
137
138
139
140 public double[] derivative(final BodiesElements elements) {
141
142
143 final double tc = elements.getTC();
144 final double a = argument(elements);
145 final double aDot = argumentDerivative(elements);
146 final SinCos sc = FastMath.sinCos(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) * sc.sin() + (cDot + s * aDot) * sc.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 CalculusFieldElement<T>> T[] value(final FieldBodiesElements<T> elements) {
192
193
194 final T tc = elements.getTC();
195 final T a = argument(elements);
196 final FieldSinCos<T> sc = FastMath.sinCos(a);
197
198
199 final T[] values = MathArrays.buildArray(tc.getField(), sinCoeff.length);
200 for (int i = 0; i < values.length; ++i) {
201 T s = tc.getField().getZero();
202 T c = tc.getField().getZero();
203 for (int j = sinCoeff[i].length - 1; j >= 0; --j) {
204 s = s.multiply(tc).add(sinCoeff[i][j]);
205 c = c.multiply(tc).add(cosCoeff[i][j]);
206 }
207 values[i] = s.multiply(sc.sin()).add(c.multiply(sc.cos()));
208 }
209
210 return values;
211
212 }
213
214
215
216
217
218
219 public <T extends CalculusFieldElement<T>> T[] derivative(final FieldBodiesElements<T> elements) {
220
221
222 final T tc = elements.getTC();
223 final T a = argument(elements);
224 final T aDot = argumentDerivative(elements);
225 final FieldSinCos<T> sc = FastMath.sinCos(a);
226
227
228 final T[] derivatives = MathArrays.buildArray(tc.getField(), sinCoeff.length);
229 for (int i = 0; i < derivatives.length; ++i) {
230 T s = tc.getField().getZero();
231 T c = tc.getField().getZero();
232 T sDot = tc.getField().getZero();
233 T cDot = tc.getField().getZero();
234 if (sinCoeff[i].length > 0) {
235 for (int j = sinCoeff[i].length - 1; j > 0; --j) {
236 s = s.multiply(tc).add(sinCoeff[i][j]);
237 c = c.multiply(tc).add(cosCoeff[i][j]);
238 sDot = sDot.multiply(tc).add(j * sinCoeff[i][j]);
239 cDot = cDot.multiply(tc).add(j * cosCoeff[i][j]);
240 }
241 s = s.multiply(tc).add(sinCoeff[i][0]);
242 c = c.multiply(tc).add(cosCoeff[i][0]);
243 sDot = sDot.divide(Constants.JULIAN_CENTURY);
244 cDot = cDot.divide(Constants.JULIAN_CENTURY);
245 }
246 derivatives[i] = sDot.subtract(c.multiply(aDot)).multiply(sc.sin()).
247 add(cDot.add(s.multiply(aDot)).multiply(sc.cos()));
248 }
249
250 return derivatives;
251
252 }
253
254
255
256
257
258
259 protected abstract <T extends CalculusFieldElement<T>> T argument(FieldBodiesElements<T> elements);
260
261
262
263
264
265
266 protected abstract <T extends CalculusFieldElement<T>> T argumentDerivative(FieldBodiesElements<T> elements);
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289 public static SeriesTerm buildTerm(final int cGamma,
290 final int cL, final int cLPrime, final int cF,
291 final int cD, final int cOmega,
292 final int cMe, final int cVe, final int cE,
293 final int cMa, final int cJu, final int cSa,
294 final int cUr, final int cNe, final int cPa) {
295 if (cGamma == 0 && cL == 0 && cLPrime == 0 && cF == 0 && cD == 0 && cOmega == 0) {
296 return new PlanetaryTerm(cMe, cVe, cE, cMa, cJu, cSa, cUr, cNe, cPa);
297 } else if (cGamma == 0 &&
298 cMe == 0 && cVe == 0 && cE == 0 && cMa == 0 && cJu == 0 &&
299 cSa == 0 && cUr == 0 && cNe == 0 && cPa == 0) {
300 return new LuniSolarTerm(cL, cLPrime, cF, cD, cOmega);
301 } else if (cGamma != 0 &&
302 cMe == 0 && cVe == 0 && cE == 0 && cMa == 0 && cJu == 0 &&
303 cSa == 0 && cUr == 0 && cNe == 0 && cPa == 0) {
304 return new TideTerm(cGamma, cL, cLPrime, cF, cD, cOmega);
305 } else if (cGamma == 0 && cLPrime == 0 && cUr == 0 && cNe == 0 && cPa == 0) {
306 return new NoFarPlanetsTerm(cL, cF, cD, cOmega,
307 cMe, cVe, cE, cMa, cJu, cSa);
308 } else if (cGamma == 0) {
309 return new GeneralTerm(cL, cLPrime, cF, cD, cOmega,
310 cMe, cVe, cE, cMa, cJu, cSa, cUr, cNe, cPa);
311 } else {
312 throw new OrekitInternalError(null);
313 }
314
315 }
316
317
318
319
320
321
322
323 private static double[][] extendArray(final int index, final int degree,
324 final double[][] array) {
325
326
327 final double[][] extended;
328 if (array.length > index) {
329 extended = array;
330 } else {
331 final int rows = index + 1;
332 extended = new double[rows][];
333 System.arraycopy(array, 0, extended, 0, array.length);
334 Arrays.fill(extended, array.length, index + 1, new double[0]);
335 }
336
337
338 extended[index] = extendArray(degree, extended[index]);
339
340 return extended;
341
342 }
343
344
345
346
347
348
349 private static double[] extendArray(final int degree, final double[] array) {
350
351 if (array.length > degree) {
352 return array;
353 } else {
354 final double[] extended = new double[degree + 1];
355 System.arraycopy(array, 0, extended, 0, array.length);
356 return extended;
357 }
358 }
359
360 }