1   /* Copyright 2002-2025 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.utilities;
18  
19  import org.hipparchus.CalculusFieldElement;
20  import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
21  import org.hipparchus.util.FastMath;
22  import org.hipparchus.util.MathUtils;
23  import org.orekit.frames.Frame;
24  import org.orekit.orbits.FieldOrbit;
25  import org.orekit.time.FieldAbsoluteDate;
26  
27  /** Container class for common parameters used by all DSST forces.
28   *  <p>
29   *  Most of them are defined in Danielson paper at § 2.1.
30   *  </p>
31   *  @author Bryan Cazabonne
32   * @param <T> type of the field elements
33   */
34  public class FieldAuxiliaryElements<T extends CalculusFieldElement<T>> {
35  
36      /** Orbit. */
37      private final FieldOrbit<T> orbit;
38  
39      /** Orbit date. */
40      private final FieldAbsoluteDate<T> date;
41  
42      /** Orbit frame. */
43      private final Frame frame;
44  
45      /** Eccentricity. */
46      private final T ecc;
47  
48      /** Keplerian mean motion. */
49      private final T n;
50  
51      /** Keplerian period. */
52      private final T period;
53  
54      /** Semi-major axis. */
55      private final T sma;
56  
57      /** x component of eccentricity vector. */
58      private final T k;
59  
60      /** y component of eccentricity vector. */
61      private final T h;
62  
63      /** x component of inclination vector. */
64      private final T q;
65  
66      /** y component of inclination vector. */
67      private final T p;
68  
69      /** Mean longitude. */
70      private final T lm;
71  
72      /** True longitude. */
73      private final T lv;
74  
75      /** Eccentric longitude. */
76      private final T le;
77  
78      /** Retrograde factor I.
79       *  <p>
80       *  DSST model needs equinoctial orbit as internal representation.
81       *  Classical equinoctial elements have discontinuities when inclination
82       *  is close to zero. In this representation, I = +1. <br>
83       *  To avoid this discontinuity, another representation exists and equinoctial
84       *  elements can be expressed in a different way, called "retrograde" orbit.
85       *  This implies I = -1. <br>
86       *  As Orekit doesn't implement the retrograde orbit, I is always set to +1.
87       *  But for the sake of consistency with the theory, the retrograde factor
88       *  has been kept in the formulas.
89       *  </p>
90       */
91      private final int    I;
92  
93      /** B = sqrt(1 - h² - k²). */
94      private final T B;
95  
96      /** C = 1 + p² + q². */
97      private final T C;
98  
99      /** Equinoctial frame f vector. */
100     private final FieldVector3D<T> f;
101 
102     /** Equinoctial frame g vector. */
103     private final FieldVector3D<T> g;
104 
105     /** Equinoctial frame w vector. */
106     private final FieldVector3D<T> w;
107 
108     /** Simple constructor.
109      * @param orbit related mean orbit for auxiliary elements
110      * @param retrogradeFactor retrograde factor I [Eq. 2.1.2-(2)]
111      */
112     public FieldAuxiliaryElements(final FieldOrbit<T> orbit, final int retrogradeFactor) {
113 
114         final T pi = orbit.getDate().getField().getZero().getPi();
115 
116         // Orbit
117         this.orbit = orbit;
118 
119         // Date of the orbit
120         date = orbit.getDate();
121 
122         // Orbit definition frame
123         frame = orbit.getFrame();
124 
125         // Eccentricity
126         ecc = orbit.getE();
127 
128         // Keplerian mean motion
129         n = orbit.getKeplerianMeanMotion();
130 
131         // Keplerian period
132         period = orbit.getKeplerianPeriod();
133 
134         // Equinoctial elements [Eq. 2.1.2-(1)]
135         sma = orbit.getA();
136         k   = orbit.getEquinoctialEx();
137         h   = orbit.getEquinoctialEy();
138         q   = orbit.getHx();
139         p   = orbit.getHy();
140         lm  = MathUtils.normalizeAngle(orbit.getLM(), pi);
141         lv  = MathUtils.normalizeAngle(orbit.getLv(), pi);
142         le  = MathUtils.normalizeAngle(orbit.getLE(), pi);
143 
144         // Retrograde factor [Eq. 2.1.2-(2)]
145         I = retrogradeFactor;
146 
147         final T k2 = k.multiply(k);
148         final T h2 = h.multiply(h);
149         final T q2 = q.multiply(q);
150         final T p2 = p.multiply(p);
151 
152         // A, B, C parameters [Eq. 2.1.6-(1)]
153         B = FastMath.sqrt(k2.add(h2).negate().add(1.));
154         C = q2.add(p2).add(1);
155 
156         // Equinoctial reference frame [Eq. 2.1.4-(1)]
157         final T ooC = C.reciprocal();
158         final T px2 = p.multiply(2.);
159         final T qx2 = q.multiply(2.);
160         final T pq2 = px2.multiply(q);
161         f = new FieldVector3D<>(ooC, new FieldVector3D<>(p2.negate().add(1.).add(q2), pq2, px2.multiply(I).negate()));
162         g = new FieldVector3D<>(ooC, new FieldVector3D<>(pq2.multiply(I), (p2.add(1.).subtract(q2)).multiply(I), qx2));
163         w = new FieldVector3D<>(ooC, new FieldVector3D<>(px2, qx2.negate(), (p2.add(q2).negate().add(1.)).multiply(I)));
164     }
165 
166     /** Get the orbit.
167      * @return the orbit
168      */
169     public FieldOrbit<T> getOrbit() {
170         return orbit;
171     }
172 
173     /** Get the date of the orbit.
174      * @return the date
175      */
176     public FieldAbsoluteDate<T> getDate() {
177         return date;
178     }
179 
180     /** Get the definition frame of the orbit.
181      * @return the definition frame
182      */
183     public Frame getFrame() {
184         return frame;
185     }
186 
187     /** Get the eccentricity.
188      * @return ecc
189      */
190     public T getEcc() {
191         return ecc;
192     }
193 
194     /** Get the Keplerian mean motion.
195      * @return n
196      */
197     public T getMeanMotion() {
198         return n;
199     }
200 
201     /** Get the Keplerian period.
202      * @return period
203      */
204     public T getKeplerianPeriod() {
205         return period;
206     }
207 
208     /** Get the semi-major axis.
209      * @return the semi-major axis a
210      */
211     public T getSma() {
212         return sma;
213     }
214 
215     /** Get the x component of eccentricity vector.
216      * <p>
217      * This element called k in DSST corresponds to ex
218      * for the {@link org.orekit.orbits.EquinoctialOrbit}
219      * </p>
220      * @return k
221      */
222     public T getK() {
223         return k;
224     }
225 
226     /** Get the y component of eccentricity vector.
227      * <p>
228      * This element called h in DSST corresponds to ey
229      * for the {@link org.orekit.orbits.EquinoctialOrbit}
230      * </p>
231      * @return h
232      */
233     public T getH() {
234         return h;
235     }
236 
237     /** Get the x component of inclination vector.
238      * <p>
239      * This element called q in DSST corresponds to hx
240      * for the {@link org.orekit.orbits.EquinoctialOrbit}
241      * </p>
242      * @return q
243      */
244     public T getQ() {
245         return q;
246     }
247 
248     /** Get the y component of inclination vector.
249      * <p>
250      * This element called p in DSST corresponds to hy
251      * for the {@link org.orekit.orbits.EquinoctialOrbit}
252      * </p>
253      * @return p
254      */
255     public T getP() {
256         return p;
257     }
258 
259     /** Get the mean longitude.
260      * @return lm
261      */
262     public T getLM() {
263         return lm;
264     }
265 
266     /** Get the true longitude.
267      * @return lv
268      */
269     public T getLv() {
270         return lv;
271     }
272 
273     /** Get the eccentric longitude.
274      * @return le
275      */
276     public T getLe() {
277         return le;
278     }
279 
280     /** Get the retrograde factor.
281      * @return the retrograde factor I
282      */
283     public int getRetrogradeFactor() {
284         return I;
285     }
286 
287     /** Get B = sqrt(1 - e²).
288      * @return B
289      */
290     public T getB() {
291         return B;
292     }
293 
294     /** Get C = 1 + p² + q².
295      * @return C
296      */
297     public T getC() {
298         return C;
299     }
300 
301     /** Get equinoctial frame vector f.
302      * @return f vector
303      */
304     public FieldVector3D<T> getVectorF() {
305         return f;
306     }
307 
308     /** Get equinoctial frame vector g.
309      * @return g vector
310      */
311     public FieldVector3D<T> getVectorG() {
312         return g;
313     }
314 
315     /** Get equinoctial frame vector w.
316      * @return w vector
317      */
318     public FieldVector3D<T> getVectorW() {
319         return w;
320     }
321 
322     /** Transforms the FieldAuxiliaryElements instance into an AuxiliaryElements instance.
323      * @return the AuxiliaryElements instance
324      * @since 11.3.3
325      */
326     public AuxiliaryElements toAuxiliaryElements() {
327         return new AuxiliaryElements(orbit.toOrbit(), getRetrogradeFactor());
328     }
329 
330 }