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