OceanLoadDeformationCoefficients.java

  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. import java.io.BufferedReader;
  19. import java.io.IOException;
  20. import java.io.InputStream;
  21. import java.io.InputStreamReader;
  22. import java.nio.charset.StandardCharsets;
  23. import java.util.HashMap;
  24. import java.util.Map;
  25. import java.util.regex.Matcher;
  26. import java.util.regex.Pattern;

  27. import org.hipparchus.exception.DummyLocalizable;
  28. import org.hipparchus.util.FastMath;
  29. import org.orekit.errors.OrekitException;
  30. import org.orekit.errors.OrekitMessages;


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

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

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

  51.     },

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

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

  66.     },

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

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

  81.     },

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

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

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

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

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

  97.             int lineNumber = 0;
  98.             String line = null;
  99.             try (InputStream stream =
  100.                             checkNull(OceanLoadDeformationCoefficients.class.getResourceAsStream(RESOURCE_NAME));
  101.                  BufferedReader reader = new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8))) {

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

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

  124.                 final double[] coefficients = new double[maxDegree + 1];
  125.                 for (final Map.Entry<Integer, Double> entry : map.entrySet()) {
  126.                     coefficients[entry.getKey()] = entry.getValue();
  127.                 }

  128.                 return coefficients;

  129.             } catch (NumberFormatException nfe) {
  130.                 throw new OrekitException(OrekitMessages.UNABLE_TO_PARSE_LINE_IN_FILE,
  131.                                           lineNumber, RESOURCE_NAME, line);
  132.             } catch (IOException ioe) {
  133.                 throw new OrekitException(ioe, new DummyLocalizable(ioe.getMessage()));
  134.             }

  135.         }

  136.         /**
  137.          * Helper method to check for null resources. Throws an exception if {@code
  138.          * stream} is null.
  139.          *
  140.          * @param stream loaded from the class resources.
  141.          * @return {@code stream}.
  142.          */
  143.         private InputStream checkNull(final InputStream stream) {
  144.             if (stream == null) {
  145.                 throw new OrekitException(OrekitMessages.UNABLE_TO_FIND_FILE, RESOURCE_NAME);
  146.             }
  147.             return stream;
  148.         }

  149.     };

  150.     /** Get the load deformation coefficients for ocean tides.
  151.      * @return load deformation coefficients for ocean tides
  152.      */
  153.     public abstract double[] getCoefficients();

  154. }