1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.propagation.semianalytical.dsst;
18
19 import java.util.ArrayList;
20 import java.util.Arrays;
21 import java.util.IdentityHashMap;
22 import java.util.List;
23 import java.util.Map;
24
25 import org.hipparchus.analysis.differentiation.Gradient;
26 import org.hipparchus.linear.MatrixUtils;
27 import org.hipparchus.linear.RealMatrix;
28 import org.orekit.orbits.OrbitType;
29 import org.orekit.orbits.PositionAngleType;
30 import org.orekit.propagation.AbstractMatricesHarvester;
31 import org.orekit.propagation.FieldSpacecraftState;
32 import org.orekit.propagation.PropagationType;
33 import org.orekit.propagation.SpacecraftState;
34 import org.orekit.propagation.semianalytical.dsst.forces.DSSTForceModel;
35 import org.orekit.propagation.semianalytical.dsst.forces.FieldShortPeriodTerms;
36 import org.orekit.propagation.semianalytical.dsst.utilities.FieldAuxiliaryElements;
37 import org.orekit.utils.DoubleArrayDictionary;
38 import org.orekit.utils.ParameterDriver;
39 import org.orekit.utils.TimeSpanMap;
40 import org.orekit.utils.TimeSpanMap.Span;
41
42
43
44
45
46
47
48 public class DSSTHarvester extends AbstractMatricesHarvester {
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63 private static final int I = 1;
64
65
66 private final DSSTPropagator propagator;
67
68
69 private final double[][] shortPeriodDerivativesStm;
70
71
72 private final DoubleArrayDictionary shortPeriodDerivativesJacobianColumns;
73
74
75 private List<String> columnsNames;
76
77
78
79
80
81
82 private final Map<DSSTForceModel, List<FieldShortPeriodTerms<Gradient>>>
83 fieldShortPeriodTerms;
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99 DSSTHarvester(final DSSTPropagator propagator, final String stmName,
100 final RealMatrix initialStm, final DoubleArrayDictionary initialJacobianColumns) {
101 super(stmName, initialStm, initialJacobianColumns);
102 this.propagator = propagator;
103 this.shortPeriodDerivativesStm = new double[STATE_DIMENSION][STATE_DIMENSION];
104 this.shortPeriodDerivativesJacobianColumns = new DoubleArrayDictionary();
105
106 this.fieldShortPeriodTerms = new IdentityHashMap<>();
107 }
108
109
110 @Override
111 public RealMatrix getStateTransitionMatrix(final SpacecraftState state) {
112
113 final RealMatrix stm = super.getStateTransitionMatrix(state);
114
115 if (propagator.getPropagationType() == PropagationType.OSCULATING) {
116
117 for (int i = 0; i < STATE_DIMENSION; i++) {
118 for (int j = 0; j < STATE_DIMENSION; j++) {
119 stm.addToEntry(i, j, shortPeriodDerivativesStm[i][j]);
120 }
121 }
122 }
123
124 return stm;
125
126 }
127
128
129 @Override
130 public RealMatrix getParametersJacobian(final SpacecraftState state) {
131
132 final RealMatrix jacobian = super.getParametersJacobian(state);
133 if (jacobian != null && propagator.getPropagationType() == PropagationType.OSCULATING) {
134
135
136 final List<String> names = getJacobiansColumnsNames();
137 for (int j = 0; j < names.size(); ++j) {
138 final double[] column = shortPeriodDerivativesJacobianColumns.get(names.get(j));
139 for (int i = 0; i < STATE_DIMENSION; i++) {
140 jacobian.addToEntry(i, j, column[i]);
141 }
142 }
143
144 }
145
146 return jacobian;
147
148 }
149
150
151
152
153
154
155
156
157 public RealMatrix getB1() {
158
159
160 final RealMatrix B1 = MatrixUtils.createRealMatrix(STATE_DIMENSION, STATE_DIMENSION);
161
162
163 for (int i = 0; i < STATE_DIMENSION; i++) {
164 for (int j = 0; j < STATE_DIMENSION; j++) {
165 B1.addToEntry(i, j, shortPeriodDerivativesStm[i][j]);
166 }
167 }
168
169
170 return B1;
171
172 }
173
174
175
176
177
178
179
180
181
182 public RealMatrix getB2(final SpacecraftState state) {
183 return super.getStateTransitionMatrix(state);
184 }
185
186
187
188
189
190
191
192
193
194 public RealMatrix getB3(final SpacecraftState state) {
195 return super.getParametersJacobian(state);
196 }
197
198
199
200
201
202
203
204
205 public RealMatrix getB4() {
206
207
208 final List<String> names = getJacobiansColumnsNames();
209 final RealMatrix B4 = MatrixUtils.createRealMatrix(STATE_DIMENSION, names.size());
210
211
212 for (int j = 0; j < names.size(); ++j) {
213 final double[] column = shortPeriodDerivativesJacobianColumns.get(names.get(j));
214 for (int i = 0; i < STATE_DIMENSION; i++) {
215 B4.addToEntry(i, j, column[i]);
216 }
217 }
218
219
220 return B4;
221
222 }
223
224
225
226
227
228
229 public void freezeColumnsNames() {
230 columnsNames = getJacobiansColumnsNames();
231 }
232
233
234 @Override
235 public List<String> getJacobiansColumnsNames() {
236 return columnsNames == null ? propagator.getJacobiansColumnsNames() : columnsNames;
237 }
238
239
240
241
242 public void initializeFieldShortPeriodTerms(final SpacecraftState reference) {
243 initializeFieldShortPeriodTerms(reference, propagator.getPropagationType());
244 }
245
246
247
248
249
250
251
252 public void initializeFieldShortPeriodTerms(final SpacecraftState reference,
253 final PropagationType type) {
254
255
256 final DSSTGradientConverter converter = new DSSTGradientConverter(reference, propagator.getAttitudeProvider());
257
258
259
260 fieldShortPeriodTerms.clear();
261
262
263 for (final DSSTForceModel forceModel : propagator.getAllForceModels()) {
264
265
266 final FieldSpacecraftState<Gradient> dsState = converter.getState(forceModel);
267 final Gradient[] dsParameters = converter.getParametersAtStateDate(dsState, forceModel);
268 final FieldAuxiliaryElements<Gradient> auxiliaryElements = new FieldAuxiliaryElements<>(dsState.getOrbit(), I);
269
270
271 final List<FieldShortPeriodTerms<Gradient>> terms =
272 forceModel.initializeShortPeriodTerms(
273 auxiliaryElements,
274 type,
275 dsParameters);
276
277 final List<FieldShortPeriodTerms<Gradient>> list;
278 synchronized (fieldShortPeriodTerms) {
279 list = fieldShortPeriodTerms.computeIfAbsent(forceModel, x -> new ArrayList<>());
280 }
281 list.addAll(terms);
282
283 }
284
285 }
286
287
288
289
290 @SuppressWarnings("unchecked")
291 public void updateFieldShortPeriodTerms(final SpacecraftState reference) {
292
293
294 final DSSTGradientConverter converter = new DSSTGradientConverter(reference, propagator.getAttitudeProvider());
295
296
297 for (final DSSTForceModel forceModel : propagator.getAllForceModels()) {
298
299
300 final FieldSpacecraftState<Gradient> dsState = converter.getState(forceModel);
301 final Gradient[] dsParameters = converter.getParameters(dsState, forceModel);
302
303
304 forceModel.updateShortPeriodTerms(dsParameters, dsState);
305
306 }
307
308 }
309
310
311 @Override
312 public void setReferenceState(final SpacecraftState reference) {
313
314
315 for (final double[] row : shortPeriodDerivativesStm) {
316 Arrays.fill(row, 0.0);
317 }
318
319 shortPeriodDerivativesJacobianColumns.clear();
320
321 final DSSTGradientConverter converter = new DSSTGradientConverter(reference, propagator.getAttitudeProvider());
322
323
324 for (final DSSTForceModel forceModel : propagator.getAllForceModels()) {
325
326 final FieldSpacecraftState<Gradient> dsState = converter.getState(forceModel);
327 final Gradient zero = dsState.getDate().getField().getZero();
328 final Gradient[] shortPeriod = new Gradient[6];
329 Arrays.fill(shortPeriod, zero);
330 final List<FieldShortPeriodTerms<Gradient>> terms;
331 synchronized (fieldShortPeriodTerms) {
332 terms = fieldShortPeriodTerms.computeIfAbsent(forceModel, x -> new ArrayList<>(0));
333 }
334 for (final FieldShortPeriodTerms<Gradient> spt : terms) {
335 final Gradient[] spVariation = spt.value(dsState.getOrbit());
336 for (int i = 0; i < spVariation .length; i++) {
337 shortPeriod[i] = shortPeriod[i].add(spVariation[i]);
338 }
339 }
340
341 final double[] derivativesASP = shortPeriod[0].getGradient();
342 final double[] derivativesExSP = shortPeriod[1].getGradient();
343 final double[] derivativesEySP = shortPeriod[2].getGradient();
344 final double[] derivativesHxSP = shortPeriod[3].getGradient();
345 final double[] derivativesHySP = shortPeriod[4].getGradient();
346 final double[] derivativesLSP = shortPeriod[5].getGradient();
347
348
349 addToRow(derivativesASP, 0);
350 addToRow(derivativesExSP, 1);
351 addToRow(derivativesEySP, 2);
352 addToRow(derivativesHxSP, 3);
353 addToRow(derivativesHySP, 4);
354 addToRow(derivativesLSP, 5);
355
356 int paramsIndex = converter.getFreeStateParameters();
357 for (ParameterDriver driver : forceModel.getParametersDrivers()) {
358 if (driver.isSelected()) {
359
360 final TimeSpanMap<String> driverNameSpanMap = driver.getNamesSpanMap();
361
362
363 for (Span<String> span = driverNameSpanMap.getFirstSpan(); span != null; span = span.next()) {
364
365 DoubleArrayDictionary.Entry entry = shortPeriodDerivativesJacobianColumns.getEntry(span.getData());
366 if (entry == null) {
367
368 shortPeriodDerivativesJacobianColumns.put(span.getData(), new double[STATE_DIMENSION]);
369 entry = shortPeriodDerivativesJacobianColumns.getEntry(span.getData());
370 }
371
372
373 entry.increment(new double[] {
374 derivativesASP[paramsIndex], derivativesExSP[paramsIndex], derivativesEySP[paramsIndex],
375 derivativesHxSP[paramsIndex], derivativesHySP[paramsIndex], derivativesLSP[paramsIndex]
376 });
377 ++paramsIndex;
378 }
379 }
380 }
381 }
382
383 }
384
385
386
387
388
389 private void addToRow(final double[] derivatives, final int index) {
390 for (int i = 0; i < 6; i++) {
391 shortPeriodDerivativesStm[index][i] += derivatives[i];
392 }
393 }
394
395
396 @Override
397 public OrbitType getOrbitType() {
398 return propagator.getOrbitType();
399 }
400
401
402 @Override
403 public PositionAngleType getPositionAngleType() {
404 return propagator.getPositionAngleType();
405 }
406
407 }