1   /* Copyright 2002-2021 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.orekit.time.AbsoluteDate;
20  
21  /** Simple implementation of {@link RawSphericalHarmonicsProvider} for gravity fields with secular trend.
22   * @author Luc Maisonobe
23   * @since 6.0
24   */
25  class SecularTrendSphericalHarmonics implements RawSphericalHarmonicsProvider {
26  
27      /** Non-secular part of the field. */
28      private final RawSphericalHarmonicsProvider provider;
29  
30      /** Reference date for the harmonics. */
31      private final AbsoluteDate referenceDate;
32  
33      /** Secular trend of the cosine coefficients. */
34      private final double[][] cTrend;
35  
36      /** Secular trend of the sine coefficients. */
37      private final double[][] sTrend;
38  
39      /** Simple constructor.
40       * @param provider underlying provider for the non secular part
41       * @param referenceDate reference date for the harmonics (considered to be at 12:00 TT)
42       * @param cTrend secular trend of the cosine coefficients (s<sup>-1</sup>)
43       * @param sTrend secular trend of the sine coefficients (s<sup>-1</sup>)
44       */
45      SecularTrendSphericalHarmonics(final RawSphericalHarmonicsProvider provider,
46                                            final AbsoluteDate referenceDate,
47                                            final double[][] cTrend, final double[][] sTrend) {
48          this.provider      = provider;
49          this.referenceDate = referenceDate;
50          this.cTrend        = cTrend;
51          this.sTrend        = sTrend;
52      }
53  
54      /** {@inheritDoc} */
55      public int getMaxDegree() {
56          return provider.getMaxDegree();
57      }
58  
59      /** {@inheritDoc} */
60      public int getMaxOrder() {
61          return provider.getMaxOrder();
62      }
63  
64      /** {@inheritDoc} */
65      public double getMu() {
66          return provider.getMu();
67      }
68  
69      /** {@inheritDoc} */
70      public double getAe() {
71          return provider.getAe();
72      }
73  
74      /** {@inheritDoc} */
75      public AbsoluteDate getReferenceDate() {
76          return referenceDate;
77      }
78  
79      /** {@inheritDoc} */
80      public double getOffset(final AbsoluteDate date) {
81          return date.durationFrom(referenceDate);
82      }
83  
84      /** {@inheritDoc} */
85      public TideSystem getTideSystem() {
86          return provider.getTideSystem();
87      }
88  
89      @Override
90      public RawSphericalHarmonics onDate(final AbsoluteDate date) {
91          final RawSphericalHarmonics harmonics = provider.onDate(date);
92          //compute date offset from reference
93          final double dateOffset = getOffset(date);
94          return new RawSphericalHarmonics() {
95  
96              @Override
97              public AbsoluteDate getDate() {
98                  return date;
99              }
100 
101             /** {@inheritDoc} */
102             public double getRawCnm(final int n, final int m) {
103 
104                 // retrieve the constant part of the coefficient
105                 double cnm = harmonics.getRawCnm(n, m);
106 
107                 if (n < cTrend.length && m < cTrend[n].length) {
108                     // add secular trend
109                     cnm += dateOffset * cTrend[n][m];
110                 }
111 
112                 return cnm;
113 
114             }
115 
116             /** {@inheritDoc} */
117             public double getRawSnm(final int n, final int m) {
118 
119                 // retrieve the constant part of the coefficient
120                 double snm = harmonics.getRawSnm(n, m);
121 
122                 if (n < sTrend.length && m < sTrend[n].length) {
123                     // add secular trend
124                     snm += dateOffset * sTrend[n][m];
125                 }
126 
127                 return snm;
128 
129             }
130 
131         };
132     }
133 
134 }