1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.forces.gravity;
18
19 import java.util.Collections;
20 import java.util.List;
21 import java.util.stream.Stream;
22
23 import org.hipparchus.Field;
24 import org.hipparchus.CalculusFieldElement;
25 import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
26 import org.hipparchus.geometry.euclidean.threed.Vector3D;
27 import org.hipparchus.util.FastMath;
28 import org.orekit.annotation.DefaultDataContext;
29 import org.orekit.bodies.CelestialBody;
30 import org.orekit.data.DataContext;
31 import org.orekit.forces.AbstractForceModel;
32 import org.orekit.propagation.FieldSpacecraftState;
33 import org.orekit.propagation.SpacecraftState;
34 import org.orekit.propagation.events.EventDetector;
35 import org.orekit.propagation.events.FieldEventDetector;
36 import org.orekit.utils.Constants;
37 import org.orekit.utils.FieldPVCoordinates;
38 import org.orekit.utils.PVCoordinates;
39 import org.orekit.utils.ParameterDriver;
40
41
42
43
44
45
46
47
48
49
50
51
52 public class DeSitterRelativity extends AbstractForceModel {
53
54
55 public static final String ATTRACTION_COEFFICIENT_SUFFIX = " attraction coefficient";
56
57
58
59
60
61
62
63 private static final double MU_SCALE = FastMath.scalb(1.0, 32);
64
65
66 private final CelestialBody sun;
67
68
69 private final CelestialBody earth;
70
71
72 private final ParameterDriver gmParameterDriver;
73
74
75
76
77
78 @DefaultDataContext
79 public DeSitterRelativity() {
80 this(DataContext.getDefault().getCelestialBodies().getEarth(),
81 DataContext.getDefault().getCelestialBodies().getSun());
82 }
83
84
85
86
87
88
89 public DeSitterRelativity(final CelestialBody earth, final CelestialBody sun) {
90 gmParameterDriver = new ParameterDriver(sun.getName() + ThirdBodyAttraction.ATTRACTION_COEFFICIENT_SUFFIX,
91 sun.getGM(), MU_SCALE,
92 0.0, Double.POSITIVE_INFINITY);
93 this.earth = earth;
94 this.sun = sun;
95 }
96
97
98
99
100
101 public CelestialBody getSun() {
102 return sun;
103 }
104
105
106
107
108
109 public CelestialBody getEarth() {
110 return earth;
111 }
112
113
114 @Override
115 public boolean dependsOnPositionOnly() {
116 return false;
117 }
118
119
120 @Override
121 public Vector3D acceleration(final SpacecraftState s, final double[] parameters) {
122
123
124 final double c2 = Constants.SPEED_OF_LIGHT * Constants.SPEED_OF_LIGHT;
125
126
127 final double gm = parameters[0];
128
129
130 final PVCoordinates pvSat = s.getPVCoordinates();
131 final Vector3D vSat = pvSat.getVelocity();
132
133
134 final PVCoordinates pvEarth = earth.getPVCoordinates(s.getDate(), sun.getInertiallyOrientedFrame());
135 final Vector3D pEarth = pvEarth.getPosition();
136 final Vector3D vEarth = pvEarth.getVelocity();
137
138
139 final double r = pEarth.getNorm();
140 final double r3 = r * r * r;
141
142
143 return new Vector3D((-3.0 * gm) / (c2 * r3), vEarth.crossProduct(pEarth).crossProduct(vSat));
144 }
145
146
147 @Override
148 public <T extends CalculusFieldElement<T>> FieldVector3D<T> acceleration(final FieldSpacecraftState<T> s,
149 final T[] parameters) {
150
151
152 final double c2 = Constants.SPEED_OF_LIGHT * Constants.SPEED_OF_LIGHT;
153
154
155 final T gm = parameters[0];
156
157
158 final FieldPVCoordinates<T> pvSat = s.getPVCoordinates();
159 final FieldVector3D<T> vSat = pvSat.getVelocity();
160
161
162 final FieldPVCoordinates<T> pvEarth = earth.getPVCoordinates(s.getDate(), sun.getInertiallyOrientedFrame());
163 final FieldVector3D<T> pEarth = pvEarth.getPosition();
164 final FieldVector3D<T> vEarth = pvEarth .getVelocity();
165
166
167 final T r = pEarth.getNorm();
168 final T r3 = r.multiply(r).multiply(r);
169
170
171 return new FieldVector3D<>(gm.multiply(-3.0).divide(r3.multiply(c2)), vEarth.crossProduct(pEarth).crossProduct(vSat));
172 }
173
174
175 @Override
176 public Stream<EventDetector> getEventsDetectors() {
177 return Stream.empty();
178 }
179
180
181 @Override
182 public <T extends CalculusFieldElement<T>> Stream<FieldEventDetector<T>> getFieldEventsDetectors(final Field<T> field) {
183 return Stream.empty();
184 }
185
186
187 @Override
188 public List<ParameterDriver> getParametersDrivers() {
189 return Collections.singletonList(gmParameterDriver);
190 }
191
192 }