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