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