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.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 */
28 class PulsatingSphericalHarmonics implements RawSphericalHarmonicsProvider {
29
30 /** Underlying part of the field. */
31 private final RawSphericalHarmonicsProvider provider;
32
33 /** Pulsation (rad/s). */
34 private final double pulsation;
35
36 /** Cosine component of the cosine coefficients. */
37 private final double[][] cosC;
38
39 /** Sine component of the cosine coefficients. */
40 private final double[][] sinC;
41
42 /** Cosine component of the sine coefficients. */
43 private final double[][] cosS;
44
45 /** Sine component of the sine coefficients. */
46 private final double[][] sinS;
47
48 /** Simple constructor.
49 * @param provider underlying part of the field
50 * @param period period of the pulsation (s)
51 * @param cosC cosine component of the cosine coefficients
52 * @param sinC sine component of the cosine coefficients
53 * @param cosS cosine component of the sine coefficients
54 * @param sinS sine component of the sine coefficients
55 */
56 PulsatingSphericalHarmonics(final RawSphericalHarmonicsProvider provider,
57 final double period,
58 final double[][] cosC, final double[][] sinC,
59 final double[][] cosS, final double[][] sinS) {
60 this.provider = provider;
61 this.pulsation = MathUtils.TWO_PI / period;
62 this.cosC = cosC;
63 this.sinC = sinC;
64 this.cosS = cosS;
65 this.sinS = sinS;
66 }
67
68 /** {@inheritDoc} */
69 public int getMaxDegree() {
70 return provider.getMaxDegree();
71 }
72
73 /** {@inheritDoc} */
74 public int getMaxOrder() {
75 return provider.getMaxOrder();
76 }
77
78 /** {@inheritDoc} */
79 public double getMu() {
80 return provider.getMu();
81 }
82
83 /** {@inheritDoc} */
84 public double getAe() {
85 return provider.getAe();
86 }
87
88 /** {@inheritDoc} */
89 public AbsoluteDate getReferenceDate() {
90 return provider.getReferenceDate();
91 }
92
93 /** {@inheritDoc} */
94 public double getOffset(final AbsoluteDate date) {
95 return provider.getOffset(date);
96 }
97
98 /** {@inheritDoc} */
99 public TideSystem getTideSystem() {
100 return provider.getTideSystem();
101 }
102
103 @Override
104 public RawSphericalHarmonics onDate(final AbsoluteDate date) {
105 //raw (constant) harmonics
106 final RawSphericalHarmonics raw = provider.onDate(date);
107 //phase angle, will loose precision for large offsets
108 final double alpha = pulsation * getOffset(date);
109 //pre-compute transcendental functions
110 final SinCos scAlpha = FastMath.sinCos(alpha);
111 return new RawSphericalHarmonics() {
112
113 @Override
114 public AbsoluteDate getDate() {
115 return date;
116 }
117
118 /** {@inheritDoc} */
119 public double getRawCnm(final int n, final int m) {
120
121 // retrieve the underlying part of the coefficient
122 double cnm = raw.getRawCnm(n, m);
123
124 if (n < cosC.length && m < cosC[n].length) {
125 // add pulsation
126 cnm += cosC[n][m] * scAlpha.cos() + sinC[n][m] * scAlpha.sin();
127 }
128
129 return cnm;
130 }
131
132 /** {@inheritDoc} */
133 public double getRawSnm(final int n, final int m) {
134
135 // retrieve the constant part of the coefficient
136 double snm = raw.getRawSnm(n, m);
137
138 if (n < cosS.length && m < cosS[n].length) {
139 // add pulsation
140 snm += cosS[n][m] * scAlpha.cos() + sinS[n][m] * scAlpha.sin();
141 }
142
143 return snm;
144 }
145
146 };
147 }
148
149 }