JSBSim Flight Dynamics Model  1.1.11 (13 Feb 2022)
An Open Source Flight Dynamics and Control Software Library in C++
FGMSIS.h
1 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2 
3  Header: FGMSIS.h
4  Description: MSIS-00 Atmosphere
5  Author: David Culp
6  Date started: 12/14/03
7 
8  ------------- Copyright (C) 2003 David P. Culp (davidculp2@comcast.net) ------
9 
10  This program is free software; you can redistribute it and/or modify it under
11  the terms of the GNU Lesser General Public License as published by the Free Software
12  Foundation; either version 2 of the License, or (at your option) any later
13  version.
14 
15  This program is distributed in the hope that it will be useful, but WITHOUT
16  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17  FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
18  details.
19 
20  You should have received a copy of the GNU Lesser General Public License along with
21  this program; if not, write to the Free Software Foundation, Inc., 59 Temple
22  Place - Suite 330, Boston, MA 02111-1307, USA.
23 
24  Further information about the GNU Lesser General Public License can also be found on
25  the world wide web at http://www.gnu.org.
26 
27 HISTORY
28 --------------------------------------------------------------------------------
29 12/14/03 DPC Created
30 01/11/04 DPC Derive from FGAtmosphere
31 
32 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
33 SENTRY
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
35 
36 #ifndef FGMSIS_H
37 #define FGMSIS_H
38 
39 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
40 INCLUDES
41 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
42 
43 #include "models/FGAtmosphere.h"
44 #include "FGFDMExec.h"
45 
46 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
47 FORWARD DECLARATIONS
48 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
49 
50 namespace JSBSim {
51 
52 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
53 CLASS DOCUMENTATION
54 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
55 
74 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
75 STRUCT DECLARATIONS
76 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
77 
79  int switches[24];
80  double sw[24];
81  double swc[24];
82 };
83 /*
84  * Switches: to turn on and off particular variations use these switches.
85  * 0 is off, 1 is on, and 2 is main effects off but cross terms on.
86  *
87  * Standard values are 0 for switch 0 and 1 for switches 1 to 23. The
88  * array "switches" needs to be set accordingly by the calling program.
89  * The arrays sw and swc are set internally.
90  *
91  * switches[i]:
92  * i - explanation
93  * -----------------
94  * 0 - output in centimeters instead of meters
95  * 1 - F10.7 effect on mean
96  * 2 - time independent
97  * 3 - symmetrical annual
98  * 4 - symmetrical semiannual
99  * 5 - asymmetrical annual
100  * 6 - asymmetrical semiannual
101  * 7 - diurnal
102  * 8 - semidiurnal
103  * 9 - daily ap [when this is set to -1 (!) the pointer
104  * ap_a in struct nrlmsise_input must
105  * point to a struct ap_array]
106  * 10 - all UT/long effects
107  * 11 - longitudinal
108  * 12 - UT and mixed UT/long
109  * 13 - mixed AP/UT/LONG
110  * 14 - terdiurnal
111  * 15 - departures from diffusive equilibrium
112  * 16 - all TINF var
113  * 17 - all TLB var
114  * 18 - all TN1 var
115  * 19 - all S var
116  * 20 - all TN2 var
117  * 21 - all NLB var
118  * 22 - all TN3 var
119  * 23 - turbo scale height var
120  */
121 
122 struct ap_array {
123  double a[7];
124 };
125 /* Array containing the following magnetic values:
126  * 0 : daily AP
127  * 1 : 3 hr AP index for current time
128  * 2 : 3 hr AP index for 3 hrs before current time
129  * 3 : 3 hr AP index for 6 hrs before current time
130  * 4 : 3 hr AP index for 9 hrs before current time
131  * 5 : Average of eight 3 hr AP indicies from 12 to 33 hrs
132  * prior to current time
133  * 6 : Average of eight 3 hr AP indicies from 36 to 57 hrs
134  * prior to current time
135  */
136 
137 
139  int year; /* year, currently ignored */
140  int doy; /* day of year */
141  double sec; /* seconds in day (UT) */
142  double alt; /* altitude in kilometers */
143  double g_lat; /* geodetic latitude */
144  double g_long; /* geodetic longitude */
145  double lst; /* local apparent solar time (hours), see note below */
146  double f107A; /* 81 day average of F10.7 flux (centered on DOY) */
147  double f107; /* daily F10.7 flux for previous day */
148  double ap; /* magnetic index(daily) */
149  struct ap_array *ap_a; /* see above */
150 };
151 /*
152  * NOTES ON INPUT VARIABLES:
153  * UT, Local Time, and Longitude are used independently in the
154  * model and are not of equal importance for every situation.
155  * For the most physically realistic calculation these three
156  * variables should be consistent (lst=sec/3600 + g_long/15).
157  * The Equation of Time departures from the above formula
158  * for apparent local time can be included if available but
159  * are of minor importance.
160  *
161  * f107 and f107A values used to generate the model correspond
162  * to the 10.7 cm radio flux at the actual distance of the Earth
163  * from the Sun rather than the radio flux at 1 AU. The following
164  * site provides both classes of values:
165  * ftp://ftp.ngdc.noaa.gov/STP/SOLAR_DATA/SOLAR_RADIO/FLUX/
166  *
167  * f107, f107A, and ap effects are neither large nor well
168  * established below 80 km and these parameters should be set to
169  * 150., 150., and 4. respectively.
170  */
171 
172 
173 
174 /* ------------------------------------------------------------------- */
175 /* ------------------------------ OUTPUT ----------------------------- */
176 /* ------------------------------------------------------------------- */
177 
179  double d[9]; /* densities */
180  double t[2]; /* temperatures */
181 };
182 /*
183  * OUTPUT VARIABLES:
184  * d[0] - HE NUMBER DENSITY(CM-3)
185  * d[1] - O NUMBER DENSITY(CM-3)
186  * d[2] - N2 NUMBER DENSITY(CM-3)
187  * d[3] - O2 NUMBER DENSITY(CM-3)
188  * d[4] - AR NUMBER DENSITY(CM-3)
189  * d[5] - TOTAL MASS DENSITY(GM/CM3) [includes d[8] in td7d]
190  * d[6] - H NUMBER DENSITY(CM-3)
191  * d[7] - N NUMBER DENSITY(CM-3)
192  * d[8] - Anomalous oxygen NUMBER DENSITY(CM-3)
193  * t[0] - EXOSPHERIC TEMPERATURE
194  * t[1] - TEMPERATURE AT ALT
195  *
196  *
197  * O, H, and N are set to zero below 72.5 km
198  *
199  * t[0], Exospheric temperature, is set to global average for
200  * altitudes below 120 km. The 120 km gradient is left at global
201  * average value for altitudes below 72 km.
202  *
203  * d[5], TOTAL MASS DENSITY, is NOT the same for subroutines GTD7
204  * and GTD7D
205  *
206  * SUBROUTINE GTD7 -- d[5] is the sum of the mass densities of the
207  * species labeled by indices 0-4 and 6-7 in output variable d.
208  * This includes He, O, N2, O2, Ar, H, and N but does NOT include
209  * anomalous oxygen (species index 8).
210  *
211  * SUBROUTINE GTD7D -- d[5] is the "effective total mass density
212  * for drag" and is the sum of the mass densities of all species
213  * in this model, INCLUDING anomalous oxygen.
214  */
215 
216 
217 
218 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
219 CLASS DECLARATION
220 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
221 
222 class MSIS : public FGAtmosphere
223 {
224 public:
225 
227  MSIS(FGFDMExec*);
229  ~MSIS();
237  bool Run(bool Holding);
238 
239  bool InitModel(void);
240 
242  void UseExternal(void);
243 
244 private:
245 
246  void Calculate(int day, // day of year (1 to 366)
247  double sec, // seconds in day (0.0 to 86400.0)
248  double alt, // altitude, feet
249  double lat, // geodetic latitude, degrees
250  double lon // geodetic longitude, degrees
251  );
252 
253  void Debug(int from);
254 
255  nrlmsise_flags flags;
256  nrlmsise_input input;
257  nrlmsise_output output;
258  ap_array aph;
259 
260  /* PARMB */
261  double gsurf;
262  double re;
263 
264  /* GTS3C */
265  double dd;
266 
267  /* DMIX */
268  double dm04, dm16, dm28, dm32, dm40, dm01, dm14;
269 
270  /* MESO7 */
271  double meso_tn1[5];
272  double meso_tn2[4];
273  double meso_tn3[5];
274  double meso_tgn1[2];
275  double meso_tgn2[2];
276  double meso_tgn3[2];
277 
278  /* LPOLY */
279  double dfa;
280  double plg[4][9];
281  double ctloc, stloc;
282  double c2tloc, s2tloc;
283  double s3tloc, c3tloc;
284  double apdf, apt[4];
285 
286  void tselec(struct nrlmsise_flags *flags);
287  void glatf(double lat, double *gv, double *reff);
288  double ccor(double alt, double r, double h1, double zh);
289  double ccor2(double alt, double r, double h1, double zh, double h2);
290  double scalh(double alt, double xm, double temp);
291  double dnet(double dd, double dm, double zhm, double xmm, double xm);
292  void splini(double *xa, double *ya, double *y2a, int n, double x, double *y);
293  void splint(double *xa, double *ya, double *y2a, int n, double x, double *y);
294  void spline(double *x, double *y, int n, double yp1, double ypn, double *y2);
295  double zeta(double zz, double zl);
296  double densm(double alt, double d0, double xm, double *tz, int mn3, double *zn3,
297  double *tn3, double *tgn3, int mn2, double *zn2, double *tn2,
298  double *tgn2);
299  double densu(double alt, double dlb, double tinf, double tlb, double xm,
300  double alpha, double *tz, double zlb, double s2, int mn1,
301  double *zn1, double *tn1, double *tgn1);
302  double g0(double a, double *p);
303  double sumex(double ex);
304  double sg0(double ex, double *p, double *ap);
305  double globe7(double *p, nrlmsise_input *input, nrlmsise_flags *flags);
306  double glob7s(double *p, nrlmsise_input *input, nrlmsise_flags *flags);
307 
308 // GTD7
309 // Neutral Atmosphere Empirical Model from the surface to lower exosphere.
310  void gtd7(nrlmsise_input *input, nrlmsise_flags *flags, nrlmsise_output *output);
311 
312 // GTD7D
313 // This subroutine provides Effective Total Mass Density for output
314 // d[5] which includes contributions from "anomalous oxygen" which can
315 // affect satellite drag above 500 km. See the section "output" for
316 // additional details.
317  void gtd7d(nrlmsise_input *input, nrlmsise_flags *flags, nrlmsise_output *output);
318 
319 // GHP7
320 // To specify outputs at a pressure level (press) rather than at
321 // an altitude.
322  void ghp7(nrlmsise_input *input, nrlmsise_flags *flags, nrlmsise_output *output, double press);
323 
324 // GTS7
325 // Thermospheric portion of NRLMSISE-00
326  void gts7(nrlmsise_input *input, nrlmsise_flags *flags, nrlmsise_output *output);
327 
328 };
329 
330 } // namespace JSBSim
331 
332 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
333 #endif
334 
JSBSim::FGFDMExec
Encapsulates the JSBSim simulation executive.
Definition: FGFDMExec.h:185
JSBSim::nrlmsise_input
Definition: FGMSIS.h:138
JSBSim::FGAtmosphere::g0
static constexpr double g0
Sea-level acceleration of gravity - ft/s^2.
Definition: FGAtmosphere.h:268
JSBSim::MSIS::MSIS
MSIS(FGFDMExec *)
Constructor.
Definition: FGMSIS.cpp:92
JSBSim::FGAtmosphere
Models an empty, abstract base atmosphere class.
Definition: FGAtmosphere.h:76
JSBSim::MSIS::UseExternal
void UseExternal(void)
Does nothing. External control is not allowed.
Definition: FGMSIS.cpp:211
JSBSim::ap_array
Definition: FGMSIS.h:122
JSBSim::nrlmsise_flags
Models the MSIS-00 atmosphere.
Definition: FGMSIS.h:78
JSBSim::nrlmsise_output
Definition: FGMSIS.h:178
JSBSim::MSIS::~MSIS
~MSIS()
Destructor.
Definition: FGMSIS.cpp:113
JSBSim::MSIS
Definition: FGMSIS.h:222
JSBSim::MSIS::Run
bool Run(bool Holding)
Runs the MSIS-00 atmosphere model; called by the Executive Can pass in a value indicating if the exec...
Definition: FGMSIS.cpp:152