1 /* Copyright 2002-2021 CS GROUP
2 * Licensed to CS GROUP (CS) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * CS licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.orekit.propagation.semianalytical.dsst.forces;
18
19 import org.hipparchus.Field;
20 import org.hipparchus.CalculusFieldElement;
21 import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
22 import org.hipparchus.util.FastMath;
23 import org.orekit.forces.gravity.potential.UnnormalizedSphericalHarmonicsProvider;
24 import org.orekit.frames.FieldTransform;
25 import org.orekit.frames.Frame;
26 import org.orekit.propagation.semianalytical.dsst.utilities.FieldAuxiliaryElements;
27
28 /**
29 * This class is a container for the common "field" parameters used in {@link DSSTTesseral}.
30 * <p>
31 * It performs parameters initialization at each integration step for the Tesseral contribution
32 * to the central body gravitational perturbation.
33 * <p>
34 * @author Bryan Cazabonne
35 * @since 10.0
36 */
37 public class FieldDSSTTesseralContext<T extends CalculusFieldElement<T>> extends FieldForceModelContext<T> {
38
39 /** Retrograde factor I.
40 * <p>
41 * DSST model needs equinoctial orbit as internal representation.
42 * Classical equinoctial elements have discontinuities when inclination
43 * is close to zero. In this representation, I = +1. <br>
44 * To avoid this discontinuity, another representation exists and equinoctial
45 * elements can be expressed in a different way, called "retrograde" orbit.
46 * This implies I = -1. <br>
47 * As Orekit doesn't implement the retrograde orbit, I is always set to +1.
48 * But for the sake of consistency with the theory, the retrograde factor
49 * has been kept in the formulas.
50 * </p>
51 */
52 private static final int I = 1;
53
54 /** A = sqrt(μ * a). */
55 private T A;
56
57 // Common factors for potential computation
58 /** Χ = 1 / sqrt(1 - e²) = 1 / B. */
59 private T chi;
60
61 /** Χ². */
62 private T chi2;
63
64 /** Central body rotation angle θ. */
65 private T theta;
66
67 // Common factors from equinoctial coefficients
68 /** 2 * a / A .*/
69 private T ax2oA;
70
71 /** 1 / (A * B) .*/
72 private T ooAB;
73
74 /** B / A .*/
75 private T BoA;
76
77 /** B / (A * (1 + B)) .*/
78 private T BoABpo;
79
80 /** C / (2 * A * B) .*/
81 private T Co2AB;
82
83 /** μ / a .*/
84 private T moa;
85
86 /** R / a .*/
87 private T roa;
88
89 /** ecc². */
90 private T e2;
91
92 /** Keplerian mean motion. */
93 private T n;
94
95 /** Keplerian period. */
96 private T period;
97
98 /** Ratio of satellite period to central body rotation period. */
99 private T ratio;
100
101 /**
102 * Simple constructor.
103 *
104 * @param auxiliaryElements auxiliary elements related to the current orbit
105 * @param centralBodyFrame rotating body frame
106 * @param provider provider for spherical harmonics
107 * @param maxFrequencyShortPeriodics maximum value for j
108 * @param bodyPeriod central body rotation period (seconds)
109 * @param parameters values of the force model parameters
110 */
111 FieldDSSTTesseralContext(final FieldAuxiliaryElements<T> auxiliaryElements,
112 final Frame centralBodyFrame,
113 final UnnormalizedSphericalHarmonicsProvider provider,
114 final int maxFrequencyShortPeriodics,
115 final double bodyPeriod,
116 final T[] parameters) {
117
118 super(auxiliaryElements);
119
120 final Field<T> field = auxiliaryElements.getDate().getField();
121 final T zero = field.getZero();
122
123 final T mu = parameters[0];
124
125 // Keplerian mean motion
126 final T absA = FastMath.abs(auxiliaryElements.getSma());
127 n = FastMath.sqrt(mu.divide(absA)).divide(absA);
128
129 // Keplerian period
130 final T a = auxiliaryElements.getSma();
131 period = (a.getReal() < 0) ? zero.add(Double.POSITIVE_INFINITY) : a.multiply(a.getPi().multiply(2.0)).multiply(a.divide(mu).sqrt());
132
133 A = FastMath.sqrt(mu.multiply(auxiliaryElements.getSma()));
134
135 // Eccentricity square
136 e2 = auxiliaryElements.getEcc().multiply(auxiliaryElements.getEcc());
137
138 // Central body rotation angle from equation 2.7.1-(3)(4).
139 final FieldTransform<T> t = centralBodyFrame.getTransformTo(auxiliaryElements.getFrame(), auxiliaryElements.getDate());
140 final FieldVector3D<T> xB = t.transformVector(FieldVector3D.getPlusI(field));
141 final FieldVector3D<T> yB = t.transformVector(FieldVector3D.getPlusJ(field));
142 theta = FastMath.atan2(auxiliaryElements.getVectorF().dotProduct(yB).negate().add((auxiliaryElements.getVectorG().dotProduct(xB)).multiply(I)),
143 auxiliaryElements.getVectorF().dotProduct(xB).add(auxiliaryElements.getVectorG().dotProduct(yB).multiply(I)));
144
145 // Common factors from equinoctial coefficients
146 // 2 * a / A
147 ax2oA = auxiliaryElements.getSma().divide(A).multiply(2.);
148 // B / A
149 BoA = auxiliaryElements.getB().divide(A);
150 // 1 / AB
151 ooAB = A.multiply(auxiliaryElements.getB()).reciprocal();
152 // C / 2AB
153 Co2AB = auxiliaryElements.getC().multiply(ooAB).divide(2.);
154 // B / (A * (1 + B))
155 BoABpo = BoA.divide(auxiliaryElements.getB().add(1.));
156 // &mu / a
157 moa = mu.divide(auxiliaryElements.getSma());
158 // R / a
159 roa = auxiliaryElements.getSma().divide(provider.getAe()).reciprocal();
160
161 // Χ = 1 / B
162 chi = auxiliaryElements.getB().reciprocal();
163 chi2 = chi.multiply(chi);
164
165 // Ratio of satellite to central body periods to define resonant terms
166 ratio = period.divide(bodyPeriod);
167
168 }
169
170 /** Get ecc².
171 * @return e2
172 */
173 public T getE2() {
174 return e2;
175 }
176
177 /** Get Central body rotation angle θ.
178 * @return theta
179 */
180 public T getTheta() {
181 return theta;
182 }
183
184 /** Get ax2oA = 2 * a / A .
185 * @return ax2oA
186 */
187 public T getAx2oA() {
188 return ax2oA;
189 }
190
191 /** Get Χ = 1 / sqrt(1 - e²) = 1 / B.
192 * @return chi
193 */
194 public T getChi() {
195 return chi;
196 }
197
198 /** Get Χ².
199 * @return chi2
200 */
201 public T getChi2() {
202 return chi2;
203 }
204
205 /** Get B / A.
206 * @return BoA
207 */
208 public T getBoA() {
209 return BoA;
210 }
211
212 /** Get ooAB = 1 / (A * B).
213 * @return ooAB
214 */
215 public T getOoAB() {
216 return ooAB;
217 }
218
219 /** Get Co2AB = C / 2AB.
220 * @return Co2AB
221 */
222 public T getCo2AB() {
223 return Co2AB;
224 }
225
226 /** Get BoABpo = B / A(1 + B).
227 * @return BoABpo
228 */
229 public T getBoABpo() {
230 return BoABpo;
231 }
232
233 /** Get μ / a .
234 * @return moa
235 */
236 public T getMoa() {
237 return moa;
238 }
239
240 /** Get roa = R / a.
241 * @return roa
242 */
243 public T getRoa() {
244 return roa;
245 }
246
247 /** Get the Keplerian period.
248 * <p>The Keplerian period is computed directly from semi major axis
249 * and central acceleration constant.</p>
250 * @return Keplerian period in seconds, or positive infinity for hyperbolic orbits
251 */
252 public T getOrbitPeriod() {
253 return period;
254 }
255
256 /** Get the Keplerian mean motion.
257 * <p>The Keplerian mean motion is computed directly from semi major axis
258 * and central acceleration constant.</p>
259 * @return Keplerian mean motion in radians per second
260 */
261 public T getMeanMotion() {
262 return n;
263 }
264
265 /** Get the ratio of satellite period to central body rotation period.
266 * @return ratio
267 */
268 public T getRatio() {
269 return ratio;
270 }
271
272 }