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.hipparchus.Field;
21  import org.orekit.forces.gravity.potential.GravityFieldFactory;
22  import org.orekit.forces.gravity.potential.TideSystem;
23  import org.orekit.forces.gravity.potential.UnnormalizedSphericalHarmonicsProvider;
24  import org.orekit.orbits.FieldOrbit;
25  import org.orekit.orbits.Orbit;
26  import org.orekit.propagation.PropagationType;
27  import org.orekit.propagation.analytical.BrouwerLyddanePropagator;
28  import org.orekit.propagation.analytical.FieldBrouwerLyddanePropagator;
29  import org.orekit.time.FieldAbsoluteDate;
30  
31  /**
32   * Brouwer-Lyddane theory for osculating to mean orbit conversion.
33   *
34   * @author Pascal Parraud
35   * @since 13.0
36   */
37  public class BrouwerLyddaneTheory implements MeanTheory {
38  
39      /** Theory used for converting from osculating to mean orbit. */
40      public static final String THEORY = "Brouwer-Lyddane";
41  
42      /** Provider for un-normalized spherical harmonics coefficients. */
43      private final UnnormalizedSphericalHarmonicsProvider provider;
44  
45      /** Value of the M2 parameter. */
46      private final double m2Value;
47  
48      /**
49       * Constructor.
50       * @param provider unnormalized spherical harmonics provider
51       * @param m2Value  value of empirical drag coefficient in rad/s².
52       *        If equal to {@link BrouwerLyddanePropagator#M2} drag is not computed
53       */
54      public BrouwerLyddaneTheory(final UnnormalizedSphericalHarmonicsProvider provider,
55                                  final double m2Value) {
56          this.provider = provider;
57          this.m2Value  = m2Value;
58      }
59  
60      /**
61       * Constructor.
62       * @param referenceRadius reference radius of the Earth for the potential model (m)
63       * @param mu central attraction coefficient (m³/s²)
64       * @param c20 un-normalized zonal coefficient (about -1.08e-3 for Earth)
65       * @param c30 un-normalized zonal coefficient (about +2.53e-6 for Earth)
66       * @param c40 un-normalized zonal coefficient (about +1.62e-6 for Earth)
67       * @param c50 un-normalized zonal coefficient (about +2.28e-7 for Earth)
68       * @param m2Value value of empirical drag coefficient in rad/s².
69       *        If equal to {@link BrouwerLyddanePropagator#M2} drag is not computed
70       */
71      public BrouwerLyddaneTheory(final double referenceRadius,
72                                  final double mu,
73                                  final double c20,
74                                  final double c30,
75                                  final double c40,
76                                  final double c50,
77                                  final double m2Value) {
78          this(GravityFieldFactory.getUnnormalizedProvider(referenceRadius, mu,
79                                                           TideSystem.UNKNOWN,
80                                                           new double[][] { { 0 }, { 0 }, { c20 }, { c30 }, { c40 }, { c50 } },
81                                                           new double[][] { { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 } }),
82               m2Value);
83      }
84  
85      /** {@inheritDoc} */
86      @Override
87      public String getTheoryName() {
88          return THEORY;
89      }
90  
91      /** {@inheritDoc} */
92      @Override
93      public double getReferenceRadius() {
94          return provider.getAe();
95      };
96  
97      /** {@inheritDoc} */
98      @Override
99      public Orbit meanToOsculating(final Orbit mean) {
100         final BrouwerLyddanePropagator propagator =
101                         new BrouwerLyddanePropagator(mean, provider, PropagationType.MEAN, m2Value);
102         return propagator.propagateOrbit(mean.getDate());
103     }
104 
105     /** {@inheritDoc} */
106     @Override
107     public <T extends CalculusFieldElement<T>> FieldOrbit<T> meanToOsculating(final FieldOrbit<T> mean) {
108 
109         final FieldAbsoluteDate<T> date = mean.getDate();
110         final Field<T> field = date.getField();
111 
112         final FieldBrouwerLyddanePropagator<T> propagator =
113                         new FieldBrouwerLyddanePropagator<>(mean, provider, PropagationType.MEAN, m2Value);
114         return propagator.propagateOrbit(date, propagator.getParameters(field, date));
115     }
116 }