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