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.OrbitParamsType;
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.drivers.ParameterDriver;
39
40
41
42
43
44
45
46 public class DSSTHarvester extends AbstractMatricesHarvester {
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61 private static final int I = 1;
62
63
64 private final DSSTPropagator propagator;
65
66
67 private final double[][] shortPeriodDerivativesStm;
68
69
70 private final DoubleArrayDictionary shortPeriodDerivativesJacobianColumns;
71
72
73 private List<String> columnsNames;
74
75
76
77
78
79
80 private final Map<DSSTForceModel, List<FieldShortPeriodTerms<Gradient>>>
81 fieldShortPeriodTerms;
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97 DSSTHarvester(final DSSTPropagator propagator, final String stmName,
98 final RealMatrix initialStm, final DoubleArrayDictionary initialJacobianColumns) {
99 setInitialStm(stmName, initialStm);
100 setInitialJacobianColumns(initialJacobianColumns);
101 this.propagator = propagator;
102 this.shortPeriodDerivativesStm = new double[getStateDimension()][getStateDimension()];
103 this.shortPeriodDerivativesJacobianColumns = new DoubleArrayDictionary();
104
105 this.fieldShortPeriodTerms = new IdentityHashMap<>();
106 }
107
108
109 @Override
110 public RealMatrix getStateTransitionMatrix(final SpacecraftState state) {
111
112 final RealMatrix stm = getB2(state);
113
114 final int stateDimension = getStateDimension();
115 if (propagator.getPropagationType() == PropagationType.OSCULATING) {
116
117 for (int i = 0; i < stateDimension; i++) {
118 for (int j = 0; j < stateDimension; 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 = getB3(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 < getStateDimension(); 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 int stateDimension = getStateDimension();
161 final RealMatrix B1 = MatrixUtils.createRealMatrix(stateDimension, stateDimension);
162
163
164 for (int i = 0; i < stateDimension; i++) {
165 for (int j = 0; j < stateDimension; j++) {
166 B1.addToEntry(i, j, shortPeriodDerivativesStm[i][j]);
167 }
168 }
169
170
171 return B1;
172
173 }
174
175
176
177
178
179
180
181
182
183 public RealMatrix getB2(final SpacecraftState state) {
184 if (!state.hasAdditionalData(getStmName())) {
185 return null;
186 }
187 return toSquareMatrix(state.getAdditionalState(getStmName()));
188 }
189
190
191
192
193
194
195
196
197
198 public RealMatrix getB3(final SpacecraftState state) {
199
200 final List<String> names = getJacobiansColumnsNames();
201
202 if (names == null || names.isEmpty()) {
203 return null;
204 }
205
206 final RealMatrix dYdP = MatrixUtils.createRealMatrix(getStateDimension(), names.size());
207 for (int j = 0; j < names.size(); j++) {
208 dYdP.setColumn(j, state.getAdditionalState(names.get(j)));
209 }
210
211 return dYdP;
212
213 }
214
215
216
217
218
219
220
221
222 public RealMatrix getB4() {
223
224
225 final List<String> names = getJacobiansColumnsNames();
226 final RealMatrix B4 = MatrixUtils.createRealMatrix(getStateDimension(), names.size());
227
228
229 for (int j = 0; j < names.size(); ++j) {
230 final double[] column = shortPeriodDerivativesJacobianColumns.get(names.get(j));
231 for (int i = 0; i < getStateDimension(); i++) {
232 B4.addToEntry(i, j, column[i]);
233 }
234 }
235
236
237 return B4;
238
239 }
240
241
242
243
244
245
246 public void freezeColumnsNames() {
247 columnsNames = getJacobiansColumnsNames();
248 }
249
250
251 @Override
252 public List<String> getJacobiansColumnsNames() {
253 return columnsNames == null ? propagator.getJacobiansColumnsNames() : columnsNames;
254 }
255
256
257
258
259 public void initializeFieldShortPeriodTerms(final SpacecraftState reference) {
260 initializeFieldShortPeriodTerms(reference, propagator.getPropagationType());
261 }
262
263
264
265
266
267
268
269 public void initializeFieldShortPeriodTerms(final SpacecraftState reference,
270 final PropagationType type) {
271
272
273 final DSSTGradientConverter converter = new DSSTGradientConverter(reference, propagator.getAttitudeProvider());
274
275
276
277 fieldShortPeriodTerms.clear();
278
279
280 for (final DSSTForceModel forceModel : propagator.getAllForceModels()) {
281
282
283 final FieldSpacecraftState<Gradient> dsState = converter.getState(forceModel);
284 final Gradient[] dsParameters = converter.getParametersAtStateDate(dsState, forceModel);
285 final FieldAuxiliaryElements<Gradient> auxiliaryElements = new FieldAuxiliaryElements<>(dsState.getOrbit(), I);
286
287
288 final List<FieldShortPeriodTerms<Gradient>> terms =
289 forceModel.initializeShortPeriodTerms(
290 auxiliaryElements,
291 type,
292 dsParameters);
293
294 final List<FieldShortPeriodTerms<Gradient>> list;
295 synchronized (fieldShortPeriodTerms) {
296 list = fieldShortPeriodTerms.computeIfAbsent(forceModel, x -> new ArrayList<>());
297 }
298 list.addAll(terms);
299
300 }
301
302 }
303
304
305
306
307 @SuppressWarnings("unchecked")
308 public void updateFieldShortPeriodTerms(final SpacecraftState reference) {
309
310
311 final DSSTGradientConverter converter = new DSSTGradientConverter(reference, propagator.getAttitudeProvider());
312
313
314 for (final DSSTForceModel forceModel : propagator.getAllForceModels()) {
315
316
317 final FieldSpacecraftState<Gradient> dsState = converter.getState(forceModel);
318 final Gradient[] dsParameters = converter.getParameters(dsState, forceModel);
319
320
321 forceModel.updateShortPeriodTerms(dsParameters, dsState);
322
323 }
324
325 }
326
327
328 @Override
329 public void setReferenceState(final SpacecraftState reference) {
330
331
332 for (final double[] row : shortPeriodDerivativesStm) {
333 Arrays.fill(row, 0.0);
334 }
335
336 shortPeriodDerivativesJacobianColumns.clear();
337
338 final DSSTGradientConverter converter = new DSSTGradientConverter(reference, propagator.getAttitudeProvider());
339
340
341 for (final DSSTForceModel forceModel : propagator.getAllForceModels()) {
342
343 final FieldSpacecraftState<Gradient> dsState = converter.getState(forceModel);
344 final Gradient zero = dsState.getDate().getField().getZero();
345 final Gradient[] shortPeriod = new Gradient[6];
346 Arrays.fill(shortPeriod, zero);
347 final List<FieldShortPeriodTerms<Gradient>> terms;
348 synchronized (fieldShortPeriodTerms) {
349 terms = fieldShortPeriodTerms.computeIfAbsent(forceModel, x -> new ArrayList<>(0));
350 }
351 for (final FieldShortPeriodTerms<Gradient> spt : terms) {
352 final Gradient[] spVariation = spt.value(dsState.getOrbit());
353 for (int i = 0; i < spVariation .length; i++) {
354 shortPeriod[i] = shortPeriod[i].add(spVariation[i]);
355 }
356 }
357
358 final double[] derivativesASP = shortPeriod[0].getGradient();
359 final double[] derivativesExSP = shortPeriod[1].getGradient();
360 final double[] derivativesEySP = shortPeriod[2].getGradient();
361 final double[] derivativesHxSP = shortPeriod[3].getGradient();
362 final double[] derivativesHySP = shortPeriod[4].getGradient();
363 final double[] derivativesLSP = shortPeriod[5].getGradient();
364
365
366 addToRow(derivativesASP, 0);
367 addToRow(derivativesExSP, 1);
368 addToRow(derivativesEySP, 2);
369 addToRow(derivativesHxSP, 3);
370 addToRow(derivativesHySP, 4);
371 addToRow(derivativesLSP, 5);
372
373 int paramsIndex = converter.getFreeStateParameters();
374 for (ParameterDriver driver : forceModel.getParametersDrivers()) {
375 if (driver.isSelected()) {
376
377
378 DoubleArrayDictionary.Entry entry = shortPeriodDerivativesJacobianColumns.getEntry(driver.getName());
379 if (entry == null) {
380
381 shortPeriodDerivativesJacobianColumns.put(driver.getName(), new double[getStateDimension()]);
382 entry = shortPeriodDerivativesJacobianColumns.getEntry(driver.getName());
383 }
384
385
386 entry.increment(new double[] {
387 derivativesASP[paramsIndex], derivativesExSP[paramsIndex], derivativesEySP[paramsIndex],
388 derivativesHxSP[paramsIndex], derivativesHySP[paramsIndex], derivativesLSP[paramsIndex]
389 });
390 ++paramsIndex;
391 }
392 }
393 }
394
395 }
396
397
398
399
400
401 private void addToRow(final double[] derivatives, final int index) {
402 for (int i = 0; i < 6; i++) {
403 shortPeriodDerivativesStm[index][i] += derivatives[i];
404 }
405 }
406
407
408 @Override
409 public OrbitParamsType getOrbitParamsType() {
410 return propagator.getOrbitParamsType();
411 }
412
413
414 @Override
415 public PositionAngleType getPositionAngleType() {
416 return propagator.getPositionAngleType();
417 }
418
419 }