atmospheric 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.adoc +317 -19
- data/lib/atmospheric/export/hypsometrical_tables.rb +139 -0
- data/lib/atmospheric/export/iso_25331975/group_base.rb +72 -0
- data/lib/atmospheric/export/iso_25331975/group_one.rb +36 -0
- data/lib/atmospheric/export/iso_25331975/group_three.rb +37 -0
- data/lib/atmospheric/export/iso_25331975/group_two.rb +38 -0
- data/lib/atmospheric/export/iso_25331975.rb +37 -0
- data/lib/atmospheric/export/iso_25331997.rb +105 -0
- data/lib/atmospheric/export/target.rb +32 -0
- data/lib/atmospheric/export.rb +8 -0
- data/lib/atmospheric/isa.rb +166 -89
- data/lib/atmospheric/version.rb +1 -1
- data/lib/atmospheric.rb +1 -0
- data/spec/fixtures/iso-2533-1975-table5.yaml +6036 -6036
- data/spec/fixtures/iso-2533-1975-table6.yaml +12192 -12201
- data/spec/fixtures/iso-2533-1975-table7.yaml +8128 -8128
- metadata +33 -9
@@ -0,0 +1,37 @@
|
|
1
|
+
module Atmospheric
|
2
|
+
module Export
|
3
|
+
module Iso25331975
|
4
|
+
class << self
|
5
|
+
def table_5
|
6
|
+
GroupOne.new.to_h
|
7
|
+
end
|
8
|
+
|
9
|
+
def table_6
|
10
|
+
GroupTwo.new.to_h
|
11
|
+
end
|
12
|
+
|
13
|
+
def table_7
|
14
|
+
GroupThree.new.to_h
|
15
|
+
end
|
16
|
+
|
17
|
+
def table_5_yaml
|
18
|
+
GroupOne.new.to_yaml
|
19
|
+
end
|
20
|
+
|
21
|
+
def table_6_yaml
|
22
|
+
GroupTwo.new.to_yaml
|
23
|
+
end
|
24
|
+
|
25
|
+
def table_7_yaml
|
26
|
+
GroupThree.new.to_yaml
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
require_relative "iso_25331975/group_base"
|
35
|
+
require_relative "iso_25331975/group_one"
|
36
|
+
require_relative "iso_25331975/group_two"
|
37
|
+
require_relative "iso_25331975/group_three"
|
@@ -0,0 +1,105 @@
|
|
1
|
+
require_relative "./target"
|
2
|
+
|
3
|
+
module Atmospheric
|
4
|
+
module Export
|
5
|
+
|
6
|
+
module Iso25331997
|
7
|
+
|
8
|
+
module GroupBaseMeters
|
9
|
+
def steps
|
10
|
+
(-5000..2000).step(50)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class GroupOne < Iso25331975::GroupOne
|
15
|
+
include Iso25331997::GroupBaseMeters
|
16
|
+
end
|
17
|
+
|
18
|
+
class GroupTwo < Iso25331975::GroupTwo
|
19
|
+
include Iso25331997::GroupBaseMeters
|
20
|
+
end
|
21
|
+
|
22
|
+
class GroupThree < Iso25331975::GroupThree
|
23
|
+
include Iso25331997::GroupBaseMeters
|
24
|
+
end
|
25
|
+
|
26
|
+
module GroupBaseFeet
|
27
|
+
def steps
|
28
|
+
(
|
29
|
+
(-16500..-13999).step(250) +
|
30
|
+
(-14000..104999).step(200) +
|
31
|
+
(105000..262500).step(500)
|
32
|
+
)
|
33
|
+
end
|
34
|
+
|
35
|
+
def steps_unit
|
36
|
+
:feet
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
class GroupFour < Iso25331975::GroupOne
|
41
|
+
include Iso25331997::GroupBaseFeet
|
42
|
+
end
|
43
|
+
|
44
|
+
class GroupFive < Iso25331975::GroupTwo
|
45
|
+
include Iso25331997::GroupBaseFeet
|
46
|
+
end
|
47
|
+
|
48
|
+
class GroupSix < Iso25331975::GroupThree
|
49
|
+
include Iso25331997::GroupBaseFeet
|
50
|
+
end
|
51
|
+
|
52
|
+
class << self
|
53
|
+
def table_1
|
54
|
+
GroupOne.new.to_h
|
55
|
+
end
|
56
|
+
|
57
|
+
def table_2
|
58
|
+
GroupTwo.new.to_h
|
59
|
+
end
|
60
|
+
|
61
|
+
def table_3
|
62
|
+
GroupThree.new.to_h
|
63
|
+
end
|
64
|
+
|
65
|
+
def table_4
|
66
|
+
GroupFour.new.to_h
|
67
|
+
end
|
68
|
+
|
69
|
+
def table_5
|
70
|
+
GroupFive.new.to_h
|
71
|
+
end
|
72
|
+
|
73
|
+
def table_6
|
74
|
+
GroupSix.new.to_h
|
75
|
+
end
|
76
|
+
|
77
|
+
def table_1_yaml
|
78
|
+
GroupOne.new.to_yaml
|
79
|
+
end
|
80
|
+
|
81
|
+
def table_2_yaml
|
82
|
+
GroupTwo.new.to_yaml
|
83
|
+
end
|
84
|
+
|
85
|
+
def table_3_yaml
|
86
|
+
GroupThree.new.to_yaml
|
87
|
+
end
|
88
|
+
|
89
|
+
def table_4_yaml
|
90
|
+
GroupFour.new.to_yaml
|
91
|
+
end
|
92
|
+
|
93
|
+
def table_5_yaml
|
94
|
+
GroupFive.new.to_yaml
|
95
|
+
end
|
96
|
+
|
97
|
+
def table_6_yaml
|
98
|
+
GroupSix.new.to_yaml
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require "measured"
|
2
|
+
require "yaml"
|
3
|
+
|
4
|
+
module Atmospheric
|
5
|
+
module Export
|
6
|
+
|
7
|
+
module Target
|
8
|
+
def round_to_sig_figs(num, num_sig_figs)
|
9
|
+
num.round(num_sig_figs - Math.log10(num).ceil).to_f
|
10
|
+
end
|
11
|
+
|
12
|
+
def m_to_ft(meters)
|
13
|
+
Measured::Length.new(meters, "m").convert_to("ft").value.to_f
|
14
|
+
end
|
15
|
+
|
16
|
+
def ft_to_m(feet)
|
17
|
+
Measured::Length.new(feet, "ft").convert_to("m").value.to_f
|
18
|
+
end
|
19
|
+
|
20
|
+
def to_yaml
|
21
|
+
to_h
|
22
|
+
.to_yaml(indentation: 4)
|
23
|
+
.gsub("\n- ", "\n\n - ")
|
24
|
+
.gsub(/^(.*):\n/, "\n\\1:") # Make fancy
|
25
|
+
end
|
26
|
+
|
27
|
+
def to_file(hash = to_yaml)
|
28
|
+
File.write(filename, hash)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
data/lib/atmospheric/isa.rb
CHANGED
@@ -6,29 +6,46 @@ module Atmospheric
|
|
6
6
|
# 2.1 Primary constants and characteristics
|
7
7
|
# Table 1 - Main constants and characteristics adopted for
|
8
8
|
# the calculation of the ISO Standard Atmosphere
|
9
|
-
|
10
|
-
g_n
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
9
|
+
constants = {
|
10
|
+
# g_n gravitation at mean sea level (m.s-2)
|
11
|
+
g_n: 9.80665,
|
12
|
+
|
13
|
+
# Avogadro constant (mol-1)
|
14
|
+
N_A: 6.02257e+23,
|
15
|
+
|
16
|
+
# p_n pressure at mean sea level (Pa)
|
17
|
+
p_n: 101325,
|
18
|
+
|
19
|
+
# rho_n standard air density
|
20
|
+
rho_n: 1.225,
|
21
|
+
|
22
|
+
# T_n standard thermodynamic air temperature at mean sea level
|
23
|
+
T_n: 288.15,
|
24
|
+
|
25
|
+
# universal gas constant
|
26
|
+
R_star: 8.31432,
|
27
|
+
|
28
|
+
# radius of the Earth (m)
|
29
|
+
radius: 6356766,
|
30
|
+
|
31
|
+
# adiabatic index (dimensionless)
|
32
|
+
k: 1.4,
|
19
33
|
}
|
20
34
|
|
21
35
|
# 2.2 The equation of the static atmosphere and the perfect gas law
|
22
36
|
# Formula (2)
|
23
37
|
# M: air molar mass at sea level, kg.kmol-1
|
24
38
|
# Value given in 2.1 as M: 28.964720
|
25
|
-
|
39
|
+
constants[:M] =
|
40
|
+
(constants[:rho_n] * constants[:R_star] * constants[:T_n]) \
|
41
|
+
/ constants[:p_n]
|
26
42
|
|
27
43
|
# Formula (3)
|
28
44
|
# R: specific gas constant, J.K-1.kg-1.
|
29
45
|
# Value given in 2.1 as R: 287.05287
|
30
|
-
|
46
|
+
constants[:R] = constants[:R_star] / constants[:M]
|
31
47
|
|
48
|
+
CONST = constants.freeze
|
32
49
|
|
33
50
|
class << self
|
34
51
|
# 2.3 Geopotential and geometric altitides; acceleration of free fall
|
@@ -67,7 +84,7 @@ module Atmospheric
|
|
67
84
|
|
68
85
|
# Formula (11)
|
69
86
|
# T
|
70
|
-
def
|
87
|
+
def temperature_at_layer_from_geopotential(geopotential_alt)
|
71
88
|
lower_layer_index = locate_lower_layer(geopotential_alt)
|
72
89
|
lower_layer = TEMPERATURE_LAYERS[lower_layer_index]
|
73
90
|
beta = lower_layer[:B]
|
@@ -78,7 +95,9 @@ module Atmospheric
|
|
78
95
|
end
|
79
96
|
|
80
97
|
def temperature_at_layer_celcius(geopotential_alt)
|
81
|
-
kelvin_to_celsius(
|
98
|
+
kelvin_to_celsius(
|
99
|
+
temperature_at_layer_from_geopotential(geopotential_alt),
|
100
|
+
)
|
82
101
|
end
|
83
102
|
|
84
103
|
def locate_lower_layer(geopotential_alt)
|
@@ -89,9 +108,9 @@ module Atmospheric
|
|
89
108
|
i = TEMPERATURE_LAYERS.length - 1
|
90
109
|
return i - 1 if geopotential_alt >= TEMPERATURE_LAYERS[i][:H]
|
91
110
|
|
92
|
-
# find last layer with H
|
93
|
-
TEMPERATURE_LAYERS.each_with_index do |layer,
|
94
|
-
return
|
111
|
+
# find last layer with H smaller than our H
|
112
|
+
TEMPERATURE_LAYERS.each_with_index do |layer, ind|
|
113
|
+
return ind - 1 if layer[:H] > geopotential_alt
|
95
114
|
end
|
96
115
|
|
97
116
|
nil
|
@@ -108,38 +127,40 @@ module Atmospheric
|
|
108
127
|
# [H: -5000, T: 320.65, B: -0.0065 ],
|
109
128
|
|
110
129
|
# This line is from ISO 2533:1975
|
111
|
-
{H: -2000, T: 301.15, B: -0.0065 },
|
112
|
-
{H: 0, T: 288.15, B: -0.0065 },
|
113
|
-
{H: 11000, T: 216.65, B: 0 },
|
114
|
-
{H: 20000, T: 216.65, B: 0.001 },
|
115
|
-
{H: 32000, T: 228.65, B: 0.0028 },
|
116
|
-
{H: 47000, T: 270.65, B: 0 },
|
117
|
-
{H: 51000, T: 270.65, B: -0.0028 },
|
118
|
-
{H: 71000, T: 214.65, B: -0.002 },
|
119
|
-
{H: 80000, T: 196.65},
|
120
|
-
]
|
121
|
-
|
130
|
+
{ H: -2000, T: 301.15, B: -0.0065 },
|
131
|
+
{ H: 0, T: 288.15, B: -0.0065 },
|
132
|
+
{ H: 11000, T: 216.65, B: 0 },
|
133
|
+
{ H: 20000, T: 216.65, B: 0.001 },
|
134
|
+
{ H: 32000, T: 228.65, B: 0.0028 },
|
135
|
+
{ H: 47000, T: 270.65, B: 0 },
|
136
|
+
{ H: 51000, T: 270.65, B: -0.0028 },
|
137
|
+
{ H: 71000, T: 214.65, B: -0.002 },
|
138
|
+
{ H: 80000, T: 196.65 },
|
139
|
+
].freeze
|
122
140
|
|
123
141
|
# 2.7 Pressure
|
124
142
|
|
125
143
|
# Base pressure values given defined `TEMPERATURE_LAYERS` and constants
|
144
|
+
# rubocop:disable Metrics/AbcSize
|
145
|
+
# rubocop:disable Metrics/PerceivedComplexity
|
146
|
+
# rubocop:disable Metrics/MethodLength
|
126
147
|
def pressure_layers
|
127
148
|
return @pressure_layers if @pressure_layers
|
128
149
|
|
129
|
-
#
|
150
|
+
# assume TEMPERATURE_LAYERS index 1 base altitude is 0 (mean sea level)
|
130
151
|
p = []
|
131
152
|
|
132
|
-
TEMPERATURE_LAYERS.each_with_index do |
|
133
|
-
last_i =
|
153
|
+
TEMPERATURE_LAYERS.each_with_index do |_x, i|
|
154
|
+
last_i = i.zero? ? 0 : i - 1
|
134
155
|
last_layer = TEMPERATURE_LAYERS[last_i]
|
135
156
|
beta = last_layer[:B]
|
136
157
|
|
137
158
|
if last_layer[:H] <= 0
|
138
|
-
|
159
|
+
p_b = CONST[:p_n]
|
139
160
|
capital_h_b = 0
|
140
161
|
capital_t_b = CONST[:T_n]
|
141
162
|
else
|
142
|
-
|
163
|
+
p_b = p[last_i]
|
143
164
|
capital_h_b = last_layer[:H]
|
144
165
|
capital_t_b = last_layer[:T]
|
145
166
|
end
|
@@ -147,18 +168,35 @@ module Atmospheric
|
|
147
168
|
current_layer = TEMPERATURE_LAYERS[i]
|
148
169
|
geopotential_alt = current_layer[:H]
|
149
170
|
temp = current_layer[:T]
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
171
|
+
height_diff = geopotential_alt - capital_h_b
|
172
|
+
|
173
|
+
p_i = if beta != 0
|
174
|
+
# Formula (12)
|
175
|
+
pressure_formula_beta_nonzero(p_b, beta, capital_t_b,
|
176
|
+
height_diff)
|
177
|
+
else
|
178
|
+
# Formula (13)
|
179
|
+
pressure_formula_beta_zero(p_b, temp, height_diff)
|
180
|
+
end
|
181
|
+
p[i] = p_i
|
158
182
|
end
|
159
183
|
|
160
184
|
@pressure_layers = p
|
161
185
|
end
|
186
|
+
# rubocop:enable Metrics/AbcSize
|
187
|
+
# rubocop:enable Metrics/PerceivedComplexity
|
188
|
+
# rubocop:enable Metrics/MethodLength
|
189
|
+
|
190
|
+
# Formula (12)
|
191
|
+
def pressure_formula_beta_nonzero(p_b, beta, temp, height_diff)
|
192
|
+
p_b * (1 + ((beta / temp) * height_diff)) \
|
193
|
+
**(-CONST[:g_n] / (beta * CONST[:R]))
|
194
|
+
end
|
195
|
+
|
196
|
+
# Formula (13)
|
197
|
+
def pressure_formula_beta_zero(p_b, temp, height_diff)
|
198
|
+
p_b * Math.exp(-(CONST[:g_n] / (CONST[:R] * temp)) * height_diff)
|
199
|
+
end
|
162
200
|
|
163
201
|
# puts "PRE-CALCULATED PRESSURE LAYERS:"
|
164
202
|
# pp @pressure_layers
|
@@ -171,63 +209,66 @@ module Atmospheric
|
|
171
209
|
pascal * 0.01
|
172
210
|
end
|
173
211
|
|
212
|
+
# rubocop:disable Metrics/MethodLength
|
174
213
|
# Pressure for a given geopotential altitude `H` (m) above mean sea level
|
175
|
-
def
|
214
|
+
def pressure_from_geopotential(geopotential_alt)
|
176
215
|
i = locate_lower_layer(geopotential_alt)
|
177
216
|
lower_temperature_layer = TEMPERATURE_LAYERS[i]
|
178
217
|
beta = lower_temperature_layer[:B]
|
179
218
|
capital_h_b = lower_temperature_layer[:H]
|
180
219
|
capital_t_b = lower_temperature_layer[:T]
|
181
|
-
temp =
|
182
|
-
|
220
|
+
temp = temperature_at_layer_from_geopotential(geopotential_alt)
|
221
|
+
p_b = pressure_layers[i]
|
222
|
+
height_diff = geopotential_alt - capital_h_b
|
183
223
|
|
184
224
|
if beta != 0
|
185
225
|
# Formula (12)
|
186
|
-
|
226
|
+
pressure_formula_beta_nonzero(p_b, beta, capital_t_b, height_diff)
|
187
227
|
else
|
188
228
|
# Formula (13)
|
189
|
-
|
229
|
+
pressure_formula_beta_zero(p_b, temp, height_diff)
|
190
230
|
end
|
191
231
|
end
|
232
|
+
# rubocop:enable Metrics/MethodLength
|
192
233
|
|
193
|
-
def
|
194
|
-
pa_to_mbar(
|
234
|
+
def pressure_from_geopotential_mbar(geopotential_alt)
|
235
|
+
pa_to_mbar(pressure_from_geopotential(geopotential_alt))
|
195
236
|
end
|
196
237
|
|
197
|
-
def
|
198
|
-
pa_to_mmhg(
|
238
|
+
def pressure_from_geopotential_mmhg(geopotential_alt)
|
239
|
+
pa_to_mmhg(pressure_from_geopotential(geopotential_alt))
|
199
240
|
end
|
200
241
|
|
201
|
-
def
|
202
|
-
|
242
|
+
def p_p_n_from_geopotential(geopotential_alt)
|
243
|
+
pressure_from_geopotential(geopotential_alt) / CONST[:p_n]
|
203
244
|
end
|
204
245
|
|
205
246
|
# 2.8 Density and specific weight
|
206
247
|
|
207
|
-
#
|
248
|
+
# Density for a given geopotential altitude `H` (m) above mean sea level
|
208
249
|
# Formula (14)
|
209
250
|
# rho
|
210
|
-
def
|
211
|
-
temp =
|
212
|
-
p =
|
251
|
+
def density_from_geopotential(geopotential_alt)
|
252
|
+
temp = temperature_at_layer_from_geopotential(geopotential_alt)
|
253
|
+
p = pressure_from_geopotential(geopotential_alt)
|
213
254
|
|
214
255
|
p / (CONST[:R] * temp)
|
215
256
|
end
|
216
257
|
|
217
|
-
def
|
218
|
-
|
258
|
+
def rho_rho_n_from_geopotential(geopotential_alt)
|
259
|
+
density_from_geopotential(geopotential_alt) / CONST[:rho_n]
|
219
260
|
end
|
220
261
|
|
221
|
-
def
|
222
|
-
Math.sqrt(
|
262
|
+
def root_rho_rho_n_from_geopotential(geopotential_alt)
|
263
|
+
Math.sqrt(rho_rho_n_from_geopotential(geopotential_alt))
|
223
264
|
end
|
224
265
|
|
225
|
-
|
226
266
|
# Specific weight
|
227
267
|
# Formula (15)
|
228
268
|
# gamma
|
229
|
-
def
|
230
|
-
|
269
|
+
def specific_weight_from_geopotential(geopotential_alt)
|
270
|
+
density_from_geopotential(geopotential_alt) *
|
271
|
+
gravity_at_geopotential(geopotential_alt)
|
231
272
|
end
|
232
273
|
|
233
274
|
# 2.9 Pressure scale height
|
@@ -237,17 +278,17 @@ module Atmospheric
|
|
237
278
|
(CONST[:R] * temp) / CONST[:g_n]
|
238
279
|
end
|
239
280
|
|
240
|
-
def
|
241
|
-
temp =
|
281
|
+
def pressure_scale_height_from_geopotential(geopotential_alt)
|
282
|
+
temp = temperature_at_layer_from_geopotential(geopotential_alt)
|
242
283
|
(CONST[:R] * temp) / gravity_at_geopotential(geopotential_alt)
|
243
284
|
end
|
244
285
|
|
245
286
|
# 2.10 Air number density
|
246
287
|
# Formula (17)
|
247
288
|
# n
|
248
|
-
def
|
249
|
-
temp =
|
250
|
-
p =
|
289
|
+
def air_number_density_from_geopotential(geopotential_alt)
|
290
|
+
temp = temperature_at_layer_from_geopotential(geopotential_alt)
|
291
|
+
p = pressure_from_geopotential(geopotential_alt)
|
251
292
|
|
252
293
|
CONST[:N_A] * p / (CONST[:R_star] * temp)
|
253
294
|
end
|
@@ -260,28 +301,31 @@ module Atmospheric
|
|
260
301
|
1.595769 * Math.sqrt(CONST[:R] * temp)
|
261
302
|
end
|
262
303
|
|
263
|
-
def
|
264
|
-
temp =
|
304
|
+
def mean_air_particle_speed_from_geopotential(geopotential_alt)
|
305
|
+
temp = temperature_at_layer_from_geopotential(geopotential_alt)
|
265
306
|
mean_air_particle_speed_from_temp(temp)
|
266
307
|
end
|
267
308
|
|
268
309
|
# 2.12 Mean free path of air particles
|
269
310
|
# Formula (19)
|
270
311
|
# l
|
271
|
-
def
|
272
|
-
1 / (1.414213562 * 3.141592654 * (
|
312
|
+
def mean_free_path_of_air_particles_from_geopotential(geopotential_alt)
|
313
|
+
1 / (1.414213562 * 3.141592654 * (3.65e-10**2) * \
|
314
|
+
air_number_density_from_geopotential(geopotential_alt))
|
273
315
|
end
|
274
316
|
|
275
317
|
# 2.13 Air-particle collision frequency
|
276
318
|
# Formula (20)
|
277
319
|
# omega
|
278
|
-
def air_particle_collision_frequency_from_temp(
|
279
|
-
4 * (
|
320
|
+
def air_particle_collision_frequency_from_temp(air_number_density, temp)
|
321
|
+
4 * (3.65e-10**2) *
|
322
|
+
((3.141592654 / (CONST[:R_star] * CONST[:M]))**0.5) *
|
323
|
+
air_number_density * CONST[:R_star] * (temp**0.5)
|
280
324
|
end
|
281
325
|
|
282
|
-
def
|
283
|
-
temp =
|
284
|
-
n =
|
326
|
+
def air_particle_collision_frequency_from_geopotential(geopotential_alt)
|
327
|
+
temp = temperature_at_layer_from_geopotential(geopotential_alt)
|
328
|
+
n = air_number_density_from_geopotential(geopotential_alt)
|
285
329
|
air_particle_collision_frequency_from_temp(n, temp)
|
286
330
|
end
|
287
331
|
|
@@ -295,12 +339,11 @@ module Atmospheric
|
|
295
339
|
Math.sqrt(kappa * CONST[:R] * temp)
|
296
340
|
end
|
297
341
|
|
298
|
-
def
|
299
|
-
temp =
|
342
|
+
def speed_of_sound_from_geopotential(geopotential_alt)
|
343
|
+
temp = temperature_at_layer_from_geopotential(geopotential_alt)
|
300
344
|
speed_of_sound_from_temp(temp)
|
301
345
|
end
|
302
346
|
|
303
|
-
|
304
347
|
# 2.15 Dynamic viscosity
|
305
348
|
# Formula (22)
|
306
349
|
# mu (Pa s)
|
@@ -309,11 +352,11 @@ module Atmospheric
|
|
309
352
|
capital_b_s = 1.458e-6
|
310
353
|
capital_s = 110.4
|
311
354
|
|
312
|
-
(capital_b_s * (temp
|
355
|
+
(capital_b_s * (temp**1.5)) / (temp + capital_s)
|
313
356
|
end
|
314
357
|
|
315
|
-
def
|
316
|
-
temp =
|
358
|
+
def dynamic_viscosity_from_geopotential(geopotential_alt)
|
359
|
+
temp = temperature_at_layer_from_geopotential(geopotential_alt)
|
317
360
|
dynamic_viscosity(temp)
|
318
361
|
end
|
319
362
|
|
@@ -324,20 +367,20 @@ module Atmospheric
|
|
324
367
|
dynamic_viscosity(temp) / CONST[:rho_n]
|
325
368
|
end
|
326
369
|
|
327
|
-
def
|
328
|
-
temp =
|
329
|
-
dynamic_viscosity(temp) /
|
370
|
+
def kinematic_viscosity_from_geopotential(geopotential_alt)
|
371
|
+
temp = temperature_at_layer_from_geopotential(geopotential_alt)
|
372
|
+
dynamic_viscosity(temp) / density_from_geopotential(geopotential_alt)
|
330
373
|
end
|
331
374
|
|
332
375
|
# 2.17 Thermal conductivity
|
333
376
|
# Formula (24)
|
334
377
|
# lambda
|
335
378
|
def thermal_conductivity_from_temp(temp)
|
336
|
-
(2.648151e-3 * (temp
|
379
|
+
(2.648151e-3 * (temp**1.5)) / (temp + (245.4 * (10**(-12.0 / temp))))
|
337
380
|
end
|
338
381
|
|
339
|
-
def
|
340
|
-
temp =
|
382
|
+
def thermal_conductivity_from_geopotential(geopotential_alt)
|
383
|
+
temp = temperature_at_layer_from_geopotential(geopotential_alt)
|
341
384
|
thermal_conductivity_from_temp(temp)
|
342
385
|
end
|
343
386
|
|
@@ -345,6 +388,40 @@ module Atmospheric
|
|
345
388
|
kelvin - 273.15
|
346
389
|
end
|
347
390
|
|
391
|
+
# ADD 1
|
392
|
+
# Formulae used in the calculation of the relationships
|
393
|
+
# between geopotential altitude and pressure
|
394
|
+
# rubocop:disable Metrics/AbcSize
|
395
|
+
# rubocop:disable Metrics/MethodLength
|
396
|
+
def geopotential_altitude_from_pressure_mbar(pressure)
|
397
|
+
if pressure >= pa_to_mbar(pressure_layers[2]) # H <= 11 000 m
|
398
|
+
(3.731444 - pressure**0.1902631) / 8.41728e-5
|
399
|
+
elsif pressure >= pa_to_mbar(pressure_layers[3]) # H <= 20 000 m
|
400
|
+
(3.1080387 - Math.log10(pressure)) / 6.848325e-5
|
401
|
+
elsif pressure >= pa_to_mbar(pressure_layers[4]) # H <= 32 000 m
|
402
|
+
(1.2386515 - pressure**0.02927125) \
|
403
|
+
/ (5.085177e-6 * pressure**0.02927125)
|
404
|
+
elsif pressure >= pa_to_mbar(pressure_layers[5]) # H <= 47 000 m
|
405
|
+
(1.9630052 - pressure**0.08195949) \
|
406
|
+
/ (2.013664e-5 * pressure**0.08195949)
|
407
|
+
end
|
408
|
+
end
|
409
|
+
|
410
|
+
def geopotential_altitude_from_pressure_mmhg(pressure)
|
411
|
+
if pressure >= pa_to_mmhg(pressure_layers[2]) # H <= 11 000 m
|
412
|
+
(3.532747 - pressure**0.1902631) / 7.96906e-5
|
413
|
+
elsif pressure >= pa_to_mmhg(pressure_layers[3]) # H <= 20 000 m
|
414
|
+
(2.9831357 - Math.log10(pressure)) / 6.848325e-5
|
415
|
+
elsif pressure >= pa_to_mmhg(pressure_layers[4]) # H <= 32 000 m
|
416
|
+
(1.2282678 - pressure**0.02927125) \
|
417
|
+
/ (5.085177e-6 * pressure**0.02927125)
|
418
|
+
elsif pressure >= pa_to_mmhg(pressure_layers[5]) # H <= 47 000 m
|
419
|
+
(1.9172753 - pressure**0.08195949) \
|
420
|
+
/ (2.013664e-5 * pressure**0.08195949)
|
421
|
+
end
|
422
|
+
end
|
423
|
+
# rubocop:enable Metrics/AbcSize
|
424
|
+
# rubocop:enable Metrics/MethodLength
|
348
425
|
end
|
349
426
|
end
|
350
427
|
end
|
data/lib/atmospheric/version.rb
CHANGED