OceanLoadDeformationCoefficients.java

  1. /* Copyright 2002-2015 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. import java.io.BufferedReader;
  19. import java.io.IOException;
  20. import java.io.InputStream;
  21. import java.io.InputStreamReader;
  22. import java.util.HashMap;
  23. import java.util.Map;
  24. import java.util.regex.Matcher;
  25. import java.util.regex.Pattern;

  26. import org.apache.commons.math3.exception.util.DummyLocalizable;
  27. import org.apache.commons.math3.util.FastMath;
  28. import org.orekit.errors.OrekitException;
  29. import org.orekit.errors.OrekitMessages;


  30. /** Supported Ocean load Deformation coefficients (Love numbers k'<sub>i</sub>).
  31.  * @see GravityFieldFactory
  32.  * @since 6.1
  33.  * @author Luc Maisonobe
  34.  */
  35. public enum OceanLoadDeformationCoefficients {

  36.     /** Coefficients from IERS 1996 conventions.
  37.      * <p>
  38.      * Note that coefficients from conventions IERS 1996, 2003 and 2010 are all equal to each other.
  39.      * </p>
  40.      */
  41.     IERS_1996 {

  42.         /** {@inheritDoc} */
  43.         @Override
  44.         public double[] getCoefficients() {
  45.             return new double[] {
  46.                 // IERS conventions 1996, chapter 6 page 48
  47.                 0.0, 0.0, -0.3075, -0.195, -0.132, -0.1032, -0.0892
  48.             };
  49.         }

  50.     },

  51.     /** Coefficients from IERS 2003 conventions.
  52.      * <p>
  53.      * Note that coefficients from conventions IERS 1996, 2003 and 2010 are all equal to each other.
  54.      * </p>
  55.      */
  56.     IERS_2003 {

  57.         /** {@inheritDoc} */
  58.         @Override
  59.         public double[] getCoefficients() {
  60.             return new double[] {
  61.                 // IERS conventions 2003, section 6.4 page 67 equation 13
  62.                 0.0, 0.0, -0.3075, -0.195, -0.132, -0.1032, -0.0892
  63.             };
  64.         }

  65.     },

  66.     /** Coefficients from IERS 2010 conventions.
  67.      * <p>
  68.      * Note that coefficients from conventions IERS 1996, 2003 and 2010 are all equal to each other.
  69.      * </p>
  70.      */
  71.     IERS_2010 {

  72.         /** {@inheritDoc} */
  73.         @Override
  74.         public double[] getCoefficients() {
  75.             return new double[] {
  76.                 // IERS conventions 2010, section 6.3.1 page 91
  77.                 0.0, 0.0, -0.3075, -0.195, -0.132, -0.1032, -0.0892
  78.             };
  79.         }

  80.     },

  81.     /** Coefficients computed by Pascal Gégout, CNRS / UMR5563 (GET).
  82.      * <p>
  83.      * These coefficients are available up to degree 250.
  84.      * </p>
  85.      */
  86.     GEGOUT {

  87.         /** Coefficients resources. */
  88.         private static final String RESOURCE_NAME = "/assets/org/orekit/fic.love.kp.gegout";

  89.         /** Pattern for fields with integer type. */
  90.         private static final String  INTEGER_TYPE_PATTERN = "[-+]?\\p{Digit}+";

  91.         /** Pattern for fields with real type. */
  92.         private static final String  REAL_TYPE_PATTERN = "[-+]?(?:(?:\\p{Digit}+(?:\\.\\p{Digit}*)?)|(?:\\.\\p{Digit}+))(?:[eE][-+]?\\p{Digit}+)?";

  93.         /** {@inheritDoc} */
  94.         @Override
  95.         public double[] getCoefficients() throws OrekitException {

  96.             final InputStream stream =
  97.                     OceanLoadDeformationCoefficients.class.getResourceAsStream(RESOURCE_NAME);
  98.             if (stream == null) {
  99.                 throw new OrekitException(OrekitMessages.UNABLE_TO_FIND_FILE, RESOURCE_NAME);
  100.             }

  101.             // regular lines are simply a degree index followed by the coefficient for this degree
  102.             final StringBuilder builder = new StringBuilder("^\\p{Space}*");
  103.             builder.append("(").append(INTEGER_TYPE_PATTERN).append(")");
  104.             builder.append("\\p{Space}+");
  105.             builder.append("(").append(REAL_TYPE_PATTERN).append(")");
  106.             builder.append("\\p{Space}*$");
  107.             final Pattern regularLinePattern = Pattern.compile(builder.toString());

  108.             int lineNumber = 0;
  109.             String line = null;
  110.             BufferedReader reader = null;
  111.             try {

  112.                 // setup the reader
  113.                 reader = new BufferedReader(new InputStreamReader(stream, "UTF-8"));
  114.                 lineNumber = 0;
  115.                 int maxDegree = 0;
  116.                 final Map<Integer, Double> map = new HashMap<Integer, Double>();
  117.                 for (line = reader.readLine(); line != null; line = reader.readLine()) {
  118.                     lineNumber++;
  119.                     final Matcher regularMatcher = regularLinePattern.matcher(line);
  120.                     if (regularMatcher.matches()) {
  121.                         // we have found a regular data line
  122.                         final int degree         = Integer.parseInt(regularMatcher.group(1));
  123.                         final double coefficient = Double.parseDouble(regularMatcher.group(2));
  124.                         map.put(degree, coefficient);
  125.                         maxDegree = FastMath.max(maxDegree, degree);
  126.                     }
  127.                 }

  128.                 final double[] coefficients = new double[maxDegree + 1];
  129.                 for (final Map.Entry<Integer, Double> entry : map.entrySet()) {
  130.                     coefficients[entry.getKey()] = entry.getValue();
  131.                 }

  132.                 return coefficients;

  133.             } catch (NumberFormatException nfe) {
  134.                 throw new OrekitException(OrekitMessages.UNABLE_TO_PARSE_LINE_IN_FILE,
  135.                                           lineNumber, RESOURCE_NAME, line);
  136.             } catch (IOException ioe) {
  137.                 throw new OrekitException(ioe, new DummyLocalizable(ioe.getMessage()));
  138.             } finally {
  139.                 try {
  140.                     if (reader != null) {
  141.                         reader.close();
  142.                     }
  143.                 } catch (IOException ioe) {
  144.                     // ignored here
  145.                 }
  146.             }

  147.         }

  148.     };

  149.     /** Get the load deformation coefficients for ocean tides.
  150.      * @return load deformation coefficients for ocean tides
  151.      * @exception OrekitException if coefficients cannot be loaded
  152.      */
  153.     public abstract double [] getCoefficients() throws OrekitException;

  154. }