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.49 2011/09/11 11:36:04 bcoconni 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;
106 Calculate(in.altitudeASL);
114 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
116 void FGAtmosphere::Calculate(double altitude)
118 Temperature = GetTemperature(altitude);
119 Pressure = GetPressure(altitude);
120 Density = Pressure/(Reng*Temperature);
121 Soundspeed = sqrt(SHRatio*Reng*(Temperature));
122 PressureAltitude = altitude;
123 DensityAltitude = altitude;
125 Viscosity = Beta * pow(Temperature, 1.5) / (SutherlandConstant + Temperature);
126 KinematicViscosity = Viscosity / Density;
129 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
131 void FGAtmosphere::SetPressureSL(double pressure, ePressure unit)
133 double press = ConvertToPSF(pressure, unit);
138 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
139 // Get the modeled density at a specified altitude
141 double FGAtmosphere::GetDensity(double altitude) const
143 return GetPressure(altitude)/(Reng * GetTemperature(altitude));
146 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
147 // This function sets the sea level temperature.
148 // Internally, the Rankine scale is used for calculations, so any temperature
149 // supplied must be converted to that unit.
151 void FGAtmosphere::SetTemperatureSL(double t, eTemperature unit)
153 SLtemperature = ConvertToRankine(t, unit);
156 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
158 double FGAtmosphere::ConvertToRankine(double t, eTemperature unit) const
160 double targetTemp=0; // in degrees Rankine
164 targetTemp = t + 459.67;
167 targetTemp = t*9.0/5.0 + 32.0 + 459.67;
173 targetTemp = t*9.0/5.0;
182 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
184 double FGAtmosphere::ConvertToPSF(double p, ePressure unit) const
186 double targetPressure=0; // Pressure in PSF
193 targetPressure = p*2.08854342;
196 targetPressure = p*0.0208854342;
199 targetPressure = p*70.7180803;
202 throw("Undefined pressure unit given");
205 return targetPressure;
208 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
210 void FGAtmosphere::bind(void)
212 typedef double (FGAtmosphere::*PMFi)(int) const;
213 typedef void (FGAtmosphere::*PMF)(int, double);
214 PropertyManager->Tie("atmosphere/T-R", this, &FGAtmosphere::GetTemperature);
215 PropertyManager->Tie("atmosphere/rho-slugs_ft3", this, &FGAtmosphere::GetDensity);
216 PropertyManager->Tie("atmosphere/P-psf", this, &FGAtmosphere::GetPressure);
217 PropertyManager->Tie("atmosphere/a-fps", this, &FGAtmosphere::GetSoundSpeed);
218 PropertyManager->Tie("atmosphere/T-sl-R", this, &FGAtmosphere::GetTemperatureSL);
219 PropertyManager->Tie("atmosphere/rho-sl-slugs_ft3", this, &FGAtmosphere::GetDensitySL);
220 PropertyManager->Tie("atmosphere/P-sl-psf", this, &FGAtmosphere::GetPressureSL);
221 PropertyManager->Tie("atmosphere/a-sl-fps", this, &FGAtmosphere::GetSoundSpeedSL);
222 PropertyManager->Tie("atmosphere/theta", this, &FGAtmosphere::GetTemperatureRatio);
223 PropertyManager->Tie("atmosphere/sigma", this, &FGAtmosphere::GetDensityRatio);
224 PropertyManager->Tie("atmosphere/delta", this, &FGAtmosphere::GetPressureRatio);
225 PropertyManager->Tie("atmosphere/a-ratio", this, &FGAtmosphere::GetSoundSpeedRatio);
226 PropertyManager->Tie("atmosphere/density-altitude", this, &FGAtmosphere::GetDensityAltitude);
227 PropertyManager->Tie("atmosphere/pressure-altitude", this, &FGAtmosphere::GetPressureAltitude);
230 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
231 // The bitmasked value choices are as follows:
232 // unset: In this case (the default) JSBSim would only print
233 // out the normally expected messages, essentially echoing
234 // the config files as they are read. If the environment
235 // variable is not set, debug_lvl is set to 1 internally
236 // 0: This requests JSBSim not to output any messages
238 // 1: This value explicity requests the normal JSBSim
240 // 2: This value asks for a message to be printed out when
241 // a class is instantiated
242 // 4: When this value is set, a message is displayed when a
243 // FGModel object executes its Run() method
244 // 8: When this value is set, various runtime state variables
245 // are printed out periodically
246 // 16: When set various parameters are sanity checked and
247 // a message is printed out when they go out of bounds
249 void FGAtmosphere::Debug(int from)
251 if (debug_lvl <= 0) return;
253 if (debug_lvl & 1) { // Standard console startup message output
254 if (from == 0) { // Constructor
257 if (debug_lvl & 2 ) { // Instantiation/Destruction notification
258 if (from == 0) std::cout << "Instantiated: FGAtmosphere" << std::endl;
259 if (from == 1) std::cout << "Destroyed: FGAtmosphere" << std::endl;
261 if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
263 if (debug_lvl & 8 ) { // Runtime state variables
265 if (debug_lvl & 16) { // Sanity checking
267 if (debug_lvl & 128) { //
269 if (debug_lvl & 64) {
270 if (from == 0) { // Constructor
271 std::cout << IdSrc << std::endl;
272 std::cout << IdHdr << std::endl;
277 } // namespace JSBSim