]> git.mxchange.org Git - flightgear.git/blob - src/FDM/JSBSim/models/FGAtmosphere.cpp
Merge branch 'next' into comm-subsystem
[flightgear.git] / src / FDM / JSBSim / models / FGAtmosphere.cpp
1 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2
3  Module:       FGAtmosphere.cpp
4  Author:       Jon Berndt, Tony Peden
5  Date started: 6/2011
6  Purpose:      Models an atmosphere interface class
7  Called by:    FGFDMExec
8
9  ------------- Copyright (C) 2011  Jon S. Berndt (jon@jsbsim.org) -------------
10
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
14  version.
15
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
19  details.
20
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.
24
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.
27
28 FUNCTIONAL DESCRIPTION
29 --------------------------------------------------------------------------------
30 This models a base atmosphere class to serve as a common interface to any derived
31 atmosphere models.
32
33 HISTORY
34 --------------------------------------------------------------------------------
35 6/18/2011 Started Jon S. Berndt
36
37 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
38 COMMENTS, REFERENCES,  and NOTES
39 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
40
41 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
42 INCLUDES
43 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
44
45 #include <iostream>
46 #include <iomanip>
47 #include <cstdlib>
48 #include "FGFDMExec.h"
49 #include "FGAtmosphere.h"
50
51 namespace JSBSim {
52
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;
55
56 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
57 CLASS IMPLEMENTATION
58 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
59
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)
65 {
66   Name = "FGAtmosphere";
67
68   bind();
69   Debug(0);
70 }
71
72 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
73
74 FGAtmosphere::~FGAtmosphere()
75 {
76   Debug(1);
77 }
78
79 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
80
81 bool FGAtmosphere::InitModel(void)
82 {
83   Calculate(0.0);
84   SLtemperature = Temperature = 518.67;
85   SLpressure = Pressure = 2116.22;
86   SLdensity = Density = Pressure/(Reng*Temperature);
87   SLsoundspeed = Soundspeed = sqrt(SHRatio*Reng*(Temperature));
88
89   rSLtemperature = 1/SLtemperature ;
90   rSLpressure    = 1/SLpressure    ;
91   rSLdensity     = 1/SLdensity     ;
92   rSLsoundspeed  = 1/SLsoundspeed  ;
93
94   return true;
95 }
96
97 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
98
99 bool FGAtmosphere::Run(bool Holding)
100 {
101   if (FGModel::Run(Holding)) return true;
102   if (Holding) return false;
103
104   RunPreFunctions();
105
106   Calculate(in.altitudeASL);
107
108   RunPostFunctions();
109
110   Debug(2);
111   return false;
112 }
113
114 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
115
116 void FGAtmosphere::Calculate(double altitude)
117 {
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;
124
125   Viscosity = Beta * pow(Temperature, 1.5) / (SutherlandConstant + Temperature);
126   KinematicViscosity = Viscosity / Density;
127 }
128
129 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
130
131 void FGAtmosphere::SetPressureSL(double pressure, ePressure unit)
132 {
133   double press = ConvertToPSF(pressure, unit);
134
135   SLpressure = press;
136 }
137
138 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
139 // Get the modeled density at a specified altitude
140
141 double FGAtmosphere::GetDensity(double altitude) const
142 {
143   return GetPressure(altitude)/(Reng * GetTemperature(altitude));
144 }
145
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.
150
151 void FGAtmosphere::SetTemperatureSL(double t, eTemperature unit)
152 {
153   SLtemperature = ConvertToRankine(t, unit);
154 }
155
156 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
157
158 double FGAtmosphere::ConvertToRankine(double t, eTemperature unit) const
159 {
160   double targetTemp=0; // in degrees Rankine
161
162   switch(unit) {
163   case eFahrenheit:
164     targetTemp = t + 459.67;
165     break;
166   case eCelsius:
167     targetTemp = t*9.0/5.0 + 32.0 + 459.67;
168     break;
169   case eRankine:
170     targetTemp = t;
171     break;
172   case eKelvin:
173     targetTemp = t*9.0/5.0;
174     break;
175   default:
176     break;
177   }
178
179   return targetTemp;
180 }
181
182 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
183
184 double FGAtmosphere::ConvertToPSF(double p, ePressure unit) const
185 {
186   double targetPressure=0; // Pressure in PSF
187
188   switch(unit) {
189   case ePSF:
190     targetPressure = p;
191     break;
192   case eMillibars:
193     targetPressure = p*2.08854342;
194     break;
195   case ePascals:
196     targetPressure = p*0.0208854342;
197     break;
198   case eInchesHg:
199     targetPressure = p*70.7180803;
200     break;
201   default:
202     throw("Undefined pressure unit given");
203   }
204
205   return targetPressure;
206 }
207
208 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
209
210 void FGAtmosphere::bind(void)
211 {
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);
228 }
229
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
237 //       whatsoever.
238 //    1: This value explicity requests the normal JSBSim
239 //       startup messages
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
248
249 void FGAtmosphere::Debug(int from)
250 {
251   if (debug_lvl <= 0) return;
252
253   if (debug_lvl & 1) { // Standard console startup message output
254     if (from == 0) { // Constructor
255     }
256   }
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;
260   }
261   if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
262   }
263   if (debug_lvl & 8 ) { // Runtime state variables
264   }
265   if (debug_lvl & 16) { // Sanity checking
266   }
267   if (debug_lvl & 128) { // 
268   }
269   if (debug_lvl & 64) {
270     if (from == 0) { // Constructor
271       std::cout << IdSrc << std::endl;
272       std::cout << IdHdr << std::endl;
273     }
274   }
275 }
276
277 } // namespace JSBSim