1   /* Copyright 2002-2022 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.forces.gravity.potential;
18  
19  import org.hipparchus.util.FastMath;
20  import org.hipparchus.util.MathUtils;
21  import org.hipparchus.util.SinCos;
22  import org.orekit.time.AbsoluteDate;
23  
24  /** Simple implementation of {@link RawSphericalHarmonicsProvider} for pulsating gravity fields.
25   * @author Luc Maisonobe
26   * @since 6.0
27   * @deprecated as of 11.1, replaced by {@link PiecewiseSphericalHarmonics}
28   */
29  @Deprecated
30  class PulsatingSphericalHarmonics implements RawSphericalHarmonicsProvider {
31  
32      /** Underlying part of the field. */
33      private final RawSphericalHarmonicsProvider provider;
34  
35      /** Pulsation (rad/s). */
36      private final double pulsation;
37  
38      /** Converter from triangular to flatten array.
39       * @since 11.1
40       */
41      private final Flattener flattener;
42  
43      /** Cosine component of the cosine coefficients. */
44      private final double[] cosC;
45  
46      /** Sine component of the cosine coefficients. */
47      private final double[] sinC;
48  
49      /** Cosine component of the sine coefficients. */
50      private final double[] cosS;
51  
52      /** Sine component of the sine coefficients. */
53      private final double[] sinS;
54  
55      /** Simple constructor.
56       * @param provider underlying part of the field
57       * @param period period of the pulsation (s)
58       * @param cosC cosine component of the cosine coefficients
59       * @param sinC sine component of the cosine coefficients
60       * @param cosS cosine component of the sine coefficients
61       * @param sinS sine component of the sine coefficients
62       * @deprecated as of 11.1, replaced by {@link #PulsatingSphericalHarmonics(RawSphericalHarmonicsProvider,
63       * double, Flattener, double[], double[], double[], double[])}
64       */
65      @Deprecated
66      PulsatingSphericalHarmonics(final RawSphericalHarmonicsProvider provider,
67                                  final double period,
68                                  final double[][] cosC, final double[][] sinC,
69                                  final double[][] cosS, final double[][] sinS) {
70          this(provider, period, buildFlattener(cosC),
71               buildFlattener(cosC).flatten(cosC), buildFlattener(sinC).flatten(sinC),
72               buildFlattener(cosS).flatten(cosS), buildFlattener(sinS).flatten(sinS));
73      }
74  
75      /** Simple constructor.
76       * @param provider underlying part of the field
77       * @param period period of the pulsation (s)
78       * @param flattener flattener from triangular to flatten array
79       * @param cosC cosine component of the cosine coefficients
80       * @param sinC sine component of the cosine coefficients
81       * @param cosS cosine component of the sine coefficients
82       * @param sinS sine component of the sine coefficients
83       * @since 11.1
84       */
85      PulsatingSphericalHarmonics(final RawSphericalHarmonicsProvider provider,
86                                  final double period, final Flattener flattener,
87                                  final double[] cosC, final double[] sinC,
88                                  final double[] cosS, final double[] sinS) {
89          this.provider  = provider;
90          this.pulsation = MathUtils.TWO_PI / period;
91          this.flattener = flattener;
92          this.cosC      = cosC.clone();
93          this.sinC      = sinC.clone();
94          this.cosS      = cosS.clone();
95          this.sinS      = sinS.clone();
96      }
97  
98      /** Get a flattener for a triangular array.
99       * @param triangular triangular array to flatten
100      * @return flattener suited for triangular array dimensions
101      * @since 11.1
102      */
103     private static Flattener buildFlattener(final double[][] triangular) {
104         return new Flattener(triangular.length - 1, triangular[triangular.length - 1].length - 1);
105     }
106 
107     /** {@inheritDoc} */
108     public int getMaxDegree() {
109         return FastMath.max(flattener.getDegree(), provider.getMaxDegree());
110     }
111 
112     /** {@inheritDoc} */
113     public int getMaxOrder() {
114         return FastMath.max(flattener.getOrder(), provider.getMaxOrder());
115     }
116 
117     /** {@inheritDoc} */
118     public double getMu() {
119         return provider.getMu();
120     }
121 
122     /** {@inheritDoc} */
123     public double getAe() {
124         return provider.getAe();
125     }
126 
127     /** {@inheritDoc} */
128     public AbsoluteDate getReferenceDate() {
129         return provider.getReferenceDate();
130     }
131 
132     /** {@inheritDoc} */
133     @Deprecated
134     public double getOffset(final AbsoluteDate date) {
135         return provider.getOffset(date);
136     }
137 
138     /** {@inheritDoc} */
139     public TideSystem getTideSystem() {
140         return provider.getTideSystem();
141     }
142 
143     @Override
144     @Deprecated
145     public RawSphericalHarmonics onDate(final AbsoluteDate date) {
146         //raw (constant) harmonics
147         final RawSphericalHarmonics raw = provider.onDate(date);
148         //phase angle, will loose precision for large offsets
149         final double alpha = pulsation * provider.getOffset(date);
150         //pre-compute transcendental functions
151         final SinCos scAlpha = FastMath.sinCos(alpha);
152         return new RawSphericalHarmonics() {
153 
154             @Override
155             public AbsoluteDate getDate() {
156                 return date;
157             }
158 
159             /** {@inheritDoc} */
160             public double getRawCnm(final int n, final int m) {
161 
162                 // retrieve the underlying part of the coefficient
163                 double cnm = raw.getRawCnm(n, m);
164 
165                 if (flattener.withinRange(n, m)) {
166                     // add pulsation
167                     cnm += cosC[flattener.index(n, m)] * scAlpha.cos() + sinC[flattener.index(n, m)] * scAlpha.sin();
168                 }
169 
170                 return cnm;
171             }
172 
173             /** {@inheritDoc} */
174             public double getRawSnm(final int n, final int m) {
175 
176                 // retrieve the constant part of the coefficient
177                 double snm = raw.getRawSnm(n, m);
178 
179                 if (flattener.withinRange(n, m)) {
180                     // add pulsation
181                     snm += cosS[flattener.index(n, m)] * scAlpha.cos() + sinS[flattener.index(n, m)] * scAlpha.sin();
182                 }
183 
184                 return snm;
185             }
186 
187         };
188     }
189 
190 }