1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.propagation.numerical;
18
19 import java.util.List;
20
21 import org.hipparchus.linear.MatrixUtils;
22 import org.hipparchus.linear.RealMatrix;
23 import org.orekit.orbits.Orbit;
24 import org.orekit.orbits.OrbitType;
25 import org.orekit.orbits.PositionAngleType;
26 import org.orekit.propagation.AbstractMatricesHarvester;
27 import org.orekit.propagation.SpacecraftState;
28 import org.orekit.utils.DoubleArrayDictionary;
29
30
31
32
33
34
35 class NumericalPropagationHarvester extends AbstractMatricesHarvester {
36
37
38 private static final double[][] IDENTITY6 = {
39 { 1.0, 0.0, 0.0, 0.0, 0.0, 0.0 },
40 { 0.0, 1.0, 0.0, 0.0, 0.0, 0.0 },
41 { 0.0, 0.0, 1.0, 0.0, 0.0, 0.0 },
42 { 0.0, 0.0, 0.0, 1.0, 0.0, 0.0 },
43 { 0.0, 0.0, 0.0, 0.0, 1.0, 0.0 },
44 { 0.0, 0.0, 0.0, 0.0, 0.0, 1.0 }
45 };
46
47
48 private final NumericalPropagator propagator;
49
50
51 private List<String> columnsNames;
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69 NumericalPropagationHarvester(final NumericalPropagator propagator, final String stmName,
70 final RealMatrix initialStm, final DoubleArrayDictionary initialJacobianColumns) {
71 setInitialStm(stmName, initialStm);
72 setInitialJacobianColumns(initialJacobianColumns);
73 this.propagator = propagator;
74 this.columnsNames = null;
75 }
76
77
78
79
80
81 private double[][] getConversionJacobian(final SpacecraftState state) {
82
83 if (state.isOrbitDefined() && state.getOrbit().getType() != OrbitType.CARTESIAN) {
84
85 final Orbit orbit = propagator.getOrbitType().convertType(state.getOrbit());
86
87
88 final double[][] dYdC = new double[IDENTITY6.length][IDENTITY6[0].length];
89 orbit.getJacobianWrtCartesian(propagator.getPositionAngleType(), dYdC);
90 return dYdC;
91 } else {
92 return IDENTITY6;
93 }
94
95 }
96
97
98 @Override
99 public void freezeColumnsNames() {
100 columnsNames = getJacobiansColumnsNames();
101 }
102
103
104 @Override
105 public List<String> getJacobiansColumnsNames() {
106 return columnsNames == null ? propagator.getJacobiansColumnsNames() : columnsNames;
107 }
108
109
110 @Override
111 public OrbitType getOrbitType() {
112 return propagator.getOrbitType();
113 }
114
115
116 @Override
117 public PositionAngleType getPositionAngleType() {
118 return propagator.getPositionAngleType();
119 }
120
121
122 @Override
123 public RealMatrix getStateTransitionMatrix(final SpacecraftState state) {
124
125 if (!state.hasAdditionalData(getStmName())) {
126 return null;
127 }
128
129
130 final double[] p = state.getAdditionalState(getStmName());
131 final RealMatrix dCdY0 = toSquareMatrix(p);
132
133 final RealMatrix dYdY0;
134 if (!state.isOrbitDefined() || state.getOrbit().getType() == OrbitType.CARTESIAN) {
135 dYdY0 = dCdY0;
136 } else {
137
138 final RealMatrix dYdC = MatrixUtils.createRealIdentityMatrix(getStateDimension());
139 dYdC.setSubMatrix(getConversionJacobian(state), 0, 0);
140
141
142 dYdY0 = dYdC.multiply(dCdY0);
143 }
144
145 return dYdY0;
146
147 }
148
149
150 @Override
151 public RealMatrix getParametersJacobian(final SpacecraftState state) {
152
153 final List<String> names = getJacobiansColumnsNames();
154
155 if (names == null || names.isEmpty()) {
156 return null;
157 }
158
159
160 final RealMatrix dYdC = MatrixUtils.createRealIdentityMatrix(getStateDimension());
161 dYdC.setSubMatrix(getConversionJacobian(state), 0, 0);
162
163
164 final RealMatrix dYdP = MatrixUtils.createRealMatrix(getStateDimension(), names.size());
165 for (int j = 0; j < names.size(); j++) {
166 final double[] p = state.getAdditionalState(names.get(j));
167 for (int i = 0; i < getStateDimension(); ++i) {
168 final double[] dYdCi = dYdC.getRow(i);
169 double sum = 0;
170 for (int k = 0; k < getStateDimension(); ++k) {
171 sum += dYdCi[k] * p[k];
172 }
173 dYdP.setEntry(i, j, sum);
174 }
175 }
176
177 return dYdP;
178
179 }
180
181 }