Vulcan
Aerospace Engineering Utilities Built on Janus
Loading...
Searching...
No Matches
USSA1976.hpp
Go to the documentation of this file.
1// US Standard Atmosphere 1976 - Table-Based Implementation
2// Vetted reference data embedded as constexpr arrays for table interpolation
3#pragma once
4
5#include <array>
6#include <cstddef>
8
9namespace vulcan::ussa1976 {
10
11// ============================================================================
12// Atmospheric State Struct
13// ============================================================================
14
23template <typename Scalar> struct AtmosphericState {
24 Scalar temperature;
25 Scalar pressure;
26 Scalar density;
28 Scalar gravity;
30};
31
32// ============================================================================
33// Embedded Reference Data (US Standard Atmosphere 1976)
34// ============================================================================
35// Data source: reference/atmos_temp.txt
36// Fine resolution (0.5 km) from -0.5 to 20 km, coarse (5-50 km) from 25-1000 km
37// Total: 94 data points
38
39namespace detail {
40
41// Number of table entries
42inline constexpr std::size_t N_POINTS = 94;
43
44// Geometric altitude [km]
45inline constexpr std::array<double, N_POINTS> altitude_km = {
46 -0.5, 0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0,
47 5.5, 6.0, 6.5, 7.0, 7.5, 8.0, 8.5, 9.0, 9.5, 10.0, 10.5, 11.0,
48 11.5, 12.0, 12.5, 13.0, 13.5, 14.0, 14.5, 15.0, 15.5, 16.0, 16.5, 17.0,
49 17.5, 18.0, 18.5, 19.0, 19.5, 20.0, 25, 30, 35, 40, 45, 50,
50 55, 60, 65, 70, 75, 80, 85, 90, 95, 100, 105, 110,
51 115, 120, 125, 130, 135, 140, 145, 150, 155, 160, 165, 170,
52 175, 180, 185, 190, 195, 200, 250, 300, 350, 400, 450, 500,
53 550, 600, 650, 700, 750, 800, 850, 900, 950, 1000};
54
55// Temperature [K]
56inline constexpr std::array<double, N_POINTS> temperature_K = {
57 291.4, 288.1, 284.9, 281.7, 278.4, 275.2, 271.9, 268.7,
58 265.4, 262.2, 258.9, 255.7, 252.4, 249.2, 245.9, 242.7,
59 239.5, 236.2, 233.0, 229.7, 226.5, 223.3, 220.0, 216.8,
60 216.6, 216.6, 216.6, 216.6, 216.6, 216.6, 216.6, 216.6,
61 216.6, 216.6, 216.6, 216.6, 216.6, 216.6, 216.6, 216.6,
62 216.6, 216.6, 221.552, 226.509, 236.513, 250.350, 264.164, 270.650,
63 260.771, 247.021, 233.292, 219.585, 208.399, 198.639, 188.893, 186.867,
64 188.418, 195.081, 208.835, 240.000, 300.000, 360.000, 417.231, 469.268,
65 516.589, 559.627, 598.776, 634.392, 666.799, 696.290, 723.132, 747.566,
66 769.811, 790.066, 808.511, 825.312, 840.616, 854.559, 941.330, 976.008,
67 990.057, 995.825, 998.225, 999.236, 999.667, 999.853, 999.934, 999.970,
68 999.986, 999.994, 999.997, 999.999, 999.999, 1000.000};
69
70// Pressure [Pa]
71inline constexpr std::array<double, N_POINTS> pressure_Pa = {
72 107477, 101325, 95461, 89876, 84559, 79501, 74691, 70121,
73 65780, 61660, 57752, 54048, 50539, 47217, 44075, 41105,
74 38299, 35651, 33154, 30800, 28584, 26499, 24540, 22699,
75 20984, 19399, 17933, 16579, 15327, 14170, 13100, 12111,
76 11197, 10352, 9571, 8849, 8182, 7565, 6994, 6467,
77 5979, 5529, 2550, 1200, 575, 287, 149, 79.8,
78 42.5, 22.0, 10.9, 5.22, 2.39, 1.05, 0.446, 0.184,
79 0.0758, 0.0320, 0.0144, 0.00715, 0.00400, 0.00254, 0.00174, 0.00125,
80 9.36e-4, 7.20e-4, 5.67e-4, 4.54e-4, 3.69e-4, 3.04e-4, 2.53e-4, 2.12e-4,
81 1.79e-4, 1.53e-4, 1.31e-4, 1.13e-4, 9.75e-5, 8.47e-5, 2.48e-5, 8.77e-6,
82 3.44e-6, 1.45e-6, 6.45e-7, 3.02e-7, 1.51e-7, 8.21e-8, 4.89e-8, 3.19e-8,
83 2.26e-8, 1.70e-8, 1.34e-8, 1.09e-8, 9.00e-9, 7.51e-9};
84
85// Density [kg/m³]
86inline constexpr std::array<double, N_POINTS> density_kgm3 = {
87 1.285, 1.225, 1.167, 1.112, 1.058, 1.007, 0.957,
88 0.909, 0.863, 0.819, 0.777, 0.736, 0.697, 0.660,
89 0.624, 0.590, 0.557, 0.526, 0.496, 0.467, 0.440,
90 0.414, 0.389, 0.365, 0.337, 0.312, 0.288, 0.267,
91 0.246, 0.228, 0.211, 0.195, 0.180, 0.166, 0.154,
92 0.142, 0.132, 0.122, 0.112, 0.104, 0.096, 0.089,
93 4.01e-2, 1.84e-2, 8.46e-3, 4.00e-3, 1.97e-3, 1.03e-3, 5.68e-4,
94 3.10e-4, 1.63e-4, 8.28e-5, 3.99e-5, 1.85e-5, 8.22e-6, 3.44e-6,
95 1.39e-6, 5.60e-7, 2.33e-7, 9.67e-8, 4.28e-8, 2.22e-8, 1.29e-8,
96 8.15e-9, 5.46e-9, 3.83e-9, 2.78e-9, 2.08e-9, 1.58e-9, 1.23e-9,
97 9.75e-10, 7.82e-10, 6.34e-10, 5.19e-10, 4.30e-10, 3.58e-10, 3.01e-10,
98 2.54e-10, 6.07e-11, 1.92e-11, 7.00e-12, 2.80e-12, 1.18e-12, 5.21e-13,
99 2.38e-13, 1.14e-13, 5.71e-14, 3.07e-14, 1.79e-14, 1.14e-14, 7.82e-15,
100 5.76e-15, 4.45e-15, 3.56e-15};
101
102// Speed of sound [m/s]
103inline constexpr std::array<double, N_POINTS> speed_of_sound_ms = {
104 342.2, 340.3, 338.4, 336.4, 334.5, 332.5, 330.6, 328.6, 326.6,
105 324.6, 322.6, 320.5, 318.5, 316.5, 314.4, 312.3, 310.2, 308.1,
106 306.0, 303.8, 301.7, 299.5, 297.4, 295.2, 295.1, 295.1, 295.1,
107 295.1, 295.1, 295.1, 295.1, 295.1, 295.1, 295.1, 295.1, 295.1,
108 295.1, 295.1, 295.1, 295.1, 295.1, 295.1, 298.39, 301.71, 308.30,
109 317.19, 325.82, 329.80, 323.72, 315.07, 306.19, 297.06, 289.40, 282.54,
110 275.52, 274.04, 275.17, 280.00, 289.70, 310.56, 347.22, 380.36, 409.48,
111 434.27, 455.64, 474.24, 490.54, 504.92, 517.66, 528.98, 539.08, 548.11,
112 556.21, 563.48, 570.02, 575.91, 581.22, 586.02, 615.06, 626.28, 630.78,
113 632.61, 633.37, 633.69, 633.83, 633.89, 633.91, 633.93, 633.93, 633.93,
114 633.93, 633.93, 633.94, 633.94};
115
116// Gravitational acceleration [m/s²]
117inline constexpr std::array<double, N_POINTS> gravity_ms2 = {
118 9.810, 9.807, 9.804, 9.801, 9.798, 9.795, 9.792, 9.789, 9.786, 9.782, 9.779,
119 9.776, 9.773, 9.770, 9.767, 9.764, 9.761, 9.757, 9.754, 9.751, 9.748, 9.745,
120 9.741, 9.738, 9.735, 9.732, 9.728, 9.725, 9.722, 9.719, 9.715, 9.712, 9.709,
121 9.706, 9.702, 9.699, 9.696, 9.693, 9.689, 9.686, 9.683, 9.680, 9.730, 9.715,
122 9.700, 9.684, 9.669, 9.654, 9.639, 9.624, 9.609, 9.594, 9.579, 9.564, 9.550,
123 9.535, 9.520, 9.505, 9.491, 9.476, 9.461, 9.447, 9.432, 9.418, 9.403, 9.389,
124 9.374, 9.360, 9.345, 9.331, 9.317, 9.302, 9.288, 9.274, 9.260, 9.246, 9.232,
125 9.218, 9.079, 8.943, 8.810, 8.680, 8.553, 8.429, 8.307, 8.188, 8.072, 7.958,
126 7.846, 7.737, 7.630, 7.525, 7.422, 7.322};
127
128// Convert std::array to Eigen::Map for Table1D
129inline janus::NumericVector altitude_m_vec() {
130 janus::NumericVector v(N_POINTS);
131 for (std::size_t i = 0; i < N_POINTS; ++i) {
132 v(static_cast<Eigen::Index>(i)) = altitude_km[i] * 1000.0;
133 }
134 return v;
135}
136
137template <std::size_t N>
138inline janus::NumericVector array_to_vec(const std::array<double, N> &arr) {
139 janus::NumericVector v(N);
140 for (std::size_t i = 0; i < N; ++i) {
141 v(static_cast<Eigen::Index>(i)) = arr[i];
142 }
143 return v;
144}
145
146// Lazy-initialized interpolation tables (constructed on first use)
147inline const Table1D &temperature_table() {
149 return table;
150}
151
152inline const Table1D &pressure_table() {
154 return table;
155}
156
157inline const Table1D &density_table() {
159 return table;
160}
161
164 return table;
165}
166
167inline const Table1D &gravity_table() {
169 return table;
170}
171
172} // namespace detail
173
174// ============================================================================
175// Altitude Bounds
176// ============================================================================
177
179inline constexpr double MIN_ALTITUDE = -500.0;
180
182inline constexpr double MAX_ALTITUDE = 1000000.0;
183
184// Sutherland formula constants for dynamic viscosity
185inline constexpr double SUTHERLAND_BETA = 1.458e-6;
186inline constexpr double SUTHERLAND_S = 110.4;
187
188// ============================================================================
189// Public API - Individual Property Accessors
190// ============================================================================
191
202template <typename Scalar> Scalar temperature(const Scalar &altitude) {
203 return detail::temperature_table()(altitude);
204}
205
213template <typename Scalar> Scalar pressure(const Scalar &altitude) {
214 return detail::pressure_table()(altitude);
215}
216
224template <typename Scalar> Scalar density(const Scalar &altitude) {
225 return detail::density_table()(altitude);
226}
227
235template <typename Scalar> Scalar speed_of_sound(const Scalar &altitude) {
236 return detail::speed_of_sound_table()(altitude);
237}
238
248template <typename Scalar> Scalar gravity(const Scalar &altitude) {
249 return detail::gravity_table()(altitude);
250}
251
262template <typename Scalar> Scalar dynamic_viscosity(const Scalar &altitude) {
263 Scalar T = detail::temperature_table()(altitude);
264 // Sutherland's formula: μ = β·T^(3/2) / (T + S)
265 return SUTHERLAND_BETA * janus::pow(T, 1.5) / (T + SUTHERLAND_S);
266}
267
268// ============================================================================
269// Public API - Combined State Accessor
270// ============================================================================
271
282template <typename Scalar>
283AtmosphericState<Scalar> state(const Scalar &altitude) {
284 Scalar T = detail::temperature_table()(altitude);
286 .temperature = T,
287 .pressure = detail::pressure_table()(altitude),
288 .density = detail::density_table()(altitude),
290 .gravity = detail::gravity_table()(altitude),
292 SUTHERLAND_BETA * janus::pow(T, 1.5) / (T + SUTHERLAND_S)};
293}
294
295} // namespace vulcan::ussa1976
Definition TableInterpolator.hpp:37
Definition USSA1976.hpp:39
constexpr std::array< double, N_POINTS > pressure_Pa
Definition USSA1976.hpp:71
const Table1D & speed_of_sound_table()
Definition USSA1976.hpp:162
constexpr std::array< double, N_POINTS > gravity_ms2
Definition USSA1976.hpp:117
constexpr std::size_t N_POINTS
Definition USSA1976.hpp:42
const Table1D & pressure_table()
Definition USSA1976.hpp:152
const Table1D & temperature_table()
Definition USSA1976.hpp:147
janus::NumericVector altitude_m_vec()
Definition USSA1976.hpp:129
const Table1D & density_table()
Definition USSA1976.hpp:157
constexpr std::array< double, N_POINTS > density_kgm3
Definition USSA1976.hpp:86
constexpr std::array< double, N_POINTS > speed_of_sound_ms
Definition USSA1976.hpp:103
const Table1D & gravity_table()
Definition USSA1976.hpp:167
constexpr std::array< double, N_POINTS > altitude_km
Definition USSA1976.hpp:45
constexpr std::array< double, N_POINTS > temperature_K
Definition USSA1976.hpp:56
janus::NumericVector array_to_vec(const std::array< double, N > &arr)
Definition USSA1976.hpp:138
Definition USSA1976.hpp:9
Scalar temperature(const Scalar &altitude)
US Standard Atmosphere 1976 - Temperature (table-based).
Definition USSA1976.hpp:202
Scalar speed_of_sound(const Scalar &altitude)
US Standard Atmosphere 1976 - Speed of Sound (table-based).
Definition USSA1976.hpp:235
constexpr double MAX_ALTITUDE
Maximum supported altitude [m].
Definition USSA1976.hpp:182
constexpr double SUTHERLAND_S
K.
Definition USSA1976.hpp:186
Scalar gravity(const Scalar &altitude)
US Standard Atmosphere 1976 - Gravitational Acceleration (table-based).
Definition USSA1976.hpp:248
constexpr double MIN_ALTITUDE
Minimum supported altitude [m].
Definition USSA1976.hpp:179
AtmosphericState< Scalar > state(const Scalar &altitude)
US Standard Atmosphere 1976 - Complete atmospheric state.
Definition USSA1976.hpp:283
Scalar pressure(const Scalar &altitude)
US Standard Atmosphere 1976 - Pressure (table-based).
Definition USSA1976.hpp:213
Scalar dynamic_viscosity(const Scalar &altitude)
US Standard Atmosphere 1976 - Dynamic Viscosity.
Definition USSA1976.hpp:262
Scalar density(const Scalar &altitude)
US Standard Atmosphere 1976 - Density (table-based).
Definition USSA1976.hpp:224
constexpr double SUTHERLAND_BETA
kg/(s·m·K^0.5)
Definition USSA1976.hpp:185
Complete atmospheric state at a given altitude.
Definition USSA1976.hpp:23
Scalar temperature
Kinetic temperature [K].
Definition USSA1976.hpp:24
Scalar density
Air density [kg/m³].
Definition USSA1976.hpp:26
Scalar gravity
Gravitational acceleration [m/s²].
Definition USSA1976.hpp:28
Scalar dynamic_viscosity
Dynamic viscosity [Pa·s].
Definition USSA1976.hpp:29
Scalar pressure
Pressure [Pa].
Definition USSA1976.hpp:25
Scalar speed_of_sound
Speed of sound [m/s].
Definition USSA1976.hpp:27