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