1 // atmosphere.hxx -- routines to model the air column
3 // Written by David Megginson, started February 2002.
4 // Modified by John Denker to correct physics errors in 2007
6 // Copyright (C) 2002 David Megginson - david@megginson.com
8 // This program is free software; you can redistribute it and/or
9 // modify it under the terms of the GNU General Public License as
10 // published by the Free Software Foundation; either version 2 of the
11 // License, or (at your option) any later version.
13 // This program is distributed in the hope that it will be useful, but
14 // WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 // General Public License for more details.
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the Free Software
20 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
25 #ifndef _ATMOSPHERE_HXX
26 #define _ATMOSPHERE_HXX
28 #include <simgear/compiler.h>
29 #include <simgear/math/interpolater.hxx>
37 * Model the atmosphere in a way consistent with the laws
40 * Each instance of this class models a particular air mass.
41 * You may freely move up, down, or sideways in the air mass.
42 * In contrast, if you want to compare different air masses,
43 * you should use a separate instance for each one.
45 * See also ./environment.hxx
48 #define SCD(name,val) const double name(val)
50 SCD(g, 9.80665); // [m/s/s] acceleration of gravity
51 SCD(mm, .0289644); // [kg/mole] molar mass of air (dry?)
52 SCD(Rgas, 8.31432); // [J/K/mole] gas constant
53 SCD(inch, 0.0254); // [m] definition of inch
54 SCD(foot, 12 * inch); // [m]
55 SCD(inHg, 101325.0 / 760 * 1000 * inch); // [Pa] definition of inHg
56 SCD(mbar, 100.); // [Pa] definition of millibar
57 SCD(freezing, 273.15); // [K] centigrade - kelvin offset
58 SCD(nm, 1852); // [m] nautical mile (NIST)
59 SCD(sm, 5280*foot); // [m] nautical mile (NIST)
62 SCD(P0, 101325.0); // [pascals] ISA sea-level pressure
63 SCD(T0, 15. + freezing); // [K] ISA sea-level temperature
64 SCD(lam0, .0065); // [K/m] ISA troposphere lapse rate
76 ISA_layer(int, double h, double, double, double, double t, double,
77 double l=-1, double=0)
78 : height(h), // [meters]
84 extern const ISA_layer ISA_def[];
86 std::pair<double,double> PT_vs_hpt(
88 const double _p0 = atmodel::ISA::P0,
89 const double _t0 = atmodel::ISA::T0);
91 double P_layer(const double height, const double href,
92 const double Pref, const double Tref, const double lapse );
94 double T_layer(const double height, const double href,
95 const double Pref, const double Tref, const double lapse );
97 // The base class is little more than a namespace.
98 // It has no constructor, no destructor, and no variables.
101 double a_vs_p(const double press, const double qnh = atmodel::ISA::P0);
102 double fake_T_vs_a_us(const double h_ft,
103 const double Tsl = atmodel::ISA::T0) const;
104 double fake_dp_vs_a_us(const double dpsl, const double h_ft);
105 void check_one(const double height);
107 // Altimeter setting _in pascals_
108 // ... caller gets to convert to inHg or millibars
109 // Field elevation in m
110 // Field pressure in pascals
111 // Valid for fields within the troposphere only.
112 double QNH(const double field_elev, const double field_press);
114 * Invert the QNH calculation to get the field pressure from a metar
115 * report. Valid for fields within the troposphere only.
116 * @param field_elev field elevation in m
117 * @param qnh altimeter setting in pascals
118 * @return field pressure _in pascals_. Caller gets to convert to inHg
121 static double fieldPressure(const double field_elev, const double qnh);
126 class FGAtmoCache : FGAtmo {
127 friend class FGAltimeter;
128 SGInterpTable * a_tvs_p; // _tvs_ means "tabulated versus"
135 void check_model(); // debug
140 class FGAltimeter : public FGAtmoCache {
146 double reading_ft(const double p_inHg,
147 const double set_inHg = atmodel::ISA::P0/atmodel::inHg);
148 inline double press_alt_ft(const double p_inHg) {
149 return a_tvs_p->interpolate(p_inHg);
151 inline double kollsman_ft(const double set_inHg) {
152 return a_tvs_p->interpolate(set_inHg);
157 void dump_stack1(const double Tref);
160 #endif // _ATMOSPHERE_HXX