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 org.hipparchus.geometry.euclidean.threed.Vector3D;
20 import org.hipparchus.util.FastMath;
21 import org.orekit.errors.OrekitIllegalArgumentException;
22 import org.orekit.errors.OrekitMessages;
23 import org.orekit.forces.ForceModel;
24 import org.orekit.orbits.OrbitType;
25 import org.orekit.orbits.PositionAngleType;
26 import org.orekit.propagation.SpacecraftState;
27
28 import java.util.Arrays;
29 import java.util.List;
30
31
32
33
34
35
36
37
38
39 class NumericalTimeDerivativesEquations implements TimeDerivativesEquations {
40
41
42 private final double[] yDot;
43
44
45 private final OrbitType orbitType;
46
47
48 private final PositionAngleType positionAngleType;
49
50
51 private final List<ForceModel> forceModels;
52
53
54 private double[][] coordinatesJacobian;
55
56
57 private SpacecraftState currentState;
58
59
60
61
62
63
64
65 NumericalTimeDerivativesEquations(final OrbitType orbitType, final PositionAngleType positionAngleType,
66 final List<ForceModel> forceModels) {
67 this.orbitType = orbitType;
68 this.positionAngleType = positionAngleType;
69 this.forceModels = forceModels;
70 this.yDot = new double[7];
71 this.coordinatesJacobian = new double[6][6];
72
73 for (int i = 0; i < coordinatesJacobian.length; ++i) {
74 Arrays.fill(coordinatesJacobian[i], 0.0);
75 coordinatesJacobian[i][i] = 1.0;
76 }
77 }
78
79
80
81
82
83 List<ForceModel> getForceModels() {
84 return forceModels;
85 }
86
87
88
89
90
91 void setCoordinatesJacobian(final double[][] coordinatesJacobian) {
92 this.coordinatesJacobian = coordinatesJacobian;
93 }
94
95
96
97
98
99 void setCurrentState(final SpacecraftState currentState) {
100 this.currentState = currentState;
101 }
102
103
104
105
106
107
108 double[] computeTimeDerivatives(final SpacecraftState state) {
109 currentState = state;
110 Arrays.fill(yDot, 0.0);
111
112
113
114
115 for (final ForceModel forceModel : forceModels) {
116 forceModel.addContribution(state, this);
117 }
118
119 if (orbitType == null) {
120
121
122 final Vector3D velocity = state.getPVCoordinates().getVelocity();
123 yDot[0] += velocity.getX();
124 yDot[1] += velocity.getY();
125 yDot[2] += velocity.getZ();
126 }
127
128 return yDot.clone();
129 }
130
131
132 @Override
133 public void addKeplerContribution(final double mu) {
134 if (orbitType == null) {
135
136 if (mu > 0) {
137
138 final Vector3D position = currentState.getPosition();
139 final double r2 = position.getNorm2Sq();
140 final double coeff = -mu / (r2 * FastMath.sqrt(r2));
141 yDot[3] += coeff * position.getX();
142 yDot[4] += coeff * position.getY();
143 yDot[5] += coeff * position.getZ();
144 }
145
146 } else {
147
148 orbitType.convertType(currentState.getOrbit()).addKeplerContribution(positionAngleType, mu, yDot);
149 }
150 }
151
152
153 @Override
154 public void addNonKeplerianAcceleration(final Vector3D gamma) {
155 for (int i = 0; i < 6; ++i) {
156 final double[] jRow = coordinatesJacobian[i];
157 yDot[i] += jRow[3] * gamma.getX() + jRow[4] * gamma.getY() + jRow[5] * gamma.getZ();
158 }
159 }
160
161
162 @Override
163 public void addMassDerivative(final double q) {
164 if (q > 0) {
165 throw new OrekitIllegalArgumentException(OrekitMessages.POSITIVE_FLOW_RATE, q);
166 }
167 yDot[6] += q;
168 }
169 }