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.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 flattener flattener from triangular to flatten array
49 * @param cTrend secular trend of the cosine coefficients (s<sup>-1</sup>)
50 * @param sTrend secular trend of the sine coefficients (s<sup>-1</sup>)
51 * @since 11.1
52 */
53 SecularTrendSphericalHarmonics(final RawSphericalHarmonicsProvider provider, final AbsoluteDate referenceDate,
54 final Flattener flattener, final double[] cTrend, final double[] sTrend) {
55 this.provider = provider;
56 this.referenceDate = referenceDate;
57 this.flattener = flattener;
58 this.cTrend = cTrend.clone();
59 this.sTrend = sTrend.clone();
60 }
61
62 /** {@inheritDoc} */
63 public int getMaxDegree() {
64 return FastMath.max(flattener.getDegree(), provider.getMaxDegree());
65 }
66
67 /** {@inheritDoc} */
68 public int getMaxOrder() {
69 return FastMath.max(flattener.getOrder(), provider.getMaxOrder());
70 }
71
72 /** {@inheritDoc} */
73 public double getMu() {
74 return provider.getMu();
75 }
76
77 /** {@inheritDoc} */
78 public double getAe() {
79 return provider.getAe();
80 }
81
82 /** {@inheritDoc} */
83 public AbsoluteDate getReferenceDate() {
84 return referenceDate;
85 }
86
87 /** {@inheritDoc} */
88 public TideSystem getTideSystem() {
89 return provider.getTideSystem();
90 }
91
92 @Override
93 public RawSphericalHarmonics onDate(final AbsoluteDate date) {
94 final RawSphericalHarmonics harmonics = provider.onDate(date);
95 //compute date offset from reference
96 final double dateOffset = date.durationFrom(referenceDate);
97 return new RawSphericalHarmonics() {
98
99 @Override
100 public AbsoluteDate getDate() {
101 return date;
102 }
103
104 /** {@inheritDoc} */
105 public double getRawCnm(final int n, final int m) {
106
107 // retrieve the constant part of the coefficient
108 double cnm = harmonics.getRawCnm(n, m);
109
110 if (flattener.withinRange(n, m)) {
111 // add secular trend
112 cnm += dateOffset * cTrend[flattener.index(n, m)];
113 }
114
115 return cnm;
116
117 }
118
119 /** {@inheritDoc} */
120 public double getRawSnm(final int n, final int m) {
121
122 // retrieve the constant part of the coefficient
123 double snm = harmonics.getRawSnm(n, m);
124
125 if (flattener.withinRange(n, m)) {
126 // add secular trend
127 snm += dateOffset * sTrend[flattener.index(n, m)];
128 }
129
130 return snm;
131
132 }
133
134 };
135 }
136
137 }