LCOV - code coverage report
Current view: top level - atmosphere/ATM - ATMProfile.h (source / functions) Hit Total Coverage
Test: casacpp_coverage.info Lines: 9 16 56.2 %
Date: 2025-08-21 08:01:32 Functions: 9 17 52.9 %

          Line data    Source code
       1             : #ifndef _ATM_PROFILE_H
       2             : #define _ATM_PROFILE_H
       3             : /*******************************************************************************
       4             :  * ALMA - Atacama Large Millimiter Array
       5             :  * (c) Instituto de Estructura de la Materia, 2009
       6             :  *
       7             :  * This library is free software; you can redistribute it and/or
       8             :  * modify it under the terms of the GNU Lesser General Public
       9             :  * License as published by the Free Software Foundation; either
      10             :  * version 2.1 of the License, or (at your option) any later version.
      11             :  *
      12             :  * This library is distributed in the hope that it will be useful,
      13             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      15             :  * Lesser General Public License for more details.
      16             :  *
      17             :  * You should have received a copy of the GNU Lesser General Public
      18             :  * License along with this library; if not, write to the Free Software
      19             :  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
      20             :  *
      21             :  * "@(#) $Id: ATMProfile.h Exp $"
      22             :  *
      23             :  * who       when      what
      24             :  * --------  --------  ----------------------------------------------
      25             :  * pardo     24/03/09  created
      26             :  */
      27             : 
      28             : #ifndef __cplusplus
      29             : #error This is a C++ include file and cannot be used from plain C
      30             : #endif
      31             : 
      32             : #include "ATMCommon.h"
      33             : #include "ATMHumidity.h"
      34             : #include "ATMLength.h"
      35             : #include "ATMMassDensity.h"
      36             : #include "ATMNumberDensity.h"
      37             : #include "ATMPressure.h"
      38             : #include "ATMTemperature.h"
      39             : #include "ATMEnumerations.h"
      40             : 
      41             : #include <string>
      42             : #include <vector>
      43             : 
      44             : using std::string;
      45             : using std::vector;
      46             : 
      47             : 
      48             : ATM_NAMESPACE_BEGIN
      49             : 
      50             : /** \brief Class for an atmospheric profile object.
      51             :  *
      52             :  *         An  atmospheric profile is composed of 4 quantities as a function of altitude z:
      53             :  *         - the layer thickness
      54             :  *         - the pressure P
      55             :  *         - the temperature T and
      56             :  *         - the gas densities for H2O, O3, CO, N2O, NO2, HCl, HCN, SO2.<br>
      57             :  *
      58             :  *   This object is needed  for computing the absorption and
      59             :  *   phase coefficients, as well as for performing radiative transfer
      60             :  *   calculations (only layer thickness/T are needed).
      61             :  *
      62             :  *   This class builds an atmospheric profile that can be used to
      63             :  *   calculate absorption and phase coefficients, as well as to
      64             :  *   perform forward and/or retrieval radiative transfer calculations.
      65             :  *   It is composed of a set of parameters needed to build a layer thickness/P/T/gas densities
      66             :  *   densities profile from simple parameters currently available at observatories
      67             :  *   (from weather stations for example) using functions from
      68             :  *   the ATM library. The set of input parameters consists of the
      69             :  *   pressure P, the temperature T and the relative humidity at the ground, the altitude of
      70             :  *   the site, the tropospheric temperature lapse rate,... The profile is built as:
      71             :  *   thickness of the considered atmospheric layers above the site, and mean
      72             :  *   P,T,H2O,O3,CO,N2O, NO2, HCl, HCN, SO2 in
      73             :  *   them. The total number of atmospheric layers in the particular profile
      74             :  *   is also available (a negative value indicates an error).<br>
      75             :  *   The zenith column  of water vapor can be calculated
      76             :  *   by simply integrating the H2O profile. \f[ column\;\;H_{2}O\;\; (mm) =\sum_{layers} \Delta z \cdot [ H_{2}O ] \f]
      77             :  */
      78             : class AtmProfile
      79             : {
      80             : public:
      81             :   /** A constructor of an empty profile with n layers, that can be filled up later. */
      82             :   AtmProfile(unsigned int n);
      83             : 
      84             :   /** A long constructor of the atmospheric profile from the basic set of parameters described above.
      85             :       Please note that this constructor assumes that the &altitude of the antenna is the SAME of the
      86             :       weather station that provides: &groundPressure, &groundTemperature, and &relativeHumidity */
      87             :   AtmProfile(const Length &altitude,
      88             :              const Pressure &groundPressure,
      89             :              const Temperature &groundTemperature,
      90             :              double tropoLapseRate,
      91             :              const Humidity &relativeHumidity,
      92             :              const Length &wvScaleHeight,
      93             :              const Pressure &pressureStep,
      94             :              double pressureStepFactor,
      95             :              const Length &topAtmProfile,
      96             :              unsigned int atmType); //Atmospheretype atmType);
      97             : 
      98             : 
      99             :   /** A long constructor of the atmospheric profile from the basic set of parameters described above which,
     100             :       in addition, includes user-defined temperature profile  */
     101             :   AtmProfile(const Length &altitude,
     102             :              const Pressure &groundPressure,
     103             :              const Temperature &groundTemperature,
     104             :              double tropoLapseRate,
     105             :              const Humidity &relativeHumidity,
     106             :              const Length &wvScaleHeight,
     107             :              const Pressure &pressureStep,
     108             :              double pressureStepFactor,
     109             :              const Length &topAtmProfile,
     110             :              unsigned int atmType,
     111             :              const vector<Length> &v_layerBoundaries,
     112             :              const vector<Temperature> &v_layerTemperature);
     113             : 
     114             : 
     115             : 
     116             :   /** A long constructor of the atmospheric profile from the basic set of parameters described above. */
     117             :   /*
     118             :    AtmProfile(Length altitude, Pressure    groundPressure,
     119             :    Temperature groundTemperature, double  tropoLapseRate,
     120             :    Humidity relativeHumidity, Length wvScaleHeight,
     121             :    Pressure pressureStep, double pressureStepFactor,
     122             :    Length topAtmProfile, int typeAtm);
     123             : 
     124             :    */
     125             : 
     126             :   /** A short constructor of the atmospheric profile. With respect to the long constructor, this one considers
     127             :    the following (recomended) default values: pressureStep = 10 mb,
     128             :    pressureStepFactor = 1.1, topAtmProfile = 48.0 km */
     129             :   AtmProfile(const Length &altitude,
     130             :              const Pressure &groundPressure,
     131             :              const Temperature &groundTemperature,
     132             :              double tropoLapseRate,
     133             :              const Humidity &relativeHumidity,
     134             :              const Length &wvScaleHeight,
     135             :              unsigned int atmType); //Atmospheretype atmType);
     136             : 
     137             :   /*AtmProfile(const Length &altitude,
     138             :              const Pressure &groundPressure,
     139             :              const Temperature &groundTemperature,
     140             :              const Humidity &relativeHumidity,
     141             :              const vector<Length> &v_layerTop,
     142             :              const vector<Pressure> &v_layerTopPressure,
     143             :              const vector<Temperature> &v_layerTopTemperature,
     144             :              const vector<Humidity> &v_layerTopHumidity); */
     145             : 
     146             :   /** The user provides his own atmospheric profile (basic one: four vectors for layer thickness in m,
     147             :    average pressure in each layer in mb, average temperature in each layer in K, and average water
     148             :    vapor density in each layer in kg/m**3). QUESTION: SHOULD O3, CO, N2O, NO2, HCl, HCN, SO2 PROFILES BE FILLED UP
     149             :    INTERNALLY FROM A STANDARD ATMOSPHERE OR LEFT ITS ABUNDANCES EQUAL TO ZERO ? */
     150             :   AtmProfile(const Length &altitude,
     151             :              const vector<Length> &v_layerThickness,
     152             :              const vector<Pressure> &v_layerPressure,
     153             :              const vector<Temperature> &v_layerTemperature,
     154             :              const vector<MassDensity> &v_layerWaterVapor);
     155             :   AtmProfile(const vector<Length> &v_layerBoundaries,
     156             :              const vector<Pressure> &v_layerPressure,
     157             :              const vector<Temperature> &v_layerTemperature,
     158             :              const vector<MassDensity> &v_layerWaterVapor);
     159             : 
     160             :   AtmProfile(const Length &altitude,
     161             :              const vector<Length> &v_layerThickness,
     162             :              const vector<Pressure> &v_layerPressure,
     163             :              const vector<Temperature> &v_layerTemperature,
     164             :              const vector<NumberDensity> &v_layerWaterVapor);
     165             :   AtmProfile(const vector<Length> &v_layerBoundaries,
     166             :              const vector<Pressure> &v_layerPressure,
     167             :              const vector<Temperature> &v_layerTemperature,
     168             :              const vector<NumberDensity> &v_layerWaterVapor);
     169             : 
     170             :   /** The user provides his own atmospheric profile (in this case five vectors for layer thickness in m,
     171             :    average pressure in each layer in mb, average temperature in each layer in K, average water vapor
     172             :    density in each layer in kg/m**3, and average ozone number density in each layer in molecules/m**3)
     173             :    QUESTION: SHOULD CO and N2O, NO2, HCl, HCN, SO2 PROFILES BE FILLED UP
     174             :    INTERNALLY FROM A STANDARD ATMOSPHERE OR LEFT ITS ABUNDANCES EQUAL TO ZERO ? */
     175             : 
     176             :   AtmProfile(const Length &altitude,
     177             :              const vector<Length> &v_layerThickness,
     178             :              const vector<Pressure> &v_layerPressure,
     179             :              const vector<Temperature> &v_layerTemperature,
     180             :              const vector<MassDensity> &v_layerWaterVapor,
     181             :              const vector<NumberDensity> &v_layerO3);
     182             :   AtmProfile(const Length &altitude,
     183             :              const vector<Length> &v_layerThickness,
     184             :              const vector<Pressure> &v_layerPressure,
     185             :              const vector<Temperature> &v_layerTemperature,
     186             :              const vector<NumberDensity> &v_layerWaterVapor,
     187             :              const vector<NumberDensity> &v_layerO3);
     188             : 
     189             :   /** The user provides his own atmospheric profile (in this case seven vectors for layer thickness in m,
     190             :    average pressure in each layer in mb, average temperature in each layer in K, average water vapor
     191             :    density in each layer in kg/m**3, average ozone number density in each layer in molecules/m**3,
     192             :    average CO number density in each layer in molecules/m**3, average N2O, NO2, HCl, HCN, SO2 number density in each
     193             :    layer in molecules/m**3) */
     194             :   AtmProfile(const Length &altitude,
     195             :              const vector<Length> &v_layerThickness,
     196             :              const vector<Pressure> &v_layerPressure,
     197             :              const vector<Temperature> &v_layerTemperature,
     198             :              const vector<MassDensity> &v_layerWaterVapor,
     199             :              const vector<NumberDensity> &v_layerO3,
     200             :              const vector<NumberDensity> &v_layerCO,
     201             :              const vector<NumberDensity> &v_layerN2O,
     202             :              const vector<NumberDensity> &v_layerNO2,
     203             :              const vector<NumberDensity> &v_layerSO2,
     204             :              const vector<NumberDensity> &v_layerHCl,
     205             :              const vector<NumberDensity> &v_layerHCN);
     206             : 
     207             :   AtmProfile(const Length &altitude,
     208             :              const vector<Length> &v_layerThickness,
     209             :              const vector<Pressure> &v_layerPressure,
     210             :              const vector<Temperature> &v_layerTemperature,
     211             :              const vector<NumberDensity> &v_layerWaterVapor,
     212             :              const vector<NumberDensity> &v_layerO3,
     213             :              const vector<NumberDensity> &v_layerCO,
     214             :              const vector<NumberDensity> &v_layerN2O,
     215             :              const vector<NumberDensity> &v_layerNO2,
     216             :              const vector<NumberDensity> &v_layerSO2,
     217             :              const vector<NumberDensity> &v_layerHCl,
     218             :              const vector<NumberDensity> &v_layerHCN);
     219             : 
     220             :   AtmProfile(const AtmProfile &a); // copy constructor
     221             : 
     222         207 :   virtual ~AtmProfile() {}
     223             : 
     224             :   /** Setter to update the AtmProfile if some basic atmospheric parameter has changed.
     225             :    * @pre   an atmospheric profile already exists
     226             :    * @param altitude          the new altitude, a Length
     227             :    * @param groundPressure    the Pressure at the ground level
     228             :    * @param groundTemperature the Temperature at the ground level
     229             :    * @param tropoLapseRate    the tropospheric lapse rate
     230             :    * @param relativeHumidity  the relative Humidity
     231             :    * @param wvScaleHeight     the scale height of the water vapor, a Length
     232             :    * @return true if the atmospheric profile has been update, else false because the basic parameters have not changed
     233             :    * @post   the atmospheric profile has been updated, only if at least one of the basic parameters has changed
     234             :    *
     235             :    * \note  there is an overriding on this method in the sub-class AbsorptionPhaseProfile which in turn
     236             :    *        has an  overriding in its WaterVaporRetrieval sub-class. Hence this method must not be overloaded
     237             :    *        in this AtmProfile class.
     238             :    */
     239             :   bool setBasicAtmosphericParameters(const Length &altitude,
     240             :                                      const Pressure &groundPressure,
     241             :                                      const Temperature &groundTemperature,
     242             :                                      double tropoLapseRate,
     243             :                                      const Humidity &relativeHumidity,
     244             :                                      const Length &wvScaleHeight);
     245             : 
     246             :   /** Accessor to the type of current atmosphere **/
     247             :   string getAtmosphereType() const;
     248             : 
     249             :   /** Accessor to the type of atmosphere specified by the number**/
     250             :   static string getAtmosphereType(unsigned int typeAtm);
     251             : 
     252             :   /** Accessor to the current Ground Temperature used in the object */
     253         120 :   Temperature getGroundTemperature() const { return groundTemperature_; }
     254             : 
     255             :   /** Accessor to the current Tropospheric Lapse Rate used in the object (temperature/length units) */
     256           0 :   double getTropoLapseRate() const { return tropoLapseRate_; }
     257             : 
     258             :   /** Accessor to the current Ground Pressure used in the object (pressure units) */
     259         120 :   Pressure getGroundPressure() const { return groundPressure_; }
     260             : 
     261             :   /** Accessor to the current Tropopause Temperature used in the object */
     262           0 :   Temperature getTropopauseTemperature() const { return tropoTemperature_; }
     263             : 
     264             :   /** Accessor to the current Ground Relative Humidity in the object (humidity units) */
     265           0 :   Humidity getRelativeHumidity() const { return relativeHumidity_; }
     266             : 
     267             :   /** Accessor to the current Water Vapor Scale Height in the object (length units) */
     268           0 :   Length getWvScaleHeight() const { return wvScaleHeight_; }
     269             : 
     270             :   /** Accessor to the current Primary Pressure Step in the object. The Primary Pressure Step
     271             :    (pressure units) is used to define the thickness of the first layer in the profile.
     272             :    Pressure difference between the boundaries of first layer will be equal to the
     273             :    Primary Pressure Step. */
     274             :   Pressure getPressureStep() const { return pressureStep_; }
     275             : 
     276             :   /** Accessor to the current Pressure_Step_Factor in the object. The Pressure_Step_Factor
     277             :    (no units) is the Pressure step change between consecutive layers when moving upwards.
     278             :    Pressure difference between the boundaries of the (n+1)-th layer (DP_n+1) will
     279             :    be DP_n**DP1. */
     280             :   
     281             :   Pressure getPressureStepFactor() const { return pressureStepFactor_; }
     282             : 
     283             :   /** Accessor to the ground altitude of site (length units) */
     284           0 :   Length getAltitude() const { return altitude_; }
     285             : 
     286             :   /** Alternative accessor to the ground altitude of site (length units) */
     287             :   Length getGroundAltitude() const { return altitude_; }
     288             : 
     289             :    /** setter for the ground altitude of site (length units). Careful! It will remove or add layers if necessary.
     290             :        Ground values of T/P/h would change as well */
     291             :   void setAltitude(const Length &groundaltitude);
     292             : 
     293             :   /** Alternative setter for the ground altitude of site (length units). Careful! It will remove or add layers if necessary.
     294             :        Ground values of T/P/h would change as well */
     295             :   // void setGroundAltitude(const Length &groundaltitude);
     296             : 
     297             :   /** Accessor to the altitude of the tropopause (length units) */
     298           0 :   Length getTropopauseAltitude() const { return tropoAltitude_; }
     299             : 
     300             :   /** Accessor to the Maximum allowed altitude for the Atmospheric Profile above the site (length units) */
     301             :   Length getTopAtmProfile() const { return topAtmProfile_; }
     302             : 
     303             :   /** Accessor to the number of layers of the atmospheric profile */
     304        7917 :   unsigned int getNumLayer() const { return numLayer_; }
     305             : 
     306             :   /** Method to access the Temperature Profile  */
     307             :   vector<Temperature> getTemperatureProfile() const;
     308             : 
     309             :   /**
     310             :    * Method to access the average Temperature in layer i (thickness of layers in ThicknessProfile)
     311             :    * @exception AtmException if the layer is not valid.
     312             :    **/
     313             :   Temperature getLayerTemperature(unsigned int i) const;
     314             : 
     315             :   /**
     316             :    * Method to access the Temperature at bottom of layer i (thickness of layers in ThicknessProfile)
     317             :    * @exception AtmException if the layer is not valid.
     318             :    **/
     319             :   Temperature getLayerBottomTemperature(unsigned int i) const;
     320             : 
     321             :   /**
     322             :    * Method to access the Temperature at top of layer i (thickness of layers in ThicknessProfile)
     323             :    * @exception AtmException if the layer is not valid.
     324             :    **/
     325             :   Temperature getLayerTopTemperature(unsigned int i) const;
     326             : 
     327             :   /** Setter for the average Temperature in layer i (allows to touch one layer each time once a profile has been defined) */
     328             :   void setLayerTemperature(unsigned int i, const Temperature &layerTemperature);
     329             : 
     330             :   /** Method to retrieve the layer thickness from site altitude upwards.
     331             :    *  Use Altitude to + ThicknessProfile to know the vertical grid. */
     332             :   vector<Length> getThicknessProfile() const;
     333             : 
     334             :   /**
     335             :    * Method to access the layer thickness of layer i
     336             :    * @exception AtmException if the layer is not valid.
     337             :    */
     338             :   Length getLayerThickness(unsigned int i) const;
     339             : 
     340             :   /** Setter for the thickness of layer i (allows to touch one layer each time once a profile has been defined). We do
     341             :    *  not advise to use this one unless you change P and T accordingly */
     342             :   void setLayerThickness(unsigned int i, const Length &layerThickness);
     343             :   //void setLayerThickness(const Length &layerThickness, unsigned int i) { setLayerThickness(i, layerThickness); }
     344             : 
     345             :   /**
     346             :    * Method to access the Bottom Height of layer i above the Ground
     347             :    * @exception AtmException if the layer is not valid.
     348             :    */
     349             :   Length getLayerBottomHeightAboveGround(unsigned int i) const;
     350             : 
     351             :   /**
     352             :    * Method to access the Bottom Height of layer i above the Sea Level
     353             :    * @exception AtmException if the layer is not valid.
     354             :    */
     355             :   Length getLayerBottomHeightAboveSeaLevel(unsigned int i) const;
     356             : 
     357             : 
     358             :   /**
     359             :    * Method to access the Top Height of layer i above the Ground
     360             :    * @exception AtmException if the layer is not valid.
     361             :    */
     362             :   Length getLayerTopHeightAboveGround(unsigned int i) const;
     363             : 
     364             :   /**
     365             :    * Method to access the Top Height of layer i above the Sea Level
     366             :    * @exception AtmException if the layer is not valid.
     367             :    */
     368             :   Length getLayerTopHeightAboveSeaLevel(unsigned int i) const;
     369             : 
     370             : 
     371             :   /** Function to retrieve Average Water vapor density in a given layer in kg/m**3
     372             :    *  (thickness of layers in ThicknessProfile)
     373             :    * @exception AtmException if the layer is not valid.
     374             :    */
     375             :   MassDensity getLayerWaterVaporMassDensity(unsigned int i) const;
     376             :   MassDensity getLayerBottomWaterVaporMassDensity(unsigned int i) const;
     377             :   MassDensity getLayerTopWaterVaporMassDensity(unsigned int i) const;
     378             :   NumberDensity getLayerWaterVaporNumberDensity(unsigned int i) const;
     379             :   NumberDensity getLayerBottomWaterVaporNumberDensity(unsigned int i) const;
     380             :   NumberDensity getLayerTopWaterVaporNumberDensity(unsigned int i) const;
     381             : 
     382             :   /** Setter for the average Water vapor density in layer i in kg/m**3 (allows to touch one layer each
     383             :    *  time once a profile has been defined) */
     384             :   void setLayerWaterVaporMassDensity(unsigned int i, const MassDensity &layerWaterVapor);
     385             :   //void setLayerWaterVaporMassDensity(const MassDensity &layerWaterVapor, unsigned int i) { setLayerWaterVaporMassDensity(i, layerWaterVapor); }
     386             :   void setLayerWaterVaporNumberDensity(unsigned int i, const NumberDensity &layerWaterVapor);
     387             :   //void setLayerWaterVapor(const NumberDensity &layerWaterVapor, unsigned int i) { setLayerWaterVapor(i, layerWaterVapor); }
     388             : 
     389             :   /** Method to get the Pressure Profile */
     390             :   vector<Pressure> getPressureProfile() const;
     391             : 
     392             :   /** Method to access the average Pressure in layer i
     393             :    * @exception AtmException if the layer is not valid.
     394             :    */
     395             :   Pressure getLayerPressure(unsigned int i) const;
     396             : 
     397             :   /** Method to access the Pressure at bottom of layer i
     398             :    * @exception AtmException if the layer is not valid.
     399             :    */
     400             :   Pressure getLayerBottomPressure(unsigned int i) const;
     401             : 
     402             :   /** Method to access the Pressure at top of layer i
     403             :    * @exception AtmException if the layer is not valid.
     404             :    */
     405             :   Pressure getLayerTopPressure(unsigned int i) const;
     406             : 
     407             :   /** Setter for the average Pressure in layer i (allows to touch one layer each
     408             :    *  time once a profile has been defined) */
     409             :   void setLayerPressure(unsigned int i, const Pressure &layerPressure) { v_layerPressure_[i] = layerPressure.get(Pressure::UnitMilliBar); }
     410             :   //void setLayerPressure(const Pressure &layerPressure, unsigned int i) { setLayerPressure(i, layerPressure); }
     411             : 
     412             :   /** Function to retrieve CO density in a given layer (thickness of layers
     413             :    *  in ThicknessProfile)  */
     414         112 :   NumberDensity getLayerCO(unsigned int i) const { return NumberDensity(v_layerCO_[i], NumberDensity::UnitInverseCubicMeter); }
     415             :   /** Setter for the average number density of CO in layer i in molecules/m**3 (allows to touch one layer each
     416             :    *  time once a profile has been defined) */
     417             :   void setLayerCO(unsigned int i, const NumberDensity &layerCO) { v_layerCO_[i] = layerCO.get(NumberDensity::UnitInverseCubicMeter); }
     418             :   //void setLayerCO(const NumberDensity &layerCO, unsigned int i) { setLayerCO(i, layerCO); }
     419             : 
     420             :   /** Function to retrieve O3 density in a given layer (thickness of layers
     421             :    *  in ThicknessProfile) */
     422         112 :   NumberDensity getLayerO3(unsigned int i) const { return NumberDensity(v_layerO3_[i], NumberDensity::UnitInverseCubicMeter); }
     423             :   /** Setter for the average number density of O3 in layer i in molecules/m**3 (allows to touch one layer each
     424             :    *  time once a profile has been defined) */
     425             :   void setLayerO3(unsigned int i, const NumberDensity &layerO3) { v_layerO3_[i] = layerO3.get(NumberDensity::UnitInverseCubicMeter); }
     426             :   //void setLayerO3(const NumberDensity &layerO3, unsigned int i) { setLayerO3(i, layerO3); }
     427             : 
     428             :   /** Function to retrieve N2O density in a given layer (thickness of layers
     429             :    *  in ThicknessProfile)   */
     430         112 :   NumberDensity getLayerN2O(unsigned int i) const { return NumberDensity(v_layerN2O_[i], NumberDensity::UnitInverseCubicMeter); }
     431             :   /** Setter for the average number density of N2O in layer i in molecules/m**3 (allows to touch one layer each
     432             :    *  time once a profile has been defined) */
     433             :   void setLayerN2O(unsigned int i, const NumberDensity &layerN2O) { v_layerN2O_[i] = layerN2O.get(NumberDensity::UnitInverseCubicMeter); }
     434             :   //void setLayerN2O(const NumberDensity &layerN2O, unsigned int i) { setLayerN2O(i, layerN2O); }
     435             : 
     436             :   /** Function to retrieve NO2 density in a given layer (thickness of layers
     437             :    *  in ThicknessProfile)   */
     438             :   NumberDensity getLayerNO2(unsigned int i) const { return NumberDensity(v_layerNO2_[i], NumberDensity::UnitInverseCubicMeter); }
     439             :   /** Setter for the average number density of NO2 in layer i in molecules/m**3 (allows to touch one layer each
     440             :    *  time once a profile has been defined) */
     441             :   void setLayerNO2(unsigned int i, const NumberDensity &layerNO2) { v_layerNO2_[i] = layerNO2.get(NumberDensity::UnitInverseCubicMeter); }
     442             :   //void setLayerNO2(const NumberDensity &layerNO2, unsigned int i) { setLayerNO2(i, layerNO2); }
     443             : 
     444             :   /** Function to retrieve SO2 density in a given layer (thickness of layers
     445             :    *  in ThicknessProfile)   */
     446             :   NumberDensity getLayerSO2(unsigned int i) const { return NumberDensity(v_layerSO2_[i], NumberDensity::UnitInverseCubicMeter); }
     447             :   /** Setter for the average number density of SO2 in layer i in molecules/m**3 (allows to touch one layer each
     448             :    *  time once a profile has been defined) */
     449             :   void setLayerSO2(unsigned int i, const NumberDensity &layerSO2) { v_layerSO2_[i] = layerSO2.get(NumberDensity::UnitInverseCubicMeter); }
     450             :   //void setLayerSO2(const NumberDensity &layerSO2, unsigned int i) { setLayerSO2(i, layerSO2); }
     451             : 
     452             :     /** Function to retrieve HCl density in a given layer (thickness of layers
     453             :    *  in ThicknessProfile)   */
     454          42 :   NumberDensity getLayerHCl(unsigned int i) const { return NumberDensity(v_layerHCl_[i], NumberDensity::UnitInverseCubicMeter); }
     455             :   /** Setter for the average number density of HCl in layer i in molecules/m**3 (allows to touch one layer each
     456             :    *  time once a profile has been defined) */
     457             :   void setLayerHCl(unsigned int i, const NumberDensity &layerHCl) { v_layerHCl_[i] = layerHCl.get(NumberDensity::UnitInverseCubicMeter); }
     458             :   //void setLayerHCl(const NumberDensity &layerHCl, unsigned int i) { setLayerHCl(i, layerHCl); }
     459             : 
     460             :     /** Function to retrieve HCN density in a given layer (thickness of layers
     461             :    *  in ThicknessProfile)   */
     462          42 :   NumberDensity getLayerHCN(unsigned int i) const { return NumberDensity(v_layerHCN_[i], NumberDensity::UnitInverseCubicMeter); }
     463             :   /** Setter for the average number density of HCN in layer i in molecules/m**3 (allows to touch one layer each
     464             :    *  time once a profile has been defined) */
     465             :   void setLayerHCN(unsigned int i, const NumberDensity &layerHCN) { v_layerHCN_[i] = layerHCN.get(NumberDensity::UnitInverseCubicMeter); }
     466             :   //void setLayerHCN(const NumberDensity &layerHCN, unsigned int i) { setLayerHCN(i, layerHCN); }
     467             : 
     468             :   void setBasicAtmosphericParameterThresholds(const Length &altitudeThreshold,
     469             :                                              const Pressure &groundPressureThreshold,
     470             :                                              const Temperature &groundTemperatureThreshold,
     471             :                                              double tropoLapseRateThreshold,
     472             :                                              const Humidity &relativeHumidityThreshold,
     473             :                                              const Length &wvScaleHeightThreshold);
     474             : 
     475             : 
     476             :   /** Method to get the zenith column  of water vapor. It is computed by
     477             :    *  simply integrating the H2O profile:
     478             :    *  \f$ column\;\;H_{2}O\;\; (mm) =\sum_{layers} \Delta z \cdot [ H_{2}O ] \f$
     479             :    */
     480             :   Length getGroundWH2O() const;
     481             : 
     482             :   // Thresholds
     483             :   Length      getAltitudeThreshold()   const {return altitudeThreshold_;};
     484             :   Pressure    getGroundPressureThreshold() const {return groundPressureThreshold_;};
     485             :   Temperature getGroundTemperatureThreshold() const {return groundTemperatureThreshold_;};
     486             :   double      getTropoLapseRateThreshold() const {return tropoLapseRateThreshold_;};
     487             :   Humidity    getRelativeHumidityThreshold() const {return relativeHumidityThreshold_;};
     488             :   Length      getWvScaleHeightThreshold() const {return wvScaleHeightThreshold_;};
     489             : 
     490             :   void        setAltitudeThreshold(const Length &altitudeThreshold) {altitudeThreshold_=altitudeThreshold;};
     491             :   void        setGroundPressureThreshold(const Pressure &groundPressureThreshold) {groundPressureThreshold_=groundPressureThreshold;};
     492             :   void        setGroundTemperatureThreshold(const Temperature &groundTemperatureThreshold) {groundTemperatureThreshold_=groundTemperatureThreshold;};
     493             : 
     494             : 
     495             :   // Used by AtmProfileTest
     496             :   vector<NumberDensity> st76(const Length &ha, unsigned int tip,unsigned int seasonal_diurnal) const;
     497             :   //@}
     498             : 
     499             : protected:
     500             :   unsigned int typeAtm_; //!< 1: tropical, 2: midlatSummer, 3: midlatWinter, 4: subarcticSummer, 5: subarcticWinter
     501             :   Temperature groundTemperature_; //!< Ambient temperature at the site (K)
     502             :   double tropoLapseRate_; //!< tropospheric lapse rate in K/km
     503             :   Temperature tropoTemperature_; //!< Temperature at the tropopause
     504             :   unsigned int tropoLayer_; //!< Layer where tropopause starts
     505             :   Length tropoAltitude_; //!< Altitude where tropopause starts
     506             :   Pressure groundPressure_; //!< Ground pressure at the site
     507             :   Humidity relativeHumidity_; /** Relative humidity at the site (%)
     508             :    used only to make an estimate
     509             :    of the water vapor column, first guess) */
     510             :   Length wvScaleHeight_; //!< scale height of water vapor distribution (km)
     511             :   Pressure pressureStep_; //!< Pressure basic step (mb) (limited to be between 8 and 12 mb  05JUN2024)
     512             :   double pressureStepFactor_; /** Multiplicative factor for presure steps (fixed to 1.1 05JUN2024) 
     513             :    of one layer with respect to the previous one: 
     514             :    Example of pressure parameters:
     515             :    P_ground=550; pressureStep_: 10 mb; 
     516             :    The pressure levels will then be 550, 560, 571, 583.1, 596.41.... */
     517             : 
     518             :   Length altitude_; //!< Altitude of the site (km)
     519             :   Length topAtmProfile_; //!< Top of atmospheric profile (km)
     520             :   unsigned int numLayer_; //!< Total number of layers in the output  atmospheric profiles
     521             :   double fractionLast_;  //!< Fraction of last layer needed for some calculations
     522             :   bool newBasicParam_;
     523             :   vector<double> v_layerThickness_; //!< Thickness of layer (m)
     524             :   vector<double> v_layerTemperature_; //!< Temp. of layers (K)
     525             :   vector<double> v_layerTemperature0_; //!< Temp. at bottom of layers (K)
     526             :   vector<double> v_layerTemperature1_; //!< Temp. at top of layer (K)
     527             :   vector<double> v_layerWaterVapor_; //!< Average water vapor kg/m**3 in the layer
     528             :   vector<double> v_layerWaterVapor0_; //!< Water vapor kg/m**3 at bottom of layer
     529             :   vector<double> v_layerWaterVapor1_; //!< Water vapor kg/m**3 at top of layer
     530             :   vector<double> v_layerPressure_; //!< Pressure of layers (mb)
     531             :   vector<double> v_layerPressure0_; //!< Pressure at bottom of layers (mb)
     532             :   vector<double> v_layerPressure1_; //!< Pressure at top of layers (mb)
     533             :   vector<double> v_layerCO_; //!< CO in molecules per m**3
     534             :   vector<double> v_layerO3_; //!< O3 in molecules per m**3
     535             :   vector<double> v_layerN2O_; //!< N2O in molecules per m**3
     536             :   vector<double> v_layerNO2_; //!< NO2 in molecules per m**3
     537             :   vector<double> v_layerSO2_; //!< SO2 in molecules per m**3
     538             :   vector<double> v_layerHCl_; //!< HCl in molecules per m**3
     539             :   vector<double> v_layerHCN_; //!< HCN in molecules per m**3
     540             :   Length altitudeThreshold_;
     541             :   Pressure groundPressureThreshold_;
     542             :   Temperature groundTemperatureThreshold_;
     543             :   double tropoLapseRateThreshold_;
     544             :   Humidity relativeHumidityThreshold_;
     545             :   Length wvScaleHeightThreshold_;
     546             : 
     547             :   unsigned int ier_;
     548             : 
     549             :   /** Default constructor (required if copy constructor in derived classes) */
     550           0 :   AtmProfile() {}
     551             : 
     552             :   /*
     553             :    * \fn Method to build the profile,
     554             :    */
     555             :   unsigned int mkAtmProfile(); /** returns error code: <0 unsuccessful           */
     556             : 
     557             :   /** Method to update an atmospheric profile based on one or more new basic parameter(s)
     558             :    * @param altitude          the new altitude, a Length
     559             :    * @param groundPressure    the Pressure at the ground level
     560             :    * @param groundTemperature the Temperature at the ground level
     561             :    * @param tropoLapseRate    the tropospheric lapse rate
     562             :    * @param relativeHumidity  the relative Humidity
     563             :    * @param wvScaleHeight     the scale height of the water vapor, a Length
     564             :    * @return true if the atmospheric profile has been update, else false because the basic parameters have not changed
     565             :    * @post   the atmospheric profile has been updated only if at least one of the basic parameters has changed
     566             :    */
     567             :   bool updateAtmProfile(const Length &altitude,
     568             :                         const Pressure &groundPressure,
     569             :                         const Temperature &groundTemperature,
     570             :                         double tropoLapseRate,
     571             :                         const Humidity &relativeHumidity,
     572             :                         const Length &wvScaleHeight);
     573             :   void initBasicAtmosphericParameterThresholds();
     574             : 
     575             : private:
     576             :   MassDensity rwat(const Temperature &t, const Humidity &rh, const Pressure &p) const;
     577             :   Humidity rwat_inv(const Temperature &tt, const MassDensity &dd, const Pressure &pp) const;
     578             : 
     579             :   double poli2(double ha,
     580             :                double x1,
     581             :                double x2,
     582             :                double x3,
     583             :                double y1,
     584             :                double y2,
     585             :                double y3) const;
     586             :   /*
     587             :    // static Pressure pressureStep_default(  10.0,Pressure::UnitMilliBar);
     588             :    //  static double pSd; // = 10.0;  // pressureStep_default in mb
     589             :    static Pressure pressureStep_default_;
     590             : 
     591             : 
     592             :    static double pressureStepFactor_default_; // =    1.2;
     593             :    //static double pSFd; // = 1.2;
     594             : 
     595             : 
     596             : 
     597             :    static Length  topAtmProfile_default_; //(  48.0,Length::UnitKiloMeter);
     598             :    //static tAPd; // = 48.0;
     599             :    */
     600             : 
     601             :   /** Default value of Atmospheric type (to reproduce behavior above the tropopause) */
     602             :   //static Atmospheretype atmType_default =  tropical;
     603             : 
     604             : }; // class AtmProfile
     605             : 
     606             : ATM_NAMESPACE_END
     607             : /*
     608             :   Pressure AtmProfile::pressureStep_default_(Pressure(1.2,Pressure::UnitMilliBar));
     609             :   double AtmProfile::pressureStepFactor_default_(1.2);
     610             :   Length AtmProfile::topAtmProfile_default_(Length(48,Length::UnitKiloMeter));
     611             : */
     612             : 
     613             : /** \page AtmProfile_example Example with the AtmProfile class.
     614             :  *  Our main function always starts like this:
     615             :  *  \skip #include "AtmTypeName.h"
     616             :  *  \until {
     617             :  *
     618             :  *  First we set a constant that will be used in the calculations:
     619             :  *  \skip double
     620             :  *  \until 0.04799274551
     621             :  *  Then we set the parameters necessary to create an atmospheric profile (if you do not want to enter the whole profile yourself):
     622             :  *  \skip  Atmospheretype
     623             :  *  \until 1.2
     624             :  *  The above input information is printed on the screen
     625             :  *  \skip cout
     626             :  *  \until K/km
     627             :  *  With all this information an AtmProfile object can now be created:
     628             :  *  \skipline AtmProfile
     629             :  *  The AtmProfile object "myProflie" is accessed and partially shown on the screen
     630             :  *  \skip cout
     631             :  *  \until scale height */
     632             : 
     633             : 
     634             : #endif /*!_ATM_PROFILE_H*/

Generated by: LCOV version 1.16