]> git.mxchange.org Git - flightgear.git/blob - src/FDM/JSBSim/models/atmosphere/FGStandardAtmosphere.cpp
Merge branch 'next' into durk-atc
[flightgear.git] / src / FDM / JSBSim / models / atmosphere / FGStandardAtmosphere.cpp
1 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2
3  Module:       FGStandardAtmosphere.cpp
4  Author:       Jon Berndt, Tony Peden
5  Date started: 5/2011
6  Purpose:      Models the 1976 U.S. Standard Atmosphere
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
31
32 HISTORY
33 --------------------------------------------------------------------------------
34
35 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
36 COMMENTS, REFERENCES,  and NOTES
37 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
38 [1]   Anderson, John D. "Introduction to Flight, Third Edition", McGraw-Hill,
39       1989, ISBN 0-07-001641-0
40
41 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
42 INCLUDES
43 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
44
45 #include <iostream>
46 #include <iomanip>
47 #include <cstdlib>
48 #include "FGFDMExec.h"
49 #include "FGStandardAtmosphere.h"
50
51 namespace JSBSim {
52
53 static const char *IdSrc = "$Id: FGStandardAtmosphere.cpp,v 1.9 2011/06/13 12:06:29 jberndt Exp $";
54 static const char *IdHdr = ID_STANDARDATMOSPHERE;
55
56 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
57 CLASS IMPLEMENTATION
58 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
59
60 FGStandardAtmosphere::FGStandardAtmosphere(FGFDMExec* fdmex) : FGModel(fdmex),
61                                                                TemperatureDeltaGradient(0.0),
62                                                                TemperatureBias(0.0),
63                                                                PressureAltitude(0.0),      // ft
64                                                                DensityAltitude(0.0),       // ft
65                                                                SutherlandConstant(198.72), // deg Rankine
66                                                                Beta(2.269690E-08)          // slug/(sec ft R^0.5)
67 {
68   Name = "FGStandardAtmosphere";
69
70   StdAtmosTemperatureTable = new FGTable(9);
71
72   // This is the U.S. Standard Atmosphere table for temperature in degrees
73   // Rankine, based on geometric altitude. The table values are often given
74   // in literature relative to geopotential altitude. 
75   //
76   //                        GeoMet Alt    Temp      GeoPot Alt  GeoMet Alt
77   //                           (ft)      (deg R)      (km)        (km)
78   //                         --------   --------    ----------  ----------
79   *StdAtmosTemperatureTable <<      0.0 << 518.67 //    0.000       0.000
80                             <<  36151.6 << 390.0  //   11.000      11.019
81                             <<  65823.5 << 390.0  //   20.000      20.063
82                             << 105518.4 << 411.6  //   32.000      32.162
83                             << 155347.8 << 487.2  //   47.000      47.350
84                             << 168677.8 << 487.2  //   51.000      51.413
85                             << 235570.9 << 386.4  //   71.000      71.802
86                             << 282152.2 << 336.5  //   84.852      86.000
87                             << 298556.4 << 336.5; //               91.000 - First layer in high altitude regime 
88
89   LapseRateVector.resize(StdAtmosTemperatureTable->GetNumRows()-1);
90   PressureBreakpointVector.resize(StdAtmosTemperatureTable->GetNumRows());
91
92   // Assume the altitude to fade out the gradient at is at the highest
93   // altitude in the table. Above that, other functions are used to
94   // calculate temperature.
95   GradientFadeoutAltitude = (*StdAtmosTemperatureTable)(StdAtmosTemperatureTable->GetNumRows(),0);
96
97   bind();
98   Debug(0);
99 }
100
101 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
102
103 FGStandardAtmosphere::~FGStandardAtmosphere()
104 {
105   LapseRateVector.clear();
106   Debug(1);
107 }
108
109 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
110
111 bool FGStandardAtmosphere::InitModel(void)
112 {
113   PressureBreakpointVector[0] = StdSLpressure = 2116.22; // psf
114   TemperatureDeltaGradient = 0.0;
115   TemperatureBias = 0.0;
116   CalculateLapseRates();
117   CalculatePressureBreakpoints();
118   Calculate(0.0);
119   StdSLtemperature = SLtemperature = Temperature;
120   SLpressure = Pressure;
121   StdSLdensity     = SLdensity = Density;
122   StdSLsoundspeed  = SLsoundspeed = Soundspeed;
123
124   rSLtemperature = 1/SLtemperature ;
125   rSLpressure    = 1/SLpressure    ;
126   rSLdensity     = 1/SLdensity     ;
127   rSLsoundspeed  = 1/SLsoundspeed  ;
128
129 //  PrintStandardAtmosphereTable();
130
131   return true;
132 }
133
134 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
135
136 bool FGStandardAtmosphere::Run(bool Holding)
137 {
138   if (FGModel::Run(Holding)) return true;
139   if (Holding) return false;
140
141   RunPreFunctions();
142
143   double altitude = FDMExec->GetPropagate()->GetAltitudeASL();
144
145   Calculate(altitude);
146
147   RunPostFunctions();
148
149   Debug(2);
150   return false;
151 }
152
153 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
154
155 void FGStandardAtmosphere::Calculate(double altitude)
156 {
157   Temperature = GetTemperature(altitude);
158   Pressure = GetPressure(altitude);
159   Density     = Pressure/(Reng*Temperature);
160   Soundspeed  = sqrt(SHRatio*Reng*(Temperature));
161
162   Viscosity = Beta * pow(Temperature, 1.5) / (SutherlandConstant + Temperature);
163   KinematicViscosity = Viscosity / Density;
164 }
165
166 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
167 // Get the actual pressure as modeled at a specified altitude
168 // These calculations are from equations 33a and 33b in the U.S. Standard Atmosphere
169 // document referenced in the documentation for this code.
170
171 double FGStandardAtmosphere::GetPressure(double altitude) const
172 {
173   unsigned int b=0;
174   double pressure = 0.0;
175   double Lmb, Exp, Tmb, deltaH, factor;
176
177   // Iterate through the altitudes to find the current Base Altitude
178   // in the table. That is, if the current altitude (the argument passed in)
179   // is 20000 ft, then the base altitude from the table is 0.0. If the
180   // passed-in altitude is 40000 ft, the base altitude is 36151.6 ft (and
181   // the index "b" is 2 - the second entry in the table).
182   double testAlt = (*StdAtmosTemperatureTable)(b+1,0);
183   while (altitude >= testAlt) {
184     b++;
185     if (b+1 > StdAtmosTemperatureTable->GetNumRows()) break;
186     testAlt = (*StdAtmosTemperatureTable)(b+1,0);
187   }
188   if (b>0) b--;
189
190   double BaseAlt = (*StdAtmosTemperatureTable)(b+1,0);
191   Tmb = GetTemperature(BaseAlt);
192   deltaH = altitude - BaseAlt;
193
194   if (LapseRateVector[b] != 0.00) {
195     Lmb = LapseRateVector[b];
196     Exp = Mair/(Rstar*Lmb);
197     factor = Tmb/(Tmb + Lmb*deltaH);
198     pressure = PressureBreakpointVector[b]*pow(factor, Exp);
199   } else {
200     pressure = PressureBreakpointVector[b]*exp(-Mair*deltaH/(Rstar*Tmb));
201   }
202
203   return pressure;
204 }
205
206 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
207
208 void FGStandardAtmosphere::SetSeaLevelPressure(double pressure, ePressure unit)
209 {
210   double press = ConvertToPSF(pressure, unit);
211
212   PressureBreakpointVector[0] = press;
213   CalculatePressureBreakpoints();
214 }
215
216 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
217 // Get the modeled temperature at a specified altitude, including any bias or gradient
218 // effects.
219
220 double FGStandardAtmosphere::GetTemperature(double altitude) const
221 {
222   double T = StdAtmosTemperatureTable->GetValue(altitude) + TemperatureBias;
223   if (altitude <= GradientFadeoutAltitude)
224     T += TemperatureDeltaGradient * (GradientFadeoutAltitude - altitude);
225
226   return T;
227 }
228
229 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
230 // Retrieves the standard temperature at a particular altitude.
231
232 double FGStandardAtmosphere::GetStdTemperature(double altitude) const
233 {
234   double Lk9 = 0.00658368; // deg R per foot
235   double Tinf = 1800.0; // Same as 1000 Kelvin
236   double temp = Tinf;
237
238   if (altitude < 298556.4) {                // 91 km - station 8
239
240     temp = StdAtmosTemperatureTable->GetValue(altitude);
241
242   } else if (altitude < 360892.4) {        // 110 km - station 9
243
244     temp = 473.7429 - 137.38176 * sqrt(1.0 - pow((altitude - 298556.4)/65429.462, 2.0));
245
246   } else if (altitude < 393700.8) {        // 120 km - station 10
247
248     temp = 432 + Lk9 * (altitude - 360892.4);
249
250   } else if (altitude < 3280839.9) {        // 1000 km station 12
251
252     double lambda = 0.00001870364;
253     double eps = (altitude - 393700.8) * (20855531.5 + 393700.8) / (20855531.5 + altitude);
254     temp = Tinf - (Tinf - 648.0) * exp(-lambda*eps);
255
256   }
257
258   return temp;
259 }
260
261 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
262
263 double FGStandardAtmosphere::GetStdPressure(double altitude) const
264 {
265   double press=0;
266   if (TemperatureBias == 0.0 && TemperatureDeltaGradient == 0.0 && PressureBreakpointVector[0] == StdSLpressure) {
267     press = GetPressure(altitude);
268   } else if (altitude <= 100000.0) {
269     GetStdPressure100K(altitude);
270   } else {
271     // Cannot currently retrieve the standard pressure
272   }
273   return press;
274 }
275
276 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
277 // This function calculates an approximation of the standard atmospheric pressure
278 // up to an altitude of about 100,000 ft. If the temperature and pressure are not
279 // altered for local conditions, the GetPressure(h) function should be used,
280 // as that is valid to a much higher altitude. This function is accurate to within
281 // a couple of psf up to 100K ft. This polynomial fit was determined using Excel.
282
283 double FGStandardAtmosphere::GetStdPressure100K(double altitude) const
284 {
285   // Limit this equation to input altitudes of 100000 ft.
286   if (altitude > 100000.0) altitude = 100000.0;
287
288   double alt[6];
289   double coef[6] = { 2116.22,
290                     -7.583514352598E-02,
291                      1.045494405501E-06,
292                     -5.881341527124E-12,
293                      3.482031690718E-18,
294                      5.683922549284E-23 };
295
296   alt[0] = 1;
297   for (int pwr=1; pwr<=5; pwr++) alt[pwr] = alt[pwr-1]*altitude;
298
299   double press = 0.0;
300   for (int ctr=0; ctr<=5; ctr++) press += coef[ctr]*alt[ctr];
301   return press;
302 }
303
304 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
305 // Get the modeled density at a specified altitude
306
307 double FGStandardAtmosphere::GetDensity(double altitude) const
308 {
309   return GetPressure(altitude)/(Reng * GetTemperature(altitude));
310 }
311
312 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
313 // Get the standard density at a specified altitude
314
315 double FGStandardAtmosphere::GetStdDensity(double altitude) const
316 {
317   return GetStdPressure(altitude)/(Reng * GetStdTemperature(altitude));
318 }
319
320 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
321
322 void FGStandardAtmosphere::SetTemperatureBias(double t, eTemperature unit)
323 {
324   TemperatureBias = ConvertToRankine(t, unit);
325   CalculatePressureBreakpoints();
326 }
327
328 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
329 // This function calculates a bias based on the supplied temperature for sea
330 // level. The bias is applied to the entire temperature profile at all altitudes.
331 // Internally, the Rankine scale is used for calculations, so any temperature
332 // supplied must be converted to that unit.
333
334 void FGStandardAtmosphere::SetSLTemperature(double t, eTemperature unit)
335 {
336   double targetSLtemp = ConvertToRankine(t, unit);
337
338   TemperatureBias = targetSLtemp - GetStdTemperatureSL();
339   CalculatePressureBreakpoints();
340 }
341
342 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
343 // Sets a Sea Level temperature delta that is ramped out by 86 km (282,152 ft).
344
345 void FGStandardAtmosphere::SetSLTemperatureGradedDelta(double deltemp, eTemperature unit)
346 {
347   SetTemperatureGradedDelta(deltemp, 0.0, unit);
348 }
349
350 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
351 // Sets a temperature delta at the supplied altitude that is ramped out by 86 km.
352 // After this calculation is performed, the lapse rates and pressure breakpoints
353 // must be recalculated. Since we are calculating a delta here and not an actual
354 // temperature, we only need to be concerned about a scale factor and not
355 // the actual temperature itself.
356
357 void FGStandardAtmosphere::SetTemperatureGradedDelta(double deltemp, double h, eTemperature unit)
358 {
359   switch(unit) {
360   case eCelsius:
361   case eKelvin:
362     deltemp *= 9.0/5.0; // If temp delta is given in metric, scale up to English
363     break;
364   }
365   TemperatureDeltaGradient = deltemp/(GradientFadeoutAltitude - h);
366   CalculateLapseRates();
367   CalculatePressureBreakpoints();
368 }
369
370 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
371
372   void FGStandardAtmosphere::PrintStandardAtmosphereTable()
373 {
374   std::cout << "Altitude (ft)   Temp (F)   Pressure (psf)   Density (sl/ft3)" << std::endl;
375   std::cout << "-------------   --------   --------------   ----------------" << std::endl;
376   for (int i=0; i<280000; i+=1000) {
377     Calculate(i);
378     std::cout  << std::setw(12) << std::setprecision(2) << i
379        << "  " << std::setw(9)  << std::setprecision(2) << Temperature-459.67
380        << "  " << std::setw(13) << std::setprecision(4) << Pressure
381        << "  " << std::setw(18) << std::setprecision(8) << Density
382        << std::endl;
383   }
384
385   // Re-execute the Run() method to reset the calculated values
386   Run(false);
387 }
388
389 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
390 // This function calculates (or recalculates) the lapse rate over an altitude range
391 // where the "bh" in this case refers to the index of the base height in the 
392 // StdAtmosTemperatureTable table. This function should be called anytime the 
393 // temperature table is altered, such as when a gradient is applied across the 
394 // temperature table for a range of altitudes.
395
396 void FGStandardAtmosphere::CalculateLapseRates()
397 {
398   for (unsigned int bh=0; bh<LapseRateVector.size(); bh++)
399   {
400     double t0 = (*StdAtmosTemperatureTable)(bh+1,1);
401     double t1 = (*StdAtmosTemperatureTable)(bh+2,1);
402     double h0 = (*StdAtmosTemperatureTable)(bh+1,0);
403     double h1 = (*StdAtmosTemperatureTable)(bh+2,0);
404     LapseRateVector[bh] = (t1 - t0) / (h1 - h0) + TemperatureDeltaGradient;
405   }
406 }
407
408 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
409
410 void FGStandardAtmosphere::CalculatePressureBreakpoints()
411 {
412   for (unsigned int b=0; b<PressureBreakpointVector.size()-1; b++) {
413     double BaseTemp = (*StdAtmosTemperatureTable)(b+1,1);
414     double BaseAlt = (*StdAtmosTemperatureTable)(b+1,0);
415     double UpperAlt = (*StdAtmosTemperatureTable)(b+2,0);
416     double deltaH = UpperAlt - BaseAlt;
417     double Tmb = BaseTemp
418                  + TemperatureBias 
419                  + (GradientFadeoutAltitude - BaseAlt)*TemperatureDeltaGradient;
420     if (LapseRateVector[b] != 0.00) {
421       double Lmb = LapseRateVector[b];
422       double Exp = Mair/(Rstar*Lmb);
423       double factor = Tmb/(Tmb + Lmb*deltaH);
424       PressureBreakpointVector[b+1] = PressureBreakpointVector[b]*pow(factor, Exp);
425     } else {
426       PressureBreakpointVector[b+1] = PressureBreakpointVector[b]*exp(-Mair*deltaH/(Rstar*Tmb));
427     }
428   }
429 }
430
431 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
432
433 void FGStandardAtmosphere::ResetSLTemperature()
434 {
435   TemperatureBias = TemperatureDeltaGradient = 0.0;
436   CalculateLapseRates();
437   CalculatePressureBreakpoints();
438 }
439
440 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
441
442 void FGStandardAtmosphere::ResetSLPressure()
443 {
444   PressureBreakpointVector[0] = StdSLpressure; // psf
445   CalculatePressureBreakpoints();
446 }
447
448 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
449
450 double FGStandardAtmosphere::ConvertToRankine(double t, eTemperature unit) const
451 {
452   double targetTemp=0; // in degrees Rankine
453
454   switch(unit) {
455   case eFahrenheit:
456     targetTemp = t + 459.67;
457     break;
458   case eCelsius:
459     targetTemp = t*9.0/5.0 + 32.0 + 459.67;
460     break;
461   case eRankine:
462     targetTemp = t;
463     break;
464   case eKelvin:
465     targetTemp = t*9.0/5.0;
466   }
467
468   return targetTemp;
469 }
470
471 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
472
473 double FGStandardAtmosphere::ConvertToPSF(double p, ePressure unit) const
474 {
475   double targetPressure=0; // Pressure in PSF
476
477   switch(unit) {
478   case ePSF:
479     targetPressure = p;
480     break;
481   case eMillibars:
482     targetPressure = p*2.08854342;
483     break;
484   case ePascals:
485     targetPressure = p*0.0208854342;
486     break;
487   case eInchesHg:
488     targetPressure = p*70.7180803;
489     break;
490   default:
491     throw("Undefined pressure unit given");
492   }
493
494   return targetPressure;
495 }
496
497 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
498
499 void FGStandardAtmosphere::bind(void)
500 {
501   typedef double (FGStandardAtmosphere::*PMFi)(int) const;
502   typedef void (FGStandardAtmosphere::*PMF)(int, double);
503   PropertyManager->Tie("stdatmosphere/T-R", this, &FGStandardAtmosphere::GetTemperature);
504   PropertyManager->Tie("stdatmosphere/rho-slugs_ft3", this, &FGStandardAtmosphere::GetDensity);
505   PropertyManager->Tie("stdatmosphere/P-psf", this, &FGStandardAtmosphere::GetPressure);
506   PropertyManager->Tie("stdatmosphere/a-fps", this, &FGStandardAtmosphere::GetSoundSpeed);
507   PropertyManager->Tie("stdatmosphere/T-sl-R", this, &FGStandardAtmosphere::GetTemperatureSL);
508   PropertyManager->Tie("stdatmosphere/rho-sl-slugs_ft3", this, &FGStandardAtmosphere::GetDensitySL);
509   PropertyManager->Tie("stdatmosphere/P-sl-psf", this, &FGStandardAtmosphere::GetPressureSL);
510   PropertyManager->Tie("stdatmosphere/a-sl-fps", this, &FGStandardAtmosphere::GetSoundSpeedSL);
511   PropertyManager->Tie("stdatmosphere/theta", this, &FGStandardAtmosphere::GetTemperatureRatio);
512   PropertyManager->Tie("stdatmosphere/sigma", this, &FGStandardAtmosphere::GetDensityRatio);
513   PropertyManager->Tie("stdatmosphere/delta", this, &FGStandardAtmosphere::GetPressureRatio);
514   PropertyManager->Tie("stdatmosphere/a-ratio", this, &FGStandardAtmosphere::GetSoundSpeedRatio);
515   PropertyManager->Tie("stdatmosphere/delta-T", this, eRankine,
516                                     (PMFi)&FGStandardAtmosphere::GetTemperatureBias,
517                                     (PMF)&FGStandardAtmosphere::SetTemperatureBias);
518 //  PropertyManager->Tie("atmosphere/density-altitude", this, &FGStandardAtmosphere::GetDensityAltitude);
519 }
520
521 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
522 //    The bitmasked value choices are as follows:
523 //    unset: In this case (the default) JSBSim would only print
524 //       out the normally expected messages, essentially echoing
525 //       the config files as they are read. If the environment
526 //       variable is not set, debug_lvl is set to 1 internally
527 //    0: This requests JSBSim not to output any messages
528 //       whatsoever.
529 //    1: This value explicity requests the normal JSBSim
530 //       startup messages
531 //    2: This value asks for a message to be printed out when
532 //       a class is instantiated
533 //    4: When this value is set, a message is displayed when a
534 //       FGModel object executes its Run() method
535 //    8: When this value is set, various runtime state variables
536 //       are printed out periodically
537 //    16: When set various parameters are sanity checked and
538 //       a message is printed out when they go out of bounds
539
540 void FGStandardAtmosphere::Debug(int from)
541 {
542   if (debug_lvl <= 0) return;
543
544   if (debug_lvl & 1) { // Standard console startup message output
545     if (from == 0) { // Constructor
546     }
547   }
548   if (debug_lvl & 2 ) { // Instantiation/Destruction notification
549     if (from == 0) std::cout << "Instantiated: FGStandardAtmosphere" << std::endl;
550     if (from == 1) std::cout << "Destroyed:    FGStandardAtmosphere" << std::endl;
551   }
552   if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
553   }
554   if (debug_lvl & 8 ) { // Runtime state variables
555   }
556   if (debug_lvl & 16) { // Sanity checking
557   }
558   if (debug_lvl & 128) { // 
559   }
560   if (debug_lvl & 64) {
561     if (from == 0) { // Constructor
562       std::cout << IdSrc << std::endl;
563       std::cout << IdHdr << std::endl;
564     }
565   }
566 }
567
568 } // namespace JSBSim