1 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 Module: FGAtmosphere.cpp
4 Author: Jon Berndt, Tony Peden
6 Purpose: Models an atmosphere interface class
9 ------------- Copyright (C) 2011 Jon S. Berndt (jon@jsbsim.org) -------------
11 This program is free software; you can redistribute it and/or modify it under
12 the terms of the GNU Lesser General Public License as published by the Free Software
13 Foundation; either version 2 of the License, or (at your option) any later
16 This program is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
21 You should have received a copy of the GNU Lesser General Public License along with
22 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
23 Place - Suite 330, Boston, MA 02111-1307, USA.
25 Further information about the GNU Lesser General Public License can also be found on
26 the world wide web at http://www.gnu.org.
28 FUNCTIONAL DESCRIPTION
29 --------------------------------------------------------------------------------
30 This models a base atmosphere class to serve as a common interface to any derived
34 --------------------------------------------------------------------------------
35 6/18/2011 Started Jon S. Berndt
37 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
38 COMMENTS, REFERENCES, and NOTES
39 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
41 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
43 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
48 #include "FGFDMExec.h"
49 #include "FGAtmosphere.h"
53 static const char *IdSrc = "$Id: FGAtmosphere.cpp,v 1.51 2012/04/13 13:18:28 jberndt Exp $";
54 static const char *IdHdr = ID_ATMOSPHERE;
56 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
58 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
60 FGAtmosphere::FGAtmosphere(FGFDMExec* fdmex) : FGModel(fdmex),
61 PressureAltitude(0.0), // ft
62 DensityAltitude(0.0), // ft
63 SutherlandConstant(198.72), // deg Rankine
64 Beta(2.269690E-08) // slug/(sec ft R^0.5)
66 Name = "FGAtmosphere";
72 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
74 FGAtmosphere::~FGAtmosphere()
79 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
81 bool FGAtmosphere::InitModel(void)
84 SLtemperature = Temperature = 518.67;
85 SLpressure = Pressure = 2116.22;
86 SLdensity = Density = Pressure/(Reng*Temperature);
87 SLsoundspeed = Soundspeed = sqrt(SHRatio*Reng*(Temperature));
89 rSLtemperature = 1/SLtemperature ;
90 rSLpressure = 1/SLpressure ;
91 rSLdensity = 1/SLdensity ;
92 rSLsoundspeed = 1/SLsoundspeed ;
97 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
99 bool FGAtmosphere::Run(bool Holding)
101 if (FGModel::Run(Holding)) return true;
102 if (Holding) return false;
104 Calculate(in.altitudeASL);
110 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
112 void FGAtmosphere::Calculate(double altitude)
114 Temperature = GetTemperature(altitude);
115 Pressure = GetPressure(altitude);
116 Density = Pressure/(Reng*Temperature);
117 Soundspeed = sqrt(SHRatio*Reng*(Temperature));
118 PressureAltitude = altitude;
119 DensityAltitude = altitude;
121 Viscosity = Beta * pow(Temperature, 1.5) / (SutherlandConstant + Temperature);
122 KinematicViscosity = Viscosity / Density;
125 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
127 void FGAtmosphere::SetPressureSL(ePressure unit, double pressure)
129 double press = ConvertToPSF(pressure, unit);
134 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
135 // Get the modeled density at a specified altitude
137 double FGAtmosphere::GetDensity(double altitude) const
139 return GetPressure(altitude)/(Reng * GetTemperature(altitude));
142 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
143 // This function sets the sea level temperature.
144 // Internally, the Rankine scale is used for calculations, so any temperature
145 // supplied must be converted to that unit.
147 void FGAtmosphere::SetTemperatureSL(double t, eTemperature unit)
149 SLtemperature = ConvertToRankine(t, unit);
152 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
154 double FGAtmosphere::ConvertToRankine(double t, eTemperature unit) const
156 double targetTemp=0; // in degrees Rankine
160 targetTemp = t + 459.67;
163 targetTemp = t*9.0/5.0 + 32.0 + 459.67;
169 targetTemp = t*9.0/5.0;
178 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
180 double FGAtmosphere::ConvertToPSF(double p, ePressure unit) const
182 double targetPressure=0; // Pressure in PSF
189 targetPressure = p*2.08854342;
192 targetPressure = p*0.0208854342;
195 targetPressure = p*70.7180803;
198 throw("Undefined pressure unit given");
201 return targetPressure;
204 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
206 void FGAtmosphere::bind(void)
208 typedef double (FGAtmosphere::*PMFi)(int) const;
209 typedef void (FGAtmosphere::*PMF)(int, double);
210 PropertyManager->Tie("atmosphere/T-R", this, &FGAtmosphere::GetTemperature);
211 PropertyManager->Tie("atmosphere/rho-slugs_ft3", this, &FGAtmosphere::GetDensity);
212 PropertyManager->Tie("atmosphere/P-psf", this, &FGAtmosphere::GetPressure);
213 PropertyManager->Tie("atmosphere/a-fps", this, &FGAtmosphere::GetSoundSpeed);
214 PropertyManager->Tie("atmosphere/T-sl-R", this, &FGAtmosphere::GetTemperatureSL);
215 PropertyManager->Tie("atmosphere/rho-sl-slugs_ft3", this, &FGAtmosphere::GetDensitySL);
216 // PropertyManager->Tie("atmosphere/P-sl-psf", this, ePSF,
217 // (PMFi)&FGAtmosphere::GetPressureSL,
218 // (PMF)&FGAtmosphere::SetPressureSL);
219 PropertyManager->Tie("atmosphere/a-sl-fps", this, &FGAtmosphere::GetSoundSpeedSL);
220 PropertyManager->Tie("atmosphere/theta", this, &FGAtmosphere::GetTemperatureRatio);
221 PropertyManager->Tie("atmosphere/sigma", this, &FGAtmosphere::GetDensityRatio);
222 PropertyManager->Tie("atmosphere/delta", this, &FGAtmosphere::GetPressureRatio);
223 PropertyManager->Tie("atmosphere/a-ratio", this, &FGAtmosphere::GetSoundSpeedRatio);
224 PropertyManager->Tie("atmosphere/density-altitude", this, &FGAtmosphere::GetDensityAltitude);
225 PropertyManager->Tie("atmosphere/pressure-altitude", this, &FGAtmosphere::GetPressureAltitude);
228 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
229 // The bitmasked value choices are as follows:
230 // unset: In this case (the default) JSBSim would only print
231 // out the normally expected messages, essentially echoing
232 // the config files as they are read. If the environment
233 // variable is not set, debug_lvl is set to 1 internally
234 // 0: This requests JSBSim not to output any messages
236 // 1: This value explicity requests the normal JSBSim
238 // 2: This value asks for a message to be printed out when
239 // a class is instantiated
240 // 4: When this value is set, a message is displayed when a
241 // FGModel object executes its Run() method
242 // 8: When this value is set, various runtime state variables
243 // are printed out periodically
244 // 16: When set various parameters are sanity checked and
245 // a message is printed out when they go out of bounds
247 void FGAtmosphere::Debug(int from)
249 if (debug_lvl <= 0) return;
251 if (debug_lvl & 1) { // Standard console startup message output
252 if (from == 0) { // Constructor
255 if (debug_lvl & 2 ) { // Instantiation/Destruction notification
256 if (from == 0) std::cout << "Instantiated: FGAtmosphere" << std::endl;
257 if (from == 1) std::cout << "Destroyed: FGAtmosphere" << std::endl;
259 if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
261 if (debug_lvl & 8 ) { // Runtime state variables
263 if (debug_lvl & 16) { // Sanity checking
265 if (debug_lvl & 128) { //
267 if (debug_lvl & 64) {
268 if (from == 0) { // Constructor
269 std::cout << IdSrc << std::endl;
270 std::cout << IdHdr << std::endl;
275 } // namespace JSBSim