1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.propagation.numerical.cr3bp;
18
19 import java.util.Collections;
20 import java.util.List;
21
22 import org.hipparchus.CalculusFieldElement;
23 import org.hipparchus.analysis.differentiation.DSFactory;
24 import org.hipparchus.analysis.differentiation.DerivativeStructure;
25 import org.hipparchus.analysis.differentiation.FDSFactory;
26 import org.hipparchus.analysis.differentiation.FieldDerivativeStructure;
27 import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
28 import org.hipparchus.geometry.euclidean.threed.Vector3D;
29 import org.hipparchus.util.FastMath;
30 import org.orekit.bodies.CR3BPSystem;
31 import org.orekit.forces.ForceModel;
32 import org.orekit.propagation.FieldSpacecraftState;
33 import org.orekit.propagation.SpacecraftState;
34 import org.orekit.utils.ParameterDriver;
35
36
37
38
39
40
41 public class CR3BPForceModel implements ForceModel {
42
43
44 public static final String MASS_RATIO_SUFFIX = "CR3BP System Mass Ratio";
45
46
47
48
49
50
51
52
53 private static final double MU_SCALE = FastMath.scalb(1.0, 32);
54
55
56 private final ParameterDriver muParameterDriver;
57
58
59
60
61 public CR3BPForceModel(final CR3BPSystem cr3bp) {
62 muParameterDriver = new ParameterDriver(cr3bp.getName() + MASS_RATIO_SUFFIX,
63 cr3bp.getMassRatio(), MU_SCALE, 0.0,
64 Double.POSITIVE_INFINITY);
65 }
66
67
68 public Vector3D acceleration(final SpacecraftState s,
69 final double[] parameters) {
70
71
72 final double vx = s.getPVCoordinates().getVelocity().getX();
73 final double vy = s.getPVCoordinates().getVelocity().getY();
74
75
76 final DerivativeStructure potential = getPotential(s);
77
78
79 final double[] dU = potential.getAllDerivatives();
80
81
82 final int idX = potential.getFactory().getCompiler().getPartialDerivativeIndex(1, 0, 0);
83 final int idY = potential.getFactory().getCompiler().getPartialDerivativeIndex(0, 1, 0);
84 final int idZ = potential.getFactory().getCompiler().getPartialDerivativeIndex(0, 0, 1);
85
86
87 final double accx = dU[idX] + 2.0 * vy;
88 final double accy = dU[idY] - 2.0 * vx;
89 final double accz = dU[idZ];
90
91
92 return new Vector3D(accx, accy, accz);
93
94 }
95
96
97 public <T extends CalculusFieldElement<T>> FieldVector3D<T> acceleration(final FieldSpacecraftState<T> s,
98 final T[] parameters) {
99
100
101 final T vx = s.getPVCoordinates().getVelocity().getX();
102 final T vy = s.getPVCoordinates().getVelocity().getY();
103
104
105 final FieldDerivativeStructure<T> fieldPotential = getPotential(s);
106
107 final T[] dU = fieldPotential.getAllDerivatives();
108
109
110 final int idX = fieldPotential.getFactory().getCompiler().getPartialDerivativeIndex(1, 0, 0);
111 final int idY = fieldPotential.getFactory().getCompiler().getPartialDerivativeIndex(0, 1, 0);
112 final int idZ = fieldPotential.getFactory().getCompiler().getPartialDerivativeIndex(0, 0, 1);
113
114
115 final T accx = dU[idX].add(vy.multiply(2.0));
116 final T accy = dU[idY].subtract(vx.multiply(2.0));
117 final T accz = dU[idZ];
118
119
120 return new FieldVector3D<>(accx, accy, accz);
121
122 }
123
124
125
126
127
128
129 public DerivativeStructure getPotential(final SpacecraftState s) {
130
131
132 final double x = s.getPosition().getX();
133 final double y = s.getPosition().getY();
134 final double z = s.getPosition().getZ();
135
136 final DSFactory factoryP = new DSFactory(3, 2);
137 final DerivativeStructure fpx = factoryP.variable(0, x);
138 final DerivativeStructure fpy = factoryP.variable(1, y);
139 final DerivativeStructure fpz = factoryP.variable(2, z);
140
141 final DerivativeStructure zero = fpx.getField().getZero();
142
143
144
145
146 final DerivativeStructure mu = zero.newInstance(muParameterDriver.getValue(s.getDate()));
147
148
149 final DerivativeStructure d1 = mu;
150 final DerivativeStructure d2 = mu.negate().add(1.0);
151
152
153 final DerivativeStructure r1 =
154 FastMath.sqrt((fpx.add(d1)).multiply(fpx.add(d1)).add(fpy.square())
155 .add(fpz.square()));
156
157
158 final DerivativeStructure r2 =
159 FastMath.sqrt((fpx.subtract(d2)).multiply(fpx.subtract(d2))
160 .add(fpy.square()).add(fpz.square()));
161
162
163 return (mu.negate().add(1.0).divide(r1)).add(mu.divide(r2))
164 .add(fpx.square().add(fpy.square()).multiply(0.5)).add(d1.multiply(d2).multiply(0.5));
165 }
166
167
168
169
170
171
172
173 public <T extends CalculusFieldElement<T>> FieldDerivativeStructure<T> getPotential(final FieldSpacecraftState<T> s) {
174
175
176 final T x = s.getPosition().getX();
177 final T y = s.getPosition().getY();
178 final T z = s.getPosition().getZ();
179
180 final FDSFactory<T> factoryP = new FDSFactory<>(s.getDate().getField(), 3, 2);
181 final FieldDerivativeStructure<T> fpx = factoryP.variable(0, x);
182 final FieldDerivativeStructure<T> fpy = factoryP.variable(1, y);
183 final FieldDerivativeStructure<T> fpz = factoryP.variable(2, z);
184 final FieldDerivativeStructure<T> zero = fpx.getField().getZero();
185
186
187
188
189 final FieldDerivativeStructure<T> mu = zero.newInstance(muParameterDriver.getValue(s.getDate().toAbsoluteDate()));
190
191
192 final FieldDerivativeStructure<T> d1 = mu;
193 final FieldDerivativeStructure<T> d2 = mu.negate().add(1.0);
194
195
196 final FieldDerivativeStructure<T> r1 =
197 FastMath.sqrt((fpx.add(d1)).multiply(fpx.add(d1)).add(fpy.square())
198 .add(fpz.square()));
199
200
201 final FieldDerivativeStructure<T> r2 =
202 FastMath.sqrt((fpx.subtract(d2)).multiply(fpx.subtract(d2))
203 .add(fpy.square()).add(fpz.square()));
204
205
206 return (mu.negate().add(1.0).divide(r1)).add(mu.divide(r2))
207 .add(fpx.square().add(fpy.square()).multiply(0.5)).add(d1.multiply(d2).multiply(0.5));
208 }
209
210
211 public List<ParameterDriver> getParametersDrivers() {
212 return Collections.singletonList(muParameterDriver);
213 }
214
215
216 public boolean dependsOnPositionOnly() {
217 return true;
218 }
219 }