JSBSim Flight Dynamics Model 1.3.0 (09 Apr 2026)
An Open Source Flight Dynamics and Control Software Library in C++
Loading...
Searching...
No Matches
FGMSIS.cpp
1/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2
3 Module: FGMSIS.cpp
4 Author: David Culp
5 (incorporated into C++ JSBSim class hierarchy, see model authors below)
6 Date started: 12/14/03
7 Purpose: Models the MSIS-00 atmosphere
8
9 ------------- Copyright (C) 2003 David P. Culp (davidculp2@comcast.net) ------
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
28FUNCTIONAL DESCRIPTION
29--------------------------------------------------------------------------------
30Models the MSIS-00 atmosphere. Provides temperature and density to FGAtmosphere,
31given day-of-year, time-of-day, altitude, latitude, longitude and local time.
32
33HISTORY
34--------------------------------------------------------------------------------
3512/14/03 DPC Created
3601/11/04 DPC Derived from FGAtmosphere
3703/18/23 BC Refactored
38
39 --------------------------------------------------------------------
40 --------- N R L M S I S E - 0 0 M O D E L 2 0 0 1 ----------
41 --------------------------------------------------------------------
42
43 This file is part of the NRLMSISE-00 C source code package - release
44 20020503
45
46 The NRLMSISE-00 model was developed by Mike Picone, Alan Hedin, and
47 Doug Drob. They also wrote a NRLMSISE-00 distribution package in
48 FORTRAN which is available at
49 http://uap-www.nrl.navy.mil/models_web/msis/msis_home.htm
50
51 Dominik Brodowski implemented and maintains this C version. You can
52 reach him at devel@brodo.de. See the file "DOCUMENTATION" for details,
53 and check http://www.brodo.de/english/pub/nrlmsise/index.html for
54 updated releases of this package.
55*/
56
57/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
58INCLUDES
59%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
60
61#include "FGFDMExec.h"
62#include "FGMSIS.h"
63#include "input_output/FGLog.h"
64
65using namespace std;
66
67namespace JSBSim {
68
69/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
70CLASS IMPLEMENTATION
71%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
72
73
75{
76 Name = "MSIS";
77
78 for(unsigned int i=0; i<24; ++i)
79 flags.switches[i] = 1;
80 input.year = 0; // Ignored by NRLMSIS
81 input.f107A = 150.;
82 input.f107 = 150.;
83 input.ap = 4.;
84 input.ap_a = nullptr;
85
86 Debug(0);
87}
88
89//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
90
92{
93 Debug(1);
94}
95
96//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
97
99{
100 FGStandardAtmosphere::InitModel();
101
102 Calculate(0.0);
103
104 return true;
105}
106
107//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
108
109bool FGMSIS::Load(Element* el)
110{
111 if (!Upload(el, true)) return false;
112
113 if (el->FindElement("day"))
114 day_of_year = el->FindElementValueAsNumber("day");
115 if (el->FindElement("utc"))
116 seconds_in_day = el->FindElementValueAsNumber("utc");
117
118 Debug(3);
119
120 return true;
121}
122
123//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
124
125void FGMSIS::Calculate(double altitude)
126{
127 double SLRair = 0.0;
128
129 Compute(0.0, SLpressure, SLtemperature, SLdensity, SLRair);
130 Compute(altitude, Pressure, Temperature, Density, Reng);
131
132 SLsoundspeed = sqrt(SHRatio*SLRair*SLtemperature);
133 Soundspeed = sqrt(SHRatio*Reng*Temperature);
134 PressureAltitude = CalculatePressureAltitude(Pressure, altitude);
135 DensityAltitude = CalculateDensityAltitude(Density, altitude);
136
137 Viscosity = Beta * pow(Temperature, 1.5) / (SutherlandConstant + Temperature);
138 KinematicViscosity = Viscosity / Density;
139 // SaturatedVaporPressure = CalculateVaporPressure(Temperature);
140 // ValidateVaporMassFraction(altitude);
141}
142
143//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
144
145void FGMSIS::Compute(double altitude, double& pressure, double& temperature,
146 double& density, double &Rair) const
147{
148 constexpr double fttokm = fttom / 1000.;
149 constexpr double kgm3_to_slugft3 = kgtoslug / m3toft3;
150 constexpr double gtoslug = kgtoslug / 1000.;
151 // Molecular weight (g/mol)
152 // N2 O2 O He H Ar N OA
153 const double species_mmol[8] {28.0134, 31.9988, 31.9988/2.0, 4.0, 1.0, 39.948,
154 28.0134/2.0, 31.9988/2.0};
155
156 double dn[10] {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
157 double h = altitude*fttokm;
158 double lat = in.GeodLatitudeDeg;
159 double lon = in.LongitudeDeg;
160
161 // Compute epoch
162 double utc_seconds = seconds_in_day + FDMExec->GetSimTime();
163 unsigned int days = utc_seconds / 86400.;
164 utc_seconds -= days * 86400.;
165 double today = day_of_year + days;
166 unsigned int year = today / 365.;
167 today -= year * 365.;
168
169 struct nrlmsise_output output;
170
171 input.doy = today;
172 input.sec = utc_seconds;
173 input.alt = h;
174 input.g_lat = lat;
175 input.g_long = lon;
176 input.lst = utc_seconds/3600 + lon/15; // Local Solar Time (hours)
177 assert(flags.switches[9] != -1); // Make sure that input.ap is used.
178
179 gtd7(&input, &flags, &output);
180
181 temperature = KelvinToRankine(output.t[1]);
182 density = output.d[5] * kgm3_to_slugft3;
183 dn[1] = output.d[2]; // N2
184 dn[2] = output.d[3]; // O2
185 dn[3] = output.d[1]; // O
186 dn[4] = output.d[0]; // He
187 dn[5] = output.d[6]; // H
188 dn[6] = output.d[4]; // Ar
189 dn[7] = output.d[7]; // N
190 // SUBROUTINE GTD7 does NOT include anomalous oxygen so we drop it from
191 // the molar mass computation as well for consistency.
192 dn[8] = 0.0; // OA
193
194 // Compute specific gas constant for air
195 double mmol = 0.0;
196 double qty_mol = 0.0;
197
198 for (unsigned int i=1; i<9; ++i) {
199 mmol += dn[i]*species_mmol[i-1];
200 qty_mol += dn[i];
201 }
202 double mair = mmol * gtoslug / qty_mol;
203 Rair = Rstar / mair;
204
205 pressure = density * Rair * temperature;
206}
207
208//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
209// The bitmasked value choices are as follows:
210// unset: In this case (the default) JSBSim would only print
211// out the normally expected messages, essentially echoing
212// the config files as they are read. If the environment
213// variable is not set, debug_lvl is set to 1 internally
214// 0: This requests JSBSim not to output any messages
215// whatsoever.
216// 1: This value explicitly requests the normal JSBSim
217// startup messages
218// 2: This value asks for a message to be printed out when
219// a class is instantiated
220// 4: When this value is set, a message is displayed when a
221// FGModel object executes its Run() method
222// 8: When this value is set, various runtime state variables
223// are printed out periodically
224// 16: When set various parameters are sanity checked and
225// a message is printed out when they go out of bounds
226
227void FGMSIS::Debug(int from)
228{
229 if (debug_lvl <= 0) return;
230
231 if (debug_lvl & 1) { // Standard console startup message output
232 if (from == 0) {} // Constructor
233 if (from == 3) { // Loading
234 FGLogging log(LogLevel::DEBUG);
235 log << " NRLMSIS atmosphere model\n" << fixed;
236 log << " day: " << day_of_year << "\n";
237 log << " UTC: " << seconds_in_day << "\n\n";
238 }
239 }
240 if (debug_lvl & 2 ) { // Instantiation/Destruction notification
241 FGLogging log(LogLevel::DEBUG);
242 if (from == 0) log << "Instantiated: MSIS\n";
243 if (from == 1) log << "Destroyed: MSIS\n";
244 }
245 if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
246 }
247 if (debug_lvl & 8 ) { // Runtime state variables
248 }
249 if (debug_lvl & 16) { // Sanity checking
250 }
251 if (debug_lvl & 128) { //
252 }
253 if (debug_lvl & 64) {
254 if (from == 0) { // Constructor
255 }
256 }
257}
258
259} // namespace JSBSim
Element * FindElement(const std::string &el="")
Searches for a specified element.
double FindElementValueAsNumber(const std::string &el="")
Searches for the named element and returns the data belonging to it as a number.
static constexpr double Rstar
Universal gas constant - ft*lbf/R/mol.
Encapsulates the JSBSim simulation executive.
Definition FGFDMExec.h:185
double GetSimTime(void) const
Returns the cumulative simulation time in seconds.
Definition FGFDMExec.h:550
static constexpr double KelvinToRankine(double kelvin)
Converts from degrees Kelvin to degrees Rankine.
Definition FGJSBBase.h:207
void Calculate(double altitude) override
Calculate the atmosphere for the given altitude.
Definition FGMSIS.cpp:125
~FGMSIS()
Destructor.
Definition FGMSIS.cpp:91
bool InitModel(void) override
Runs the MSIS-00 atmosphere model; called by the Executive Can pass in a value indicating if the exec...
Definition FGMSIS.cpp:98
FGMSIS(FGFDMExec *)
Constructor.
Definition FGMSIS.cpp:74
bool Upload(Element *el, bool preLoad)
Uploads this model in memory.
Definition FGModel.cpp:111
double CalculateDensityAltitude(double density, double geometricAlt) override
Calculates the density altitude given any temperature or pressure bias.
double CalculatePressureAltitude(double pressure, double geometricAlt) override
Calculates the pressure altitude given any temperature or pressure bias.
Main namespace for the JSBSim Flight Dynamics Model.
Definition FGFDMExec.cpp:71