48 #include "FGFDMExec.h" 49 #include "FGStandardAtmosphere.h" 53 IDENT(IdSrc,
"$Id: FGStandardAtmosphere.cpp,v 1.24 2014/05/17 15:07:48 jberndt Exp $");
54 IDENT(IdHdr,ID_STANDARDATMOSPHERE);
62 TemperatureDeltaGradient(0.0)
64 Name =
"FGStandardAtmosphere";
66 StdAtmosTemperatureTable =
new FGTable(9);
88 *StdAtmosTemperatureTable << 0.0000 << 518.67
89 << 36089.2388 << 389.97
90 << 65616.7979 << 389.97
91 << 104986.8766 << 411.57
92 << 154199.4751 << 487.17
93 << 167322.8346 << 487.17
94 << 232939.6325 << 386.37
95 << 278385.8268 << 336.50
96 << 298556.40 << 336.50;
98 LapseRateVector.resize(StdAtmosTemperatureTable->GetNumRows()-1);
99 PressureBreakpointVector.resize(StdAtmosTemperatureTable->GetNumRows());
104 GradientFadeoutAltitude = (*StdAtmosTemperatureTable)(StdAtmosTemperatureTable->GetNumRows(),0);
114 delete StdAtmosTemperatureTable;
115 LapseRateVector.clear();
121 bool FGStandardAtmosphere::InitModel(
void)
123 PressureBreakpointVector[0] = StdSLpressure = 2116.22;
124 TemperatureDeltaGradient = 0.0;
125 TemperatureBias = 0.0;
129 StdSLtemperature = SLtemperature = Temperature;
130 SLpressure = Pressure;
131 StdSLdensity = SLdensity = Density;
132 StdSLsoundspeed = SLsoundspeed = Soundspeed;
134 rSLtemperature = 1/SLtemperature ;
135 rSLpressure = 1/SLpressure ;
136 rSLdensity = 1/SLdensity ;
137 rSLsoundspeed = 1/SLsoundspeed ;
152 double pressure = 0.0;
153 double Lmb, Exp, Tmb, deltaH, factor;
154 double numRows = StdAtmosTemperatureTable->GetNumRows();
161 double testAlt = (*StdAtmosTemperatureTable)(b+1,0);
162 double GeoPotAlt = (altitude*20855531.5)/(20855531.5+altitude);
163 while ((GeoPotAlt >= testAlt) && (b <= numRows-2)) {
165 testAlt = (*StdAtmosTemperatureTable)(b+1,0);
169 double BaseAlt = (*StdAtmosTemperatureTable)(b+1,0);
171 deltaH = GeoPotAlt - BaseAlt;
173 if (LapseRateVector[b] != 0.00) {
174 Lmb = LapseRateVector[b];
175 Exp = Mair/(Rstar*Lmb);
176 factor = Tmb/(Tmb + Lmb*deltaH);
177 pressure = PressureBreakpointVector[b]*pow(factor, Exp);
179 pressure = PressureBreakpointVector[b]*exp(-Mair*deltaH/(Rstar*Tmb));
189 double press = ConvertToPSF(pressure, unit);
191 PressureBreakpointVector[0] = press;
201 double GeoPotAlt = (altitude*20855531.5)/(20855531.5+altitude);
203 double T = StdAtmosTemperatureTable->GetValue(GeoPotAlt) + TemperatureBias;
204 if (altitude <= GradientFadeoutAltitude)
205 T += TemperatureDeltaGradient * (GradientFadeoutAltitude - altitude);
215 double Lk9 = 0.00658368;
216 double Tinf = 1800.0;
219 if (altitude < 298556.4) {
221 double GeoPotAlt = (altitude*20855531.5)/(20855531.5+altitude);
222 temp = StdAtmosTemperatureTable->GetValue(GeoPotAlt);
224 }
else if (altitude < 360892.4) {
226 temp = 473.7429 - 137.38176 * sqrt(1.0 - pow((altitude - 298556.4)/65429.462, 2.0));
228 }
else if (altitude < 393700.8) {
230 temp = 432 + Lk9 * (altitude - 360892.4);
232 }
else if (altitude < 3280839.9) {
234 double lambda = 0.00001870364;
235 double eps = (altitude - 393700.8) * (20855531.5 + 393700.8) / (20855531.5 + altitude);
236 temp = Tinf - (Tinf - 648.0) * exp(-lambda*eps);
248 if (TemperatureBias == 0.0 && TemperatureDeltaGradient == 0.0 && PressureBreakpointVector[0] == StdSLpressure) {
250 }
else if (altitude <= 100000.0) {
268 if (altitude > 100000.0) altitude = 100000.0;
271 const double coef[5] = { 2116.217,
278 for (
int pwr=1; pwr<=4; pwr++) alt[pwr] = alt[pwr-1]*altitude;
281 for (
int ctr=0; ctr<=4; ctr++) press += coef[ctr]*alt[ctr];
297 double targetSLtemp = ConvertToRankine(t, unit);
299 TemperatureBias = 0.0;
308 if (unit == eCelsius || unit == eKelvin)
343 if (unit == eCelsius || unit == eKelvin)
346 TemperatureDeltaGradient = deltemp/(GradientFadeoutAltitude - h);
355 std::cout <<
"Altitude (ft) Temp (F) Pressure (psf) Density (sl/ft3)" << std::endl;
356 std::cout <<
"------------- -------- -------------- ----------------" << std::endl;
357 for (
int i=0; i<280000; i+=1000) {
359 std::cout << std::setw(12) << std::setprecision(2) << i
360 <<
" " << std::setw(9) << std::setprecision(2) << Temperature - 459.67
361 <<
" " << std::setw(13) << std::setprecision(4) << Pressure
362 <<
" " << std::setw(18) << std::setprecision(8) << Density
379 for (
unsigned int bh=0; bh<LapseRateVector.size(); bh++)
381 double t0 = (*StdAtmosTemperatureTable)(bh+1,1);
382 double t1 = (*StdAtmosTemperatureTable)(bh+2,1);
383 double h0 = (*StdAtmosTemperatureTable)(bh+1,0);
384 double h1 = (*StdAtmosTemperatureTable)(bh+2,0);
385 LapseRateVector[bh] = (t1 - t0) / (h1 - h0) + TemperatureDeltaGradient;
393 for (
unsigned int b=0; b<PressureBreakpointVector.size()-1; b++) {
394 double BaseTemp = (*StdAtmosTemperatureTable)(b+1,1);
395 double BaseAlt = (*StdAtmosTemperatureTable)(b+1,0);
396 double UpperAlt = (*StdAtmosTemperatureTable)(b+2,0);
397 double deltaH = UpperAlt - BaseAlt;
398 double Tmb = BaseTemp
400 + (GradientFadeoutAltitude - BaseAlt)*TemperatureDeltaGradient;
401 if (LapseRateVector[b] != 0.00) {
402 double Lmb = LapseRateVector[b];
403 double Exp = Mair/(Rstar*Lmb);
404 double factor = Tmb/(Tmb + Lmb*deltaH);
405 PressureBreakpointVector[b+1] = PressureBreakpointVector[b]*pow(factor, Exp);
407 PressureBreakpointVector[b+1] = PressureBreakpointVector[b]*exp(-Mair*deltaH/(Rstar*Tmb));
416 TemperatureBias = TemperatureDeltaGradient = 0.0;
425 PressureBreakpointVector[0] = StdSLpressure;
431 void FGStandardAtmosphere::bind(
void)
435 PropertyManager->
Tie(
"atmosphere/delta-T",
this, eRankine,
438 PropertyManager->
Tie(
"atmosphere/SL-graded-delta-T",
this, eRankine,
441 PropertyManager->
Tie(
"atmosphere/P-sl-psf",
this, ePSF,
442 (PMFi)&FGStandardAtmosphere::GetPressureSL,
465 void FGStandardAtmosphere::Debug(
int from)
467 if (debug_lvl <= 0)
return;
473 if (debug_lvl & 2 ) {
474 if (from == 0) std::cout <<
"Instantiated: FGStandardAtmosphere" << std::endl;
475 if (from == 1) std::cout <<
"Destroyed: FGStandardAtmosphere" << std::endl;
477 if (debug_lvl & 4 ) {
479 if (debug_lvl & 8 ) {
481 if (debug_lvl & 16) {
483 if (debug_lvl & 128) {
485 if (debug_lvl & 64) {
487 std::cout << IdSrc << std::endl;
488 std::cout << IdHdr << std::endl;
virtual double GetStdDensity(double altitude) const
Returns the standard density at a specified altitude.
virtual double GetTemperatureBias(eTemperature to) const
Returns the temperature bias over the sea level value in degrees Rankine.
void CalculateLapseRates()
Recalculate the lapse rate vectors when the temperature profile is altered in a way that would change...
void Calculate(double altitude)
Calculate the atmosphere for the given altitude.
virtual void SetTemperatureSL(double t, eTemperature unit=eFahrenheit)
Sets the Sea Level temperature, if it is to be different than the standard.
virtual void SetTemperature(double t, double h, eTemperature unit=eFahrenheit)
Sets the temperature at the supplied altitude, if it is to be different than the standard temperature...
ePressure
Enums for specifying pressure units.
virtual double GetPressure(void) const
Returns the pressure in psf.
virtual void PrintStandardAtmosphereTable()
Prints the U.S. Standard Atmosphere table.
FGStandardAtmosphere(FGFDMExec *)
Constructor.
virtual void SetTemperatureGradedDelta(double t, double h, eTemperature unit=eFahrenheit)
Sets the temperature delta value at the supplied altitude/elevation above sea level, to be added to the standard temperature and ramped out by 86 km.
void Tie(const std::string &name, bool *pointer, bool useDefault=true)
Tie a property to an external bool variable.
virtual double GetStdPressure(double altitude) const
Returns the standard pressure at the specified altitude.
void CalculatePressureBreakpoints()
Calculate (or recalculate) the atmospheric pressure breakpoints at the altitudes in the standard temp...
bool Run(bool Holding)
Runs the atmosphere forces model; called by the Executive.
Models an empty, abstract base atmosphere class.
virtual void SetPressureSL(ePressure unit, double pressure)
Sets the sea level pressure for modeling an off-standard pressure profile.
virtual void SetTemperatureBias(eTemperature unit, double t)
Sets the temperature bias to be added to the standard temperature at all altitudes.
virtual void ResetSLTemperature()
This function resets the model to apply no bias or delta gradient to the temperature.
virtual double GetTemperatureDeltaGradient(eTemperature to)
Returns the temperature gradient to be applied on top of the standard temperature gradient...
virtual ~FGStandardAtmosphere()
Destructor.
eTemperature
Enums for specifying temperature units.
virtual void ResetSLPressure()
Resets the sea level to the Standard sea level pressure, and recalculates dependent parameters so tha...
virtual double GetStdTemperature(double altitude) const
Returns the standard temperature in degrees Rankine at a specified altitude.
Encapsulates the JSBSim simulation executive.
virtual double GetTemperature() const
Returns the actual, modeled temperature at the current altitude in degrees Rankine.
virtual void SetSLTemperatureGradedDelta(eTemperature unit, double t)
Sets a Sea Level temperature delta that is ramped out by 86 km.
virtual double GetStdPressure100K(double altitude) const
Returns the standard pressure at a specified altitude in psf.