atmospheric 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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