CIPM2007.java

  1. /* Copyright 2022-2025 Thales Alenia Space
  2.  * Licensed to CS Communication & Systèmes (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.models.earth.weather.water;

  18. import org.hipparchus.CalculusFieldElement;
  19. import org.hipparchus.util.FastMath;
  20. import org.orekit.models.earth.troposphere.TroposphericModelUtils;

  21. /** Official model CIPM-2007 (identical to CIPM-1981/91) from Comité International des Poids et Mesures.
  22.  * <p>
  23.  * This water vapor model is the one from Giacomo and Davis as indicated in IERS TN 32, chap. 9.
  24.  * </p>
  25.  * @see <a href="https://www.nist.gov/system/files/documents/calibrations/CIPM-2007.pdf">Revised
  26.  * formula for the density of moist air (CIPM-2007), Metrologia 45 (2008) 149–155</a>
  27.  *
  28.  * @author Luc Maisonobe
  29.  * @since 12.1
  30.  */
  31. public class CIPM2007 implements WaterVaporPressureProvider {

  32.     /** Laurent series coefficient for degree +2. */
  33.     private static final double L_P2 = 1.2378847e-5;

  34.     /** Laurent series coefficient for degree +1. */
  35.     private static final double L_P1 = -1.9121316e-2;

  36.     /** Laurent series coefficient for degree 0. */
  37.     private static final double L_0 = 33.93711047;

  38.     /** Laurent series coefficient for degree -1. */
  39.     private static final double L_M1 = -6343.1645;

  40.     /** Celsius temperature offset. */
  41.     private static final double CELSIUS = 273.15;

  42.     /** Constant enhancement factor. */
  43.     private static final double F_0 = 1.00062;

  44.     /** Pressure enhancement factor. */
  45.     private static final double F_P = 3.14e-6;

  46.     /** Temperature enhancement factor. */
  47.     private static final double F_T2 = 5.6e-7;

  48.     /** {@inheritDoc} */
  49.     @Override
  50.     public double waterVaporPressure(final double p, final double t, final double rh) {

  51.         // saturation water vapor, equation A1.1 (now in Pa, not hPa)
  52.         final double psv = FastMath.exp(t * (t * L_P2 + L_P1) + L_0 + L_M1 / t);

  53.         // enhancement factor, equation A1.2
  54.         final double tC = t - CELSIUS;
  55.         final double fw = TroposphericModelUtils.HECTO_PASCAL.fromSI(p) * F_P + tC * tC * F_T2 + F_0;

  56.         return rh * fw * psv;

  57.     }

  58.     /** {@inheritDoc} */
  59.     @Override
  60.     public <T extends CalculusFieldElement<T>> T waterVaporPressure(final T p, final T t, final T rh) {

  61.         // saturation water vapor, equation A1.1 (now in Pa, not hPa)
  62.         final T psv = FastMath.exp(t.multiply(t.multiply(L_P2).add(L_P1)).add(L_0).add(t.reciprocal().multiply(L_M1)));

  63.         // enhancement factor, equation A1.2
  64.         final T tC = t.subtract(CELSIUS);
  65.         final T fw = TroposphericModelUtils.HECTO_PASCAL.fromSI(p).multiply(F_P).add(tC.multiply(tC).multiply(F_T2)).add(F_0);

  66.         return rh.multiply(fw).multiply(psv);

  67.     }

  68. }