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.conversion.osc2mean;
18  
19  import org.hipparchus.CalculusFieldElement;
20  import org.orekit.forces.gravity.potential.GravityFieldFactory;
21  import org.orekit.forces.gravity.potential.TideSystem;
22  import org.orekit.forces.gravity.potential.UnnormalizedSphericalHarmonicsProvider;
23  import org.orekit.orbits.FieldOrbit;
24  import org.orekit.orbits.Orbit;
25  import org.orekit.orbits.OrbitType;
26  import org.orekit.propagation.PropagationType;
27  import org.orekit.propagation.analytical.EcksteinHechlerPropagator;
28  import org.orekit.propagation.analytical.FieldEcksteinHechlerPropagator;
29  
30  /**
31   * Eckstein-Hechler theory for osculating to mean orbit conversion.
32   *
33   * @author Pascal Parraud
34   * @since 13.0
35   */
36  public class EcksteinHechlerTheory implements MeanTheory {
37  
38      /** Theory used for converting from osculating to mean orbit. */
39      public static final String THEORY = "Eckstein-Hechler";
40  
41      /** Unnormalized spherical harmonics provider. */
42      private final UnnormalizedSphericalHarmonicsProvider provider;
43  
44      /**
45       * Constructor.
46       * @param provider unnormalized spherical harmonics provider
47       */
48      public EcksteinHechlerTheory(final UnnormalizedSphericalHarmonicsProvider provider) {
49          this.provider = provider;
50      }
51  
52      /**
53       * Constructor.
54       * @param referenceRadius reference radius of the Earth for the potential model (m)
55       * @param mu central attraction coefficient (m³/s²)
56       * @param c20 un-normalized zonal coefficient (about -1.08e-3 for Earth)
57       * @param c30 un-normalized zonal coefficient (about +2.53e-6 for Earth)
58       * @param c40 un-normalized zonal coefficient (about +1.62e-6 for Earth)
59       * @param c50 un-normalized zonal coefficient (about +2.28e-7 for Earth)
60       * @param c60 un-normalized zonal coefficient (about -5.41e-7 for Earth)
61       */
62      public EcksteinHechlerTheory(final double referenceRadius,
63                                   final double mu,
64                                   final double c20,
65                                   final double c30,
66                                   final double c40,
67                                   final double c50,
68                                   final double c60) {
69          this(GravityFieldFactory.getUnnormalizedProvider(referenceRadius, mu,
70                                                           TideSystem.UNKNOWN,
71                                                           new double[][] { { 0 }, { 0 }, { c20 }, { c30 }, { c40 }, { c50 }, { c60 } },
72                                                           new double[][] { { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 } }));
73      }
74  
75      /** {@inheritDoc} */
76      @Override
77      public String getTheoryName() {
78          return THEORY;
79      }
80  
81      /** {@inheritDoc} */
82      @Override
83      public double getReferenceRadius() {
84          return provider.getAe();
85      };
86  
87      /** {@inheritDoc} */
88      @Override
89      public Orbit meanToOsculating(final Orbit mean) {
90          final EcksteinHechlerPropagator propagator =
91                          new EcksteinHechlerPropagator(mean, provider, PropagationType.MEAN);
92          return propagator.getOsculatingCircularOrbit(mean.getDate());
93      }
94  
95      /** {@inheritDoc} */
96      @Override
97      public <T extends CalculusFieldElement<T>> FieldOrbit<T> meanToOsculating(final FieldOrbit<T> mean) {
98          final FieldEcksteinHechlerPropagator<T> propagator =
99                          new FieldEcksteinHechlerPropagator<>(mean, provider, PropagationType.MEAN);
100         return propagator.getOsculatingCircularOrbit(mean.getDate());
101     }
102 
103     /** Post-treatment of the converted mean orbit.
104      * <p>The mean orbit returned is circular.</p>
105      * @param osculating the osculating orbit to be converted
106      * @param mean the converted mean orbit
107      * @return postprocessed mean orbit
108      */
109     @Override
110     public Orbit postprocessing(final Orbit osculating, final Orbit mean) {
111         return OrbitType.CIRCULAR.convertType(mean);
112     }
113 
114     /** Post-treatment of the converted mean orbit.
115      * <p>The mean orbit returned is circular.</p>
116      * @param <T> type of the field elements
117      * @param osculating the osculating orbit to be converted
118      * @param mean the converted mean orbit
119      * @return postprocessed mean orbit
120      */
121     @Override
122     public <T extends CalculusFieldElement<T>> FieldOrbit<T> postprocessing(final FieldOrbit<T> osculating,
123                                                                             final FieldOrbit<T> mean) {
124         return OrbitType.CIRCULAR.convertType(mean);
125     }
126 }