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 setInitialStm(stmName, initialStm);
102 setInitialJacobianColumns(initialJacobianColumns);
103 this.propagator = propagator;
104 this.shortPeriodDerivativesStm = new double[getStateDimension()][getStateDimension()];
105 this.shortPeriodDerivativesJacobianColumns = new DoubleArrayDictionary();
106
107 this.fieldShortPeriodTerms = new IdentityHashMap<>();
108 }
109
110
111 @Override
112 public RealMatrix getStateTransitionMatrix(final SpacecraftState state) {
113
114 final RealMatrix stm = getB2(state);
115
116 final int stateDimension = getStateDimension();
117 if (propagator.getPropagationType() == PropagationType.OSCULATING) {
118
119 for (int i = 0; i < stateDimension; i++) {
120 for (int j = 0; j < stateDimension; j++) {
121 stm.addToEntry(i, j, shortPeriodDerivativesStm[i][j]);
122 }
123 }
124 }
125
126 return stm;
127
128 }
129
130
131 @Override
132 public RealMatrix getParametersJacobian(final SpacecraftState state) {
133
134 final RealMatrix jacobian = getB3(state);
135 if (jacobian != null && propagator.getPropagationType() == PropagationType.OSCULATING) {
136
137
138 final List<String> names = getJacobiansColumnsNames();
139 for (int j = 0; j < names.size(); ++j) {
140 final double[] column = shortPeriodDerivativesJacobianColumns.get(names.get(j));
141 for (int i = 0; i < getStateDimension(); i++) {
142 jacobian.addToEntry(i, j, column[i]);
143 }
144 }
145
146 }
147
148 return jacobian;
149
150 }
151
152
153
154
155
156
157
158
159 public RealMatrix getB1() {
160
161
162 final int stateDimension = getStateDimension();
163 final RealMatrix B1 = MatrixUtils.createRealMatrix(stateDimension, stateDimension);
164
165
166 for (int i = 0; i < stateDimension; i++) {
167 for (int j = 0; j < stateDimension; j++) {
168 B1.addToEntry(i, j, shortPeriodDerivativesStm[i][j]);
169 }
170 }
171
172
173 return B1;
174
175 }
176
177
178
179
180
181
182
183
184
185 public RealMatrix getB2(final SpacecraftState state) {
186 if (!state.hasAdditionalData(getStmName())) {
187 return null;
188 }
189 return toSquareMatrix(state.getAdditionalState(getStmName()));
190 }
191
192
193
194
195
196
197
198
199
200 public RealMatrix getB3(final SpacecraftState state) {
201
202 final List<String> names = getJacobiansColumnsNames();
203
204 if (names == null || names.isEmpty()) {
205 return null;
206 }
207
208 final RealMatrix dYdP = MatrixUtils.createRealMatrix(getStateDimension(), names.size());
209 for (int j = 0; j < names.size(); j++) {
210 dYdP.setColumn(j, state.getAdditionalState(names.get(j)));
211 }
212
213 return dYdP;
214
215 }
216
217
218
219
220
221
222
223
224 public RealMatrix getB4() {
225
226
227 final List<String> names = getJacobiansColumnsNames();
228 final RealMatrix B4 = MatrixUtils.createRealMatrix(getStateDimension(), names.size());
229
230
231 for (int j = 0; j < names.size(); ++j) {
232 final double[] column = shortPeriodDerivativesJacobianColumns.get(names.get(j));
233 for (int i = 0; i < getStateDimension(); i++) {
234 B4.addToEntry(i, j, column[i]);
235 }
236 }
237
238
239 return B4;
240
241 }
242
243
244
245
246
247
248 public void freezeColumnsNames() {
249 columnsNames = getJacobiansColumnsNames();
250 }
251
252
253 @Override
254 public List<String> getJacobiansColumnsNames() {
255 return columnsNames == null ? propagator.getJacobiansColumnsNames() : columnsNames;
256 }
257
258
259
260
261 public void initializeFieldShortPeriodTerms(final SpacecraftState reference) {
262 initializeFieldShortPeriodTerms(reference, propagator.getPropagationType());
263 }
264
265
266
267
268
269
270
271 public void initializeFieldShortPeriodTerms(final SpacecraftState reference,
272 final PropagationType type) {
273
274
275 final DSSTGradientConverter converter = new DSSTGradientConverter(reference, propagator.getAttitudeProvider());
276
277
278
279 fieldShortPeriodTerms.clear();
280
281
282 for (final DSSTForceModel forceModel : propagator.getAllForceModels()) {
283
284
285 final FieldSpacecraftState<Gradient> dsState = converter.getState(forceModel);
286 final Gradient[] dsParameters = converter.getParametersAtStateDate(dsState, forceModel);
287 final FieldAuxiliaryElements<Gradient> auxiliaryElements = new FieldAuxiliaryElements<>(dsState.getOrbit(), I);
288
289
290 final List<FieldShortPeriodTerms<Gradient>> terms =
291 forceModel.initializeShortPeriodTerms(
292 auxiliaryElements,
293 type,
294 dsParameters);
295
296 final List<FieldShortPeriodTerms<Gradient>> list;
297 synchronized (fieldShortPeriodTerms) {
298 list = fieldShortPeriodTerms.computeIfAbsent(forceModel, x -> new ArrayList<>());
299 }
300 list.addAll(terms);
301
302 }
303
304 }
305
306
307
308
309 @SuppressWarnings("unchecked")
310 public void updateFieldShortPeriodTerms(final SpacecraftState reference) {
311
312
313 final DSSTGradientConverter converter = new DSSTGradientConverter(reference, propagator.getAttitudeProvider());
314
315
316 for (final DSSTForceModel forceModel : propagator.getAllForceModels()) {
317
318
319 final FieldSpacecraftState<Gradient> dsState = converter.getState(forceModel);
320 final Gradient[] dsParameters = converter.getParameters(dsState, forceModel);
321
322
323 forceModel.updateShortPeriodTerms(dsParameters, dsState);
324
325 }
326
327 }
328
329
330 @Override
331 public void setReferenceState(final SpacecraftState reference) {
332
333
334 for (final double[] row : shortPeriodDerivativesStm) {
335 Arrays.fill(row, 0.0);
336 }
337
338 shortPeriodDerivativesJacobianColumns.clear();
339
340 final DSSTGradientConverter converter = new DSSTGradientConverter(reference, propagator.getAttitudeProvider());
341
342
343 for (final DSSTForceModel forceModel : propagator.getAllForceModels()) {
344
345 final FieldSpacecraftState<Gradient> dsState = converter.getState(forceModel);
346 final Gradient zero = dsState.getDate().getField().getZero();
347 final Gradient[] shortPeriod = new Gradient[6];
348 Arrays.fill(shortPeriod, zero);
349 final List<FieldShortPeriodTerms<Gradient>> terms;
350 synchronized (fieldShortPeriodTerms) {
351 terms = fieldShortPeriodTerms.computeIfAbsent(forceModel, x -> new ArrayList<>(0));
352 }
353 for (final FieldShortPeriodTerms<Gradient> spt : terms) {
354 final Gradient[] spVariation = spt.value(dsState.getOrbit());
355 for (int i = 0; i < spVariation .length; i++) {
356 shortPeriod[i] = shortPeriod[i].add(spVariation[i]);
357 }
358 }
359
360 final double[] derivativesASP = shortPeriod[0].getGradient();
361 final double[] derivativesExSP = shortPeriod[1].getGradient();
362 final double[] derivativesEySP = shortPeriod[2].getGradient();
363 final double[] derivativesHxSP = shortPeriod[3].getGradient();
364 final double[] derivativesHySP = shortPeriod[4].getGradient();
365 final double[] derivativesLSP = shortPeriod[5].getGradient();
366
367
368 addToRow(derivativesASP, 0);
369 addToRow(derivativesExSP, 1);
370 addToRow(derivativesEySP, 2);
371 addToRow(derivativesHxSP, 3);
372 addToRow(derivativesHySP, 4);
373 addToRow(derivativesLSP, 5);
374
375 int paramsIndex = converter.getFreeStateParameters();
376 for (ParameterDriver driver : forceModel.getParametersDrivers()) {
377 if (driver.isSelected()) {
378
379 final TimeSpanMap<String> driverNameSpanMap = driver.getNamesSpanMap();
380
381
382 for (Span<String> span = driverNameSpanMap.getFirstSpan(); span != null; span = span.next()) {
383
384 DoubleArrayDictionary.Entry entry = shortPeriodDerivativesJacobianColumns.getEntry(span.getData());
385 if (entry == null) {
386
387 shortPeriodDerivativesJacobianColumns.put(span.getData(), new double[getStateDimension()]);
388 entry = shortPeriodDerivativesJacobianColumns.getEntry(span.getData());
389 }
390
391
392 entry.increment(new double[] {
393 derivativesASP[paramsIndex], derivativesExSP[paramsIndex], derivativesEySP[paramsIndex],
394 derivativesHxSP[paramsIndex], derivativesHySP[paramsIndex], derivativesLSP[paramsIndex]
395 });
396 ++paramsIndex;
397 }
398 }
399 }
400 }
401
402 }
403
404
405
406
407
408 private void addToRow(final double[] derivatives, final int index) {
409 for (int i = 0; i < 6; i++) {
410 shortPeriodDerivativesStm[index][i] += derivatives[i];
411 }
412 }
413
414
415 @Override
416 public OrbitType getOrbitType() {
417 return propagator.getOrbitType();
418 }
419
420
421 @Override
422 public PositionAngleType getPositionAngleType() {
423 return propagator.getPositionAngleType();
424 }
425
426 }