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.forces.AbstractForceModel;
29 import org.orekit.propagation.FieldSpacecraftState;
30 import org.orekit.propagation.SpacecraftState;
31 import org.orekit.propagation.events.EventDetector;
32 import org.orekit.propagation.events.FieldEventDetector;
33 import org.orekit.utils.Constants;
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 public class Relativity extends AbstractForceModel {
49
50
51
52
53
54
55
56 private static final double MU_SCALE = FastMath.scalb(1.0, 32);
57
58
59 private final ParameterDriver gmParameterDriver;
60
61
62
63
64
65
66
67 public Relativity(final double gm) {
68 gmParameterDriver = new ParameterDriver(NewtonianAttraction.CENTRAL_ATTRACTION_COEFFICIENT,
69 gm, MU_SCALE,
70 0.0, Double.POSITIVE_INFINITY);
71 }
72
73
74 @Override
75 public boolean dependsOnPositionOnly() {
76 return false;
77 }
78
79
80 @Override
81 public Vector3D acceleration(final SpacecraftState s, final double[] parameters) {
82
83 final double gm = parameters[0];
84
85 final PVCoordinates pv = s.getPVCoordinates();
86 final Vector3D p = pv.getPosition();
87 final Vector3D v = pv.getVelocity();
88
89 final double r2 = p.getNormSq();
90 final double r = FastMath.sqrt(r2);
91
92 final double s2 = v.getNormSq();
93 final double c2 = Constants.SPEED_OF_LIGHT * Constants.SPEED_OF_LIGHT;
94
95 return new Vector3D(
96 4 * gm / r - s2,
97 p,
98 4 * p.dotProduct(v),
99 v)
100 .scalarMultiply(gm / (r2 * r * c2));
101
102 }
103
104
105 @Override
106 public <T extends CalculusFieldElement<T>> FieldVector3D<T> acceleration(final FieldSpacecraftState<T> s,
107 final T[] parameters) {
108
109 final T gm = parameters[0];
110
111 final FieldPVCoordinates<T> pv = s.getPVCoordinates();
112 final FieldVector3D<T> p = pv.getPosition();
113 final FieldVector3D<T> v = pv.getVelocity();
114
115 final T r2 = p.getNormSq();
116 final T r = r2.sqrt();
117
118 final T s2 = v.getNormSq();
119 final double c2 = Constants.SPEED_OF_LIGHT * Constants.SPEED_OF_LIGHT;
120
121 return new FieldVector3D<>(r.reciprocal().multiply(4).multiply(gm).subtract(s2),
122 p,
123 p.dotProduct(v).multiply(4),
124 v).scalarMultiply(r2.multiply(r).multiply(c2).reciprocal().multiply(gm));
125
126 }
127
128
129 @Override
130 public Stream<EventDetector> getEventsDetectors() {
131 return Stream.empty();
132 }
133
134
135 @Override
136 public <T extends CalculusFieldElement<T>> Stream<FieldEventDetector<T>> getFieldEventsDetectors(final Field<T> field) {
137 return Stream.empty();
138 }
139
140
141 @Override
142 public List<ParameterDriver> getParametersDrivers() {
143 return Collections.singletonList(gmParameterDriver);
144 }
145
146 }