FlightGear next
atmosphere.hxx
Go to the documentation of this file.
1// atmosphere.hxx -- routines to model the air column
2//
3// Written by David Megginson, started February 2002.
4// Modified by John Denker to correct physics errors in 2007
5//
6// Copyright (C) 2002 David Megginson - david@megginson.com
7//
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.
12//
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.
17//
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.
21//
22// $Id$
23
24
25#ifndef _ATMOSPHERE_HXX
26#define _ATMOSPHERE_HXX
27
28#include <simgear/compiler.h>
29#include <simgear/math/interpolater.hxx>
30
31#include <cmath>
32#include <utility>
33
45
46#define SCD(name,val) const double name(val)
47namespace atmodel {
48 SCD(g, 9.80665); // [m/s/s] acceleration of gravity
49 SCD(mm, .0289644); // [kg/mole] molar mass of air (dry?)
50 SCD(Rgas, 8.31432); // [J/K/mole] gas constant
51 SCD(inch, 0.0254); // [m] definition of inch
52 SCD(foot, 12 * inch); // [m]
53 SCD(inHg, 101325.0 / 760 * 1000 * inch); // [Pa] definition of inHg
54 SCD(mbar, 100.); // [Pa] definition of millibar
55 SCD(freezing, 273.15); // [K] centigrade - kelvin offset
56 SCD(nm, 1852); // [m] nautical mile (NIST)
57 SCD(sm, 5280*foot); // [m] nautical mile (NIST)
58
59 namespace ISA {
60 SCD(P0, 101325.0); // [pascals] ISA sea-level pressure
61 SCD(T0, 15. + freezing); // [K] ISA sea-level temperature
62 SCD(lam0, .0065); // [K/m] ISA troposphere lapse rate
63 }
64}
65#undef SCD
66
67
68
69class ISA_layer {
70public:
71 double height;
72 double temp;
73 double lapse;
74 ISA_layer(int, double h, double, double, double, double t, double,
75 double l=-1, double=0)
76 : height(h), // [meters]
77 temp(t), // [kelvin]
78 lapse(l) // [K/m]
79 {}
80};
81
82extern const ISA_layer ISA_def[];
83
84std::pair<double,double> PT_vs_hpt(
85 const double hh,
86 const double _p0 = atmodel::ISA::P0,
87 const double _t0 = atmodel::ISA::T0);
88
89double P_layer(const double height, const double href,
90 const double Pref, const double Tref, const double lapse );
91
92double T_layer(const double height, const double href,
93 const double Pref, const double Tref, const double lapse );
94
95// The base class is little more than a namespace.
96// It has no constructor, no destructor, and no variables.
97class FGAtmo {
98public:
99 double a_vs_p(const double press, const double qnh = atmodel::ISA::P0);
100 double fake_T_vs_a_us(const double h_ft,
101 const double Tsl = atmodel::ISA::T0) const;
102 double fake_dp_vs_a_us(const double dpsl, const double h_ft);
103 void check_one(const double height);
104
105// Altimeter setting _in pascals_
106// ... caller gets to convert to inHg or millibars
107// Field elevation in m
108// Field pressure in pascals
109// Valid for fields within the troposphere only.
110 double QNH(const double field_elev, const double field_press);
119 static double fieldPressure(const double field_elev, const double qnh);
120
126 static double ISATemperatureKAtAltitudeFt(const double alt,
127 const double Tsl = atmodel::ISA::T0);
128
132 static double CSMetersPerSecondAtAltitudeFt(const double alt,
133 const double Tsl = atmodel::ISA::T0);
134
135 static double densityAtAltitudeFt(const double alt, const double Tsl = atmodel::ISA::T0);
136
137 static double machFromKnotsAtAltitudeFt(const double knots,
138 const double altFt,
139 const double Tsl = atmodel::ISA::T0);
140
141 static double knotsFromMachAtAltitudeFt(const double mach,
142 const double altFt,
143 const double Tsl = atmodel::ISA::T0);
144};
145
146
147
149 friend class FGAltimeter;
150 SGInterpTable * a_tvs_p; // _tvs_ means "tabulated versus"
151
152public:
153 FGAtmoCache();
154 ~FGAtmoCache();
155 void tabulate();
156 void cache();
157 void check_model(); // debug
158};
159
160
161
162class FGAltimeter : public FGAtmoCache {
163public:
164 FGAltimeter();
165 double reading_ft(const double p_inHg,
166 const double set_inHg = atmodel::ISA::P0/atmodel::inHg);
167 inline double press_alt_ft(const double p_inHg) {
168 return a_tvs_p->interpolate(p_inHg);
169 }
170 inline double kollsman_ft(const double set_inHg) {
171 return a_tvs_p->interpolate(set_inHg);
172 }
173
174 // debug
175 void dump_stack();
176 void dump_stack1(const double Tref);
177};
178
179#endif // _ATMOSPHERE_HXX
const ISA_layer ISA_def[]
double P_layer(const double height, const double href, const double Pref, const double Tref, const double lapse)
double T_layer(const double height, const double href, const double Pref, const double Tref, const double lapse)
#define SCD(name, val)
Model the atmosphere in a way consistent with the laws of physics.
std::pair< double, double > PT_vs_hpt(const double hh, const double _p0=atmodel::ISA::P0, const double _t0=atmodel::ISA::T0)
void dump_stack1(const double Tref)
double reading_ft(const double p_inHg, const double set_inHg=atmodel::ISA::P0/atmodel::inHg)
void dump_stack()
double kollsman_ft(const double set_inHg)
double press_alt_ft(const double p_inHg)
friend class FGAltimeter
void tabulate()
void check_model()
void check_one(const double height)
double QNH(const double field_elev, const double field_press)
static double densityAtAltitudeFt(const double alt, const double Tsl=atmodel::ISA::T0)
double a_vs_p(const double press, const double qnh=atmodel::ISA::P0)
static double ISATemperatureKAtAltitudeFt(const double alt, const double Tsl=atmodel::ISA::T0)
Compute the outisde temperature at an altitude, according to the standard atmosphere model.
static double knotsFromMachAtAltitudeFt(const double mach, const double altFt, const double Tsl=atmodel::ISA::T0)
static double CSMetersPerSecondAtAltitudeFt(const double alt, const double Tsl=atmodel::ISA::T0)
Compute the speed of sound at an altitude.
static double fieldPressure(const double field_elev, const double qnh)
Invert the QNH calculation to get the field pressure from a metar report.
static double machFromKnotsAtAltitudeFt(const double knots, const double altFt, const double Tsl=atmodel::ISA::T0)
double fake_T_vs_a_us(const double h_ft, const double Tsl=atmodel::ISA::T0) const
double fake_dp_vs_a_us(const double dpsl, const double h_ft)
ISA_layer(int, double h, double, double, double, double t, double, double l=-1, double=0)
double lapse
double temp
double height
const double lam0(.0065)
const double P0(101325.0)
const double T0(15.+freezing)
const double g(9.80665)
const double nm(1852)
const double inch(0.0254)
const double inHg(101325.0/760 *1000 *inch)
const double Rgas(8.31432)
const double freezing(273.15)
const double mm(.0289644)
const double foot(12 *inch)
const double sm(5280 *foot)
const double mbar(100.)