1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.propagation.analytical;
18
19 import java.util.Arrays;
20 import java.util.List;
21
22 import org.hipparchus.analysis.differentiation.Gradient;
23 import org.hipparchus.linear.MatrixUtils;
24 import org.hipparchus.linear.RealMatrix;
25 import org.orekit.orbits.FieldOrbit;
26 import org.orekit.orbits.OrbitType;
27 import org.orekit.orbits.PositionAngleType;
28 import org.orekit.propagation.AbstractMatricesHarvester;
29 import org.orekit.propagation.AdditionalDataProvider;
30 import org.orekit.propagation.FieldSpacecraftState;
31 import org.orekit.propagation.SpacecraftState;
32 import org.orekit.time.AbsoluteDate;
33 import org.orekit.time.FieldAbsoluteDate;
34 import org.orekit.utils.DoubleArrayDictionary;
35 import org.orekit.utils.FieldPVCoordinates;
36 import org.orekit.utils.ParameterDriver;
37 import org.orekit.utils.TimeSpanMap;
38 import org.orekit.utils.TimeSpanMap.Span;
39
40
41
42
43
44
45
46
47 public abstract class AbstractAnalyticalMatricesHarvester extends AbstractMatricesHarvester
48 implements AdditionalDataProvider<double[]> {
49
50
51 private List<String> columnsNames;
52
53
54 private AbsoluteDate epoch;
55
56
57 private final double[][] analyticalDerivativesStm;
58
59
60 private final DoubleArrayDictionary analyticalDerivativesJacobianColumns;
61
62
63 private final AbstractAnalyticalPropagator propagator;
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79 protected AbstractAnalyticalMatricesHarvester(final AbstractAnalyticalPropagator propagator, final String stmName,
80 final RealMatrix initialStm, final DoubleArrayDictionary initialJacobianColumns) {
81 super(stmName, initialStm, initialJacobianColumns);
82 this.propagator = propagator;
83 this.epoch = propagator.getInitialState().getDate();
84 this.columnsNames = null;
85 this.analyticalDerivativesStm = getInitialStateTransitionMatrix().getData();
86 this.analyticalDerivativesJacobianColumns = new DoubleArrayDictionary();
87 }
88
89
90 @Override
91 public List<String> getJacobiansColumnsNames() {
92 return columnsNames == null ? propagator.getJacobiansColumnsNames() : columnsNames;
93 }
94
95
96 @Override
97 public void freezeColumnsNames() {
98 columnsNames = getJacobiansColumnsNames();
99 }
100
101
102 @Override
103 public String getName() {
104 return getStmName();
105 }
106
107
108 @Override
109 public double[] getAdditionalData(final SpacecraftState state) {
110
111 updateDerivativesIfNeeded(state);
112
113 return toArray(analyticalDerivativesStm);
114 }
115
116
117 @Override
118 public RealMatrix getStateTransitionMatrix(final SpacecraftState state) {
119
120 if (!state.hasAdditionalData(getName())) {
121 return null;
122 }
123
124 return toSquareMatrix(state.getAdditionalState(getName()));
125 }
126
127
128 @Override
129 public RealMatrix getParametersJacobian(final SpacecraftState state) {
130
131 updateDerivativesIfNeeded(state);
132
133
134 final List<String> names = getJacobiansColumnsNames();
135 if (names == null || names.isEmpty()) {
136 return null;
137 }
138
139
140 final RealMatrix dYdP = MatrixUtils.createRealMatrix(getStateDimension(), names.size());
141
142
143 for (int j = 0; j < names.size(); ++j) {
144 final double[] column = analyticalDerivativesJacobianColumns.get(names.get(j));
145 if (column != null) {
146 for (int i = 0; i < getStateDimension(); i++) {
147 dYdP.addToEntry(i, j, column[i]);
148 }
149 }
150 }
151
152
153 return dYdP;
154 }
155
156
157 @Override
158 public void setReferenceState(final SpacecraftState reference) {
159
160
161 for (final double[] row : analyticalDerivativesStm) {
162 Arrays.fill(row, 0.0);
163 }
164 analyticalDerivativesJacobianColumns.clear();
165
166 final AbstractAnalyticalGradientConverter converter = getGradientConverter();
167 final FieldAbstractAnalyticalPropagator<Gradient> gPropagator = converter.getPropagator();
168
169
170 final AbsoluteDate target = reference.getDate();
171 final FieldAbsoluteDate<Gradient> start = gPropagator.getInitialState().getDate();
172 final double dt = target.durationFrom(start.toAbsoluteDate());
173 final FieldSpacecraftState<Gradient> state = gPropagator.getInitialState();
174 final Gradient[] parameters = converter.getParameters(state, converter);
175 final FieldOrbit<Gradient> gOrbit = gPropagator.propagateOrbit(start.shiftedBy(dt), parameters);
176 final FieldPVCoordinates<Gradient> gPv = gOrbit.getPVCoordinates();
177
178 final double[] derivativesX = gPv.getPosition().getX().getGradient();
179 final double[] derivativesY = gPv.getPosition().getY().getGradient();
180 final double[] derivativesZ = gPv.getPosition().getZ().getGradient();
181 final double[] derivativesVx = gPv.getVelocity().getX().getGradient();
182 final double[] derivativesVy = gPv.getVelocity().getY().getGradient();
183 final double[] derivativesVz = gPv.getVelocity().getZ().getGradient();
184
185
186 addToRow(derivativesX, 0);
187 addToRow(derivativesY, 1);
188 addToRow(derivativesZ, 2);
189 addToRow(derivativesVx, 3);
190 addToRow(derivativesVy, 4);
191 addToRow(derivativesVz, 5);
192
193
194 int paramsIndex = converter.getFreeStateParameters();
195 for (ParameterDriver driver : converter.getParametersDrivers()) {
196 if (driver.isSelected()) {
197
198 final TimeSpanMap<String> driverNameSpanMap = driver.getNamesSpanMap();
199
200 for (Span<String> span = driverNameSpanMap.getFirstSpan(); span != null; span = span.next()) {
201
202 DoubleArrayDictionary.Entry entry = analyticalDerivativesJacobianColumns.getEntry(span.getData());
203 if (entry == null) {
204
205 analyticalDerivativesJacobianColumns.put(span.getData(), new double[getStateDimension()]);
206 entry = analyticalDerivativesJacobianColumns.getEntry(span.getData());
207 }
208
209
210 entry.increment(new double[] {
211 derivativesX[paramsIndex], derivativesY[paramsIndex], derivativesZ[paramsIndex],
212 derivativesVx[paramsIndex], derivativesVy[paramsIndex], derivativesVz[paramsIndex]
213 });
214 ++paramsIndex;
215 }
216 }
217 }
218
219
220 epoch = target;
221
222 }
223
224
225
226
227 private void updateDerivativesIfNeeded(final SpacecraftState state) {
228 if (!state.getDate().isEqualTo(epoch)) {
229 setReferenceState(state);
230 }
231 }
232
233
234
235
236
237 private void addToRow(final double[] derivatives, final int index) {
238 for (int i = 0; i < 6; i++) {
239 analyticalDerivativesStm[index][i] += derivatives[i];
240 }
241 }
242
243
244 @Override
245 public OrbitType getOrbitType() {
246
247 return OrbitType.CARTESIAN;
248 }
249
250
251 @Override
252 public PositionAngleType getPositionAngleType() {
253
254 return PositionAngleType.MEAN;
255 }
256
257
258
259
260
261 public abstract AbstractAnalyticalGradientConverter getGradientConverter();
262
263 }