LCOV - code coverage report
Current view: top level - atmosphere/ATM - ATMProfile.cc (source / functions) Hit Total Coverage
Test: casacpp_coverage.info Lines: 418 1119 37.4 %
Date: 2025-08-21 08:01:32 Functions: 17 50 34.0 %

          Line data    Source code
       1             :  /*******************************************************************************
       2             :  * ALMA - Atacama Large Millimiter Array
       3             :  * (c) CSIC - Instituto de FĂ­sica Fundamental (Spain), 2024
       4             :  *
       5             :  * This library is free software; you can redistribute it and/or
       6             :  * modify it under the terms of the GNU Lesser General Public
       7             :  * License as published by the Free Software Foundation; either
       8             :  * version 2.1 of the License, or (at your option) any later version.
       9             :  *
      10             :  * This library is distributed in the hope that it will be useful,
      11             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      12             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13             :  * Lesser General Public License for more details.
      14             :  *
      15             :  * You should have received a copy of the GNU Lesser General Public
      16             :  * License along with this library; if not, write to the Free Software
      17             :  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
      18             :  *
      19             :  * "@(#) $Id: ATMProfile.cpp Exp $"
      20             :  *
      21             :  * who       when      what
      22             :  * --------  --------  ----------------------------------------------
      23             :  * pardo     24/03/09  created
      24             :  */
      25             : 
      26             : #include "ATMProfile.h"
      27             : #include "ATMException.h"
      28             : #include <iostream>
      29             : #include <math.h>
      30             : #include <sstream>
      31             : 
      32             : 
      33             : 
      34             : ATM_NAMESPACE_BEGIN
      35             : 
      36           0 : AtmProfile::AtmProfile(unsigned int n)
      37             : {
      38           0 :   numLayer_ = n;
      39           0 :   initBasicAtmosphericParameterThresholds();
      40           0 :   for(unsigned int i = 0; i < numLayer_; ++i) {
      41           0 :     v_layerO3_.push_back(0.0);
      42           0 :     v_layerCO_.push_back(0.0);
      43           0 :     v_layerN2O_.push_back(0.0);
      44           0 :     v_layerNO2_.push_back(0.0);
      45           0 :     v_layerSO2_.push_back(0.0);
      46           0 :     v_layerHCl_.push_back(0.0);
      47           0 :     v_layerHCN_.push_back(0.0);
      48           0 :     v_layerThickness_.push_back(0.0);
      49           0 :     v_layerTemperature_.push_back(0.0);
      50           0 :     v_layerTemperature0_.push_back(0.0);
      51           0 :     v_layerTemperature1_.push_back(0.0);
      52           0 :     v_layerPressure_.push_back(0.0);
      53           0 :     v_layerPressure0_.push_back(0.0);
      54           0 :     v_layerPressure1_.push_back(0.0);
      55           0 :     v_layerWaterVapor_.push_back(0.0);
      56           0 :     v_layerWaterVapor0_.push_back(0.0);
      57           0 :     v_layerWaterVapor1_.push_back(0.0);
      58             :   }
      59           0 : }
      60             : 
      61             : 
      62             : 
      63           5 : AtmProfile::AtmProfile(const Length &altitude,
      64             :                        const Pressure &groundPressure,
      65             :                        const Temperature &groundTemperature,
      66             :                        double tropoLapseRate,
      67             :                        const Humidity &relativeHumidity,
      68             :                        const Length &wvScaleHeight,
      69             :                        const Pressure &pressureStep,
      70             :                        double pressureStepFactor,
      71             :                        const Length &topAtmProfile,
      72           5 :                        unsigned int atmType) :
      73             :       //                         Atmospheretype atmType):
      74           5 :       typeAtm_(atmType), groundTemperature_(groundTemperature),
      75           5 :       tropoLapseRate_(tropoLapseRate), groundPressure_(groundPressure),
      76           5 :       relativeHumidity_(relativeHumidity), wvScaleHeight_(wvScaleHeight),
      77           5 :       pressureStep_(pressureStep), pressureStepFactor_(1.075),        // pressureStepFactor_(pressureStepFactor),   05JUN2024
      78          10 :       altitude_(altitude), topAtmProfile_(topAtmProfile)
      79             : {
      80             : 
      81           5 :   if(pressureStep_.get("mb")<5.0 || pressureStep_.get("mb")>12.5){pressureStep_=Pressure(10,"mb");}
      82             :   //  std::cout << "Warning pressureStep out of limits. Fixed to 10 mb" << std::endl; }    //pressureStep has to be betwee 5 and 12.5 mb 05JUN2024
      83           5 :   numLayer_ = 0;
      84           5 :   numLayer_ = mkAtmProfile();
      85             :   // std::cout << "ad numLayer_=" << numLayer_ << std::endl;
      86           5 :   initBasicAtmosphericParameterThresholds();
      87           5 :   newBasicParam_ = true;
      88             : 
      89             : 
      90           5 : }
      91             : 
      92           0 : AtmProfile::AtmProfile(const Length &altitude,
      93             :                        const Pressure &groundPressure,
      94             :                        const Temperature &groundTemperature,
      95             :                        double tropoLapseRate,
      96             :                        const Humidity &relativeHumidity,
      97             :                        const Length &wvScaleHeight,
      98             :                        const Pressure &pressureStep,
      99             :                        double pressureStepFactor,
     100             :                        const Length &topAtmProfile,
     101             :                        unsigned int atmType,
     102             :                        const vector<Length> &v_layerBoundaries,
     103           0 :                        const vector<Temperature> &v_layerTemperature):
     104           0 :       typeAtm_(atmType), groundTemperature_(groundTemperature),
     105           0 :       tropoLapseRate_(tropoLapseRate), groundPressure_(groundPressure),
     106           0 :       relativeHumidity_(relativeHumidity), wvScaleHeight_(wvScaleHeight),
     107           0 :       pressureStep_(pressureStep), pressureStepFactor_(1.075),   // pressureStepFactor_(pressureStepFactor),   05JUN2024
     108           0 :       altitude_(altitude), topAtmProfile_(topAtmProfile)
     109             : {
     110           0 :   if(pressureStep_.get("mb")<5.0 || pressureStep_.get("mb")>12.5){pressureStep_=Pressure(10,"mb");}
     111             :   //  std::cout << "Warning pressureStep out of limits. Fixed to 10 mb" << std::endl; }    //pressureStep has to be between 5 and 12.5 mb 05JUN2024
     112           0 :   numLayer_ = 0;
     113           0 :   numLayer_ = mkAtmProfile();
     114           0 :   initBasicAtmosphericParameterThresholds();
     115           0 :   newBasicParam_ = true;
     116           0 :   unsigned int nL1 = v_layerBoundaries.size();
     117           0 :   unsigned int nL2 = v_layerTemperature.size();
     118           0 :   if(nL1 == nL2 ) {
     119           0 :     double h=altitude_.get(Length::UnitMeter);
     120             :     double h0;
     121             :     double h1;
     122             :     double counter;
     123             :     double avT;
     124           0 :     for(unsigned int n = 0; n < numLayer_; n++) {
     125           0 :       h0=h;
     126           0 :       h1 = h0 + v_layerThickness_[n];
     127           0 :       counter = 0.0;
     128           0 :       avT = 0.0;
     129           0 :       for(unsigned int m = 0; m < nL1; m++) {
     130           0 :         if( h0 <= v_layerBoundaries[m].get(Length::UnitMeter) && h1 >= v_layerBoundaries[m].get(Length::UnitMeter) ){
     131             :           //      std::cout << "n=" << n << " h0=" << h0 << " h1=" << h1 << " v_layerBoundaries[" << m << "]=" <<  v_layerBoundaries[m].get(Length::UnitMeter) << std::endl;
     132           0 :           avT = avT + v_layerTemperature[m].get(Temperature::UnitKelvin);
     133           0 :           counter = counter + 1.0;
     134             :         }
     135             :       }
     136           0 :       if(avT > 0.0){
     137             :         // std::cout << "layer" << n << "old average temperature:" << v_layerTemperature_[n] << std::endl;
     138           0 :         v_layerTemperature_[n] = avT/counter;
     139             :         // std::cout << "layer" << n << "new average temperature:" << v_layerTemperature_[n] << std::endl;
     140             :       }
     141           0 :       h=h1;
     142             :     }
     143             :   }
     144           0 : }
     145             : 
     146           0 : AtmProfile::AtmProfile(const Length &altitude,
     147             :                        const Pressure &groundPressure,
     148             :                        const Temperature &groundTemperature,
     149             :                        double tropoLapseRate,
     150             :                        const Humidity &relativeHumidity,
     151             :                        const Length &wvScaleHeight,
     152           0 :                        unsigned int atmType) :
     153             :       //                         Atmospheretype atmType):
     154           0 :       typeAtm_(atmType), groundTemperature_(groundTemperature),
     155           0 :       tropoLapseRate_(tropoLapseRate), groundPressure_(groundPressure),
     156           0 :       relativeHumidity_(relativeHumidity), wvScaleHeight_(wvScaleHeight),
     157           0 :       pressureStep_(10.0, Pressure::UnitMilliBar), pressureStepFactor_(1.075), altitude_(altitude),    //pressureStepFactor fixed to 1.1 05JUN2024
     158           0 :       topAtmProfile_(48.0, Length::UnitKiloMeter)
     159             : {
     160           0 :   numLayer_ = 0;
     161           0 :   numLayer_ = mkAtmProfile();
     162           0 :   initBasicAtmosphericParameterThresholds();
     163           0 :   newBasicParam_ = true;
     164           0 : }
     165             : 
     166           0 : AtmProfile::AtmProfile(const Length &altitude,
     167             :                        const vector<Length> &v_layerThickness,
     168             :                        const vector<Pressure> &v_layerPressure,
     169             :                        const vector<Temperature> &v_layerTemperature,
     170           0 :                        const vector<MassDensity> &v_layerWaterVapor)
     171             : {
     172           0 :   newBasicParam_ = true;
     173           0 :   unsigned int nL1 = v_layerThickness.size();
     174           0 :   unsigned int nL2 = v_layerPressure.size();
     175           0 :   unsigned int nL3 = v_layerTemperature.size();
     176           0 :   unsigned int nL4 = v_layerWaterVapor.size();
     177             : 
     178           0 :   if(nL1 + 1 == nL2 && nL2 == nL3 && nL3 == nL4) {
     179           0 :     numLayer_ = nL1;
     180           0 :     for(unsigned int n = 0; n < numLayer_; n++) {
     181           0 :       v_layerO3_.push_back(0.0);
     182           0 :       v_layerCO_.push_back(0.0);
     183           0 :       v_layerN2O_.push_back(0.0);
     184           0 :       v_layerNO2_.push_back(0.0);
     185           0 :       v_layerSO2_.push_back(0.0);
     186           0 :       v_layerHCl_.push_back(0.0);
     187           0 :       v_layerHCN_.push_back(0.0);
     188           0 :       v_layerThickness_.push_back(v_layerThickness[n].get(Length::UnitMeter));
     189           0 :       v_layerTemperature_.push_back((v_layerTemperature[n].get(Temperature::UnitKelvin) + v_layerTemperature[n+1].get(Temperature::UnitKelvin))/2.0);
     190           0 :       v_layerTemperature0_.push_back(v_layerTemperature[n].get(Temperature::UnitKelvin));
     191           0 :       v_layerTemperature1_.push_back(v_layerTemperature[n+1].get(Temperature::UnitKelvin));
     192           0 :       v_layerPressure_.push_back(exp((log(v_layerPressure[n].get(Pressure::UnitMilliBar))+ log(v_layerPressure[n + 1].get(Pressure::UnitMilliBar)))/2.0));
     193           0 :       v_layerPressure0_.push_back(v_layerPressure[n].get(Pressure::UnitMilliBar));
     194           0 :       v_layerPressure1_.push_back(v_layerPressure[n+1].get(Pressure::UnitMilliBar));
     195           0 :       v_layerWaterVapor_.push_back(exp((log(v_layerWaterVapor[n].get(MassDensity::UnitKiloGramPerCubicMeter))+ log(v_layerWaterVapor[n + 1].get(MassDensity::UnitKiloGramPerCubicMeter)))/2.0));
     196           0 :       v_layerWaterVapor0_.push_back(v_layerWaterVapor[n].get(MassDensity::UnitKiloGramPerCubicMeter));
     197           0 :       v_layerWaterVapor1_.push_back(v_layerWaterVapor[n+1].get(MassDensity::UnitKiloGramPerCubicMeter));
     198             :     }
     199           0 :   } else {
     200           0 :     numLayer_ = 0;
     201             :   }
     202           0 :   initBasicAtmosphericParameterThresholds();
     203           0 : }
     204             : 
     205           0 : AtmProfile::AtmProfile(const vector<Length> &v_layerBoundaries,
     206             :                        const vector<Pressure> &v_layerPressure,
     207             :                        const vector<Temperature> &v_layerTemperature,
     208           0 :                        const vector<MassDensity> &v_layerWaterVapor)
     209             : {
     210           0 :   newBasicParam_ = true;
     211           0 :   unsigned int nL1 = v_layerBoundaries.size();
     212           0 :   unsigned int nL2 = v_layerPressure.size();
     213           0 :   unsigned int nL3 = v_layerTemperature.size();
     214           0 :   unsigned int nL4 = v_layerWaterVapor.size();
     215             : 
     216           0 :   if(nL1 == nL2 && nL2 == nL3 && nL3 == nL4) {
     217           0 :     numLayer_ = nL1 - 1;
     218           0 :     altitude_ = v_layerBoundaries[0];
     219           0 :     for(unsigned int n = 0; n < numLayer_; n++) {
     220           0 :       v_layerO3_.push_back(0.0);
     221           0 :       v_layerCO_.push_back(0.0);
     222           0 :       v_layerN2O_.push_back(0.0);
     223           0 :       v_layerNO2_.push_back(0.0);
     224           0 :       v_layerSO2_.push_back(0.0);
     225           0 :       v_layerHCl_.push_back(0.0);
     226           0 :       v_layerHCN_.push_back(0.0);
     227           0 :       v_layerThickness_.push_back(v_layerBoundaries[n+1].get(Length::UnitMeter) - v_layerBoundaries[n].get(Length::UnitMeter));
     228           0 :       v_layerTemperature_.push_back((v_layerTemperature[n].get(Temperature::UnitKelvin) + v_layerTemperature[n+1].get(Temperature::UnitKelvin))/2.0);
     229           0 :       v_layerTemperature0_.push_back(v_layerTemperature[n].get(Temperature::UnitKelvin));
     230           0 :       v_layerTemperature1_.push_back(v_layerTemperature[n+1].get(Temperature::UnitKelvin));
     231           0 :       v_layerPressure_.push_back(exp((log(v_layerPressure[n].get(Pressure::UnitMilliBar))+ log(v_layerPressure[n + 1].get(Pressure::UnitMilliBar)))/2.0));
     232           0 :       v_layerPressure0_.push_back(v_layerPressure[n].get(Pressure::UnitMilliBar));
     233           0 :       v_layerPressure1_.push_back(v_layerPressure[n+1].get(Pressure::UnitMilliBar));
     234           0 :       v_layerWaterVapor_.push_back(exp((log(v_layerWaterVapor[n].get(MassDensity::UnitKiloGramPerCubicMeter))+ log(v_layerWaterVapor[n + 1].get(MassDensity::UnitKiloGramPerCubicMeter)))/2.0));
     235           0 :       v_layerWaterVapor0_.push_back(v_layerWaterVapor[n].get(MassDensity::UnitKiloGramPerCubicMeter));
     236           0 :       v_layerWaterVapor1_.push_back(v_layerWaterVapor[n+1].get(MassDensity::UnitKiloGramPerCubicMeter));
     237             :     }
     238           0 :   } else {
     239           0 :     numLayer_ = 0;
     240             :   }
     241           0 :   initBasicAtmosphericParameterThresholds();
     242           0 : }
     243             : 
     244           0 : AtmProfile::AtmProfile(const Length &altitude,
     245             :                        const vector<Length> &v_layerThickness,
     246             :                        const vector<Pressure> &v_layerPressure,
     247             :                        const vector<Temperature> &v_layerTemperature,
     248           0 :                        const vector<NumberDensity> &v_layerWaterVapor)
     249             : {
     250           0 :   newBasicParam_ = true;
     251           0 :   unsigned int nL1 = v_layerThickness.size();
     252           0 :   unsigned int nL2 = v_layerPressure.size();
     253           0 :   unsigned int nL3 = v_layerTemperature.size();
     254           0 :   unsigned int nL4 = v_layerWaterVapor.size();
     255             : 
     256           0 :   if(nL1 + 1 == nL2 && nL2 == nL3 && nL3 == nL4) {
     257           0 :     numLayer_ = nL1;
     258           0 :     for(unsigned int n = 0; n < numLayer_; n++) {
     259           0 :       v_layerO3_.push_back(0.0);
     260           0 :       v_layerCO_.push_back(0.0);
     261           0 :       v_layerN2O_.push_back(0.0);
     262           0 :       v_layerNO2_.push_back(0.0);
     263           0 :       v_layerSO2_.push_back(0.0);
     264           0 :       v_layerHCl_.push_back(0.0);
     265           0 :       v_layerHCN_.push_back(0.0);
     266           0 :       v_layerThickness_.push_back(v_layerThickness[n].get(Length::UnitMeter));
     267           0 :       v_layerTemperature_.push_back((v_layerTemperature[n].get(Temperature::UnitKelvin) + v_layerTemperature[n+1].get(Temperature::UnitKelvin))/2.0);
     268           0 :       v_layerTemperature0_.push_back(v_layerTemperature[n].get(Temperature::UnitKelvin));
     269           0 :       v_layerTemperature1_.push_back(v_layerTemperature[n+1].get(Temperature::UnitKelvin));
     270           0 :       v_layerPressure_.push_back(exp((log(v_layerPressure[n].get(Pressure::UnitMilliBar))+ log(v_layerPressure[n + 1].get(Pressure::UnitMilliBar)))/2.0));
     271           0 :       v_layerPressure0_.push_back(v_layerPressure[n].get(Pressure::UnitMilliBar));
     272           0 :       v_layerPressure1_.push_back(v_layerPressure[n+1].get(Pressure::UnitMilliBar));
     273           0 :       v_layerWaterVapor_.push_back( (exp((log(v_layerWaterVapor[n].get(NumberDensity::UnitInverseCubicMeter))+ log(v_layerWaterVapor[n + 1].get(NumberDensity::UnitInverseCubicMeter)))/2.0))* 18.0
     274           0 :                                     / (1000.0 * 6.023e23));
     275           0 :       v_layerWaterVapor0_.push_back(v_layerWaterVapor[n].get(NumberDensity::UnitInverseCubicMeter) * 18.0
     276           0 :           / (1000.0 * 6.023e23));
     277           0 :       v_layerWaterVapor1_.push_back(v_layerWaterVapor[n+1].get(NumberDensity::UnitInverseCubicMeter) * 18.0
     278           0 :           / (1000.0 * 6.023e23));
     279             :     }
     280           0 :   } else {
     281           0 :     numLayer_ = 0;
     282             :   }
     283           0 :   initBasicAtmosphericParameterThresholds();
     284           0 : }
     285             : 
     286           0 : AtmProfile::AtmProfile(const vector<Length> &v_layerBoundaries,
     287             :                        const vector<Pressure> &v_layerPressure,
     288             :                        const vector<Temperature> &v_layerTemperature,
     289           0 :                        const vector<NumberDensity> &v_layerWaterVapor)
     290             : {
     291           0 :   newBasicParam_ = true;
     292           0 :   unsigned int nL1 = v_layerBoundaries.size();
     293           0 :   unsigned int nL2 = v_layerPressure.size();
     294           0 :   unsigned int nL3 = v_layerTemperature.size();
     295           0 :   unsigned int nL4 = v_layerWaterVapor.size();
     296             : 
     297           0 :   if(nL1 == nL2 && nL2 == nL3 && nL3 == nL4) {
     298           0 :     numLayer_ = nL1 - 1;
     299           0 :     altitude_ = v_layerBoundaries[0];
     300           0 :     for(unsigned int n = 0; n < numLayer_; n++) {
     301           0 :       v_layerO3_.push_back(0.0);
     302           0 :       v_layerCO_.push_back(0.0);
     303           0 :       v_layerN2O_.push_back(0.0);
     304           0 :       v_layerNO2_.push_back(0.0);
     305           0 :       v_layerSO2_.push_back(0.0);
     306           0 :       v_layerHCl_.push_back(0.0);
     307           0 :       v_layerHCN_.push_back(0.0);
     308           0 :       v_layerThickness_.push_back(v_layerBoundaries[n+1].get(Length::UnitMeter) - v_layerBoundaries[n].get(Length::UnitMeter));
     309           0 :       v_layerTemperature_.push_back((v_layerTemperature[n].get(Temperature::UnitKelvin) + v_layerTemperature[n+1].get(Temperature::UnitKelvin))/2.0);
     310           0 :       v_layerTemperature0_.push_back(v_layerTemperature[n].get(Temperature::UnitKelvin));
     311           0 :       v_layerTemperature1_.push_back(v_layerTemperature[n+1].get(Temperature::UnitKelvin));
     312           0 :       v_layerPressure_.push_back(exp((log(v_layerPressure[n].get(Pressure::UnitMilliBar))+ log(v_layerPressure[n + 1].get(Pressure::UnitMilliBar)))/2.0));
     313           0 :       v_layerPressure0_.push_back(v_layerPressure[n].get(Pressure::UnitMilliBar));
     314           0 :       v_layerPressure1_.push_back(v_layerPressure[n+1].get(Pressure::UnitMilliBar));
     315           0 :       v_layerWaterVapor_.push_back( (exp((log(v_layerWaterVapor[n].get(NumberDensity::UnitInverseCubicMeter))+ log(v_layerWaterVapor[n + 1].get(NumberDensity::UnitInverseCubicMeter)))/2.0))* 18.0
     316           0 :                                      / (1000.0 * 6.023e23));
     317           0 :       v_layerWaterVapor0_.push_back(v_layerWaterVapor[n].get(NumberDensity::UnitInverseCubicMeter) * 18.0
     318           0 :           / (1000.0 * 6.023e23));
     319           0 :       v_layerWaterVapor1_.push_back(v_layerWaterVapor[n+1].get(NumberDensity::UnitInverseCubicMeter) * 18.0
     320           0 :           / (1000.0 * 6.023e23));
     321             :     }
     322           0 :   } else {
     323           0 :     numLayer_ = 0;
     324             :   }
     325           0 :   initBasicAtmosphericParameterThresholds();
     326           0 : }
     327             : 
     328           0 : AtmProfile::AtmProfile(const Length &altitude,
     329             :                        const vector<Length> &v_layerThickness,
     330             :                        const vector<Pressure> &v_layerPressure,
     331             :                        const vector<Temperature> &v_layerTemperature,
     332             :                        const vector<MassDensity> &v_layerWaterVapor,
     333           0 :                        const vector<NumberDensity> &v_layerO3)
     334             : {
     335           0 :   newBasicParam_ = true;
     336           0 :   unsigned int nL1 = v_layerThickness.size();
     337           0 :   unsigned int nL2 = v_layerPressure.size();
     338           0 :   unsigned int nL3 = v_layerTemperature.size();
     339           0 :   unsigned int nL4 = v_layerWaterVapor.size();
     340           0 :   unsigned int nL5 = v_layerO3.size();
     341             : 
     342           0 :   if(nL1 * 1 == nL2 && nL2 == nL3 && nL3 == nL4 && nL4 == nL5) {
     343           0 :     numLayer_ = nL1;
     344           0 :     for(unsigned int n = 0; n < numLayer_; n++) {
     345           0 :       v_layerO3_.push_back(v_layerO3[n].get(NumberDensity::UnitInverseCubicMeter));
     346           0 :       v_layerCO_.push_back(0.0);
     347           0 :       v_layerN2O_.push_back(0.0);
     348           0 :       v_layerNO2_.push_back(0.0);
     349           0 :       v_layerSO2_.push_back(0.0);
     350           0 :       v_layerHCl_.push_back(0.0);
     351           0 :       v_layerHCN_.push_back(0.0);
     352           0 :       v_layerThickness_.push_back(v_layerThickness[n].get(Length::UnitMeter));
     353           0 :       v_layerTemperature_.push_back((v_layerTemperature[n].get(Temperature::UnitKelvin) + v_layerTemperature[n+1].get(Temperature::UnitKelvin))/2.0);
     354           0 :       v_layerTemperature0_.push_back(v_layerTemperature[n].get(Temperature::UnitKelvin));
     355           0 :       v_layerTemperature1_.push_back(v_layerTemperature[n+1].get(Temperature::UnitKelvin));
     356           0 :       v_layerPressure_.push_back(exp((log(v_layerPressure[n].get(Pressure::UnitMilliBar))+ log(v_layerPressure[n + 1].get(Pressure::UnitMilliBar)))/2.0));
     357           0 :       v_layerPressure0_.push_back(v_layerPressure[n].get(Pressure::UnitMilliBar));
     358           0 :       v_layerPressure1_.push_back(v_layerPressure[n+1].get(Pressure::UnitMilliBar));
     359           0 :       v_layerWaterVapor_.push_back(exp((log(v_layerWaterVapor[n].get(MassDensity::UnitKiloGramPerCubicMeter))+ log(v_layerWaterVapor[n + 1].get(MassDensity::UnitKiloGramPerCubicMeter)))/2.0));
     360           0 :       v_layerWaterVapor0_.push_back(v_layerWaterVapor[n].get(MassDensity::UnitKiloGramPerCubicMeter));
     361           0 :       v_layerWaterVapor1_.push_back(v_layerWaterVapor[n+1].get(MassDensity::UnitKiloGramPerCubicMeter));
     362             :     }
     363           0 :   } else {
     364           0 :     numLayer_ = 0;
     365             :   }
     366           0 :   initBasicAtmosphericParameterThresholds();
     367           0 : }
     368             : 
     369           0 : AtmProfile::AtmProfile(const Length &altitude,
     370             :                        const vector<Length> &v_layerThickness,
     371             :                        const vector<Pressure> &v_layerPressure,
     372             :                        const vector<Temperature> &v_layerTemperature,
     373             :                        const vector<NumberDensity> &v_layerWaterVapor,
     374           0 :                        const vector<NumberDensity> &v_layerO3)
     375             : {
     376           0 :   newBasicParam_ = true;
     377           0 :   unsigned int nL1 = v_layerThickness.size();
     378           0 :   unsigned int nL2 = v_layerPressure.size();
     379           0 :   unsigned int nL3 = v_layerTemperature.size();
     380           0 :   unsigned int nL4 = v_layerWaterVapor.size();
     381           0 :   unsigned int nL5 = v_layerO3.size();
     382             : 
     383           0 :   if(nL1 + 1 == nL2 && nL2 == nL3 && nL3 == nL4 && nL4 == nL5) {
     384           0 :     numLayer_ = nL1;
     385           0 :     for(unsigned int n = 0; n < numLayer_; n++) {
     386           0 :       v_layerO3_.push_back(v_layerO3[n].get(NumberDensity::UnitInverseCubicMeter));
     387           0 :       v_layerCO_.push_back(0.0);
     388           0 :       v_layerN2O_.push_back(0.0);
     389           0 :       v_layerNO2_.push_back(0.0);
     390           0 :       v_layerSO2_.push_back(0.0);
     391           0 :       v_layerHCl_.push_back(0.0);
     392           0 :       v_layerHCN_.push_back(0.0);
     393           0 :       v_layerThickness_.push_back(v_layerThickness[n].get(Length::UnitMeter));
     394           0 :       v_layerTemperature_.push_back((v_layerTemperature[n].get(Temperature::UnitKelvin) + v_layerTemperature[n+1].get(Temperature::UnitKelvin))/2.0);
     395           0 :       v_layerTemperature0_.push_back(v_layerTemperature[n].get(Temperature::UnitKelvin));
     396           0 :       v_layerTemperature1_.push_back(v_layerTemperature[n+1].get(Temperature::UnitKelvin));
     397           0 :       v_layerPressure_.push_back(exp((log(v_layerPressure[n].get(Pressure::UnitMilliBar))+ log(v_layerPressure[n + 1].get(Pressure::UnitMilliBar)))/2.0));
     398           0 :       v_layerPressure0_.push_back(v_layerPressure[n].get(Pressure::UnitMilliBar));
     399           0 :       v_layerPressure1_.push_back(v_layerPressure[n+1].get(Pressure::UnitMilliBar));
     400           0 :       v_layerWaterVapor_.push_back( (exp((log(v_layerWaterVapor[n].get(NumberDensity::UnitInverseCubicMeter))+ log(v_layerWaterVapor[n + 1].get(NumberDensity::UnitInverseCubicMeter)))/2.0))* 18.0
     401           0 :                                     / (1000.0 * 6.023e23));
     402           0 :       v_layerWaterVapor0_.push_back(v_layerWaterVapor[n].get(NumberDensity::UnitInverseCubicMeter) * 18.0
     403           0 :           / (1000.0 * 6.023e23));
     404           0 :       v_layerWaterVapor1_.push_back(v_layerWaterVapor[n+1].get(NumberDensity::UnitInverseCubicMeter) * 18.0
     405           0 :           / (1000.0 * 6.023e23));
     406             :     }
     407           0 :   } else {
     408           0 :     numLayer_ = 0;
     409             :   }
     410           0 :   initBasicAtmosphericParameterThresholds();
     411           0 : }
     412             : 
     413           0 : AtmProfile::AtmProfile(const Length &altitude,
     414             :                        const vector<Length> &v_layerThickness,
     415             :                        const vector<Pressure> &v_layerPressure,
     416             :                        const vector<Temperature> &v_layerTemperature,
     417             :                        const vector<MassDensity> &v_layerWaterVapor,
     418             :                        const vector<NumberDensity> &v_layerO3,
     419             :                        const vector<NumberDensity> &v_layerCO,
     420             :                        const vector<NumberDensity> &v_layerN2O,
     421             :                        const vector<NumberDensity> &v_layerNO2,
     422             :                        const vector<NumberDensity> &v_layerSO2,
     423             :                        const vector<NumberDensity> &v_layerHCl,
     424           0 :                        const vector<NumberDensity> &v_layerHCN)
     425             :  {
     426           0 :   newBasicParam_ = true;
     427           0 :   unsigned int nL1 = v_layerThickness.size();
     428           0 :   unsigned int nL2 = v_layerPressure.size();
     429           0 :   unsigned int nL3 = v_layerTemperature.size();
     430           0 :   unsigned int nL4 = v_layerWaterVapor.size();
     431           0 :   unsigned int nL5 = v_layerO3.size();
     432           0 :   unsigned int nL6 = v_layerCO.size();
     433           0 :   unsigned int nL7 = v_layerN2O.size();
     434           0 :   unsigned int nL8 = v_layerNO2.size();
     435           0 :   unsigned int nL9 = v_layerSO2.size();
     436           0 :   unsigned int nL10 = v_layerHCl.size();
     437           0 :   unsigned int nL11 = v_layerHCN.size();
     438             : 
     439           0 :   if(nL1 + 1 == nL2 && nL2 == nL3 && nL3 == nL4 && nL4 == nL5 && nL5 == nL6 && nL6
     440           0 :       == nL7 && nL7 == nL8 && nL8 == nL9 && nL9 == nL10 && nL10 == nL11) {
     441           0 :     numLayer_ = nL1;
     442           0 :     for(unsigned int n = 0; n < numLayer_; n++) {
     443           0 :       v_layerO3_.push_back(v_layerO3[n].get(NumberDensity::UnitInverseCubicMeter));
     444           0 :       v_layerCO_.push_back(v_layerCO[n].get(NumberDensity::UnitInverseCubicMeter));
     445           0 :       v_layerN2O_.push_back(v_layerN2O[n].get(NumberDensity::UnitInverseCubicMeter));
     446           0 :       v_layerNO2_.push_back(v_layerNO2[n].get(NumberDensity::UnitInverseCubicMeter));
     447           0 :       v_layerSO2_.push_back(v_layerSO2[n].get(NumberDensity::UnitInverseCubicMeter));
     448           0 :       v_layerHCl_.push_back(v_layerHCl[n].get(NumberDensity::UnitInverseCubicMeter));
     449           0 :       v_layerHCN_.push_back(v_layerHCN[n].get(NumberDensity::UnitInverseCubicMeter));
     450           0 :       v_layerThickness_.push_back(v_layerThickness[n].get(Length::UnitMeter));
     451           0 :       v_layerTemperature_.push_back((v_layerTemperature[n].get(Temperature::UnitKelvin) + v_layerTemperature[n+1].get(Temperature::UnitKelvin))/2.0);
     452           0 :       v_layerTemperature0_.push_back(v_layerTemperature[n].get(Temperature::UnitKelvin));
     453           0 :       v_layerTemperature1_.push_back(v_layerTemperature[n+1].get(Temperature::UnitKelvin));
     454           0 :       v_layerPressure_.push_back(exp((log(v_layerPressure[n].get(Pressure::UnitMilliBar))+ log(v_layerPressure[n + 1].get(Pressure::UnitMilliBar)))/2.0));
     455           0 :       v_layerPressure0_.push_back(v_layerPressure[n].get(Pressure::UnitMilliBar));
     456           0 :       v_layerPressure1_.push_back(v_layerPressure[n+1].get(Pressure::UnitMilliBar));
     457           0 :       v_layerWaterVapor_.push_back(exp((log(v_layerWaterVapor[n].get(MassDensity::UnitKiloGramPerCubicMeter))+ log(v_layerWaterVapor[n + 1].get(MassDensity::UnitKiloGramPerCubicMeter)))/2.0));
     458           0 :       v_layerWaterVapor0_.push_back(v_layerWaterVapor[n].get(MassDensity::UnitKiloGramPerCubicMeter));
     459           0 :       v_layerWaterVapor1_.push_back(v_layerWaterVapor[n+1].get(MassDensity::UnitKiloGramPerCubicMeter));
     460             :     }
     461           0 :   } else {
     462           0 :     numLayer_ = 0;
     463             :   }
     464           0 :   initBasicAtmosphericParameterThresholds();
     465           0 : }
     466             : 
     467           0 : AtmProfile::AtmProfile(const Length &altitude,
     468             :                        const vector<Length> &v_layerThickness,
     469             :                        const vector<Pressure> &v_layerPressure,
     470             :                        const vector<Temperature> &v_layerTemperature,
     471             :                        const vector<NumberDensity> &v_layerWaterVapor,
     472             :                        const vector<NumberDensity> &v_layerO3,
     473             :                        const vector<NumberDensity> &v_layerCO,
     474             :                        const vector<NumberDensity> &v_layerN2O,
     475             :                        const vector<NumberDensity> &v_layerNO2,
     476             :                        const vector<NumberDensity> &v_layerSO2,
     477             :                        const vector<NumberDensity> &v_layerHCl,
     478           0 :                        const vector<NumberDensity> &v_layerHCN)
     479             : {
     480           0 :   newBasicParam_ = true;
     481           0 :   unsigned int nL1 = v_layerThickness.size();
     482           0 :   unsigned int nL2 = v_layerPressure.size();
     483           0 :   unsigned int nL3 = v_layerTemperature.size();
     484           0 :   unsigned int nL4 = v_layerWaterVapor.size();
     485           0 :   unsigned int nL5 = v_layerO3.size();
     486           0 :   unsigned int nL6 = v_layerCO.size();
     487           0 :   unsigned int nL7 = v_layerN2O.size();
     488           0 :   unsigned int nL8 = v_layerNO2.size();
     489           0 :   unsigned int nL9 = v_layerSO2.size();
     490           0 :   unsigned int nL10 = v_layerHCl.size();
     491           0 :   unsigned int nL11 = v_layerHCN.size();
     492             : 
     493           0 :   if(nL1 + 1 == nL2 && nL2 == nL3 && nL3 == nL4 && nL4 == nL5 && nL5 == nL6 && nL6
     494           0 :       == nL7 && nL7 == nL8 && nL8 == nL9 && nL9 == nL10 && nL10 == nL11) {
     495           0 :     numLayer_ = nL1;
     496           0 :     for(unsigned int n = 0; n < numLayer_; n++) {
     497           0 :       v_layerO3_.push_back(v_layerO3[n].get(NumberDensity::UnitInverseCubicMeter));
     498           0 :       v_layerCO_.push_back(v_layerCO[n].get(NumberDensity::UnitInverseCubicMeter));
     499           0 :       v_layerN2O_.push_back(v_layerN2O[n].get(NumberDensity::UnitInverseCubicMeter));
     500           0 :       v_layerNO2_.push_back(v_layerNO2[n].get(NumberDensity::UnitInverseCubicMeter));
     501           0 :       v_layerSO2_.push_back(v_layerSO2[n].get(NumberDensity::UnitInverseCubicMeter));
     502           0 :       v_layerHCl_.push_back(v_layerHCl[n].get(NumberDensity::UnitInverseCubicMeter));
     503           0 :       v_layerHCN_.push_back(v_layerHCN[n].get(NumberDensity::UnitInverseCubicMeter));
     504           0 :       v_layerThickness_.push_back(v_layerThickness[n].get(Length::UnitMeter));
     505           0 :       v_layerTemperature_.push_back((v_layerTemperature[n].get(Temperature::UnitKelvin) + v_layerTemperature[n+1].get(Temperature::UnitKelvin))/2.0);
     506           0 :       v_layerTemperature0_.push_back(v_layerTemperature[n].get(Temperature::UnitKelvin));
     507           0 :       v_layerTemperature1_.push_back(v_layerTemperature[n+1].get(Temperature::UnitKelvin));
     508           0 :       v_layerPressure_.push_back(exp((log(v_layerPressure[n].get(Pressure::UnitMilliBar))+ log(v_layerPressure[n + 1].get(Pressure::UnitMilliBar)))/2.0));
     509           0 :       v_layerPressure0_.push_back(v_layerPressure[n].get(Pressure::UnitMilliBar));
     510           0 :       v_layerPressure1_.push_back(v_layerPressure[n+1].get(Pressure::UnitMilliBar));
     511           0 :       v_layerWaterVapor_.push_back( (exp((log(v_layerWaterVapor[n].get(NumberDensity::UnitInverseCubicMeter))+ log(v_layerWaterVapor[n + 1].get(NumberDensity::UnitInverseCubicMeter)))/2.0))* 18.0
     512           0 :                                     / (1000.0 * 6.023e23));
     513           0 :       v_layerWaterVapor0_.push_back(v_layerWaterVapor[n].get(NumberDensity::UnitInverseCubicMeter) * 18.0
     514           0 :           / (1000.0 * 6.023e23));
     515           0 :       v_layerWaterVapor1_.push_back(v_layerWaterVapor[n+1].get(NumberDensity::UnitInverseCubicMeter) * 18.0
     516           0 :           / (1000.0 * 6.023e23));
     517             :     }
     518           0 :   } else {
     519           0 :     numLayer_ = 0;
     520             :   }
     521           0 :   initBasicAtmosphericParameterThresholds();
     522           0 : }
     523             : 
     524         202 : AtmProfile::AtmProfile(const AtmProfile &a)
     525             : { //:AtmType(a.type_){
     526             :   // std::cout<<"AtmProfile copy constructor"<<endl;  COMMENTED OUT BY JUAN MAY/16/2005
     527         202 :   typeAtm_ = a.typeAtm_;
     528         202 :   groundTemperature_ = a.groundTemperature_;
     529         202 :   tropoLapseRate_ = a.tropoLapseRate_;
     530         202 :   groundPressure_ = a.groundPressure_;
     531         202 :   relativeHumidity_ = a.relativeHumidity_;
     532         202 :   wvScaleHeight_ = a.wvScaleHeight_;
     533         202 :   pressureStep_ = a.pressureStep_;
     534         202 :   pressureStepFactor_ = a.pressureStepFactor_;
     535         202 :   altitude_ = a.altitude_;
     536         202 :   topAtmProfile_ = a.topAtmProfile_;
     537         202 :   numLayer_ = a.numLayer_;
     538         202 :   newBasicParam_ = a.newBasicParam_;
     539         202 :   v_layerThickness_.reserve(numLayer_);
     540         202 :   v_layerPressure_.reserve(numLayer_);
     541         202 :   v_layerPressure0_.reserve(numLayer_);
     542         202 :   v_layerPressure1_.reserve(numLayer_);
     543         202 :   v_layerTemperature_.reserve(numLayer_);
     544         202 :   v_layerTemperature0_.reserve(numLayer_);
     545         202 :   v_layerTemperature1_.reserve(numLayer_);
     546         202 :   v_layerWaterVapor_.reserve(numLayer_);
     547         202 :   v_layerWaterVapor0_.reserve(numLayer_);
     548         202 :   v_layerWaterVapor1_.reserve(numLayer_);
     549         202 :   v_layerCO_.reserve(numLayer_);
     550         202 :   v_layerO3_.reserve(numLayer_);
     551         202 :   v_layerN2O_.reserve(numLayer_);
     552         202 :   v_layerNO2_.reserve(numLayer_);
     553         202 :   v_layerSO2_.reserve(numLayer_);
     554         202 :   v_layerHCl_.reserve(numLayer_);
     555         202 :   v_layerHCN_.reserve(numLayer_);
     556             :   // std::cout << "numLayer_=" << numLayer_ << std::endl;  COMMENTED OUT BY JUAN MAY/16/2005
     557        8642 :   for(unsigned int n = 0; n < numLayer_; n++) {
     558        8440 :     v_layerThickness_.push_back(a.v_layerThickness_[n]);
     559        8440 :     v_layerTemperature_.push_back(a.v_layerTemperature_[n]);
     560        8440 :     v_layerTemperature0_.push_back(a.v_layerTemperature0_[n]);
     561        8440 :     v_layerTemperature1_.push_back(a.v_layerTemperature1_[n]);
     562             :     //cout << "n=" << n << std::endl;
     563        8440 :     v_layerWaterVapor_.push_back(a.v_layerWaterVapor_[n]);
     564        8440 :     v_layerWaterVapor0_.push_back(a.v_layerWaterVapor0_[n]);
     565        8440 :     v_layerWaterVapor1_.push_back(a.v_layerWaterVapor1_[n]);
     566        8440 :     v_layerPressure_.push_back(a.v_layerPressure_[n]);
     567        8440 :     v_layerPressure0_.push_back(a.v_layerPressure1_[n]);
     568        8440 :     v_layerPressure1_.push_back(a.v_layerPressure1_[n]);
     569        8440 :     v_layerCO_.push_back(a.v_layerCO_[n]);
     570        8440 :     v_layerO3_.push_back(a.v_layerO3_[n]);
     571        8440 :     v_layerN2O_.push_back(a.v_layerN2O_[n]);
     572        8440 :     v_layerNO2_.push_back(a.v_layerNO2_[n]);
     573        8440 :     v_layerSO2_.push_back(a.v_layerSO2_[n]);
     574        8440 :     v_layerHCl_.push_back(a.v_layerHCl_[n]);
     575        8440 :     v_layerHCN_.push_back(a.v_layerHCN_[n]);
     576             :   }
     577         202 :   altitudeThreshold_ = a.altitudeThreshold_;
     578         202 :   groundPressureThreshold_ = a.groundPressureThreshold_;
     579         202 :   groundTemperatureThreshold_ = a.groundTemperatureThreshold_;
     580         202 :   tropoLapseRateThreshold_ = a.tropoLapseRateThreshold_;
     581         202 :   relativeHumidityThreshold_ = a.relativeHumidityThreshold_;
     582         202 :   wvScaleHeightThreshold_ = a.wvScaleHeightThreshold_;
     583         202 : }
     584           0 : void AtmProfile::setBasicAtmosphericParameterThresholds(const Length &altitudeThreshold,
     585             :                                                         const Pressure &groundPressureThreshold,
     586             :                                                         const Temperature &groundTemperatureThreshold,
     587             :                                                         double tropoLapseRateThreshold,
     588             :                                                         const Humidity &relativeHumidityThreshold,
     589             :                                                         const Length &wvScaleHeightThreshold)
     590             : {
     591           0 :   altitudeThreshold_ = altitudeThreshold;
     592           0 :   groundPressureThreshold_ = groundPressureThreshold;
     593           0 :   groundTemperatureThreshold_ = groundTemperatureThreshold;
     594           0 :   tropoLapseRateThreshold_ = tropoLapseRateThreshold;
     595           0 :   relativeHumidityThreshold_ = relativeHumidityThreshold;
     596           0 :   wvScaleHeightThreshold_ =wvScaleHeightThreshold;
     597           0 : }
     598             : 
     599           5 : void AtmProfile::initBasicAtmosphericParameterThresholds()
     600             : {
     601           5 :   altitudeThreshold_ = Length(1.0,Length::UnitMeter);
     602           5 :   groundPressureThreshold_ =  Pressure(99.,Pressure::UnitPascal);  // DB 2014-03-06 : Choose 99 Pascal instead of 100 Pascal because the threshold must be lower than the value of delta_pressure used in getAverageDispersiveDryPathLength_GroundPressureDerivative()
     603           5 :   groundTemperatureThreshold_ =  Temperature(0.3,Temperature::UnitKelvin);
     604           5 :   tropoLapseRateThreshold_ = 0.01;
     605           5 :   relativeHumidityThreshold_ = Humidity(100.,Percent::UnitPercent);
     606           5 :   wvScaleHeightThreshold_ = Length(20.,Length::UnitMeter);
     607           5 : }
     608             : 
     609         120 : bool AtmProfile::updateAtmProfile(const Length &altitude,
     610             :                                   const Pressure &groundPressure,
     611             :                                   const Temperature &groundTemperature,
     612             :                                   double tropoLapseRate,
     613             :                                   const Humidity &relativeHumidity,
     614             :                                   const Length &wvScaleHeight)
     615             : {
     616             : 
     617             :   /* TODO A faire: pour decider s'il faut recalculer le profile on devrait plutot donner des seuils, eg
     618             :    if(fabs(altitude_.get()-altitude.get())>0.1)mkNewProfile=true;
     619             :    */
     620             : 
     621             :   unsigned int numLayer;
     622         120 :   bool mkNewProfile = false;
     623             : 
     624             : //   if(altitude_.get() != altitude.get()) mkNewProfile = true; //if(mkNewProfile)cout<<"altitude has changed"          <<endl;
     625             : //   if(groundPressure_.get() != groundPressure.get()) mkNewProfile = true; //if(mkNewProfile)cout<<"ground pressure has changed"   <<endl;
     626             : //   if(groundTemperature_.get() != groundTemperature.get()) mkNewProfile = true; //if(mkNewProfile)cout<<"ground temperature has changed"<<endl;
     627             : //   if(wvScaleHeight_.get() != wvScaleHeight.get()) mkNewProfile = true; //if(mkNewProfile)cout<<"wv scale height has changed"   <<endl;
     628             : //   if(tropoLapseRate_ != tropoLapseRate) mkNewProfile = true; //if(mkNewProfile)cout<<"tropo lapse rate has changed"  <<endl;
     629             : //   if(relativeHumidity_.get() != relativeHumidity.get()) mkNewProfile = true; //if(mkNewProfile)cout<<"relative humidity has changed" <<endl;
     630             :   //! all these thresholds shoudl be parametrized.
     631         120 :   if(fabs(altitude_.get()-altitude.get())> altitudeThreshold_.get()) { // Length(0.1,Length::UnitMeter).get())  {
     632           0 :     mkNewProfile = true;
     633             :     //cout<<"altitude has changed"          <<endl;
     634             :   }
     635         120 :   if(fabs(groundPressure_.get()-groundPressure.get())> groundPressureThreshold_.get()) { // Pressure(100.,Pressure::UnitPascal).get()) {
     636         120 :     mkNewProfile = true;
     637             :     //cout<<"ground pressure has changed"   <<endl;
     638             :   }
     639         120 :   if(fabs(groundTemperature_.get()-groundTemperature.get()) > groundTemperatureThreshold_.get()) { //  Temperature(0.3,Temperature::UnitKelvin).get()) {
     640           0 :     mkNewProfile = true;
     641             :     //cout<<"ground temperature has changed"<<endl;
     642             :   }
     643         120 :   if(fabs(wvScaleHeight_.get()-wvScaleHeight.get()) > wvScaleHeightThreshold_.get()) { // Length(20.,Length::UnitMeter).get() ) {
     644           0 :     mkNewProfile = true;
     645             :     //cout<<"wv scale height has changed"   <<endl;
     646             :   }
     647         120 :   if(fabs(tropoLapseRate_-tropoLapseRate) > tropoLapseRateThreshold_) { // 0.01) {
     648           0 :     mkNewProfile = true;
     649             :     //cout<<"tropo lapse rate has changed"  <<endl;
     650             :   }
     651             :   // we use WVR...
     652         120 :   if(fabs(relativeHumidity_.get()-relativeHumidity.get())> relativeHumidityThreshold_.get()) { // Humidity(100.,Percent::UnitPercent).get()) {
     653           0 :     mkNewProfile = true;
     654             :     //cout<<"relative humidity has changed" <<endl;
     655             :   }
     656         120 :   if(mkNewProfile) {
     657         120 :     newBasicParam_ = true;
     658         120 :     altitude_ = altitude;
     659         120 :     groundPressure_ = groundPressure;
     660         120 :     groundTemperature_ = groundTemperature;
     661         120 :     tropoLapseRate_ = tropoLapseRate;
     662         120 :     relativeHumidity_ = relativeHumidity;
     663         120 :     wvScaleHeight_ = wvScaleHeight;
     664         120 :     numLayer = mkAtmProfile();
     665         120 :     numLayer_ = numLayer;
     666             :     //      std::cout << "There are new basic parameters, with " << numLayer_ << " layers " << std::endl;
     667             :   } else {
     668           0 :     numLayer = getNumLayer();
     669           0 :     numLayer_ = numLayer;
     670             :   }
     671             : 
     672         120 :   return mkNewProfile;
     673             : }
     674             : 
     675             : // Note that this setBasicAtmosphericParameters will be overrided by the subclasses.
     676           0 : bool AtmProfile::setBasicAtmosphericParameters(const Length &altitude,
     677             :                                                const Pressure &groundPressure,
     678             :                                                const Temperature &groundTemperature,
     679             :                                                double tropoLapseRate,
     680             :                                                const Humidity &relativeHumidity,
     681             :                                                const Length &wvScaleHeight)
     682             : {
     683           0 :   return updateAtmProfile(altitude,
     684             :                           groundPressure,
     685             :                           groundTemperature,
     686             :                           tropoLapseRate,
     687             :                           relativeHumidity,
     688           0 :                           wvScaleHeight);
     689             : }
     690             : 
     691           3 : string AtmProfile::getAtmosphereType() const
     692             : {
     693           3 :   return getAtmosphereType(typeAtm_);
     694             : }
     695             : 
     696           3 : string AtmProfile::getAtmosphereType(unsigned int typeAtm)
     697             : {
     698           3 :     string type;
     699             :     string typeNames[] = { "TROPICAL", "MIDLATSUMMER", "MIDLATWINTER",
     700          24 :                            "SUBARTSUMMER", "SUBARTWINTER","US_ST76"};
     701             : 
     702           3 :     if(typeAtm < typeATM_end) {
     703           3 :       type = typeNames[typeAtm-1];
     704             :     } else {
     705           0 :       type = "DEFAULT";
     706             :     }
     707           6 :     return type;
     708          21 : }
     709             : 
     710           1 : vector<Temperature> AtmProfile::getTemperatureProfile() const
     711             : {
     712           1 :   vector<Temperature> t;
     713           1 :   t.reserve(v_layerTemperature_.size());
     714          43 :   for(unsigned int i = 0; i < v_layerTemperature_.size(); i++) {
     715          42 :     Temperature tt(v_layerTemperature_[i], Temperature::UnitKelvin);
     716          42 :     t.push_back(tt);
     717          42 :   }
     718           1 :   return t;
     719           0 : }
     720             : 
     721        7452 : Temperature AtmProfile::getLayerTemperature(unsigned int i) const
     722             : {
     723             :   /*if(i > v_layerTemperature_.size() - 1) {
     724             :     Temperature t(-999.0, Temperature::UnitKelvin);
     725             :     return t;
     726             :   } else {
     727             :     Temperature t(v_layerTemperature_[i], Temperature::UnitKelvin);
     728             :     return t;
     729             :   }*/
     730        7452 :   if(i > v_layerTemperature_.size() - 1) {
     731           0 :     std::ostringstream oss;
     732           0 :     oss << "Not a valid layer: " << i;
     733           0 :     throw AtmException(ATM_EXCEPTION_ARGS(oss.str().c_str()));
     734           0 :   }
     735        7452 :   return Temperature(v_layerTemperature_[i], Temperature::UnitKelvin);
     736             : }
     737             : 
     738           0 : Temperature AtmProfile::getLayerBottomTemperature(unsigned int i) const
     739             : {
     740           0 :   if(i > v_layerTemperature0_.size() - 1) {
     741           0 :     std::ostringstream oss;
     742           0 :     oss << "Not a valid layer: " << i;
     743           0 :     throw AtmException(ATM_EXCEPTION_ARGS(oss.str().c_str()));
     744           0 :   }
     745           0 :   return Temperature(v_layerTemperature0_[i], Temperature::UnitKelvin);
     746             : }
     747             : 
     748           0 : Temperature AtmProfile::getLayerTopTemperature(unsigned int i) const
     749             : {
     750           0 :   if(i > v_layerTemperature1_.size() - 1) {
     751           0 :     std::ostringstream oss;
     752           0 :     oss << "Not a valid layer: " << i;
     753           0 :     throw AtmException(ATM_EXCEPTION_ARGS(oss.str().c_str()));
     754           0 :   }
     755           0 :   return Temperature(v_layerTemperature1_[i], Temperature::UnitKelvin);
     756             : }
     757             : 
     758             : 
     759           0 : void AtmProfile::setAltitude(const Length &groundaltitude)
     760             : {
     761             : 
     762           0 :   if (groundaltitude <= altitude_){
     763             : 
     764             :     // std::cout << "extrapolar para abajo" << std::endl;
     765             : 
     766           0 :     int nextralayers = int( 0.50001+(altitude_-groundaltitude).get(Length::UnitMeter)/v_layerThickness_[0]);
     767           0 :     if (nextralayers == 0) {nextralayers=1;}
     768             :     //    std::cout << "aaa=" << ( 0.50001+(altitude_-groundaltitude).get(Length::UnitMeter)/v_layerThickness_[0]) << std::endl;
     769           0 :     double newThickness = (altitude_-groundaltitude).get(Length::UnitMeter) / nextralayers;
     770             : 
     771             :     //  std::cout << "Number of extra layers: " << nextralayers << " of thickness = " <<  newThickness << " m"  << std::endl;
     772             :     //  std::cout << "nextralayers-1 " << nextralayers-1 << std::endl;
     773             : 
     774           0 :     for(int i=nextralayers; i>0; i--){
     775           0 :       v_layerThickness_.push_back(newThickness);
     776           0 :       v_layerTemperature_.push_back(v_layerTemperature_[0]);
     777           0 :       v_layerTemperature0_.push_back(v_layerTemperature0_[0]);
     778           0 :       v_layerTemperature1_.push_back(v_layerTemperature1_[0]);
     779           0 :       v_layerWaterVapor_.push_back(v_layerWaterVapor_[0]);
     780           0 :       v_layerWaterVapor0_.push_back(v_layerWaterVapor0_[0]);
     781           0 :       v_layerWaterVapor1_.push_back(v_layerWaterVapor1_[0]);
     782           0 :       v_layerPressure_.push_back(v_layerPressure_[0]);
     783           0 :       v_layerPressure0_.push_back(v_layerPressure0_[0]);
     784           0 :       v_layerPressure1_.push_back(v_layerPressure1_[0]);
     785           0 :       v_layerCO_.push_back(v_layerCO_[0]);
     786           0 :       v_layerO3_.push_back(v_layerO3_[0]);
     787           0 :       v_layerN2O_.push_back(v_layerN2O_[0]);
     788           0 :       v_layerNO2_.push_back(v_layerNO2_[0]);
     789           0 :       v_layerSO2_.push_back(v_layerSO2_[0]);
     790           0 :       v_layerHCl_.push_back(v_layerHCl_[0]);
     791           0 :       v_layerHCN_.push_back(v_layerHCN_[0]);
     792             :     }
     793             : 
     794           0 :     for(int i=v_layerThickness_.size()-1; i>nextralayers-1; i--){
     795           0 :       v_layerThickness_[i] = v_layerThickness_[i-nextralayers];
     796           0 :       v_layerTemperature_[i] = v_layerTemperature_[i-nextralayers];
     797           0 :       v_layerTemperature0_[i] = v_layerTemperature0_[i-nextralayers];
     798           0 :       v_layerTemperature1_[i] = v_layerTemperature1_[i-nextralayers];
     799           0 :       v_layerWaterVapor_[i] = v_layerWaterVapor_[i-nextralayers];
     800           0 :       v_layerWaterVapor0_[i] = v_layerWaterVapor0_[i-nextralayers];
     801           0 :       v_layerWaterVapor1_[i] = v_layerWaterVapor1_[i-nextralayers];
     802           0 :       v_layerPressure_[i] = v_layerPressure_[i-nextralayers];
     803           0 :       v_layerPressure0_[i] = v_layerPressure0_[i-nextralayers];
     804           0 :       v_layerPressure1_[i] = v_layerPressure1_[i-nextralayers];
     805           0 :       v_layerCO_[i] = v_layerCO_[i-nextralayers];
     806           0 :       v_layerO3_[i] = v_layerO3_[i-nextralayers];
     807           0 :       v_layerN2O_[i] = v_layerN2O_[i-nextralayers];
     808           0 :       v_layerNO2_[i] = v_layerNO2_[i-nextralayers];
     809           0 :       v_layerSO2_[i] = v_layerSO2_[i-nextralayers];
     810           0 :       v_layerHCl_[i] = v_layerHCl_[i-nextralayers];
     811           0 :       v_layerHCN_[i] = v_layerHCN_[i-nextralayers];
     812             :     }
     813             : 
     814             :     // std::cout << "nextralayers=" << nextralayers << std::endl;
     815             : 
     816           0 :     for(int i=nextralayers; i>0 ; i--){
     817             : 
     818           0 :       v_layerThickness_[i-1] = newThickness;
     819           0 :       v_layerTemperature1_[i-1] = v_layerTemperature0_[i];
     820           0 :       v_layerTemperature0_[i-1] = v_layerTemperature0_[i]-tropoLapseRate_*0.001*v_layerThickness_[i-1];
     821           0 :       v_layerTemperature_[i-1] = (v_layerTemperature0_[i]+v_layerTemperature1_[i])/2.0;
     822             : 
     823           0 :       v_layerPressure1_[i-1] = v_layerPressure0_[i];
     824           0 :       v_layerPressure0_[i-1] = v_layerPressure0_[i]* exp(-0.0341695 *
     825           0 :                                          (-newThickness)/ v_layerTemperature_[i-1] );
     826           0 :       v_layerPressure_[i-1] = exp((log(v_layerPressure0_[i-1])+ log(v_layerPressure1_[i-1]))/2.0);
     827             : 
     828           0 :       v_layerWaterVapor1_[i-1] = v_layerWaterVapor0_[i];
     829           0 :       v_layerWaterVapor0_[i-1] = v_layerWaterVapor0_[i]*(v_layerPressure0_[i-1]/v_layerPressure0_[i]);
     830           0 :       v_layerWaterVapor_[i-1] = exp((log(v_layerWaterVapor0_[i-1])+ log(v_layerWaterVapor1_[i-1]))/2.0);
     831             : 
     832           0 :       v_layerCO_[i-1] = v_layerCO_[i]*(v_layerPressure0_[i-1]/v_layerPressure0_[i]);
     833           0 :       v_layerO3_[i-1] = v_layerO3_[i]*(v_layerPressure0_[i-1]/v_layerPressure0_[i]);
     834           0 :       v_layerN2O_[i-1] = v_layerN2O_[i]*(v_layerPressure0_[i-1]/v_layerPressure0_[i]);
     835           0 :       v_layerNO2_[i-1] = v_layerNO2_[i]*(v_layerPressure0_[i-1]/v_layerPressure0_[i]);
     836           0 :       v_layerSO2_[i-1] = v_layerSO2_[i]*(v_layerPressure0_[i-1]/v_layerPressure0_[i]);
     837           0 :       v_layerHCl_[i-1] = v_layerHCl_[i]*(v_layerPressure0_[i-1]/v_layerPressure0_[i]);
     838           0 :       v_layerHCN_[i-1] = v_layerHCN_[i]*(v_layerPressure0_[i-1]/v_layerPressure0_[i]);
     839             :     }
     840             : 
     841           0 :     tropoLayer_ = tropoLayer_ + (v_layerThickness_.size()-numLayer_);
     842           0 :     numLayer_=v_layerThickness_.size();
     843             : 
     844             :   }else{
     845             :     //    std::cout << "extrapolar para arriba" << std::endl;
     846           0 :     double extraheight = fabs(groundaltitude.get(Length::UnitMeter)-altitude_.get(Length::UnitMeter));
     847           0 :     double cumulheight = 0.0;
     848             : 
     849             :     // std::cout << "before v_layerTemperature_.size()=" << v_layerTemperature_.size() << std::endl;
     850             : 
     851           0 :     for(unsigned int i=0; i<numLayer_; i++){
     852           0 :       cumulheight = cumulheight +  v_layerThickness_[i];
     853             :       // std::cout << i << " cumulheight = " << cumulheight <<  " extraheight= " << extraheight << std::endl;
     854           0 :       if (cumulheight>=extraheight) {
     855             : 
     856           0 :         double remainingheight = fabs(cumulheight-extraheight);
     857             :         // std::cout << "remainingheight = " <<  remainingheight << " m" << std::endl;
     858           0 :         v_layerThickness_.erase(v_layerThickness_.begin(),v_layerThickness_.begin()+i);
     859           0 :         v_layerThickness_[0] = remainingheight;
     860             : 
     861             : 
     862           0 :         v_layerTemperature0_.erase(v_layerTemperature0_.begin(),v_layerTemperature0_.begin()+i);
     863           0 :         v_layerTemperature1_.erase(v_layerTemperature1_.begin(),v_layerTemperature1_.begin()+i);
     864           0 :         v_layerTemperature_.erase(v_layerTemperature_.begin(),v_layerTemperature_.begin()+i);
     865           0 :         v_layerTemperature0_[0] = v_layerTemperature0_[1]-tropoLapseRate_*0.001*v_layerThickness_[0];
     866           0 :         v_layerTemperature_[0] = (v_layerTemperature0_[0]+v_layerTemperature1_[0])/2.0;
     867             : 
     868           0 :         v_layerPressure0_.erase(v_layerPressure0_.begin(),v_layerPressure0_.begin()+i);
     869             :         // std::cout << "v_layerPressure1_[0]=" << v_layerPressure1_[0] << " remainingheight=" << remainingheight << std::endl;
     870           0 :         v_layerPressure1_.erase(v_layerPressure1_.begin(),v_layerPressure1_.begin()+i);
     871           0 :         v_layerPressure_.erase(v_layerPressure_.begin(),v_layerPressure_.begin()+i);
     872           0 :         v_layerPressure0_[0] = v_layerPressure1_[0]* exp(-0.0341695 *
     873           0 :                                          (-remainingheight)/ v_layerTemperature_[0] );
     874           0 :         v_layerPressure_[0] = exp((log(v_layerPressure0_[0])+ log(v_layerPressure1_[0]))/2.0);
     875             : 
     876           0 :         v_layerWaterVapor0_.erase(v_layerWaterVapor0_.begin(),v_layerWaterVapor0_.begin()+i);
     877           0 :         v_layerWaterVapor1_.erase(v_layerWaterVapor1_.begin(),v_layerWaterVapor1_.begin()+i);
     878           0 :         v_layerWaterVapor_.erase(v_layerWaterVapor_.begin(),v_layerWaterVapor_.begin()+i);
     879           0 :         v_layerWaterVapor0_[0] = v_layerWaterVapor1_[0]*(v_layerPressure0_[0]/v_layerPressure1_[0]);
     880           0 :         v_layerWaterVapor_[0] = exp((log(v_layerWaterVapor0_[0])+ log(v_layerWaterVapor1_[0]))/2.0);
     881             : 
     882           0 :         v_layerCO_.erase(v_layerCO_.begin(),v_layerCO_.begin()+i);
     883           0 :         v_layerO3_.erase(v_layerO3_.begin(),v_layerO3_.begin()+i);
     884           0 :         v_layerN2O_.erase(v_layerN2O_.begin(),v_layerN2O_.begin()+i);
     885           0 :         v_layerNO2_.erase(v_layerNO2_.begin(),v_layerNO2_.begin()+i);
     886           0 :         v_layerSO2_.erase(v_layerSO2_.begin(),v_layerSO2_.begin()+i);
     887           0 :         v_layerHCl_.erase(v_layerHCl_.begin(),v_layerHCl_.begin()+i);
     888           0 :         v_layerHCN_.erase(v_layerHCN_.begin(),v_layerHCN_.begin()+i);
     889             : 
     890           0 :         tropoLayer_ = tropoLayer_ - i;
     891             : 
     892             :         // std::cout << "after v_layerTemperature_.size()=" << v_layerTemperature_.size() << std::endl;
     893           0 :         break;
     894             :       }
     895             :     }
     896             : 
     897           0 :     numLayer_ = v_layerThickness_.size();
     898             : 
     899             :   }
     900             : 
     901           0 :   altitude_ = groundaltitude;
     902           0 :   groundTemperature_ = v_layerTemperature0_[0];
     903             : 
     904             :   //  std::cout << "v_layerPressure0_[0]=" << v_layerPressure0_[0] << std::endl;
     905             : 
     906           0 :   groundPressure_ = v_layerPressure0_[0]*100.0;  // default units for Pressure are Pascals
     907             : 
     908             :   /*
     909             :   const Temperature Tdif(((true_antenna_altitude.get(Length::UnitKiloMeter)-altitude.get(Length::UnitKiloMeter))*tropoLapseRate),Temperature::UnitKelvin);
     910             :   groundTemperature_ = groundTemperature+Tdif;
     911             :   groundPressure_ = groundPressure * exp(-0.0341695 * pow((6.371/(6.371+altitude.get(Length::UnitKiloMeter))),2.0)
     912             :                                          * (true_antenna_altitude.get(Length::UnitMeter)-altitude.get(Length::UnitMeter))
     913             :                                          / ((groundTemperature.get(Temperature::UnitKelvin)+Tdif.get(Temperature::UnitKelvin))/2.0) );
     914             :   */
     915             : 
     916             : 
     917             : 
     918           0 : }
     919             : 
     920           0 : void AtmProfile::setLayerTemperature(unsigned int i, const Temperature &layerTemperature)
     921             : {
     922           0 :   if(i < v_layerTemperature_.size()) {
     923           0 :     v_layerTemperature_[i] = layerTemperature.get(Temperature::UnitKelvin);
     924             :   }
     925           0 : }
     926             : 
     927           0 : vector<Length> AtmProfile::getThicknessProfile() const
     928             : {
     929           0 :   vector<Length> l;
     930           0 :   l.reserve(v_layerThickness_.size());
     931           0 :   for(unsigned int i = 0; i < v_layerThickness_.size(); i++) {
     932           0 :     Length ll(v_layerThickness_[i], Length::UnitMeter);
     933           0 :     l.push_back(ll);
     934           0 :   }
     935           0 :   return l;
     936           0 : }
     937             : 
     938        4270 : Length AtmProfile::getLayerThickness(unsigned int i) const
     939             : {
     940             :   /*if(i > v_layerThickness_.size() - 1) {
     941             :     Length l(-999.0, Length::UnitMeter);
     942             :     return l;
     943             :   } else {
     944             :     Length l(v_layerThickness_[i], Length::UnitMeter);
     945             :     return l;
     946             :   }*/
     947        4270 :   if(i > v_layerThickness_.size() - 1) {
     948           0 :     std::ostringstream oss;
     949           0 :     oss << "Not a valid layer: " << i;
     950           0 :     throw AtmException(ATM_EXCEPTION_ARGS(oss.str().c_str()));
     951           0 :   }
     952        4270 :   return Length(v_layerThickness_[i], Length::UnitMeter);
     953             : }
     954             : 
     955           0 : Length AtmProfile::getLayerBottomHeightAboveGround(unsigned int i) const
     956             : {
     957           0 :   if(i > v_layerThickness_.size() - 1) {
     958           0 :     std::ostringstream oss;
     959           0 :     oss << "Not a valid layer: " << i;
     960           0 :     throw AtmException(ATM_EXCEPTION_ARGS(oss.str().c_str()));
     961           0 :   }
     962           0 :   double h=0.0;
     963           0 :   for(unsigned int j = 0; j < i; j++) {
     964           0 :     h = h + v_layerThickness_[j];
     965             :   }
     966           0 :   return Length(h, Length::UnitMeter);
     967             : }
     968             : 
     969           0 : Length AtmProfile::getLayerTopHeightAboveGround(unsigned int i) const
     970             : {
     971           0 :   if(i > v_layerThickness_.size() - 1) {
     972           0 :     std::ostringstream oss;
     973           0 :     oss << "Not a valid layer: " << i;
     974           0 :     throw AtmException(ATM_EXCEPTION_ARGS(oss.str().c_str()));
     975           0 :   }
     976           0 :   double h=0.0;
     977           0 :   for(unsigned int j = 0; j < i+1; j++) {
     978           0 :     h = h + v_layerThickness_[j];
     979             :   }
     980           0 :   return Length(h, Length::UnitMeter);
     981             : }
     982             : 
     983           0 : Length AtmProfile::getLayerBottomHeightAboveSeaLevel(unsigned int i) const
     984             : {
     985           0 :   if(i > v_layerThickness_.size() - 1) {
     986           0 :     std::ostringstream oss;
     987           0 :     oss << "Not a valid layer: " << i;
     988           0 :     throw AtmException(ATM_EXCEPTION_ARGS(oss.str().c_str()));
     989           0 :   }
     990           0 :   double h=altitude_.get(Length::UnitMeter);
     991           0 :   for(unsigned int j = 0; j < i; j++) {
     992           0 :     h = h + v_layerThickness_[j];
     993             :   }
     994           0 :   return Length(h, Length::UnitMeter);
     995             : }
     996             : 
     997           0 : Length AtmProfile::getLayerTopHeightAboveSeaLevel(unsigned int i) const
     998             : {
     999           0 :   if(i > v_layerThickness_.size() - 1) {
    1000           0 :     std::ostringstream oss;
    1001           0 :     oss << "Not a valid layer: " << i;
    1002           0 :     throw AtmException(ATM_EXCEPTION_ARGS(oss.str().c_str()));
    1003           0 :   }
    1004           0 :   double h=altitude_.get(Length::UnitMeter);
    1005           0 :   for(unsigned int j = 0; j < i+1; j++) {
    1006           0 :     h = h + v_layerThickness_[j];
    1007             :   }
    1008           0 :   return Length(h, Length::UnitMeter);
    1009             : }
    1010             : 
    1011             : 
    1012           0 : void AtmProfile::setLayerThickness(unsigned int i, const Length &layerThickness)
    1013             : {
    1014           0 :   if(i < v_layerThickness_.size()) {
    1015           0 :     v_layerThickness_[i] = layerThickness.get(Length::UnitMeter);
    1016             :   }
    1017           0 : }
    1018             : 
    1019         112 : MassDensity AtmProfile::getLayerWaterVaporMassDensity(unsigned int i) const
    1020             : {
    1021             :   /*if(i > v_layerWaterVapor_.size() - 1) {
    1022             :     MassDensity m(-999.0, MassDensity::UnitKiloGramPerCubicMeter);
    1023             :     return m;
    1024             :   } else {
    1025             :     MassDensity m(v_layerWaterVapor_[i], MassDensity::UnitKiloGramPerCubicMeter);
    1026             :     return m;
    1027             :   }*/
    1028         112 :   if(i > v_layerWaterVapor_.size() - 1) {
    1029           0 :     std::ostringstream oss;
    1030           0 :     oss << "Not a valid layer: " << i;
    1031           0 :     throw AtmException(ATM_EXCEPTION_ARGS(oss.str().c_str()));
    1032           0 :   }
    1033         112 :   return MassDensity(v_layerWaterVapor_[i], MassDensity::UnitKiloGramPerCubicMeter);
    1034             : }
    1035           0 : MassDensity AtmProfile::getLayerBottomWaterVaporMassDensity(unsigned int i) const
    1036             : {
    1037           0 :   if(i > v_layerWaterVapor0_.size() - 1) {
    1038           0 :     std::ostringstream oss;
    1039           0 :     oss << "Not a valid layer: " << i;
    1040           0 :     throw AtmException(ATM_EXCEPTION_ARGS(oss.str().c_str()));
    1041           0 :   }
    1042           0 :   return MassDensity(v_layerWaterVapor0_[i], MassDensity::UnitKiloGramPerCubicMeter);
    1043             : }
    1044           0 : MassDensity AtmProfile::getLayerTopWaterVaporMassDensity(unsigned int i) const
    1045             : {
    1046           0 :   if(i > v_layerWaterVapor1_.size() - 1) {
    1047           0 :     std::ostringstream oss;
    1048           0 :     oss << "Not a valid layer: " << i;
    1049           0 :     throw AtmException(ATM_EXCEPTION_ARGS(oss.str().c_str()));
    1050           0 :   }
    1051           0 :   return MassDensity(v_layerWaterVapor1_[i], MassDensity::UnitKiloGramPerCubicMeter);
    1052             : }
    1053             : 
    1054         112 : NumberDensity AtmProfile::getLayerWaterVaporNumberDensity(unsigned int i) const
    1055             : {
    1056             :   /*if(i > v_layerWaterVapor_.size() - 1) {
    1057             :     NumberDensity m(-999.0, NumberDensity::UnitInverseCubicMeter);
    1058             :     return m;
    1059             :   } else {
    1060             :     NumberDensity
    1061             :         m(v_layerWaterVapor_[i] * 6.023e23 * 1000.0 / 18.0, NumberDensity::UnitInverseCubicMeter);
    1062             :     return m;
    1063             :   }*/
    1064         112 :   if(i > v_layerWaterVapor_.size() - 1) {
    1065           0 :     std::ostringstream oss;
    1066           0 :     oss << "Not a valid layer: " << i;
    1067           0 :     throw AtmException(ATM_EXCEPTION_ARGS(oss.str().c_str()));
    1068           0 :   }
    1069         112 :   return NumberDensity(v_layerWaterVapor_[i] * 6.023e23 * 1000.0 / 18.0, NumberDensity::UnitInverseCubicMeter);
    1070             : }
    1071           0 : NumberDensity AtmProfile::getLayerBottomWaterVaporNumberDensity(unsigned int i) const
    1072             : {
    1073           0 :   if(i > v_layerWaterVapor0_.size() - 1) {
    1074           0 :     std::ostringstream oss;
    1075           0 :     oss << "Not a valid layer: " << i;
    1076           0 :     throw AtmException(ATM_EXCEPTION_ARGS(oss.str().c_str()));
    1077           0 :   }
    1078           0 :   return NumberDensity(v_layerWaterVapor0_[i] * 6.023e23 * 1000.0 / 18.0, NumberDensity::UnitInverseCubicMeter);
    1079             : }
    1080           0 : NumberDensity AtmProfile::getLayerTopWaterVaporNumberDensity(unsigned int i) const
    1081             : {
    1082           0 :   if(i > v_layerWaterVapor1_.size() - 1) {
    1083           0 :     std::ostringstream oss;
    1084           0 :     oss << "Not a valid layer: " << i;
    1085           0 :     throw AtmException(ATM_EXCEPTION_ARGS(oss.str().c_str()));
    1086           0 :   }
    1087           0 :   return NumberDensity(v_layerWaterVapor1_[i] * 6.023e23 * 1000.0 / 18.0, NumberDensity::UnitInverseCubicMeter);
    1088             : }
    1089             : 
    1090           0 : void AtmProfile::setLayerWaterVaporMassDensity(unsigned int i, const MassDensity &layerWaterVapor)
    1091             : {
    1092           0 :   if(i <= v_layerWaterVapor_.size() - 1) {
    1093           0 :     v_layerWaterVapor_[i] = layerWaterVapor.get(MassDensity::UnitKiloGramPerCubicMeter);
    1094             :   }
    1095           0 : }
    1096             : 
    1097           0 : void AtmProfile::setLayerWaterVaporNumberDensity(unsigned int i, const NumberDensity &layerWaterVapor)
    1098             : {
    1099           0 :   if(i <= v_layerWaterVapor_.size() - 1) {
    1100           0 :     v_layerWaterVapor_[i] = layerWaterVapor.get(NumberDensity::UnitInverseCubicMeter) * 18.0 / (6.023e23 * 1000.0);
    1101             :   }
    1102           0 : }
    1103             : 
    1104           0 : vector<Pressure> AtmProfile::getPressureProfile() const
    1105             : {
    1106           0 :   vector<Pressure> p;
    1107           0 :   p.reserve(v_layerPressure_.size());
    1108           0 :   for(unsigned int i = 0; i < v_layerPressure_.size(); i++) {
    1109           0 :     Pressure pp(v_layerPressure_[i], Pressure::UnitMilliBar);
    1110           0 :     p.push_back(pp);
    1111           0 :   }
    1112           0 :   return p;
    1113           0 : }
    1114             : 
    1115        3336 : Pressure AtmProfile::getLayerPressure(unsigned int i) const
    1116             : {
    1117             :   /*if(i > v_layerPressure_.size() - 1) {
    1118             :     Pressure p(-999.0, Pressure::UnitMilliBar);
    1119             :     return p;
    1120             :   } else {
    1121             :     Pressure p(v_layerPressure_[i], Pressure::UnitMilliBar);
    1122             :     return p;
    1123             :   }*/
    1124        3336 :   if(i > v_layerPressure_.size() - 1) {
    1125           0 :     std::ostringstream oss;
    1126           0 :     oss << "Not a valid layer: " << i;
    1127           0 :     throw AtmException(ATM_EXCEPTION_ARGS(oss.str().c_str()));
    1128           0 :   }
    1129        3336 :   return Pressure(v_layerPressure_[i], Pressure::UnitMilliBar);
    1130             : }
    1131             : 
    1132           0 : Pressure AtmProfile::getLayerBottomPressure(unsigned int i) const
    1133             : {
    1134           0 :   if(i > v_layerPressure0_.size() - 1) {
    1135           0 :     std::ostringstream oss;
    1136           0 :     oss << "Not a valid layer: " << i;
    1137           0 :     throw AtmException(ATM_EXCEPTION_ARGS(oss.str().c_str()));
    1138           0 :   }
    1139           0 :   return Pressure(v_layerPressure0_[i], Pressure::UnitMilliBar);
    1140             : }
    1141             : 
    1142           0 : Pressure AtmProfile::getLayerTopPressure(unsigned int i) const
    1143             : {
    1144           0 :   if(i > v_layerPressure1_.size() - 1) {
    1145           0 :     std::ostringstream oss;
    1146           0 :     oss << "Not a valid layer: " << i;
    1147           0 :     throw AtmException(ATM_EXCEPTION_ARGS(oss.str().c_str()));
    1148           0 :   }
    1149           0 :   return Pressure(v_layerPressure1_[i], Pressure::UnitMilliBar);
    1150             : }
    1151             : 
    1152             : 
    1153       11507 : Length AtmProfile::getGroundWH2O() const
    1154             : {
    1155       11507 :   double wm = 0;
    1156      347535 :   for(unsigned int j = 0; j < numLayer_; j++) {
    1157      336028 :     wm = wm + v_layerWaterVapor_[j] * v_layerThickness_[j]; // kg/m**2 or mm (from m*kg/m**3 IS units)
    1158             :   }
    1159       11507 :   wm = wm * 1e-3; // (pasar de mm a m)
    1160       11507 :   Length wh2o(wm);
    1161       11507 :   return wh2o;
    1162             : }
    1163             : 
    1164         125 : MassDensity AtmProfile::rwat(const Temperature &tt, const Humidity &rh, const Pressure &pp) const
    1165             : {
    1166         125 :   double t = tt.get(Temperature::UnitKelvin);
    1167         125 :   double p = pp.get(Pressure::UnitMilliBar);
    1168         125 :   double u = rh.get(Percent::UnitPercent);
    1169             :   double e, es, rwat0;
    1170             : 
    1171         125 :   if(p <= 0 || t <= 0 || u <= 0) {
    1172           0 :     return MassDensity(0.0, MassDensity::UnitGramPerCubicMeter);
    1173             :   } else {
    1174         125 :     es = 6.105 * exp(25.22 / t * (t - 273.0) - 5.31 * log(t / 273.0));
    1175         125 :     e = 1.0 - (1.0 - u / 100.0) * es / p;
    1176         125 :     e = es * u / 100.0 / e;
    1177         125 :     rwat0 = e * 216.502 / t; //(en g/m*3)
    1178             :   }
    1179         125 :   return MassDensity(rwat0, MassDensity::UnitGramPerCubicMeter);
    1180             : }
    1181             : 
    1182           0 : Humidity AtmProfile::rwat_inv(const Temperature &tt, const MassDensity &dd, const Pressure &pp) const
    1183             : {
    1184           0 :   double p = pp.get(Pressure::UnitMilliBar);
    1185           0 :   double t = tt.get(Temperature::UnitKelvin);
    1186           0 :   double r = dd.get(MassDensity::UnitGramPerCubicMeter);
    1187             :   double es, e, rinv;
    1188             : 
    1189           0 :   if(p <= 0 || t <= 0 || r <= 0) {
    1190           0 :     rinv = 0.0;
    1191             :   } else {
    1192           0 :     es = 6.105 * exp(25.22 / t * (t - 273.0) - 5.31 * log(t / 273.0));
    1193           0 :     e = r * t / 216.502;
    1194           0 :     rinv = 100 * (e * (p - es) / (es * (p - e)));
    1195           0 :     if(rinv < 0 && p < 3) rinv = 0.0;
    1196             :   }
    1197           0 :   return Humidity(rinv, Percent::UnitPercent);
    1198             : }
    1199             : 
    1200        3448 : vector<NumberDensity> AtmProfile::st76(const Length &h, unsigned int tip, unsigned int seasonal_diurnal) const
    1201             : {
    1202             :   unsigned int i1, i2, i3, i_layer;
    1203             :   double x1, x2, x3, d;
    1204        3448 :   vector<NumberDensity> minorden;
    1205        3448 :   NumberDensity o3den, n2oden, coden, no2den, so2den, hclden, hcnden;
    1206             :   static const double avogad = 6.022045E+23;
    1207             :   static const double airmwt = 28.964;
    1208             :   //    static const double h2omwt=18.015;
    1209        3448 :   double ha = h.get(Length::UnitKiloMeter);
    1210             :   // std::cout << "tip = " << tip << std::endl;
    1211             :   // if (tip > 10)  {seasonal_diurnal=tip-10; tip=1;}else{seasonal_diurnal=0;}
    1212             :   // std::cout << "in st76 seasonal_diurnal,tip = " << seasonal_diurnal << "," << tip << std::endl;
    1213             :   static const double
    1214             :       alt[50] = { 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0,
    1215             :                   13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0,
    1216             :                   24.0, 25.0, 27.5, 30.0, 32.5, 35.0, 37.5, 40.0, 42.5, 45.0, 47.5,
    1217             :                   50.0, 55.0, 60.0, 65.0, 70.0, 75.0, 80.0, 85.0, 90.0, 95.0, 100.0,
    1218             :                   105.0, 110.0, 115.0, 120.0 };     // REFERENCE LEVELS IN KM
    1219             : 
    1220             :   static const double
    1221             :       ozone[6][50] = { { 2.869E-02, 3.150E-02, 3.342E-02, 3.504E-02, 3.561E-02, 3.767E-02, 3.989E-02, 4.223E-02,
    1222             :                          4.471E-02, 5.000E-02, 5.595E-02, 6.613E-02, 7.815E-02, 9.289E-02, 1.050E-01, 1.256E-01,
    1223             :                          1.444E-01, 2.500E-01, 5.000E-01, 9.500E-01, 1.400E+00, 1.800E+00, 2.400E+00, 3.400E+00,
    1224             :                          4.300E+00, 5.400E+00, 7.800E+00, 9.300E+00, 9.850E+00, 9.700E+00, 8.800E+00, 7.500E+00,
    1225             :                          5.900E+00, 4.500E+00, 3.450E+00, 2.800E+00, 1.800E+00, 1.100E+00, 6.500E-01, 3.000E-01,
    1226             :                          1.800E-01, 3.300E-01, 5.000E-01, 5.200E-01, 5.000E-01, 4.000E-01, 2.000E-01, 5.000E-02,
    1227             :                          5.000E-03, 5.000E-04 },
    1228             :                        { 3.017E-02, 3.337E-02, 3.694E-02, 4.222E-02, 4.821E-02, 5.512E-02, 6.408E-02, 7.764E-02,
    1229             :                          9.126E-02, 1.111E-01, 1.304E-01, 1.793E-01, 2.230E-01, 3.000E-01, 4.400E-01, 5.000E-01,
    1230             :                          6.000E-01, 7.000E-01, 1.000E+00, 1.500E+00, 2.000E+00, 2.400E+00, 2.900E+00, 3.400E+00,
    1231             :                          4.000E+00, 4.800E+00, 6.000E+00, 7.000E+00, 8.100E+00, 8.900E+00, 8.700E+00, 7.550E+00,
    1232             :                          5.900E+00, 4.500E+00, 3.500E+00, 2.800E+00, 1.800E+00, 1.300E+00, 8.000E-01, 4.000E-01,
    1233             :                          1.900E-01, 2.000E-01, 5.700E-01, 7.500E-01, 7.000E-01, 4.000E-01, 2.000E-01, 5.000E-02,
    1234             :                          5.000E-03, 5.000E-04 },
    1235             :                        { 2.778E-02, 2.800E-02, 2.849E-02, 3.200E-02, 3.567E-02, 4.720E-02, 5.837E-02, 7.891E-02,
    1236             :                          1.039E-01, 1.567E-01, 2.370E-01, 3.624E-01, 5.232E-01, 7.036E-01, 8.000E-01, 9.000E-01,
    1237             :                          1.100E+00, 1.400E+00, 1.800E+00, 2.300E+00, 2.900E+00, 3.500E+00, 3.900E+00, 4.300E+00,
    1238             :                          4.700E+00, 5.100E+00, 5.600E+00, 6.100E+00, 6.800E+00, 7.100E+00, 7.200E+00, 6.900E+00,
    1239             :                          5.900E+00, 4.600E+00, 3.700E+00, 2.750E+00, 1.700E+00, 1.000E-00, 5.500E-01, 3.200E-01,
    1240             :                          2.500E-01, 2.300E-01, 5.500E-01, 8.000E-01, 8.000E-01, 4.000E-01, 2.000E-01, 5.000E-02,
    1241             :                          5.000E-03, 5.000E-04 },
    1242             :                        { 2.412E-02, 2.940E-02, 3.379E-02, 3.887E-02, 4.478E-02, 5.328E-02, 6.564E-02, 7.738E-02,
    1243             :                          9.114E-02, 1.420E-01, 1.890E-01, 3.050E-01, 4.100E-01, 5.000E-01, 6.000E-01, 7.000E-01,
    1244             :                          8.500E-01, 1.000E+00, 1.300E+00, 1.700E+00, 2.100E+00, 2.700E+00, 3.300E+00, 3.700E+00,
    1245             :                          4.200E+00, 4.500E+00, 5.300E+00, 5.700E+00, 6.900E+00, 7.700E+00, 7.800E+00, 7.000E+00,
    1246             :                          5.400E+00, 4.200E+00, 3.200E+00, 2.500E+00, 1.700E+00, 1.200E+00, 8.000E-01, 4.000E-01,
    1247             :                          2.000E-01, 1.800E-01, 6.500E-01, 9.000E-01, 8.000E-01, 4.000E-01, 2.000E-01, 5.000E-02,
    1248             :                          5.000E-03, 5.000E-04 },
    1249             :                        { 1.802E-02, 2.072E-02, 2.336E-02, 2.767E-02, 3.253E-02, 3.801E-02, 4.446E-02, 7.252E-02,
    1250             :                          1.040E-01, 2.100E-01, 3.000E-01, 3.500E-01, 4.000E-01, 6.500E-01, 9.000E-01, 1.200E+00,
    1251             :                          1.500E+00, 1.900E+00, 2.450E+00, 3.100E+00, 3.700E+00, 4.000E+00, 4.200E+00, 4.500E+00,
    1252             :                          4.600E+00, 4.700E+00, 4.900E+00, 5.400E+00, 5.900E+00, 6.200E+00, 6.250E+00, 5.900E+00,
    1253             :                          5.100E+00, 4.100E+00, 3.000E+00, 2.600E+00, 1.600E+00, 9.500E-01, 6.500E-01, 5.000E-01,
    1254             :                          3.300E-01, 1.300E-01, 7.500E-01, 8.000E-01, 8.000E-01, 4.000E-01, 2.000E-01, 5.000E-02,
    1255             :                          5.000E-03, 5.000E-04 },
    1256             :                        { 2.660E-02, 2.931E-02, 3.237E-02, 3.318E-02, 3.387E-02, 3.768E-02, 4.112E-02, 5.009E-02,
    1257             :                          5.966E-02, 9.168E-02, 1.313E-01, 2.149E-01, 3.095E-01, 3.846E-01, 5.030E-01, 6.505E-01,
    1258             :                          8.701E-01, 1.187E+00, 1.587E+00, 2.030E+00, 2.579E+00, 3.028E+00, 3.647E+00, 4.168E+00,
    1259             :                          4.627E+00, 5.118E+00, 5.803E+00, 6.553E+00, 7.373E+00, 7.837E+00, 7.800E+00, 7.300E+00,
    1260             :                          6.200E+00, 5.250E+00, 4.100E+00, 3.100E+00, 1.800E+00, 1.100E+00, 7.000E-01, 3.000E-01,
    1261             :                          2.500E-01, 3.000E-01, 5.000E-01, 7.000E-01, 7.000E-01, 4.000E-01, 2.000E-01, 5.000E-02,
    1262             :                          5.000E-03, 5.000E-04 } };
    1263             : 
    1264             :   static const double
    1265             :       n2o[6][50] = { { 3.200E-01, 3.200E-01, 3.200E-01, 3.200E-01, 3.200E-01, 3.200E-01, 3.200E-01, 3.200E-01,
    1266             :                        3.200E-01, 3.195E-01, 3.179E-01, 3.140E-01, 3.095E-01, 3.048E-01, 2.999E-01, 2.944E-01,
    1267             :                        2.877E-01, 2.783E-01, 2.671E-01, 2.527E-01, 2.365E-01, 2.194E-01, 2.051E-01, 1.967E-01,
    1268             :                        1.875E-01, 1.756E-01, 1.588E-01, 1.416E-01, 1.165E-01, 9.275E-02, 6.693E-02, 4.513E-02,
    1269             :                        2.751E-02, 1.591E-02, 9.378E-03, 4.752E-03, 3.000E-03, 2.065E-03, 1.507E-03, 1.149E-03,
    1270             :                        8.890E-04, 7.056E-04, 5.716E-04, 4.708E-04, 3.932E-04, 3.323E-04, 2.837E-04, 2.443E-04,
    1271             :                        2.120E-04, 1.851E-04 },
    1272             :                      { 3.200E-01, 3.200E-01, 3.200E-01, 3.200E-01, 3.200E-01, 3.200E-01, 3.200E-01, 3.200E-01,
    1273             :                        3.195E-01, 3.163E-01, 3.096E-01, 2.989E-01, 2.936E-01, 2.860E-01, 2.800E-01, 2.724E-01,
    1274             :                        2.611E-01, 2.421E-01, 2.174E-01, 1.843E-01, 1.607E-01, 1.323E-01, 1.146E-01, 1.035E-01,
    1275             :                        9.622E-02, 8.958E-02, 8.006E-02, 6.698E-02, 4.958E-02, 3.695E-02, 2.519E-02, 1.736E-02,
    1276             :                        1.158E-02, 7.665E-03, 5.321E-03, 3.215E-03, 2.030E-03, 1.397E-03, 1.020E-03, 7.772E-04,
    1277             :                        6.257E-04, 5.166E-04, 4.352E-04, 3.727E-04, 3.237E-04, 2.844E-04, 2.524E-04, 2.260E-04,
    1278             :                        2.039E-04, 1.851E-04 },
    1279             :                      { 3.200E-01, 3.200E-01, 3.200E-01, 3.200E-01, 3.200E-01, 3.200E-01, 3.200E-01, 3.200E-01,
    1280             :                        3.195E-01, 3.163E-01, 3.096E-01, 2.989E-01, 2.936E-01, 2.860E-01, 2.800E-01, 2.724E-01,
    1281             :                        2.611E-01, 2.421E-01, 2.174E-01, 1.843E-01, 1.621E-01, 1.362E-01, 1.230E-01, 1.124E-01,
    1282             :                        1.048E-01, 9.661E-02, 8.693E-02, 7.524E-02, 6.126E-02, 5.116E-02, 3.968E-02, 2.995E-02,
    1283             :                        2.080E-02, 1.311E-02, 8.071E-03, 4.164E-03, 2.629E-03, 1.809E-03, 1.321E-03, 1.007E-03,
    1284             :                        7.883E-04, 6.333E-04, 5.194E-04, 4.333E-04, 3.666E-04, 3.140E-04, 2.717E-04, 2.373E-04,
    1285             :                        2.089E-04, 1.851E-04 },
    1286             :                      { 3.100E-01, 3.100E-01, 3.100E-01, 3.100E-01, 3.079E-01, 3.024E-01, 2.906E-01, 2.822E-01,
    1287             :                        2.759E-01, 2.703E-01, 2.651E-01, 2.600E-01, 2.549E-01, 2.494E-01, 2.433E-01, 2.355E-01,
    1288             :                        2.282E-01, 2.179E-01, 2.035E-01, 1.817E-01, 1.567E-01, 1.350E-01, 1.218E-01, 1.102E-01,
    1289             :                        9.893E-02, 8.775E-02, 7.327E-02, 5.941E-02, 4.154E-02, 3.032E-02, 1.949E-02, 1.274E-02,
    1290             :                        9.001E-03, 6.286E-03, 4.558E-03, 2.795E-03, 1.765E-03, 1.214E-03, 8.866E-04, 6.756E-04,
    1291             :                        5.538E-04, 4.649E-04, 3.979E-04, 3.459E-04, 3.047E-04, 2.713E-04, 2.439E-04, 2.210E-04,
    1292             :                        2.017E-04, 1.851E-04 },
    1293             :                      { 3.200E-01, 3.200E-01, 3.200E-01, 3.200E-01, 3.200E-01, 3.200E-01, 3.200E-01, 3.200E-01,
    1294             :                        3.195E-01, 3.163E-01, 3.096E-01, 2.989E-01, 2.936E-01, 2.860E-01, 2.800E-01, 2.724E-01,
    1295             :                        2.611E-01, 2.421E-01, 2.174E-01, 1.843E-01, 1.621E-01, 1.362E-01, 1.230E-01, 1.122E-01,
    1296             :                        1.043E-01, 9.570E-02, 8.598E-02, 7.314E-02, 5.710E-02, 4.670E-02, 3.439E-02, 2.471E-02,
    1297             :                        1.631E-02, 1.066E-02, 7.064E-03, 3.972E-03, 2.508E-03, 1.726E-03, 1.260E-03, 9.602E-04,
    1298             :                        7.554E-04, 6.097E-04, 5.024E-04, 4.210E-04, 3.579E-04, 3.080E-04, 2.678E-04, 2.350E-04,
    1299             :                        2.079E-04, 1.851E-04 },
    1300             :                      { 3.200E-01, 3.200E-01, 3.200E-01, 3.200E-01, 3.200E-01, 3.200E-01, 3.200E-01, 3.200E-01,
    1301             :                        3.200E-01, 3.195E-01, 3.179E-01, 3.140E-01, 3.095E-01, 3.048E-01, 2.999E-01, 2.944E-01,
    1302             :                        2.877E-01, 2.783E-01, 2.671E-01, 2.527E-01, 2.365E-01, 2.194E-01, 2.051E-01, 1.967E-01,
    1303             :                        1.875E-01, 1.756E-01, 1.588E-01, 1.416E-01, 1.165E-01, 9.275E-02, 6.693E-02, 4.513E-02,
    1304             :                        2.751E-02, 1.591E-02, 9.378E-03, 4.752E-03, 3.000E-03, 2.065E-03, 1.507E-03, 1.149E-03,
    1305             :                        8.890E-04, 7.056E-04, 5.716E-04, 4.708E-04, 3.932E-04, 3.323E-04, 2.837E-04, 2.443E-04,
    1306             :                        2.120E-04, 1.851E-04 } };
    1307             : 
    1308             :   static const double
    1309             :       co[6][50] = { { 1.500E-01, 1.450E-01, 1.399E-01, 1.349E-01, 1.312E-01, 1.303E-01, 1.288E-01, 1.247E-01,
    1310             :                       1.185E-01, 1.094E-01, 9.962E-02, 8.964E-02, 7.814E-02, 6.374E-02, 5.025E-02, 3.941E-02,
    1311             :                       3.069E-02, 2.489E-02, 1.966E-02, 1.549E-02, 1.331E-02, 1.232E-02, 1.232E-02, 1.307E-02,
    1312             :                       1.400E-02, 1.521E-02, 1.722E-02, 1.995E-02, 2.266E-02, 2.487E-02, 2.738E-02, 3.098E-02,
    1313             :                       3.510E-02, 3.987E-02, 4.482E-02, 5.092E-02, 5.985E-02, 6.960E-02, 9.188E-02, 1.938E-01,
    1314             :                       5.688E-01, 1.549E+00, 3.849E+00, 6.590E+00, 1.044E+01, 1.705E+01, 2.471E+01, 3.358E+01,
    1315             :                       4.148E+01, 5.000E+01 },
    1316             :                     { 1.500E-01, 1.450E-01, 1.399E-01, 1.349E-01, 1.312E-01, 1.303E-01, 1.288E-01, 1.247E-01,
    1317             :                       1.185E-01, 1.094E-01, 9.962E-02, 8.964E-02, 7.814E-02, 6.374E-02, 5.025E-02, 3.941E-02,
    1318             :                       3.069E-02, 2.489E-02, 1.966E-02, 1.549E-02, 1.331E-02, 1.232E-02, 1.232E-02, 1.307E-02,
    1319             :                       1.400E-02, 1.521E-02, 1.722E-02, 1.995E-02, 2.266E-02, 2.487E-02, 2.716E-02, 2.962E-02,
    1320             :                       3.138E-02, 3.307E-02, 3.487E-02, 3.645E-02, 3.923E-02, 4.673E-02, 6.404E-02, 1.177E-01,
    1321             :                       2.935E-01, 6.815E-01, 1.465E+00, 2.849E+00, 5.166E+00, 1.008E+01, 1.865E+01, 2.863E+01,
    1322             :                       3.890E+01, 5.000E+01 },
    1323             :                     { 1.500E-01, 1.450E-01, 1.399E-01, 1.349E-01, 1.312E-01, 1.303E-01, 1.288E-01, 1.247E-01,
    1324             :                       1.185E-01, 1.094E-01, 9.962E-02, 8.964E-02, 7.814E-02, 6.374E-02, 5.025E-02, 3.941E-02,
    1325             :                       3.069E-02, 2.489E-02, 1.966E-02, 1.549E-02, 1.331E-02, 1.232E-02, 1.232E-02, 1.307E-02,
    1326             :                       1.400E-02, 1.498E-02, 1.598E-02, 1.710E-02, 1.850E-02, 1.997E-02, 2.147E-02, 2.331E-02,
    1327             :                       2.622E-02, 3.057E-02, 3.803E-02, 6.245E-02, 1.480E-01, 2.926E-01, 5.586E-01, 1.078E+00,
    1328             :                       1.897E+00, 2.960E+00, 4.526E+00, 6.862E+00, 1.054E+01, 1.709E+01, 2.473E+01, 3.359E+01,
    1329             :                       4.149E+01, 5.000E+01 },
    1330             :                     { 1.500E-01, 1.450E-01, 1.399E-01, 1.349E-01, 1.312E-01, 1.303E-01, 1.288E-01, 1.247E-01,
    1331             :                       1.185E-01, 1.094E-01, 9.962E-02, 8.964E-02, 7.814E-02, 6.374E-02, 5.025E-02, 3.941E-02,
    1332             :                       3.069E-02, 2.489E-02, 1.966E-02, 1.549E-02, 1.331E-02, 1.232E-02, 1.232E-02, 1.307E-02,
    1333             :                       1.400E-02, 1.510E-02, 1.649E-02, 1.808E-02, 1.997E-02, 2.183E-02, 2.343E-02, 2.496E-02,
    1334             :                       2.647E-02, 2.809E-02, 2.999E-02, 3.220E-02, 3.650E-02, 4.589E-02, 6.375E-02, 1.176E-01,
    1335             :                       3.033E-01, 7.894E-01, 1.823E+00, 3.402E+00, 5.916E+00, 1.043E+01, 1.881E+01, 2.869E+01,
    1336             :                       3.892E+01, 5.000E+01 },
    1337             :                     { 1.500E-01, 1.450E-01, 1.399E-01, 1.349E-01, 1.312E-01, 1.303E-01, 1.288E-01, 1.247E-01,
    1338             :                       1.185E-01, 1.094E-01, 9.962E-02, 8.964E-02, 7.814E-02, 6.374E-02, 5.025E-02, 3.941E-02,
    1339             :                       3.069E-02, 2.489E-02, 1.966E-02, 1.549E-02, 1.331E-02, 1.232E-02, 1.232E-02, 1.307E-02,
    1340             :                       1.400E-02, 1.521E-02, 1.722E-02, 2.037E-02, 2.486E-02, 3.168E-02, 4.429E-02, 6.472E-02,
    1341             :                       1.041E-01, 1.507E-01, 2.163E-01, 3.141E-01, 4.842E-01, 7.147E-01, 1.067E+00, 1.516E+00,
    1342             :                       2.166E+00, 3.060E+00, 4.564E+00, 6.877E+00, 1.055E+01, 1.710E+01, 2.473E+01, 3.359E+01,
    1343             :                       4.149E+01, 5.000E+01 },
    1344             :                     { 1.500E-01, 1.450E-01, 1.399E-01, 1.349E-01, 1.312E-01, 1.303E-01, 1.288E-01, 1.247E-01,
    1345             :                       1.185E-01, 1.094E-01, 9.962E-02, 8.964E-02, 7.814E-02, 6.374E-02, 5.025E-02, 3.941E-02,
    1346             :                       3.069E-02, 2.489E-02, 1.966E-02, 1.549E-02, 1.331E-02, 1.232E-02, 1.232E-02, 1.307E-02,
    1347             :                       1.400E-02, 1.498E-02, 1.598E-02, 1.710E-02, 1.850E-02, 2.009E-02, 2.220E-02, 2.497E-02,
    1348             :                       2.824E-02, 3.241E-02, 3.717E-02, 4.597E-02, 6.639E-02, 1.073E-01, 1.862E-01, 3.059E-01,
    1349             :                       6.375E-01, 1.497E+00, 3.239E+00, 5.843E+00, 1.013E+01, 1.692E+01, 2.467E+01, 3.356E+01,
    1350             :                       4.148E+01, 5.000E+01 } };
    1351             : 
    1352             :   static const double
    1353             :       den[6][50] = { { 2.450E+19, 2.231E+19, 2.028E+19, 1.827E+19, 1.656E+19, 1.499E+19, 1.353E+19, 1.218E+19,
    1354             :                        1.095E+19, 9.789E+18, 8.747E+18, 7.780E+18, 6.904E+18, 6.079E+18, 5.377E+18, 4.697E+18,
    1355             :                        4.084E+18, 3.486E+18, 2.877E+18, 2.381E+18, 1.981E+18, 1.651E+18, 1.381E+18, 1.169E+18,
    1356             :                        9.920E+17, 8.413E+17, 5.629E+17, 3.807E+17, 2.598E+17, 1.789E+17, 1.243E+17, 8.703E+16,
    1357             :                        6.147E+16, 4.352E+16, 3.119E+16, 2.291E+16, 1.255E+16, 6.844E+15, 3.716E+15, 1.920E+15,
    1358             :                        9.338E+14, 4.314E+14, 1.801E+14, 7.043E+13, 2.706E+13, 1.098E+13, 4.445E+12, 1.941E+12,
    1359             :                        8.706E+11, 4.225E+11 },
    1360             :                      { .496E+19, 2.257E+19, 2.038E+19, 1.843E+19, 1.666E+19, 1.503E+19, 1.351E+19, 1.212E+19,
    1361             :                        1.086E+19, 9.716E+18, 8.656E+18, 7.698E+18, 6.814E+18, 6.012E+18, 5.141E+18, 4.368E+18,
    1362             :                        3.730E+18, 3.192E+18, 2.715E+18, 2.312E+18, 1.967E+18, 1.677E+18, 1.429E+18, 1.223E+18,
    1363             :                        1.042E+18, 8.919E+17, 6.050E+17, 4.094E+17, 2.820E+17, 1.927E+17, 1.338E+17, 9.373E+16,
    1364             :                        6.624E+16, 4.726E+16, 3.398E+16, 2.500E+16, 1.386E+16, 7.668E+15, 4.196E+15, 2.227E+15,
    1365             :                        1.109E+15, 4.996E+14, 1.967E+14, 7.204E+13, 2.541E+13, 9.816E+12, 3.816E+12, 1.688E+12,
    1366             :                        8.145E+11, 4.330E+11 },
    1367             :                      { .711E+19, 2.420E+19, 2.158E+19, 1.922E+19, 1.724E+19, 1.542E+19, 1.376E+19, 1.225E+19,
    1368             :                        1.086E+19, 9.612E+18, 8.472E+18, 7.271E+18, 6.237E+18, 5.351E+18, 4.588E+18, 3.931E+18,
    1369             :                        3.368E+18, 2.886E+18, 2.473E+18, 2.115E+18, 1.809E+18, 1.543E+18, 1.317E+18, 1.125E+18,
    1370             :                        9.633E+17, 8.218E+17, 5.536E+17, 3.701E+17, 2.486E+17, 1.647E+17, 1.108E+17, 7.540E+16,
    1371             :                        5.202E+16, 3.617E+16, 2.570E+16, 1.863E+16, 1.007E+16, 5.433E+15, 2.858E+15, 1.477E+15,
    1372             :                        7.301E+14, 3.553E+14, 1.654E+14, 7.194E+13, 3.052E+13, 1.351E+13, 6.114E+12, 2.952E+12,
    1373             :                        1.479E+12, 7.836E+11 },
    1374             :                      { .549E+19, 2.305E+19, 2.080E+19, 1.873E+19, 1.682E+19, 1.508E+19, 1.357E+19, 1.216E+19,
    1375             :                        1.088E+19, 9.701E+18, 8.616E+18, 7.402E+18, 6.363E+18, 5.471E+18, 4.699E+18, 4.055E+18,
    1376             :                        3.476E+18, 2.987E+18, 2.568E+18, 2.208E+18, 1.899E+18, 1.632E+18, 1.403E+18, 1.207E+18,
    1377             :                        1.033E+18, 8.834E+17, 6.034E+17, 4.131E+17, 2.839E+17, 1.938E+17, 1.344E+17, 9.402E+16,
    1378             :                        6.670E+16, 4.821E+16, 3.516E+16, 2.581E+16, 1.421E+16, 7.946E+15, 4.445E+15, 2.376E+15,
    1379             :                        1.198E+15, 5.311E+14, 2.022E+14, 7.221E+13, 2.484E+13, 9.441E+12, 3.624E+12, 1.610E+12,
    1380             :                        7.951E+11, 4.311E+11 },
    1381             :                      { .855E+19, 2.484E+19, 2.202E+19, 1.950E+19, 1.736E+19, 1.552E+19, 1.383E+19, 1.229E+19,
    1382             :                        1.087E+19, 9.440E+18, 8.069E+18, 6.898E+18, 5.893E+18, 5.039E+18, 4.308E+18, 3.681E+18,
    1383             :                        3.156E+18, 2.704E+18, 2.316E+18, 1.982E+18, 1.697E+18, 1.451E+18, 1.241E+18, 1.061E+18,
    1384             :                        9.065E+17, 7.742E+17, 5.134E+17, 3.423E+17, 2.292E+17, 1.533E+17, 1.025E+17, 6.927E+16,
    1385             :                        4.726E+16, 3.266E+16, 2.261E+16, 1.599E+16, 8.364E+15, 4.478E+15, 2.305E+15, 1.181E+15,
    1386             :                        6.176E+14, 3.127E+14, 1.531E+14, 7.244E+13, 3.116E+13, 1.403E+13, 6.412E+12, 3.099E+12,
    1387             :                        1.507E+12, 7.814E+11 },
    1388             :                      { .548E+19, 2.313E+19, 2.094E+19, 1.891E+19, 1.704E+19, 1.532E+19, 1.373E+19, 1.228E+19,
    1389             :                        1.094E+19, 9.719E+18, 8.602E+18, 7.589E+18, 6.489E+18, 5.546E+18, 4.739E+18, 4.050E+18,
    1390             :                        3.462E+18, 2.960E+18, 2.530E+18, 2.163E+18, 1.849E+18, 1.575E+18, 1.342E+18, 1.144E+18,
    1391             :                        9.765E+17, 8.337E+17, 5.640E+17, 3.830E+17, 2.524E+17, 1.761E+17, 1.238E+17, 8.310E+16,
    1392             :                        5.803E+16, 4.090E+16, 2.920E+16, 2.136E+16, 1.181E+16, 6.426E+15, 3.386E+15, 1.723E+15,
    1393             :                        8.347E+14, 3.832E+14, 1.711E+14, 7.136E+13, 2.924E+13, 1.189E+13, 5.033E+12, 2.144E+12,
    1394             :                        9.688E+11, 5.114E+11 } };
    1395             : 
    1396             :  static const double so2[50] = { 3.00E-04,  2.74E-04,  2.36E-04,  1.90E-04,  1.46E-04,
    1397             :                                  1.18E-04,  9.71E-05,  8.30E-05,  7.21E-05,  6.56E-05,
    1398             :                                  6.08E-05,  5.79E-05,  5.60E-05,  5.59E-05,  5.64E-05,
    1399             :                                  5.75E-05,  5.75E-05,  5.37E-05,  4.78E-05,  3.97E-05,
    1400             :                                  3.19E-05,  2.67E-05,  2.28E-05,  2.07E-05,  1.90E-05,
    1401             :                                  1.75E-05,  1.54E-05,  1.34E-05,  1.21E-05,  1.16E-05,
    1402             :                                  1.21E-05,  1.36E-05,  1.65E-05,  2.10E-05,  2.77E-05,
    1403             :                                  3.56E-05,  4.59E-05,  5.15E-05,  5.11E-05,  4.32E-05,
    1404             :                                  2.83E-05,  1.33E-05,  5.56E-06,  2.24E-06,  8.96E-07,
    1405             :                                  3.58E-07,  1.43E-07,  5.73E-08,  2.29E-08,  9.17E-09};
    1406             : 
    1407             :  static const double no2[50] = { 2.30E-05,  2.30E-05,  2.30E-05,  2.30E-05,  2.30E-05,    
    1408             :                                  2.30E-05,  2.30E-05,  2.30E-05,  2.30E-05,  2.32E-05,
    1409             :                                  2.38E-05,  2.62E-05,  3.15E-05,  4.45E-05,  7.48E-05,
    1410             :                                  1.71E-04,  3.19E-04,  5.19E-04,  7.71E-04,  1.06E-03,
    1411             :                                  1.39E-03,  1.76E-03,  2.16E-03,  2.58E-03,  3.06E-03,
    1412             :                                  3.74E-03,  4.81E-03,  6.16E-03,  7.21E-03,  7.28E-03,
    1413             :                                  6.26E-03,  4.03E-03,  2.17E-03,  1.15E-03,  6.66E-04,
    1414             :                                  4.43E-04,  3.39E-04,  2.85E-04,  2.53E-04,  2.31E-04,
    1415             :                                  2.15E-04,  2.02E-04,  1.92E-04,  1.83E-04,  1.76E-04,
    1416             :                                  1.70E-04,  1.64E-04,  1.59E-04,  1.55E-04,  1.51E-04};   
    1417             : 
    1418             :  static const double hcl[50] = { 1.00E-03,  7.49E-04,  5.61E-04,  4.22E-04,  3.19E-04,    
    1419             :                                  2.39E-04,  1.79E-04,  1.32E-04,  9.96E-05,  7.48E-05,
    1420             :                                  5.68E-05,  4.59E-05,  4.36E-05,  6.51E-05,  1.01E-04,
    1421             :                                  1.63E-04,  2.37E-04,  3.13E-04,  3.85E-04,  4.42E-04,
    1422             :                                  4.89E-04,  5.22E-04,  5.49E-04,  5.75E-04,  6.04E-04,
    1423             :                                  6.51E-04,  7.51E-04,  9.88E-04,  1.28E-03,  1.57E-03,
    1424             :                                  1.69E-03,  1.74E-03,  1.76E-03,  1.79E-03,  1.80E-03,
    1425             :                                  1.80E-03,  1.80E-03,  1.80E-03,  1.80E-03,  1.80E-03,
    1426             :                                  1.80E-03,  1.80E-03,  1.80E-03,  1.80E-03,  1.80E-03,
    1427             :                                  1.80E-03,  1.80E-03,  1.80E-03,  1.80E-03,  1.80E-03};
    1428             : 
    1429             :  static const double hcn[50] = { 1.70E-04,  1.65E-04,  1.63E-04,  1.61E-04,  1.60E-04,
    1430             :                                  1.60E-04,  1.60E-04,  1.60E-04,  1.60E-04,  1.60E-04,
    1431             :                                  1.60E-04,  1.60E-04,  1.60E-04,  1.59E-04,  1.57E-04,
    1432             :                                  1.55E-04,  1.52E-04,  1.49E-04,  1.45E-04,  1.41E-04,
    1433             :                                  1.37E-04,  1.34E-04,  1.30E-04,  1.25E-04,  1.19E-04,
    1434             :                                  1.13E-04,  1.05E-04,  9.73E-05,  9.04E-05,  8.46E-05,
    1435             :                                  8.02E-05,  7.63E-05,  7.30E-05,  7.00E-05,  6.70E-05,
    1436             :                                  6.43E-05,  6.21E-05,  6.02E-05,  5.88E-05,  5.75E-05,
    1437             :                                  5.62E-05,  5.50E-05,  5.37E-05,  5.25E-05,  5.12E-05};
    1438             : 
    1439             : 
    1440        3448 :  bool v2018 = false;
    1441             :  
    1442             :  //   --------------------------------------------[ altitude for interpolation ]
    1443             : 
    1444        3448 :   if((ha < 0.0) || (ha > 120.0)) {
    1445             : 
    1446           0 :     o3den = NumberDensity(0.0, NumberDensity::UnitInverseCubicMeter);
    1447           0 :     n2oden = NumberDensity(0.0, NumberDensity::UnitInverseCubicMeter);
    1448           0 :     coden = NumberDensity(0.0, NumberDensity::UnitInverseCubicMeter);
    1449           0 :     no2den = NumberDensity(0.0, NumberDensity::UnitInverseCubicMeter);
    1450           0 :     so2den = NumberDensity(0.0, NumberDensity::UnitInverseCubicMeter);
    1451           0 :     hclden = NumberDensity(0.0, NumberDensity::UnitInverseCubicMeter);
    1452           0 :     hcnden = NumberDensity(0.0, NumberDensity::UnitInverseCubicMeter);
    1453             : 
    1454             :   } else {
    1455             : 
    1456        3448 :     i1 = 0; i2 = 0; i3 = 0;
    1457        3448 :     x1 = 0.0; x2 = 0.0; x3 = 0.0;
    1458             : 
    1459       48761 :     for(i_layer = 0; i_layer < 50; i_layer++) {
    1460             : 
    1461       48760 :       if(ha < alt[i_layer]) {
    1462             : 
    1463        3447 :         if(i_layer == 49) {
    1464             : 
    1465           1 :           i1 = i_layer - 2; i2 = i_layer - 1; i3 = i_layer;
    1466             : 
    1467             :         } else {
    1468             : 
    1469        3446 :           if(i_layer == 0) {
    1470             : 
    1471           0 :             i1 = i_layer; i2 = i_layer + 1; i3 = i_layer + 2;
    1472             : 
    1473             :           } else {
    1474             : 
    1475        3446 :             i1 = i_layer - 1; i2 = i_layer; i3 = i_layer + 1;
    1476             : 
    1477             :           }
    1478             : 
    1479             :         }
    1480             : 
    1481        3447 :         x1 = alt[i1]; x2 = alt[i2]; x3 = alt[i3];
    1482        3447 :         goto calc;
    1483             :       }
    1484             :     }
    1485             : 
    1486           1 :     calc:
    1487             : 
    1488        3448 :     if(x1 == 0.0 && x2 == 0.0 && x3 == 0.0) {
    1489             : 
    1490           1 :       o3den = NumberDensity(0.0, NumberDensity::UnitInverseCubicMeter);
    1491           1 :       n2oden = NumberDensity(0.0, NumberDensity::UnitInverseCubicMeter);
    1492           1 :       coden = NumberDensity(0.0, NumberDensity::UnitInverseCubicMeter);
    1493           1 :       no2den = NumberDensity(0.0, NumberDensity::UnitInverseCubicMeter);
    1494           1 :       so2den = NumberDensity(0.0, NumberDensity::UnitInverseCubicMeter);
    1495           1 :       hclden = NumberDensity(0.0, NumberDensity::UnitInverseCubicMeter);
    1496           1 :       hcnden = NumberDensity(0.0, NumberDensity::UnitInverseCubicMeter);
    1497             : 
    1498             :     } else {
    1499             : 
    1500             :       //     ----- ---------------------------------------[ pressure ]
    1501             : 
    1502             :       //        p=poli2(ha,x1,x2,x3,p[tip][i1],p[tip][i2],p[tip][i3]);
    1503             : 
    1504             :       //     --------------------------------------------[ TEMPERATURE ]
    1505             : 
    1506             :       //        t=poli2(ha,x1,x2,x3,t[tip][i1],t[tip][i2],t[tip][i3]);
    1507             : 
    1508             :       //     --------------------------------------------[ DENSITY ]
    1509             : 
    1510        3447 :       d = poli2(ha,x1,x2,x3,den[tip - 1][i1],den[tip - 1][i2],den[tip - 1][i3])
    1511        3447 :         * airmwt * 1e6 / avogad; // en g/m**3
    1512             : 
    1513             :       //   D=A+B*HA+C*HA2    en cm**-3, pero dividido por 1E19   D=D*airmwt*1e6/avogad  // en g/m**3
    1514             : 
    1515             :       //     --------------------------------------------[ H2O ]
    1516             : 
    1517             :       //    rr=poli2(ha,x1,x2,x3,agua[tip][i1],agua[tip][i2],agua[tip][i3]);   // RR=A+B*HA+C*HA2  en ppmv
    1518             :       //    rr=rr*1e-6*(h2omwt/airmwt)*d;  // en g/m**3
    1519             : 
    1520             :       //     --------------------------------------------[ OZONE ]
    1521             : 
    1522        6894 :       o3den= NumberDensity(poli2(ha, x1, x2, x3, ozone[tip - 1][i1], ozone[tip- 1][i2], ozone[tip - 1][i3])
    1523        3447 :                            * 1e-12 * d * avogad / airmwt,NumberDensity::UnitInverseCubicCentiMeter);
    1524             : 
    1525        3447 :       if(v2018){
    1526             : 
    1527             :       }else{      
    1528        3447 :         if (seasonal_diurnal == 1) {
    1529             :           // std::cout <<  "MODEL Winter&Day (W/D): 20210624 20220511 20220825 20220828 20220901 20220903 20220905" << std::endl;
    1530        3398 :           if(i2 < 29){
    1531        3141 :             if(i2 < 24){o3den=o3den*0.650;}else{o3den=o3den*0.860;}    //0.770 0.830 1.35 1.65 2.40
    1532             :           }else{
    1533         257 :             if(i2 < 32){o3den=o3den*1.35;}else{if(i2 < 35){o3den=o3den*1.60;}else{o3den=o3den*2.45;} }     // 1.45 1.50 2.40 on APRIL 24, 2022
    1534             :           }  
    1535          49 :         }else if(seasonal_diurnal == 2){
    1536             :           // std::cout << "MODEL Winter&Night (W/N): 20220827" << std::endl;
    1537           0 :           if(i2 < 29){
    1538           0 :             if(i2 < 24){o3den=o3den*0.650;}else{o3den=o3den*0.890;}
    1539             :           }else{
    1540           0 :             if(i2 < 32){o3den=o3den*1.45;}else{if(i2 < 35){o3den=o3den*1.6;}else{o3den=o3den*2.55;}}      
    1541             :           }
    1542          49 :         }else if(seasonal_diurnal == 3){
    1543             :           // std::cout << "MODEL Summer&Day (S/D): 20201206 end of observing run" << std::endl; 
    1544           0 :           if(i2 < 30){
    1545           0 :             if(i2 < 24){o3den=o3den*0.500;}else{o3den=o3den*0.800;}    //PROBAR 0.600 0.850
    1546             :           }else{
    1547           0 :             if(i2 < 32){o3den=o3den*1.65;}else{if(i2 < 35){o3den=o3den*1.70;}else{o3den=o3den*2.40;}}   //PROBAR 1.67 2.25 2.95   
    1548             :           }  
    1549          49 :         }else if(seasonal_diurnal == 4){
    1550             :           // std::cout << "MODEL Summer&Night (S/N): 20201021 20201205 20201206 20211031" << std::endl;
    1551           0 :           if(i2 < 30){
    1552           0 :             if(i2 < 24){o3den=o3den*0.500;}else{o3den=o3den*0.800;}    //PROBAR 0.600 0.850
    1553             :           }else{
    1554           0 :             if(i2 < 32){o3den=o3den*1.65;}else{if(i2 < 35){o3den=o3den*1.70;}else{o3den=o3den*2.50;}}   //PROBAR 1.67 2.25 2.95   
    1555             :           }  
    1556             :         }else{
    1557             :         // MODEL St76 Default
    1558             :         }
    1559             :       }
    1560             :       
    1561             :       // std::cout << "ha o3den " << ha << " " << o3den.get() << std::endl;
    1562             : 
    1563             :       //  OZONO=A+B*HA+C*HA2     // en ppmv 
    1564             : 
    1565             :       //     --------------------------------------------[ N2O ]
    1566             : 
    1567        6894 :       n2oden = NumberDensity(poli2(ha, x1, x2, x3, n2o[tip - 1][i1], n2o[tip - 1][i2], n2o[tip - 1][i3])
    1568        3447 :                              * 1e-12 * d * avogad / airmwt, NumberDensity::UnitInverseCubicCentiMeter);
    1569        3447 :       if(v2018){
    1570             : 
    1571             :       }else{
    1572        3447 :         if(ha>36.0){n2oden=n2oden*1.5; }else if(ha>30){ n2oden=n2oden*2.5; }else{  }
    1573             :       }
    1574             : 
    1575             :       
    1576             :        // 12FEB2024 increasing N2O above 30m to match observed lines at Chajnantor
    1577             :       //  N2O=A+B*HA+C*HA2       // en ppmv
    1578             : 
    1579             :       //     --------------------------------------------[ NO2 ]
    1580             : 
    1581        6894 :       no2den = NumberDensity(poli2(ha, x1, x2, x3, no2[i1], no2[i2], no2[i3])
    1582        3447 :                              * 1e-12 * d * avogad / airmwt, NumberDensity::UnitInverseCubicCentiMeter);
    1583             : 
    1584             :       // no2den = no2den * 100.0;    // USADO EN PRUEBAS 20240117
    1585             :       //  N2O=A+B*HA+C*HA2       // en ppmv
    1586             : 
    1587             :       //    --------------------------------------------[ HCl ]
    1588             : 
    1589        3447 :       hclden = NumberDensity(poli2(ha, x1, x2, x3, hcl[i1], hcl[i2], hcl[i3]) * 1e-12 * d * avogad / airmwt, NumberDensity::UnitInverseCubicCentiMeter);
    1590             : 
    1591        3447 :       if(v2018){
    1592           0 :         hclden=0.0;
    1593             :       }else{
    1594             : 
    1595        3447 :         if(i2 < 30){           
    1596        3170 :           hclden=hclden*1.0;           //   FIX 15/1/2024          
    1597             :         }else{
    1598         277 :           hclden=hclden*3.5;
    1599             :         }
    1600             : 
    1601             :       }
    1602             : 
    1603             :       //    --------------------------------------------[ HCN ]
    1604             : 
    1605        3447 :       hcnden = NumberDensity(poli2(ha, x1, x2, x3, hcn[i1], hcn[i2], hcn[i3]) * 1e-12 * d * avogad / airmwt, NumberDensity::UnitInverseCubicCentiMeter);
    1606             : 
    1607        3447 :       if(v2018){
    1608           0 :         hcnden=0.0;
    1609             :       }else{
    1610             : 
    1611        3447 :         if(i2 < 25){           
    1612        2915 :           hcnden=hcnden*0.9;           //   FIX 15/1/2024          
    1613             :         }else{
    1614         532 :           hcnden=hcnden*2.5;
    1615             :         }
    1616             : 
    1617             :       }
    1618             :       
    1619             : 
    1620             :       //    --------------------------------------------[ SO2 ]
    1621             : 
    1622        3447 :       so2den = NumberDensity(poli2(ha, x1, x2, x3, so2[i1], so2[i2], so2[i3]) * 1e-12 * d * avogad / airmwt, NumberDensity::UnitInverseCubicCentiMeter);
    1623             : 
    1624             :       //    --------------------------------------------[ CO ]
    1625             : 
    1626        6894 :       coden = NumberDensity(poli2(ha,x1,x2,x3,co[tip-1][i1],co[tip-1][i2],co[tip-1][i3])
    1627        3447 :                             * 1e-12 * d * avogad / airmwt,NumberDensity::UnitInverseCubicCentiMeter);
    1628             : 
    1629             : 
    1630             : 
    1631             :     }
    1632             : 
    1633             :   }
    1634             : 
    1635        3448 :   minorden.push_back(o3den);
    1636        3448 :   minorden.push_back(n2oden);
    1637        3448 :   minorden.push_back(coden);
    1638        3448 :   minorden.push_back(no2den);
    1639        3448 :   minorden.push_back(so2den);
    1640        3448 :   minorden.push_back(hclden);
    1641        3448 :   minorden.push_back(hcnden);
    1642             : 
    1643        6896 :   return minorden;
    1644        3448 : }
    1645             : 
    1646       27576 : double AtmProfile::poli2(double ha,
    1647             :                          double x1,
    1648             :                          double x2,
    1649             :                          double x3,
    1650             :                          double y1,
    1651             :                          double y2,
    1652             :                          double y3) const
    1653             : {
    1654             :   double a, b, c;
    1655             : 
    1656       27576 :   c = (y3 - y2) * (x2 - x1) - (y2 - y1) * (x3 - x2);
    1657       27576 :   b = (x2 - x1) * (x3 * x3 - x2 * x2) - (x2 * x2 - x1 * x1) * (x3 - x2);
    1658       27576 :   c = c / b;
    1659       27576 :   b = (y2 - y1) - c * (x2 * x2 - x1 * x1);
    1660       27576 :   b = b / (x2 - x1);
    1661       27576 :   a = y1 - c * x1 * x1 - b * x1;
    1662             : 
    1663       27576 :   return a + b * ha + c * pow(ha, 2);
    1664             : }
    1665             : 
    1666         125 : unsigned int AtmProfile::mkAtmProfile()
    1667             : {
    1668         125 :   const int MAXNHX = 20;
    1669             :   static const double
    1670             :       hx[MAXNHX] = { 9.225, 10.225, 11.225, 12.850, 14.850, 16.850, 18.850, 22.600, 26.600, 30.600,
    1671             :                  34.850, 40.850, 46.850, 52.850, 58.850, 65.100, 73.100, 81.100, 89.100, 95.600 };
    1672             : 
    1673             :   static const double
    1674             :       px[6][MAXNHX] = { { 0.3190E+03, 0.2768E+03, 0.2391E+03, 0.1864E+03, 0.1354E+03, 0.9613E+02, 0.6833E+02,
    1675             :                       0.3726E+02, 0.2023E+02, 0.1121E+02, 0.6142E+01, 0.2732E+01, 0.1260E+01, 0.6042E+00,
    1676             :                       0.2798E+00, 0.1202E+00, 0.3600E-01, 0.9162E-02, 0.2076E-02, 0.6374E-03 },
    1677             :                     { 0.3139E+03, 0.2721E+03, 0.2350E+03, 0.1833E+03, 0.1332E+03, 0.9726E+02, 0.7115E+02,
    1678             :                       0.3992E+02, 0.2185E+02, 0.1216E+02, 0.6680E+01, 0.2985E+01, 0.1400E+01, 0.6780E+00,
    1679             :                       0.3178E+00, 0.1380E+00, 0.4163E-01, 0.9881E-02, 0.2010E-02, 0.5804E-03 },
    1680             :                     { 0.2892E+03, 0.2480E+03, 0.2124E+03, 0.1649E+03, 0.1206E+03, 0.8816E+02, 0.6433E+02,
    1681             :                       0.3558E+02, 0.1901E+02, 0.1014E+02, 0.5316E+01, 0.2255E+01, 0.1022E+01, 0.4814E+00,
    1682             :                       0.2206E+00, 0.9455E-01, 0.3000E-01, 0.8729E-02, 0.2332E-02, 0.8164E-03 },
    1683             :                     { 0.3006E+03, 0.2587E+03, 0.2223E+03, 0.1739E+03, 0.1288E+03, 0.9495E+02, 0.7018E+02,
    1684             :                       0.3983E+02, 0.2199E+02, 0.1232E+02, 0.6771E+01, 0.3056E+01, 0.1452E+01, 0.7051E+00,
    1685             :                       0.3353E+00, 0.1459E+00, 0.4431E-01, 0.1024E-01, 0.1985E-02, 0.5627E-03 },
    1686             :                     { 0.2731E+03, 0.2335E+03, 0.1995E+03, 0.1546E+03, 0.1130E+03, 0.8252E+02, 0.6017E+02,
    1687             :                       0.3314E+02, 0.1751E+02, 0.9306E+01, 0.4826E+01, 0.1988E+01, 0.8645E+00, 0.4000E+00,
    1688             :                       0.1819E+00, 0.7866E-01, 0.2639E-01, 0.8264E-02, 0.2364E-02, 0.8439E-03 },
    1689             :                     { 0.2978E+03, 0.2559E+03, 0.2191E+03, 0.1698E+03, 0.1240E+03, 0.9060E+02, 0.6621E+02,
    1690             :                       0.3688E+02, 0.1999E+02, 0.1087E+02, 0.5862E+01, 0.2565E+01, 0.1182E+01, 0.5572E+00,
    1691             :                       0.2551E+00, 0.1074E+00, 0.3224E-01, 0.8697E-02, 0.2158E-02, 0.6851E-03 } };
    1692             : 
    1693             :   static const double
    1694             :       tx[6][MAXNHX] = { { 0.2421E+03, 0.2354E+03, 0.2286E+03, 0.2180E+03, 0.2046E+03, 0.1951E+03, 0.2021E+03,
    1695             :                       0.2160E+03, 0.2250E+03, 0.2336E+03, 0.2428E+03, 0.2558E+03, 0.2686E+03, 0.2667E+03,
    1696             :                       0.2560E+03, 0.2357E+03, 0.2083E+03, 0.1826E+03, 0.1767E+03, 0.1841E+03 },
    1697             :                     { 0.2403E+03, 0.2338E+03, 0.2273E+03, 0.2167E+03, 0.2157E+03, 0.2157E+03, 0.2177E+03,
    1698             :                       0.2223E+03, 0.2271E+03, 0.2349E+03, 0.2448E+03, 0.2596E+03, 0.2740E+03, 0.2727E+03,
    1699             :                       0.2603E+03, 0.2394E+03, 0.2045E+03, 0.1715E+03, 0.1644E+03, 0.1785E+03 },
    1700             :                     { 0.2239E+03, 0.2196E+03, 0.2191E+03, 0.2183E+03, 0.2173E+03, 0.2163E+03, 0.2153E+03,
    1701             :                       0.2152E+03, 0.2152E+03, 0.2178E+03, 0.2275E+03, 0.2458E+03, 0.2637E+03, 0.2633E+03,
    1702             :                       0.2531E+03, 0.2407E+03, 0.2243E+03, 0.2072E+03, 0.1991E+03, 0.2091E+03 },
    1703             :                     { 0.2301E+03, 0.2252E+03, 0.2252E+03, 0.2252E+03, 0.2252E+03, 0.2252E+03, 0.2252E+03,
    1704             :                       0.2252E+03, 0.2298E+03, 0.2361E+03, 0.2468E+03, 0.2648E+03, 0.2756E+03, 0.2763E+03,
    1705             :                       0.2662E+03, 0.2392E+03, 0.2023E+03, 0.1681E+03, 0.1609E+03, 0.1770E+03 },
    1706             :                     { 0.2172E+03, 0.2172E+03, 0.2172E+03, 0.2172E+03, 0.2172E+03, 0.2161E+03, 0.2149E+03,
    1707             :                       0.2126E+03, 0.2127E+03, 0.2165E+03, 0.2222E+03, 0.2368E+03, 0.2516E+03, 0.2601E+03,
    1708             :                       0.2523E+03, 0.2486E+03, 0.2388E+03, 0.2215E+03, 0.2033E+03, 0.2113E+03 },
    1709             :                     { 228.260, 221.838, 216.778, 216.700, 216.700, 216.700, 216.700, 219.200, 223.136,
    1710             :                       227.340, 236.110, 252.746, 268.936, 265.057, 250.174, 233.026, 212.656, 196.466,
    1711             :                       187.260, 189.204}   };
    1712             : 
    1713         125 :   double T_ground = groundTemperature_.get(Temperature::UnitKelvin); //  std::cout<<"T_ground: " << T_ground <<"K"<<endl;
    1714         125 :   double P_ground = groundPressure_.get(Pressure::UnitMilliBar); //  std::cout<<"P_ground: " << P_ground <<"mb"<<endl;
    1715         125 :   double rh = relativeHumidity_.get(Percent::UnitPercent); //  std::cout<<"rh:       " << rh <<"%"<<endl;
    1716         125 :   double h0 = wvScaleHeight_.get(Length::UnitKiloMeter); //  std::cout<<"h0:       " << h0 <<"km"<<endl;
    1717         125 :   double dp = pressureStep_.get(Pressure::UnitMilliBar); //  std::cout<<"dp:       " << dp <<"mb"<<endl;
    1718         125 :   double alti = altitude_.get(Length::UnitKiloMeter); //  std::cout<<"alti:     " << alti <<"km"<<endl;
    1719         125 :   double atmh = topAtmProfile_.get(Length::UnitKiloMeter); //  std::cout<<"atmh:     " << atmh <<"km"<<endl;
    1720         125 :   double dp1 = pressureStepFactor_; //  std::cout<<"dp1:      " << dp1 <<" "<<endl;
    1721         125 :   double dt = tropoLapseRate_; // TODO implementer des unites (K/km) ici localement
    1722             :   double prLimit;
    1723             :   double minmin;
    1724         125 :   unsigned int seasonal_diurnal = 0;
    1725             : 
    1726         125 :   if(dp<5.0 || dp>12.5){dp = 10.0; std::cout << "ATMProfile WARNING: Primary Pressure step fixed to 10 mb for numerical reasons" << std::endl; }
    1727         125 :   if(dp1<1.074 || dp1 > 1.076 ){dp = 1.075; std::cout << "ATMProfile WARNING: Pressure Step factor fixed to 1.075 for numerical reasons" << std::endl; }
    1728             :   
    1729         125 :   if(typeAtm_ == 1) {                             // TROPICAL US St. 76
    1730         125 :     prLimit = 125;    //100.0;   // 100.0 230.2;   TEMPORAL FIX 20220606
    1731         125 :     seasonal_diurnal=1;
    1732           0 :   } else if(typeAtm_ == 11) {                     // CHAJNANTOR Winter + Daytime
    1733           0 :     typeAtm_ = 1;
    1734           0 :     seasonal_diurnal=1;
    1735           0 :     prLimit = 125.0;  //100.0;   // 100.0 230.2;   TEMPORAL FIX 20220606
    1736           0 :   } else if(typeAtm_ == 12) {                     // CHAJNANTOR Winter + Nighttime
    1737           0 :     typeAtm_ = 1; 
    1738           0 :     seasonal_diurnal=2;
    1739           0 :     prLimit = 125.0;  //100.0;   // 100.0 230.2;   TEMPORAL FIX 20220606
    1740           0 :   } else if(typeAtm_ == 13) {                     // CHAJNANTOR Summer + Daytime 
    1741           0 :     typeAtm_ = 1; 
    1742           0 :     seasonal_diurnal=3;
    1743           0 :     prLimit = 125.0;  //100.0;   // 100.0 230.2;   TEMPORAL FIX 20220606
    1744           0 :   } else if(typeAtm_ == 14) {                     // CHAJNANTOR Summer + Nighttime
    1745           0 :     typeAtm_ = 1; 
    1746           0 :     seasonal_diurnal=4;
    1747           0 :     prLimit = 125.0;
    1748           0 :   } else if(typeAtm_ == 2) {
    1749           0 :     prLimit = 100.0;   // 198.0;
    1750           0 :     seasonal_diurnal=1;
    1751           0 :   } else if(typeAtm_ == 3) {
    1752           0 :     prLimit = 100.0;   // 300.0
    1753           0 :     seasonal_diurnal=1;
    1754           0 :   } else if(typeAtm_ == 4) {
    1755           0 :     prLimit = 100.0;   // 311.0
    1756           0 :     seasonal_diurnal=1;
    1757           0 :   } else if(typeAtm_ == 5) {
    1758           0 :     prLimit = 100.0;   // 332.0
    1759           0 :     seasonal_diurnal=1;
    1760           0 :   } else if(typeAtm_ == 6) {
    1761           0 :     prLimit = 100.0;   // 332.0
    1762           0 :     seasonal_diurnal=1;
    1763             :   } else { 
    1764           0 :     typeAtm_ = 6;      // Default: US St76 Atm.
    1765           0 :     prLimit = 100.0;   // 250.0;
    1766           0 :     seasonal_diurnal=1;
    1767             :   }
    1768             : 
    1769         125 :   unsigned int npp = 0; // number of layers initialized
    1770             : 
    1771         125 :   double rt = 6371.2E+0; // Earth radius in km
    1772         125 :   double g0 = 9.80665E+0; // Earth gravity at the surface  (m/s**2)
    1773             : 
    1774             :   // static bool first = true;  // [-Wunused_but_set_variable]
    1775             : 
    1776             :   unsigned int i;
    1777             :   unsigned int i0;
    1778             :   unsigned int j;
    1779             :   unsigned int k;
    1780             :   // double wh2o, wh2o0;  // [-Wunused_but_set_variable]
    1781             :   double wgr0;
    1782         125 :   double g = g0;
    1783             :   double www, altura;
    1784             :   // double abun_ozono, abun_n2o, abun_co;
    1785         125 :   NumberDensity ozono, n2o, co;
    1786             :   double wgr, dh;
    1787             : // double humrel; // [-Wunused_but_set_variable]
    1788             :   // bool   errcode;
    1789             : 
    1790             :   //int    nmaxLayers=40;  // FV peut etre devrions nos avoir un garde-fou au cas ou le nb de couches serait stupidement trop grand
    1791             : 
    1792         125 :   vector<double> v_layerPressure;
    1793         125 :   vector<double> v_layerPressure0;
    1794         125 :   vector<double> v_layerPressure1;
    1795         125 :   vector<double> v_layerTemperature;
    1796         125 :   vector<double> v_layerTemperature0;
    1797         125 :   vector<double> v_layerTemperature1;
    1798         125 :   vector<double> v_layerThickness;
    1799         125 :   vector<double> v_layerWaterVapor;
    1800         125 :   vector<double> v_layerWaterVapor0;
    1801         125 :   vector<double> v_layerWaterVapor1;
    1802         125 :   vector<double> v_layerO3;
    1803         125 :   vector<double> v_layerCO;
    1804         125 :   vector<double> v_layerN2O;
    1805         125 :   vector<double> v_layerNO2;
    1806         125 :   vector<double> v_layerSO2;
    1807         125 :   vector<double> v_layerHCl;
    1808         125 :   vector<double> v_layerHCN;
    1809             : 
    1810         125 :   vector<double> v_layerO3_aux;
    1811         125 :   vector<double> v_layerCO_aux;
    1812         125 :   vector<double> v_layerN2O_aux;
    1813         125 :   vector<double> v_layerNO2_aux;
    1814         125 :   vector<double> v_layerSO2_aux;
    1815         125 :   vector<double> v_layerHCl_aux;
    1816         125 :   vector<double> v_layerHCN_aux;
    1817         125 :   vector<double> v_layerPressure_aux;
    1818         125 :   vector<double> v_layerPressure0_aux;
    1819         125 :   vector<double> v_layerPressure1_aux;
    1820         125 :   vector<double> v_layerTemperature_aux;
    1821         125 :   vector<double> v_layerTemperature0_aux;
    1822         125 :   vector<double> v_layerTemperature1_aux;
    1823         125 :   vector<double> v_layerThickness_aux;
    1824         125 :   vector<double> v_layerWaterVapor_aux;
    1825         125 :   vector<double> v_layerWaterVapor0_aux;
    1826         125 :   vector<double> v_layerWaterVapor1_aux;
    1827         125 :   vector<NumberDensity> minorden;
    1828             : 
    1829         125 :   v_layerPressure.push_back(P_ground);
    1830         125 :   v_layerThickness.push_back(alti * 1000);
    1831         125 :   v_layerTemperature.push_back(T_ground);
    1832             : 
    1833         250 :   wgr = rwat(Temperature(v_layerTemperature[0], Temperature::UnitKelvin),
    1834         250 :              Humidity(rh, Percent::UnitPercent),
    1835         375 :              Pressure(v_layerPressure[0], Pressure::UnitMilliBar)).get(MassDensity::UnitGramPerCubicMeter);
    1836             : 
    1837             :   // Absolute Humidity in gr/m**3 at altitude alti
    1838         125 :   wgr0 = wgr * exp(alti / h0); // h0 in km ==> wgr0 would be the absolute humidity (gr/m**3) at sea level
    1839             :   // wh2o0 = wgr0 * h0; // wh2o0 is the zenith column of water above sea level (kgr/m**2 or mm) // [-Wunused_but_set_variable]
    1840             :   // wh2o = wh2o0 * exp(-alti / h0); // wh2o is the zenith column of water above alti (kgr/m**2 or mm) // [-Wunused_but_set_variable]
    1841             : 
    1842         125 :   v_layerWaterVapor.push_back(wgr); // in gr/m**3
    1843             : 
    1844         125 :   i0 = 0;
    1845         125 :   i = 0;
    1846         125 :   j = 0;
    1847         125 :   npp = 0;
    1848             : 
    1849             :   //  std::cout << "layer " << i << " v_layerThickness[" << i  << "]=" << v_layerThickness[i] << " v_layerPressure[" << i << "]=" << v_layerPressure[i] << std::endl;
    1850             : 
    1851         125 :   bool control = true;
    1852             :   //  bool control2 = true;
    1853             :   while(true) {
    1854        3523 :     i++;
    1855             : 
    1856             :     //    std::cout << "layer: " << i << " " << v_layerPressure[i - 1] - dp * pow(dp1, i - 1) << " " << prLimit << std::endl;
    1857             : 
    1858        3523 :     if( (v_layerPressure[i - 1] - dp * pow(dp1, i - 1) <= prLimit ) ) { //&& (v_layerTemperature[i - 1] <= tx[typeAtm_ - 1][0]) ) {  //  &&(fabs(prLimit-v_layerPressure[i - 1]-dp*pow(dp1,i-1))>=20.0) ) {
    1859             : 
    1860        1085 :       if(control) {
    1861             : 
    1862             :         //std::cout << "capa " << i-1 << " temperature=" << v_layerTemperature[i - 1] << " K " <<  " tx[0]=" << tx[typeAtm_ - 1][0] << std::endl;
    1863             : 
    1864             :         //      std::cout <<  "prLimit=" << prLimit << std::endl;
    1865             :         // std::cout << "aaa " <<  v_layerPressure[i - 1] - dp * pow(dp1, i - 1) << std::endl;
    1866             : 
    1867             :         /*      for(k = 0; k < 20; k++) {
    1868             :           if(control2) {
    1869             :             if(v_layerPressure[i - 1] - dp * pow(dp1, i - 1) >= px[typeAtm_ - 1][k]) {
    1870             :               j = k;
    1871             :               std::cout << "P=" << v_layerPressure[i - 1] - dp * pow(dp1, i - 1)
    1872             :                         << " prLimit=" << prLimit << " px[" << typeAtm_ - 1 << "][" << k << "]="
    1873             :                         << px[typeAtm_ - 1][k] << std::endl;
    1874             :               control2 = false;
    1875             :             }
    1876             :           }
    1877             :           } */
    1878             : 
    1879         125 :         minmin = 20000.0;
    1880             : 
    1881        2625 :         for(k = 0; k < MAXNHX; k++) {
    1882             : 
    1883        4328 :           if( (fabs(v_layerPressure[i - 1] - dp * pow(dp1, i - 1) > 1.05*px[typeAtm_ - 1][k])) &&
    1884        1828 :               (fabs(v_layerPressure[i - 1] - dp * pow(dp1, i - 1) - px[typeAtm_ - 1][k])) <= minmin ) {
    1885             : 
    1886         125 :             j = k;
    1887             : 
    1888             :             /* std::cout << "P=" << v_layerPressure[i - 1] - dp * pow(dp1, i - 1)
    1889             :                       << " prLimit=" << prLimit << " px[" << typeAtm_ - 1 << "][" << k << "]="
    1890             :                       << px[typeAtm_ - 1][k] << std::endl;    FIXED 20240606   */
    1891         125 :             minmin = fabs(v_layerPressure[i - 1] - dp * pow(dp1, i - 1) - px[typeAtm_ - 1][k]);
    1892             :             // std::cout << " minmin=" << minmin << std::endl;      FIXED 20240606   
    1893             : 
    1894             :           }
    1895             : 
    1896             :         }
    1897             : 
    1898             : 
    1899             :       }
    1900             : 
    1901             :       //      std::cout << "i,j,v_layerPressure.size()-1=" << i << "," << j << "," << v_layerPressure.size() - 1 << std::endl;
    1902             : 
    1903        1085 :       if(i0 == 0) i0 = i - 1;
    1904             : 
    1905             :       //      std::cout << "i0,j " << i0 << "," << j << std::endl;
    1906             : 
    1907             : 
    1908        1085 :       if(i < v_layerPressure.size() - 1) {
    1909           0 :         if(control) {
    1910           0 :           int j0 = (j>0) ? j-1:0;
    1911           0 :           v_layerPressure[i] = px[typeAtm_ - 1][j0];
    1912           0 :           v_layerTemperature[i] = tx[typeAtm_ - 1][j0];
    1913             : 
    1914           0 :           std::cout << "v_layerTemperature[i]=" << v_layerTemperature[i] << std::endl;
    1915             :           //        - tx[typeAtm_ - 1][0] + v_layerTemperature[i0];   COMMENTED OUT 31/5/2017
    1916             : 
    1917           0 :           www = v_layerWaterVapor[i - 1] / 1000.0;
    1918           0 :           dh = 288.6948 * v_layerTemperature[i - 1] * (1.0 + 0.61 * www / 1000.0)
    1919           0 :               * log(v_layerPressure[i - 1] / v_layerPressure[i]) / g;
    1920           0 :           v_layerThickness[i] = v_layerThickness[i - 1] + dh;
    1921             :         } else {
    1922           0 :           j++;
    1923           0 :           v_layerPressure[i] = px[typeAtm_ - 1][j - 1];
    1924           0 :           v_layerTemperature[i] = tx[typeAtm_ - 1][j - 1];
    1925             :             //  - tx[typeAtm_ - 1][0] + v_layerTemperature[i0];   COMMENTED OUT 31/5/2017
    1926           0 :           if(j < MAXNHX) {
    1927           0 :             v_layerThickness[i] = (hx[j] - hx[j - 1]) * 1000.0 + v_layerThickness[i - 1];
    1928             :           }
    1929             :         }
    1930             :         //        std::cout << "layer " << i << " j=" << j << " v_layerThickness[" << i << "]="  << v_layerThickness[i] << " v_layerPressure[" << i << "]=" << v_layerPressure[i]  << std::endl;
    1931           0 :         v_layerWaterVapor[i] = wgr0 * exp(-v_layerThickness[i] / (1000.0 * h0));
    1932             :       } else {
    1933        1085 :         if(control) {
    1934         125 :           int j0 = (j>0) ? j-1:0;
    1935         125 :           v_layerPressure.push_back(px[typeAtm_ - 1][j0]);
    1936         125 :           v_layerTemperature.push_back(tx[typeAtm_ - 1][j0]);
    1937             :           //- tx[typeAtm_ - 1][0] + v_layerTemperature[i0]);   COMMENTED OUT 31/5/2017
    1938             : 
    1939         125 :           www = v_layerWaterVapor[i - 1] / 1000.0;
    1940         125 :           dh = 288.6948 * v_layerTemperature[i - 1] * (1.0 + 0.61 * www / 1000.0)
    1941         125 :               * log(v_layerPressure[i - 1] / v_layerPressure[i]) / g;
    1942         125 :           v_layerThickness.push_back(v_layerThickness[i - 1] + dh);
    1943             :         } else {
    1944         960 :           j++;
    1945         960 :           v_layerPressure.push_back(px[typeAtm_ - 1][j - 1]);
    1946         960 :           v_layerTemperature.push_back(tx[typeAtm_ - 1][j - 1]);
    1947             :             //  - tx[typeAtm_ - 1][0] + v_layerTemperature[i0]);   COMMENTED OUT 31/5/2017
    1948         960 :           if(j < MAXNHX) {
    1949         959 :             v_layerThickness.push_back((hx[j] - hx[j - 1]) * 1000.0 + v_layerThickness[i - 1]);
    1950             :           }
    1951             : 
    1952             :         }
    1953        1085 :         v_layerWaterVapor.push_back(wgr0 * exp(-v_layerThickness[i] / (1000.0 * h0)));
    1954             :       }
    1955             :       //  std::cout << "layer " << i << " j=" << j << " v_layerThickness[" << i << "]="  << v_layerThickness[i] << " v_layerPressure[" << i << "]=" << v_layerPressure[i]  << std::endl;
    1956        1085 :      if(control) {
    1957         125 :         tropoLayer_ = i - 1;
    1958             :         //      std::cout << "tropoLayer_=" << tropoLayer_ << std::endl;
    1959         125 :         control = false;
    1960             :       }
    1961             :       //      std::cout << "2 layer " << i << " alt at end of layer = " <<  v_layerThickness[i] << " atmh=" << atmh*1000 << std::endl;
    1962             : 
    1963             :       // besides the thickness threshold, if j goes >=MAXNHX this loop cannot iterate further
    1964        1085 :       if((j >= MAXNHX) || (v_layerThickness[i] > (atmh * 1000.0)))
    1965         125 :           break;
    1966             :     } else {
    1967             : 
    1968             :       //      std::cout << "i,j,v_layerPressure.size()-1=" << i << "," << j << "," << v_layerPressure.size() - 1 << std::endl;
    1969             : 
    1970        2438 :       if(i > v_layerPressure.size() - 1) {
    1971        2438 :         v_layerPressure.push_back(v_layerPressure[i - 1] - dp * pow(dp1, i - 1));
    1972             : 
    1973        2438 :         www = v_layerWaterVapor[i - 1] / 1000.0; // in kg/m**3
    1974        2438 :         g = g0 * pow(1. + ((v_layerThickness[i - 1] / 1000.0)) / rt, -2); // gravity corrected for the height
    1975        2438 :         dh = 288.6948 * v_layerTemperature[i - 1] * (1.0 + 0.61 * www / 1000.0)
    1976        2438 :             * log(v_layerPressure[i - 1] / v_layerPressure[i]) / g;
    1977        2438 :         v_layerThickness.push_back(v_layerThickness[i - 1] + dh);
    1978             :         //std::cout << "layer " << i << " v_layerThickness[" << i << "]=" << v_layerThickness[i]  << " v_layerPressure[" << i << "]=" << v_layerPressure[i] << std::endl;
    1979        2438 :         v_layerTemperature.push_back(v_layerTemperature[i - 1] + dt * dh / 1000.0);
    1980        2438 :         v_layerWaterVapor.push_back(wgr0 * exp(-v_layerThickness[i] / (1000.0 * h0))); //r[i] in kgr/(m**2*1000m) [gr/m**3]
    1981             :       } else {
    1982           0 :         v_layerPressure[i] = v_layerPressure[i - 1] - dp * pow(dp1, i - 1);
    1983           0 :         www = v_layerWaterVapor[i - 1] / 1000.0; // in kg/m**3
    1984           0 :         g = g0 * pow(1. + ((v_layerThickness[i - 1] / 1000.0)) / rt, -2); // gravity corrected for the height
    1985           0 :         dh = 288.6948 * v_layerTemperature[i - 1] * (1.0 + 0.61 * www / 1000.0)
    1986           0 :             * log(v_layerPressure[i - 1] / v_layerPressure[i]) / g;
    1987           0 :         v_layerThickness[i] = v_layerThickness[i - 1] + dh;
    1988             :         //std::cout << "layer " << i << " v_layerThickness[" << i << "]=" << v_layerThickness[i]  << " v_layerPressure[" << i << "]=" << v_layerPressure[i] << std::endl;
    1989           0 :         v_layerTemperature[i] = v_layerTemperature[i - 1] + dt * dh / 1000.0;
    1990           0 :         v_layerWaterVapor[i] = wgr0 * exp(-v_layerThickness[i] / (1000.0 * h0)); //r[i] in kgr/(m**2*1000m) [gr/m**3]
    1991             :       }
    1992             : 
    1993             :       //std::cout << "dh=" << dh << std::endl;
    1994        2438 :       if( v_layerTemperature[i] <= tx[typeAtm_ - 1][4] && v_layerPressure[i] <= px[typeAtm_ - 1][4] )    // [0]
    1995             :         {
    1996             :           // std::cout << "v_layerThickness[i]=" << v_layerThickness[i] <<  " " << v_layerThickness[i-1] <<std::endl;
    1997             :           // std::cout << "dh=" << dh << std::endl;
    1998             :           // std::cout << "old prLimit =" << prLimit << std::endl;
    1999          11 :           prLimit=v_layerPressure[i];  //14NOV2017
    2000             :           // std::cout << "new prLimit =" << prLimit << std::endl;
    2001             :         }
    2002             : 
    2003             : //       humrel = rwat_inv(Temperature(v_layerTemperature[i], Temperature::UnitKelvin),
    2004             : //                         MassDensity(v_layerWaterVapor[i], MassDensity::UnitGramPerCubicMeter),
    2005             : //                         Pressure(v_layerPressure[i], Pressure::UnitMilliBar)).get(Percent::UnitPercent);
    2006             : 
    2007             : 
    2008             :       /*        cout << "layer " << i
    2009             :        << " P " << v_layerPressure[i] << " prLimit " << prLimit
    2010             :        << " T " << v_layerTemperature[i]
    2011             :        << " Alti (layer top in m) " << v_layerThickness[i]
    2012             :        << " WaterVapor " << v_layerWaterVapor[i] << std::endl;      */
    2013             :       //      std::cout << "1 layer " << i << " alt at end of layer = " <<  v_layerThickness[i] << " atmh=" << atmh*1000 << std::endl;
    2014        2438 :       if(v_layerThickness[i] > (atmh * 1000.0)) break;
    2015             :     }
    2016             :     //    std::cout << "v_layerPressure[" << i << "]" << v_layerPressure[i] << "  v_layerTemperature[" << i << "] " << v_layerTemperature[i] << std::endl;
    2017        3398 :   }
    2018             : 
    2019         125 :   npp = i - 1;
    2020             : 
    2021             :   // std::cout << "npp=" << npp << std::endl;
    2022             :   // std::cout << "tropoLayer=" << tropoLayer_ << std::endl;
    2023         125 :   tropoTemperature_ = Temperature(v_layerTemperature[tropoLayer_], Temperature::UnitKelvin);
    2024         125 :   tropoAltitude_ = Length(v_layerThickness[tropoLayer_], Length::UnitMeter);
    2025             :   // std::cout << "tropoAltitude=" << tropoAltitude_.get(Length::UnitKiloMeter) << " km" << std::endl;
    2026             :   // std::cout << "tropoTemperature=" << tropoTemperature_.get(Temperature::UnitKelvin) << " K" << std::endl;
    2027             :   // std::cout << "ground Altitude=" << altitude_.get(Length::UnitKiloMeter) << " km" << std::endl;
    2028             :   // std::cout << "ground Temperature=" << groundTemperature_.get(Temperature::UnitKelvin) << " K" << std::endl;
    2029             :   // std::cout << "Calculated Lapse Rate=" << (tropoTemperature_.get(Temperature::UnitKelvin)-groundTemperature_.get(Temperature::UnitKelvin))/(tropoAltitude_.get(Length::UnitKiloMeter)-altitude_.get(Length::UnitKiloMeter)) << " K/km" << std::endl;
    2030             : 
    2031             : 
    2032         125 :   altura = alti;
    2033             : 
    2034             :   /*
    2035             :    if(first){
    2036             :    v_layerO3_.reserve(npp);
    2037             :    v_layerCO_.reserve(npp);
    2038             :    v_layerN2O_.reserve(npp);
    2039             :    v_layerNO2_.reserve(npp);
    2040             :    v_layerSO2_.reserve(npp);
    2041             :    v_layerHCl_.reserve(npp);
    2042             :    v_layerHCN_.reserve(npp);
    2043             :    }
    2044             :    */
    2045             : 
    2046             : 
    2047        3523 :   for(unsigned int jj = 0; jj < npp; jj++) {
    2048             : 
    2049        3398 :     v_layerTemperature0.push_back(v_layerTemperature[jj]);
    2050        3398 :     v_layerTemperature1.push_back(v_layerTemperature[jj + 1]);
    2051        3398 :     v_layerPressure0.push_back(v_layerPressure[jj]);
    2052        3398 :     v_layerPressure1.push_back(v_layerPressure[jj + 1]);
    2053        3398 :     v_layerWaterVapor0.push_back(1.0E-3*v_layerWaterVapor[jj]);
    2054        3398 :     v_layerWaterVapor1.push_back(1.0E-3*v_layerWaterVapor[jj + 1]);
    2055             : 
    2056             :   }
    2057             : 
    2058        3523 :   for(j = 0; j < npp; j++) {
    2059             : 
    2060        3398 :     v_layerThickness[j] = (v_layerThickness[j + 1] - v_layerThickness[j]); // in m
    2061        3398 :     altura = altura + v_layerThickness[j] / 2.0E3; // in km
    2062        3398 :     v_layerTemperature[j] = (v_layerTemperature[j + 1] + v_layerTemperature[j])            // AVERAGING MAY/30/2017
    2063        3398 :         / 2.; // in K
    2064        3398 :     v_layerPressure[j] = exp((log(v_layerPressure[j + 1])
    2065        3398 :         + log(v_layerPressure[j])) / 2.0); // in mb
    2066        3398 :     if(altura < 40.0 ){ 
    2067        6532 :       v_layerWaterVapor[j] = 1.0E-3 * exp((log(v_layerWaterVapor[j + 1]) +       // units:
    2068        3266 :                                            log(v_layerWaterVapor[j])) / 2.0);    // kg/m**3
    2069             :     }else{
    2070         132 :       v_layerWaterVapor[j] = v_layerWaterVapor[j-1];                             // 12FEB2024 TO KEEP MESOSPHERIC WATER CONSTANT
    2071             :     }
    2072             :     //      std::cout << "type_=" << type_ << std::endl;
    2073             :     //      std::cout << "typeAtm_=" << typeAtm_ << std::endl;
    2074             : 
    2075        3398 :     unsigned int atmType = typeAtm_; // conversion in int
    2076             : 
    2077             :     //      std::cout << "going to minorden with atmType=" << atmType << std::endl;
    2078             : 
    2079             :     // std::cout << "Going to st76 seasonal_diurnal=" << seasonal_diurnal << std::endl;
    2080        3398 :     minorden = st76(Length(altura, Length::UnitKiloMeter), atmType, seasonal_diurnal);
    2081             : 
    2082             :     //      std::cout << "Ozone: " << abun_ozono << "  " << ozono.get(NumberDensity::UnitInverseCubicCentiMeter) << std::endl;
    2083             :     // std::cout << "N2O  : " << abun_n2o << "  " << n2o.get(NumberDensity::UnitInverseCubicCentiMeter) << std::endl;
    2084             :     // std::cout << "CO   : " << abun_co  << "  " << co.get(NumberDensity::UnitInverseCubicCentiMeter) << std::endl;
    2085             : 
    2086             : 
    2087             :     /* std::cout << j << " " << v_layerO3_.size()-1 << std::endl; */
    2088             : 
    2089             :     /*    if(j>v_layerO3_.size()-1){
    2090             :      v_layerO3_.push_back(  1.E6*abun_ozono); // in m**-3
    2091             :      v_layerCO_.push_back(  1.E6*abun_co   ); // in m**-3
    2092             :      v_layerN2O_.push_back( 1.E6*abun_n2o  ); // in m**-3
    2093             :      v_layerNO2_.push_back( 1.E6*abun_no2  ); // in m**-3
    2094             :      v_layerSO2_.push_back( 1.E6*abun_so2  ); // in m**-3
    2095             :      v_layerHCl_.push_back( 1.E6*abun_hcl  ); // in m**-3
    2096             :      v_layerHCN_.push_back( 1.E6*abun_hcn  ); // in m**-3
    2097             :      std::cout << "uno" << std::endl;
    2098             :      }else{ */
    2099             : 
    2100             :     /*    v_layerO3_[j]  = 1.E6*abun_ozono;        // in m**-3
    2101             :      v_layerCO_[j]  = 1.E6*abun_co;           // in m**-3
    2102             :      v_layerN2O_[j] = 1.E6*abun_n2o;          // in m**-3
    2103             :      v_layerNO2_[j] = 1.E6*abun_no2;          // in m**-3
    2104             :      v_layerSO2_[j] = 1.E6*abun_so2;          // in m**-3 
    2105             :      v_layerHCl_[j] = 1.E6*abun_hcl;          // in m**-3 
    2106             :      v_layerHCN_[j] = 1.E6*abun_hcn;          // in m**-3 */
    2107             : 
    2108             :     // v_layerO3.push_back(1.E6*abun_ozono);        // in m**-3
    2109             :     // v_layerCO.push_back(1.E6*abun_co);           // in m**-3
    2110             :     // v_layerN2O.push_back(1.E6*abun_n2o);          // in m**-3
    2111             :     // v_layerNO2.push_back(1.E6*abun_no2);          // in m**-3
    2112             :     // v_layerSO2.push_back(1.E6*abun_so2);          // in m**-3
    2113             :     // v_layerHCl.push_back(1.E6*abun_hcl);          // in m**-3
    2114             :     // v_layerHCN.push_back(1.E6*abun_hcn);          // in m**-3
    2115             : 
    2116        3398 :     v_layerO3.push_back(1.E6 * minorden[0].get(NumberDensity::UnitInverseCubicCentiMeter)); // in m**-3
    2117        3398 :     v_layerN2O.push_back(1.E6 * minorden[1].get(NumberDensity::UnitInverseCubicCentiMeter)); // in m**-3
    2118        3398 :     v_layerCO.push_back(1.E6 * minorden[2].get(NumberDensity::UnitInverseCubicCentiMeter)); // in m**-3
    2119             :     //std::cout << "minorden[3]  " << minorden[3].get("m**-3") << std::endl;
    2120        3398 :     v_layerNO2.push_back(1.E6 * minorden[3].get(NumberDensity::UnitInverseCubicCentiMeter)); // in m**-3
    2121        3398 :     v_layerSO2.push_back(1.E6 * minorden[4].get(NumberDensity::UnitInverseCubicCentiMeter)); // in m**-3
    2122        3398 :     v_layerHCl.push_back(1.E6 * minorden[5].get(NumberDensity::UnitInverseCubicCentiMeter)); // in m**-3
    2123        3398 :     v_layerHCN.push_back(1.E6 * minorden[6].get(NumberDensity::UnitInverseCubicCentiMeter)); // in m**-3
    2124             : 
    2125             : 
    2126             : 
    2127             :     /*     } */
    2128             : 
    2129        3398 :     altura = altura + v_layerThickness[j] / 2.0E3;
    2130             : 
    2131             :     /* std::cout << "j=" << j << "v_layerThickness.size()=" << v_layerThickness.size() <<  std::endl; */
    2132             : 
    2133             :   }
    2134             : 
    2135             :   /*  std::cout << "j=" << j << " v_layerThickness_aux.size()= " << v_layerThickness_aux.size() <<  std::endl; */
    2136             : 
    2137             :   /* if(v_layerThickness.size()>npp){
    2138             :    for(j=npp; j<v_layerThickness.size(); j++){
    2139             :    delete v_layerThickness[j];
    2140             :    }
    2141             :    } */
    2142             : 
    2143        3523 :   for(j = 0; j < npp; j++) {
    2144             : 
    2145        3398 :     v_layerPressure_aux.push_back(v_layerPressure[j]);
    2146        3398 :     v_layerPressure0_aux.push_back(v_layerPressure0[j]);
    2147        3398 :     v_layerPressure1_aux.push_back(v_layerPressure1[j]);
    2148        3398 :     v_layerTemperature_aux.push_back(v_layerTemperature[j]);
    2149        3398 :     v_layerTemperature0_aux.push_back(v_layerTemperature0[j]);
    2150        3398 :     v_layerTemperature1_aux.push_back(v_layerTemperature1[j]);
    2151        3398 :     v_layerThickness_aux.push_back(v_layerThickness[j]);
    2152        3398 :     v_layerWaterVapor_aux.push_back(v_layerWaterVapor[j]);
    2153        3398 :     v_layerWaterVapor0_aux.push_back(v_layerWaterVapor0[j]);
    2154        3398 :     v_layerWaterVapor1_aux.push_back(v_layerWaterVapor1[j]);
    2155        3398 :     v_layerO3_aux.push_back(v_layerO3[j]);
    2156        3398 :     v_layerCO_aux.push_back(v_layerCO[j]);
    2157        3398 :     v_layerN2O_aux.push_back(v_layerN2O[j]);
    2158        3398 :     v_layerNO2_aux.push_back(v_layerNO2[j]);
    2159        3398 :     v_layerSO2_aux.push_back(v_layerSO2[j]);
    2160        3398 :     v_layerHCl_aux.push_back(v_layerHCl[j]);
    2161        3398 :     v_layerHCN_aux.push_back(v_layerHCN[j]);
    2162             : 
    2163             :   }
    2164             : 
    2165         125 :   if(j > v_layerPressure_.size() - 1) { // ?????
    2166         119 :     v_layerPressure_.reserve(npp);
    2167         119 :     v_layerPressure0_.reserve(npp);
    2168         119 :     v_layerPressure1_.reserve(npp);
    2169         119 :     v_layerTemperature_.reserve(npp);
    2170         119 :     v_layerTemperature0_.reserve(npp);
    2171         119 :     v_layerTemperature1_.reserve(npp);
    2172         119 :     v_layerThickness_.reserve(npp);
    2173         119 :     v_layerWaterVapor_.reserve(npp);
    2174         119 :     v_layerWaterVapor0_.reserve(npp);
    2175         119 :     v_layerWaterVapor1_.reserve(npp);
    2176         119 :     v_layerO3_.reserve(npp);
    2177         119 :     v_layerCO_.reserve(npp);
    2178         119 :     v_layerN2O_.reserve(npp);
    2179         119 :     v_layerNO2_.reserve(npp);
    2180         119 :     v_layerSO2_.reserve(npp);
    2181         119 :     v_layerHCl_.reserve(npp);
    2182         119 :     v_layerHCN_.reserve(npp);
    2183             :   }
    2184             : 
    2185         125 :   v_layerPressure_ = v_layerPressure_aux;
    2186         125 :   v_layerPressure0_ = v_layerPressure0_aux;
    2187         125 :   v_layerPressure1_ = v_layerPressure1_aux;
    2188         125 :   v_layerTemperature_ = v_layerTemperature_aux;
    2189         125 :   v_layerTemperature0_ = v_layerTemperature0_aux;
    2190         125 :   v_layerTemperature1_ = v_layerTemperature1_aux;
    2191         125 :   v_layerThickness_ = v_layerThickness_aux;
    2192         125 :   v_layerWaterVapor_ = v_layerWaterVapor_aux;
    2193         125 :   v_layerWaterVapor0_ = v_layerWaterVapor0_aux;
    2194         125 :   v_layerWaterVapor1_ = v_layerWaterVapor1_aux;
    2195         125 :   v_layerO3_ = v_layerO3_aux;
    2196         125 :   v_layerCO_ = v_layerCO_aux;
    2197         125 :   v_layerN2O_ = v_layerN2O_aux;
    2198         125 :   v_layerNO2_ = v_layerNO2_aux;
    2199         125 :   v_layerSO2_ = v_layerSO2_aux;
    2200         125 :   v_layerHCl_ = v_layerHCl_aux;
    2201         125 :   v_layerHCN_ = v_layerHCN_aux;
    2202             : 
    2203             :   // first = false; // ?????    [-Wunused_but_set_variable]
    2204             : 
    2205         125 :   return npp;
    2206         125 : }
    2207             : 
    2208             : ATM_NAMESPACE_END
    2209             : 

Generated by: LCOV version 1.16