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 org.hipparchus.analysis.differentiation.Gradient;
20 import org.hipparchus.exception.LocalizedCoreFormats;
21 import org.hipparchus.linear.MatrixUtils;
22 import org.hipparchus.linear.RealMatrix;
23 import org.orekit.attitudes.AttitudeProvider;
24 import org.orekit.errors.OrekitException;
25 import org.orekit.propagation.FieldSpacecraftState;
26 import org.orekit.propagation.PropagationType;
27 import org.orekit.propagation.SpacecraftState;
28 import org.orekit.propagation.integration.AdditionalDerivativesProvider;
29 import org.orekit.propagation.integration.CombinedDerivatives;
30 import org.orekit.propagation.semianalytical.dsst.forces.DSSTForceModel;
31 import org.orekit.propagation.semianalytical.dsst.utilities.FieldAuxiliaryElements;
32 import org.orekit.time.AbsoluteDate;
33 import org.orekit.utils.DoubleArrayDictionary;
34 import org.orekit.utils.ParameterDriver;
35 import org.orekit.utils.TimeSpanMap.Span;
36
37 import java.util.HashMap;
38 import java.util.List;
39 import java.util.Map;
40
41
42
43
44
45 class DSSTStateTransitionMatrixGenerator implements AdditionalDerivativesProvider {
46
47
48 private static final int SPACE_DIMENSION = 3;
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63 private static final int I = 1;
64
65
66 public static final int STATE_DIMENSION = 2 * SPACE_DIMENSION;
67
68
69 private final String stmName;
70
71
72 private final List<DSSTForceModel> forceModels;
73
74
75 private final AttitudeProvider attitudeProvider;
76
77
78 private final Map<String, DSSTPartialsObserver> partialsObservers;
79
80
81 private final PropagationType propagationType;
82
83
84
85
86
87
88
89 DSSTStateTransitionMatrixGenerator(final String stmName,
90 final List<DSSTForceModel> forceModels,
91 final AttitudeProvider attitudeProvider,
92 final PropagationType propagationType) {
93 this.stmName = stmName;
94 this.forceModels = forceModels;
95 this.attitudeProvider = attitudeProvider;
96 this.propagationType = propagationType;
97 this.partialsObservers = new HashMap<>();
98 }
99
100
101
102
103
104
105
106
107
108
109 void addObserver(final String name, final DSSTPartialsObserver observer) {
110 partialsObservers.put(name, observer);
111 }
112
113
114 @Override
115 public String getName() {
116 return stmName;
117 }
118
119
120 @Override
121 public int getDimension() {
122 return STATE_DIMENSION * STATE_DIMENSION;
123 }
124
125 @Override
126 @SuppressWarnings("unchecked")
127 public void init(final SpacecraftState initialState, final AbsoluteDate target) {
128
129
130
131
132
133
134
135 final DSSTGradientConverter converter =
136 new DSSTGradientConverter(initialState, attitudeProvider);
137
138
139 final PropagationType type = propagationType;
140
141
142 for (final DSSTForceModel forceModel : forceModels) {
143 final FieldSpacecraftState<Gradient> dsState = converter.getState(forceModel);
144 final Gradient[] parameters = converter.getParametersAtStateDate(dsState, forceModel);
145 final FieldAuxiliaryElements<Gradient> auxiliaryElements = new FieldAuxiliaryElements<>(dsState.getOrbit(), I);
146 forceModel.initializeShortPeriodTerms(auxiliaryElements, type, parameters);
147 }
148
149
150 if (type == PropagationType.OSCULATING) {
151
152 for (DSSTForceModel forceModel : forceModels) {
153 final FieldSpacecraftState<Gradient> dsState = converter.getState(forceModel);
154 final Gradient[] parameters = converter.getParametersAtStateDate(dsState, forceModel);
155 forceModel.updateShortPeriodTerms(parameters, dsState);
156 }
157 }
158
159 }
160
161
162 @Override
163 public boolean yields(final SpacecraftState state) {
164 return !state.hasAdditionalData(getName());
165 }
166
167
168
169
170
171
172
173
174
175
176 SpacecraftState setInitialStateTransitionMatrix(final SpacecraftState state, final RealMatrix dYdY0) {
177
178 if (dYdY0 != null) {
179 if (dYdY0.getRowDimension() != STATE_DIMENSION ||
180 dYdY0.getColumnDimension() != STATE_DIMENSION) {
181 throw new OrekitException(LocalizedCoreFormats.DIMENSIONS_MISMATCH_2x2,
182 dYdY0.getRowDimension(), dYdY0.getColumnDimension(),
183 STATE_DIMENSION, STATE_DIMENSION);
184 }
185 }
186
187
188 final double[] flat = new double[STATE_DIMENSION * STATE_DIMENSION];
189 int k = 0;
190 for (int i = 0; i < STATE_DIMENSION; ++i) {
191 for (int j = 0; j < STATE_DIMENSION; ++j) {
192 flat[k++] = dYdY0.getEntry(i, j);
193 }
194 }
195
196
197 return state.addAdditionalData(stmName, flat);
198
199 }
200
201
202 public CombinedDerivatives combinedDerivatives(final SpacecraftState state) {
203
204 final double[] p = state.getAdditionalState(getName());
205 final double[] res = new double[p.length];
206
207
208 final RealMatrix factor = computePartials(state);
209 int index = 0;
210 for (int i = 0; i < STATE_DIMENSION; ++i) {
211 for (int j = 0; j < STATE_DIMENSION; ++j) {
212 double sum = 0;
213 for (int k = 0; k < STATE_DIMENSION; ++k) {
214 sum += factor.getEntry(i, k) * p[j + k * STATE_DIMENSION];
215 }
216 res[index++] = sum;
217 }
218 }
219
220 return new CombinedDerivatives(res, null);
221
222 }
223
224
225
226
227
228 private RealMatrix computePartials(final SpacecraftState state) {
229
230
231 final RealMatrix factor = MatrixUtils.createRealMatrix(STATE_DIMENSION, STATE_DIMENSION);
232 final DoubleArrayDictionary meanElementsPartials = new DoubleArrayDictionary();
233 final DSSTGradientConverter converter = new DSSTGradientConverter(state, attitudeProvider);
234
235
236 for (final DSSTForceModel forceModel : forceModels) {
237
238 final FieldSpacecraftState<Gradient> dsState = converter.getState(forceModel);
239 final Gradient[] parameters = converter.getParametersAtStateDate(dsState, forceModel);
240 final FieldAuxiliaryElements<Gradient> auxiliaryElements = new FieldAuxiliaryElements<>(dsState.getOrbit(), I);
241
242 final Gradient[] meanElementRate = forceModel.getMeanElementRate(dsState, auxiliaryElements, parameters);
243 final double[] derivativesA = meanElementRate[0].getGradient();
244 final double[] derivativesEx = meanElementRate[1].getGradient();
245 final double[] derivativesEy = meanElementRate[2].getGradient();
246 final double[] derivativesHx = meanElementRate[3].getGradient();
247 final double[] derivativesHy = meanElementRate[4].getGradient();
248 final double[] derivativesL = meanElementRate[5].getGradient();
249
250
251 addToRow(derivativesA, 0, factor);
252 addToRow(derivativesEx, 1, factor);
253 addToRow(derivativesEy, 2, factor);
254 addToRow(derivativesHx, 3, factor);
255 addToRow(derivativesHy, 4, factor);
256 addToRow(derivativesL, 5, factor);
257
258
259 int paramsIndex = converter.getFreeStateParameters();
260 for (ParameterDriver driver : forceModel.getParametersDrivers()) {
261 if (driver.isSelected()) {
262
263 for (Span<String> span = driver.getNamesSpanMap().getFirstSpan(); span != null; span = span.next()) {
264
265
266 DoubleArrayDictionary.Entry entry = meanElementsPartials.getEntry(span.getData());
267 if (entry == null) {
268
269 meanElementsPartials.put(span.getData(), new double[STATE_DIMENSION]);
270 entry = meanElementsPartials.getEntry(span.getData());
271 }
272
273 entry.increment(new double[] {
274 derivativesA[paramsIndex], derivativesEx[paramsIndex], derivativesEy[paramsIndex],
275 derivativesHx[paramsIndex], derivativesHy[paramsIndex], derivativesL[paramsIndex]
276 });
277 ++paramsIndex;
278 }
279
280 }
281 }
282
283 }
284
285
286 for (Map.Entry<String, DSSTPartialsObserver> observersEntry : partialsObservers.entrySet()) {
287 final DoubleArrayDictionary.Entry entry = meanElementsPartials.getEntry(observersEntry.getKey());
288 observersEntry.getValue().partialsComputed(state, factor, entry == null ? new double[STATE_DIMENSION] : entry.getValue());
289 }
290
291 return factor;
292
293 }
294
295
296
297
298
299
300 private void addToRow(final double[] derivatives, final int index, final RealMatrix factor) {
301 for (int i = 0; i < 6; i++) {
302 factor.addToEntry(index, i, derivatives[i]);
303 }
304 }
305
306
307 @FunctionalInterface
308 public interface DSSTPartialsObserver {
309
310
311
312
313
314
315
316 void partialsComputed(SpacecraftState state, RealMatrix factor, double[] meanElementsPartials);
317
318 }
319
320 }
321