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.orekit.time.AbsoluteDate;
21
22 /** Simple implementation of {@link RawSphericalHarmonicsProvider} for gravity fields with secular trend.
23 * @author Luc Maisonobe
24 * @since 6.0
25 */
26 class SecularTrendSphericalHarmonics implements RawSphericalHarmonicsProvider {
27
28 /** Non-secular part of the field. */
29 private final RawSphericalHarmonicsProvider provider;
30
31 /** Reference date for the harmonics. */
32 private final AbsoluteDate referenceDate;
33
34 /** Converter from triangular to flatten array.
35 * @since 11.1
36 */
37 private final Flattener flattener;
38
39 /** Secular trend of the cosine coefficients. */
40 private final double[] cTrend;
41
42 /** Secular trend of the sine coefficients. */
43 private final double[] sTrend;
44
45 /** Simple constructor.
46 * @param provider underlying provider for the non secular part
47 * @param referenceDate reference date for the harmonics (considered to be at 12:00 TT)
48 * @param cTrend secular trend of the cosine coefficients (s<sup>-1</sup>)
49 * @param sTrend secular trend of the sine coefficients (s<sup>-1</sup>)
50 * @deprecated as of 11.1, replaced by {@link #SecularTrendSphericalHarmonics(RawSphericalHarmonicsProvider,
51 * AbsoluteDate, Flattener, double[], double[])
52 */
53 @Deprecated
54 SecularTrendSphericalHarmonics(final RawSphericalHarmonicsProvider provider,
55 final AbsoluteDate referenceDate,
56 final double[][] cTrend, final double[][] sTrend) {
57 this(provider, referenceDate, buildFlattener(cTrend),
58 buildFlattener(cTrend).flatten(cTrend), buildFlattener(sTrend).flatten(sTrend));
59 }
60
61 /** Simple constructor.
62 * @param provider underlying provider for the non secular part
63 * @param referenceDate reference date for the harmonics (considered to be at 12:00 TT)
64 * @param flattener flattener from triangular to flatten array
65 * @param cTrend secular trend of the cosine coefficients (s<sup>-1</sup>)
66 * @param sTrend secular trend of the sine coefficients (s<sup>-1</sup>)
67 * @since 11.1
68 */
69 SecularTrendSphericalHarmonics(final RawSphericalHarmonicsProvider provider, final AbsoluteDate referenceDate,
70 final Flattener flattener, final double[] cTrend, final double[] sTrend) {
71 this.provider = provider;
72 this.referenceDate = referenceDate;
73 this.flattener = flattener;
74 this.cTrend = cTrend.clone();
75 this.sTrend = sTrend.clone();
76 }
77
78 /** Get a flattener for a triangular array.
79 * @param triangular triangular array to flatten
80 * @return flattener suited for triangular array dimensions
81 * @since 11.1
82 */
83 private static Flattener buildFlattener(final double[][] triangular) {
84 return new Flattener(triangular.length - 1, triangular[triangular.length - 1].length - 1);
85 }
86
87 /** {@inheritDoc} */
88 public int getMaxDegree() {
89 return FastMath.max(flattener.getDegree(), provider.getMaxDegree());
90 }
91
92 /** {@inheritDoc} */
93 public int getMaxOrder() {
94 return FastMath.max(flattener.getOrder(), provider.getMaxOrder());
95 }
96
97 /** {@inheritDoc} */
98 public double getMu() {
99 return provider.getMu();
100 }
101
102 /** {@inheritDoc} */
103 public double getAe() {
104 return provider.getAe();
105 }
106
107 /** {@inheritDoc} */
108 public AbsoluteDate getReferenceDate() {
109 return referenceDate;
110 }
111
112 /** {@inheritDoc} */
113 @Deprecated
114 public double getOffset(final AbsoluteDate date) {
115 return date.durationFrom(referenceDate);
116 }
117
118 /** {@inheritDoc} */
119 public TideSystem getTideSystem() {
120 return provider.getTideSystem();
121 }
122
123 @Override
124 public RawSphericalHarmonics onDate(final AbsoluteDate date) {
125 final RawSphericalHarmonics harmonics = provider.onDate(date);
126 //compute date offset from reference
127 final double dateOffset = date.durationFrom(referenceDate);
128 return new RawSphericalHarmonics() {
129
130 @Override
131 public AbsoluteDate getDate() {
132 return date;
133 }
134
135 /** {@inheritDoc} */
136 public double getRawCnm(final int n, final int m) {
137
138 // retrieve the constant part of the coefficient
139 double cnm = harmonics.getRawCnm(n, m);
140
141 if (flattener.withinRange(n, m)) {
142 // add secular trend
143 cnm += dateOffset * cTrend[flattener.index(n, m)];
144 }
145
146 return cnm;
147
148 }
149
150 /** {@inheritDoc} */
151 public double getRawSnm(final int n, final int m) {
152
153 // retrieve the constant part of the coefficient
154 double snm = harmonics.getRawSnm(n, m);
155
156 if (flattener.withinRange(n, m)) {
157 // add secular trend
158 snm += dateOffset * sTrend[flattener.index(n, m)];
159 }
160
161 return snm;
162
163 }
164
165 };
166 }
167
168 }