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.forces;
18  
19  import org.hipparchus.geometry.euclidean.threed.Vector3D;
20  import org.hipparchus.util.FastMath;
21  import org.orekit.forces.gravity.potential.UnnormalizedSphericalHarmonicsProvider;
22  import org.orekit.frames.Frame;
23  import org.orekit.frames.StaticTransform;
24  import org.orekit.propagation.semianalytical.dsst.utilities.AuxiliaryElements;
25  
26  /**
27   * This class is a container for the common parameters used in {@link DSSTTesseral} and {@link DSSTZonal}.
28   * <p>
29   * It performs parameters initialization at each integration step for the Tesseral  and Zonal contribution
30   * to the central body gravitational perturbation.
31   * </p>
32   * @author Bryan Cazabonne
33   * @author Maxime Journot
34   * @since 12.2
35   */
36  public class DSSTGravityContext extends ForceModelContext {
37  
38      /** A = sqrt(μ * a). */
39      private final double A;
40  
41      /** &Chi; = 1 / sqrt(1 - e²) = 1 / B. */
42      private final double chi;
43  
44      /** &Chi;². */
45      private final double chi2;
46  
47      // Common factors from equinoctial coefficients
48      /** 2 * a / A . */
49      private final double ax2oA;
50  
51      /** 1 / (A * B) . */
52      private final double ooAB;
53  
54      /** B / A . */
55      private final double BoA;
56  
57      /** B / (A * (1 + B)) . */
58      private final double BoABpo;
59  
60      /** C / (2 * A * B) . */
61      private final double Co2AB;
62  
63      /** μ / a . */
64      private final double muoa;
65  
66      /** R / a . */
67      private final double roa;
68  
69      /** Keplerian mean motion. */
70      private final double n;
71  
72      /** Direction cosine α. */
73      private final double alpha;
74  
75      /** Direction cosine β. */
76      private final double beta;
77  
78      /** Direction cosine γ. */
79      private final double gamma;
80  
81      /** Transform from body-fixed frame to inertial frame. */
82      private final StaticTransform bodyFixedToInertialTransform;
83  
84      /**
85       * Constructor.
86       *
87       * @param auxiliaryElements auxiliary elements related to the current orbit
88       * @param bodyFixedFrame  rotating body frame
89       * @param provider   provider for spherical harmonics
90       * @param parameters values of the force model parameters
91       */
92      DSSTGravityContext(final AuxiliaryElements auxiliaryElements,
93                         final Frame bodyFixedFrame,
94                         final UnnormalizedSphericalHarmonicsProvider provider,
95                         final double[] parameters) {
96  
97          super(auxiliaryElements);
98  
99          // µ
100         final double mu = parameters[0];
101 
102         // Semi-major axis
103         final double a = auxiliaryElements.getSma();
104 
105         // Keplerian Mean Motion
106         final double absA = FastMath.abs(a);
107         this.n = FastMath.sqrt(mu / absA) / absA;
108 
109         // A = sqrt(µ * |a|)
110         this.A = FastMath.sqrt(mu * absA);
111 
112         // &Chi; = 1 / B
113         final double B = auxiliaryElements.getB();
114         this.chi = 1. / B;
115         this.chi2 = chi * chi;
116 
117         // Common factors from equinoctial coefficients
118         // 2 * a / A
119         this.ax2oA = 2. * a / A;
120         // B / A
121         this.BoA = B / A;
122         // 1 / AB
123         this.ooAB = 1. / (A * B);
124         // C / 2AB
125         this.Co2AB = auxiliaryElements.getC() * ooAB / 2.;
126         // B / (A * (1 + B))
127         this.BoABpo = BoA / (1. + B);
128         // &mu / a
129         this.muoa = mu / a;
130         // R / a
131         this.roa = provider.getAe() / a;
132 
133         // If (centralBodyFrame == null), then centralBodyFrame = orbit frame (see DSSTZonal constructors for more on this).
134         final Frame internalBodyFixedFrame = bodyFixedFrame == null ? auxiliaryElements.getFrame() : bodyFixedFrame;
135 
136         // Transform from body-fixed frame (typically ITRF) to inertial frame
137         this.bodyFixedToInertialTransform = internalBodyFixedFrame.
138                         getStaticTransformTo(auxiliaryElements.getFrame(), auxiliaryElements.getDate());
139 
140         final Vector3D zB = bodyFixedToInertialTransform.transformVector(Vector3D.PLUS_K);
141 
142         // Direction cosines for central body [Eq. 2.1.9-(1)]
143         this.alpha = Vector3D.dotProduct(zB, auxiliaryElements.getVectorF());
144         this.beta  = Vector3D.dotProduct(zB, auxiliaryElements.getVectorG());
145         this.gamma = Vector3D.dotProduct(zB, auxiliaryElements.getVectorW());
146     }
147 
148     /** Getter for the a.
149      * @return the a
150      */
151     public double getA() {
152         return A;
153     }
154 
155     /** Getter for the chi.
156      * @return the chi
157      */
158     public double getChi() {
159         return chi;
160     }
161 
162     /** Getter for the chi2.
163      * @return the chi2
164      */
165     public double getChi2() {
166         return chi2;
167     }
168 
169     /** Getter for the ax2oA.
170      * @return the ax2oA
171      */
172     public double getAx2oA() {
173         return ax2oA;
174     }
175 
176     /** ooAB = 1 / (A * B).
177      * @return the ooAB
178      */
179     public double getOoAB() {
180         return ooAB;
181     }
182 
183     /** Get B / A.
184      * @return the boA
185      */
186     public double getBoA() {
187         return BoA;
188     }
189 
190     /** Get BoABpo = B / A(1 + B).
191      * @return the boABpo
192      */
193     public double getBoABpo() {
194         return BoABpo;
195     }
196 
197     /** Get Co2AB = C / 2AB.
198      * @return the co2AB
199      */
200     public double getCo2AB() {
201         return Co2AB;
202     }
203 
204     /** Get μ / a.
205      * @return the muoa
206      */
207     public double getMuoa() {
208         return muoa;
209     }
210 
211     /** Get roa = R / a.
212      * @return the roa
213      */
214     public double getRoa() {
215         return roa;
216     }
217 
218     /**
219      * Get the Keplerian mean motion.
220      * <p>
221      * The Keplerian mean motion is computed directly from semi major axis and
222      * central acceleration constant.
223      * </p>
224      * @return Keplerian mean motion in radians per second
225      */
226     public double getMeanMotion() {
227         return n;
228     }
229 
230     /** Get direction cosine α for central body.
231      * @return α
232      */
233     public double getAlpha() {
234         return alpha;
235     }
236 
237     /** Get direction cosine β for central body.
238      * @return β
239      */
240     public double getBeta() {
241         return beta;
242     }
243 
244     /** Get direction cosine γ for central body.
245      * @return γ
246      */
247     public double getGamma() {
248         return gamma;
249     }
250 
251     /** Getter for the bodyFixedToInertialTransform.
252      * @return the bodyFixedToInertialTransform
253      */
254     public StaticTransform getBodyFixedToInertialTransform() {
255         return bodyFixedToInertialTransform;
256     }
257 }