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 fieldShortPeriodTerms.computeIfAbsent(forceModel, x -> new ArrayList<>())
278 .addAll(terms);
279
280 }
281
282 }
283
284
285
286
287 @SuppressWarnings("unchecked")
288 public void updateFieldShortPeriodTerms(final SpacecraftState reference) {
289
290
291 final DSSTGradientConverter converter = new DSSTGradientConverter(reference, propagator.getAttitudeProvider());
292
293
294 for (final DSSTForceModel forceModel : propagator.getAllForceModels()) {
295
296
297 final FieldSpacecraftState<Gradient> dsState = converter.getState(forceModel);
298 final Gradient[] dsParameters = converter.getParameters(dsState, forceModel);
299
300
301 forceModel.updateShortPeriodTerms(dsParameters, dsState);
302
303 }
304
305 }
306
307
308 @Override
309 public void setReferenceState(final SpacecraftState reference) {
310
311
312 for (final double[] row : shortPeriodDerivativesStm) {
313 Arrays.fill(row, 0.0);
314 }
315
316 shortPeriodDerivativesJacobianColumns.clear();
317
318 final DSSTGradientConverter converter = new DSSTGradientConverter(reference, propagator.getAttitudeProvider());
319
320
321 for (final DSSTForceModel forceModel : propagator.getAllForceModels()) {
322
323 final FieldSpacecraftState<Gradient> dsState = converter.getState(forceModel);
324 final Gradient zero = dsState.getDate().getField().getZero();
325 final Gradient[] shortPeriod = new Gradient[6];
326 Arrays.fill(shortPeriod, zero);
327 final List<FieldShortPeriodTerms<Gradient>> terms = fieldShortPeriodTerms
328 .computeIfAbsent(forceModel, x -> new ArrayList<>(0));
329 for (final FieldShortPeriodTerms<Gradient> spt : terms) {
330 final Gradient[] spVariation = spt.value(dsState.getOrbit());
331 for (int i = 0; i < spVariation .length; i++) {
332 shortPeriod[i] = shortPeriod[i].add(spVariation[i]);
333 }
334 }
335
336 final double[] derivativesASP = shortPeriod[0].getGradient();
337 final double[] derivativesExSP = shortPeriod[1].getGradient();
338 final double[] derivativesEySP = shortPeriod[2].getGradient();
339 final double[] derivativesHxSP = shortPeriod[3].getGradient();
340 final double[] derivativesHySP = shortPeriod[4].getGradient();
341 final double[] derivativesLSP = shortPeriod[5].getGradient();
342
343
344 addToRow(derivativesASP, 0);
345 addToRow(derivativesExSP, 1);
346 addToRow(derivativesEySP, 2);
347 addToRow(derivativesHxSP, 3);
348 addToRow(derivativesHySP, 4);
349 addToRow(derivativesLSP, 5);
350
351 int paramsIndex = converter.getFreeStateParameters();
352 for (ParameterDriver driver : forceModel.getParametersDrivers()) {
353 if (driver.isSelected()) {
354
355 final TimeSpanMap<String> driverNameSpanMap = driver.getNamesSpanMap();
356
357
358 for (Span<String> span = driverNameSpanMap.getFirstSpan(); span != null; span = span.next()) {
359
360 DoubleArrayDictionary.Entry entry = shortPeriodDerivativesJacobianColumns.getEntry(span.getData());
361 if (entry == null) {
362
363 shortPeriodDerivativesJacobianColumns.put(span.getData(), new double[STATE_DIMENSION]);
364 entry = shortPeriodDerivativesJacobianColumns.getEntry(span.getData());
365 }
366
367
368 entry.increment(new double[] {
369 derivativesASP[paramsIndex], derivativesExSP[paramsIndex], derivativesEySP[paramsIndex],
370 derivativesHxSP[paramsIndex], derivativesHySP[paramsIndex], derivativesLSP[paramsIndex]
371 });
372 ++paramsIndex;
373 }
374 }
375 }
376 }
377
378 }
379
380
381
382
383
384 private void addToRow(final double[] derivatives, final int index) {
385 for (int i = 0; i < 6; i++) {
386 shortPeriodDerivativesStm[index][i] += derivatives[i];
387 }
388 }
389
390
391 @Override
392 public OrbitType getOrbitType() {
393 return propagator.getOrbitType();
394 }
395
396
397 @Override
398 public PositionAngleType getPositionAngleType() {
399 return propagator.getPositionAngleType();
400 }
401
402 }