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