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 java.io.BufferedReader;
20 import java.io.IOException;
21 import java.io.InputStream;
22 import java.io.InputStreamReader;
23 import java.nio.charset.StandardCharsets;
24 import java.util.HashMap;
25 import java.util.Map;
26 import java.util.regex.Matcher;
27 import java.util.regex.Pattern;
28
29 import org.hipparchus.exception.DummyLocalizable;
30 import org.hipparchus.util.FastMath;
31 import org.orekit.errors.OrekitException;
32 import org.orekit.errors.OrekitMessages;
33
34
35 /** Supported Ocean load Deformation coefficients (Love numbers k'<sub>i</sub>).
36 * @see GravityFields
37 * @since 6.1
38 * @author Luc Maisonobe
39 */
40 public enum OceanLoadDeformationCoefficients {
41
42 /** Coefficients from IERS 1996 conventions.
43 * <p>
44 * Note that coefficients from conventions IERS 1996, 2003 and 2010 are all equal to each other.
45 * </p>
46 */
47 IERS_1996 {
48
49 /** {@inheritDoc} */
50 @Override
51 public double[] getCoefficients() {
52 return new double[] {
53 // IERS conventions 1996, chapter 6 page 48
54 0.0, 0.0, -0.3075, -0.195, -0.132, -0.1032, -0.0892
55 };
56 }
57
58 },
59
60 /** Coefficients from IERS 2003 conventions.
61 * <p>
62 * Note that coefficients from conventions IERS 1996, 2003 and 2010 are all equal to each other.
63 * </p>
64 */
65 IERS_2003 {
66
67 /** {@inheritDoc} */
68 @Override
69 public double[] getCoefficients() {
70 return new double[] {
71 // IERS conventions 2003, section 6.4 page 67 equation 13
72 0.0, 0.0, -0.3075, -0.195, -0.132, -0.1032, -0.0892
73 };
74 }
75
76 },
77
78 /** Coefficients from IERS 2010 conventions.
79 * <p>
80 * Note that coefficients from conventions IERS 1996, 2003 and 2010 are all equal to each other.
81 * </p>
82 */
83 IERS_2010 {
84
85 /** {@inheritDoc} */
86 @Override
87 public double[] getCoefficients() {
88 return new double[] {
89 // IERS conventions 2010, section 6.3.1 page 91
90 0.0, 0.0, -0.3075, -0.195, -0.132, -0.1032, -0.0892
91 };
92 }
93
94 },
95
96 /** Coefficients computed by Pascal Gégout, CNRS / UMR5563 (GET).
97 * <p>
98 * These coefficients are available up to degree 250.
99 * </p>
100 */
101 GEGOUT {
102
103 /** Coefficients resources. */
104 private static final String RESOURCE_NAME = "/assets/org/orekit/fic.love.kp.gegout";
105
106 /** Pattern for fields with integer type. */
107 private static final String INTEGER_TYPE_PATTERN = "[-+]?\\p{Digit}+";
108
109 /** Pattern for fields with real type. */
110 private static final String REAL_TYPE_PATTERN = "[-+]?(?:(?:\\p{Digit}+(?:\\.\\p{Digit}*)?)|(?:\\.\\p{Digit}+))(?:[eE][-+]?\\p{Digit}+)?";
111
112 /** {@inheritDoc} */
113 @Override
114 public double[] getCoefficients() {
115
116 int lineNumber = 0;
117 String line = null;
118 try (InputStream stream =
119 checkNull(OceanLoadDeformationCoefficients.class.getResourceAsStream(RESOURCE_NAME));
120 BufferedReader reader = new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8))) {
121
122 // regular lines are simply a degree index followed by the coefficient for this degree
123 final StringBuilder builder = new StringBuilder("^\\p{Space}*");
124 builder.append("(").append(INTEGER_TYPE_PATTERN).append(")");
125 builder.append("\\p{Space}+");
126 builder.append("(").append(REAL_TYPE_PATTERN).append(")");
127 builder.append("\\p{Space}*$");
128 final Pattern regularLinePattern = Pattern.compile(builder.toString());
129
130 // setup the reader
131 lineNumber = 0;
132 int maxDegree = 0;
133 final Map<Integer, Double> map = new HashMap<>();
134 for (line = reader.readLine(); line != null; line = reader.readLine()) {
135 lineNumber++;
136 final Matcher regularMatcher = regularLinePattern.matcher(line);
137 if (regularMatcher.matches()) {
138 // we have found a regular data line
139 final int degree = Integer.parseInt(regularMatcher.group(1));
140 final double coefficient = Double.parseDouble(regularMatcher.group(2));
141 map.put(degree, coefficient);
142 maxDegree = FastMath.max(maxDegree, degree);
143 }
144 }
145
146 final double[] coefficients = new double[maxDegree + 1];
147 for (final Map.Entry<Integer, Double> entry : map.entrySet()) {
148 coefficients[entry.getKey()] = entry.getValue();
149 }
150
151 return coefficients;
152
153 } catch (NumberFormatException nfe) {
154 throw new OrekitException(OrekitMessages.UNABLE_TO_PARSE_LINE_IN_FILE,
155 lineNumber, RESOURCE_NAME, line);
156 } catch (IOException ioe) {
157 throw new OrekitException(ioe, new DummyLocalizable(ioe.getMessage()));
158 }
159
160 }
161
162 /**
163 * Helper method to check for null resources. Throws an exception if {@code
164 * stream} is null.
165 *
166 * @param stream loaded from the class resources.
167 * @return {@code stream}.
168 */
169 private InputStream checkNull(final InputStream stream) {
170 if (stream == null) {
171 throw new OrekitException(OrekitMessages.UNABLE_TO_FIND_FILE, RESOURCE_NAME);
172 }
173 return stream;
174 }
175
176 };
177
178 /** Get the load deformation coefficients for ocean tides.
179 * @return load deformation coefficients for ocean tides
180 */
181 public abstract double[] getCoefficients();
182
183 }