atmospheric 0.1.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 +7 -0
- data/LICENSE.txt +25 -0
- data/README.adoc +97 -0
- data/lib/atmospheric/isa.rb +350 -0
- data/lib/atmospheric/version.rb +5 -0
- data/lib/atmospheric.rb +9 -0
- data/spec/fixtures/iso-2533-1975-table5.yaml +18297 -0
- data/spec/fixtures/iso-2533-1975-table6.yaml +18307 -0
- data/spec/fixtures/iso-2533-1975-table7.yaml +16265 -0
- metadata +82 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 91653cc446f211fbec67bb75c9ca04fb3135e24bb7d1e1e52707e865508285d5
|
4
|
+
data.tar.gz: c7cb3677f1d0d1c896815a6607241a58b2649bc43313efc270ce8d124ddf44e7
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: f8233e299548737ac029e652c50effc3a94fccc83bf1038295429242f9554da545c0c9abdc8c57638da3abf5e91535ec29d01c9cb3e8d978c4d05411d9b30a6c
|
7
|
+
data.tar.gz: a8c034abf9efec7b006e9be2d22119083f2d46fbacda5b2592e6d0fcc1fd657e9d1894dcb5e0ec0b81ac07268be51baa29ee3d8e8d2c8f31a26bd0adb1b3330e
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
BSD 2-Clause License
|
2
|
+
|
3
|
+
Copyright (c) 2018, Ribose
|
4
|
+
All rights reserved.
|
5
|
+
|
6
|
+
Redistribution and use in source and binary forms, with or without
|
7
|
+
modification, are permitted provided that the following conditions are met:
|
8
|
+
|
9
|
+
* Redistributions of source code must retain the above copyright notice, this
|
10
|
+
list of conditions and the following disclaimer.
|
11
|
+
|
12
|
+
* Redistributions in binary form must reproduce the above copyright notice,
|
13
|
+
this list of conditions and the following disclaimer in the documentation
|
14
|
+
and/or other materials provided with the distribution.
|
15
|
+
|
16
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
17
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
18
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
19
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
20
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
21
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
22
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
23
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
24
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
25
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/README.adoc
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
= Atmospheric for Ruby (International Standard Atmosphere / ICAO Standard Atmosphere (ISA))
|
2
|
+
|
3
|
+
== Purpose
|
4
|
+
|
5
|
+
This repository provides Ruby code for calculating values defined in the
|
6
|
+
following documents:
|
7
|
+
|
8
|
+
* International Standard Atmosphere (ISA) from ISO 2533:1975
|
9
|
+
* ICAO Standard Atmosphere (ICAO Doc 7488/3, 1994)
|
10
|
+
|
11
|
+
Which are technically identical documents but different in presentation and
|
12
|
+
units (the ICAO document includes `ft` in addition to `m`).
|
13
|
+
|
14
|
+
== Usage
|
15
|
+
|
16
|
+
[source,ruby]
|
17
|
+
----
|
18
|
+
> require 'atmospheric'
|
19
|
+
> instance = Atmospheric::Isa.method_name
|
20
|
+
> # method_name is one of the following
|
21
|
+
----
|
22
|
+
|
23
|
+
The available methods are:
|
24
|
+
|
25
|
+
* `geometric_altitude_from_geopotential(geopotential_altitude)`
|
26
|
+
* `geopotential_altitude_from_geometric(geometric_altitude)`
|
27
|
+
* `temperature_at_layer_from_H(geopotential_altitude)`
|
28
|
+
* `temperature_at_layer_celcius(geopotential_altitude)`
|
29
|
+
* `pressure_from_H_mbar(geopotential_altitude)`
|
30
|
+
* `pressure_from_H_mmhg(geopotential_altitude)`
|
31
|
+
* `density_from_H(geopotential_altitude)`
|
32
|
+
* `gravity_at_geopotential(geopotential_altitude)`
|
33
|
+
* `p_p_n_from_H(geopotential_altitude)`
|
34
|
+
* `rho_rho_n_from_H(geopotential_altitude)`
|
35
|
+
* `root_rho_rho_n_from_H(geopotential_altitude)`
|
36
|
+
* `speed_of_sound_from_H(geopotential_altitude)`
|
37
|
+
* `dynamic_viscosity_from_H(geopotential_altitude)`
|
38
|
+
* `kinematic_viscosity_from_H(geopotential_altitude)`
|
39
|
+
* `thermal_conductivity_from_H(geopotential_altitude)`
|
40
|
+
* `pressure_scale_height_from_H(geopotential_altitude)`
|
41
|
+
* `specific_weight_from_H(geopotential_altitude)`
|
42
|
+
* `air_number_density_from_H(geopotential_altitude)`
|
43
|
+
* `mean_air_particle_speed_from_H(geopotential_altitude)`
|
44
|
+
* `air_particle_collision_frequency_from_H(geopotential_altitude)`
|
45
|
+
* `mean_free_path_of_air_particles_from_H(geopotential_altitude)`
|
46
|
+
|
47
|
+
|
48
|
+
== Testing
|
49
|
+
|
50
|
+
[source,sh]
|
51
|
+
----
|
52
|
+
$ rspec
|
53
|
+
----
|
54
|
+
|
55
|
+
Tests are encoded in `spec/fixtures/tests.yml` in the following format:
|
56
|
+
|
57
|
+
[source,yml]
|
58
|
+
----
|
59
|
+
- H: -2000.0
|
60
|
+
h: -1999.0
|
61
|
+
TK: 301.15
|
62
|
+
TC: 28.0
|
63
|
+
p_mbar: 1277.74
|
64
|
+
p_mmhg: 958.382
|
65
|
+
rho: 1.47808
|
66
|
+
g: 9.8128
|
67
|
+
p_p_n: 1.26103
|
68
|
+
rho_rho_n: 1.20659
|
69
|
+
root_rho_rho_n: 1.09845
|
70
|
+
a: 347.886
|
71
|
+
mu: 1.8514e-05
|
72
|
+
v: 1.2526e-05
|
73
|
+
lambda: 0.026359
|
74
|
+
H_p: 8809.5
|
75
|
+
gamma: 14.504
|
76
|
+
n: 3.0734e+25
|
77
|
+
v_bar: 469.18
|
78
|
+
omega: 8535100000.0
|
79
|
+
l: 549710000.0
|
80
|
+
----
|
81
|
+
|
82
|
+
Each of these values are associated with a cell in the tables of the source
|
83
|
+
documents.
|
84
|
+
|
85
|
+
The only defining value in a tests is `H` (geopotential altitude).
|
86
|
+
It is used to generate all the other values.
|
87
|
+
|
88
|
+
|
89
|
+
== License
|
90
|
+
|
91
|
+
Copyright Ribose and its respective owners.
|
92
|
+
|
93
|
+
|
94
|
+
== TODO
|
95
|
+
|
96
|
+
* make into module
|
97
|
+
* expose this as a plugin to LutaML / Metanorma YAML2text
|
@@ -0,0 +1,350 @@
|
|
1
|
+
module Atmospheric
|
2
|
+
module Isa
|
3
|
+
# International Standard Atmosphere (ISA) (ISO 2533:1975)
|
4
|
+
# ICAO Standard Atmosphere (ICAO Doc 7488/3, 1994)
|
5
|
+
|
6
|
+
# 2.1 Primary constants and characteristics
|
7
|
+
# Table 1 - Main constants and characteristics adopted for
|
8
|
+
# the calculation of the ISO Standard Atmosphere
|
9
|
+
CONST = {
|
10
|
+
g_n: 9.80665, # m.s-2
|
11
|
+
N_A: 602.257e21, # Avogadro constant, mol-1
|
12
|
+
p_n: 101325, # In Pascal
|
13
|
+
rho_n: 1.225, # rho_n standard air density
|
14
|
+
T_n: 288.15, # T_n standard thermodynamic air temperature at mean sea level
|
15
|
+
R_star: 8.31432, # universal gas constant
|
16
|
+
|
17
|
+
radius: 6356766, # radius of the Earth (m)
|
18
|
+
k: 1.4 # adiabatic index, dimensionless
|
19
|
+
}
|
20
|
+
|
21
|
+
# 2.2 The equation of the static atmosphere and the perfect gas law
|
22
|
+
# Formula (2)
|
23
|
+
# M: air molar mass at sea level, kg.kmol-1
|
24
|
+
# Value given in 2.1 as M: 28.964720
|
25
|
+
CONST[:M] = (CONST[:rho_n] * CONST[:R_star] * CONST[:T_n]) / CONST[:p_n]
|
26
|
+
|
27
|
+
# Formula (3)
|
28
|
+
# R: specific gas constant, J.K-1.kg-1.
|
29
|
+
# Value given in 2.1 as R: 287.05287
|
30
|
+
CONST[:R] = CONST[:R_star] / CONST[:M]
|
31
|
+
|
32
|
+
|
33
|
+
class << self
|
34
|
+
# 2.3 Geopotential and geometric altitides; acceleration of free fall
|
35
|
+
|
36
|
+
# 2.3 Formula (8)
|
37
|
+
# H to h
|
38
|
+
# h(m)
|
39
|
+
def geometric_altitude_from_geopotential(geopotential_alt)
|
40
|
+
CONST[:radius] * geopotential_alt / (CONST[:radius] - geopotential_alt)
|
41
|
+
end
|
42
|
+
|
43
|
+
# 2.3 Formula (9)
|
44
|
+
# h to H
|
45
|
+
# H(m)
|
46
|
+
def geopotential_altitude_from_geometric(geometric_alt)
|
47
|
+
CONST[:radius] * geometric_alt / (CONST[:radius] + geometric_alt)
|
48
|
+
end
|
49
|
+
|
50
|
+
# 2.3 Formula (7)
|
51
|
+
# g(h)
|
52
|
+
def gravity_at_geometric(geometric_alt)
|
53
|
+
temp = CONST[:radius] / (CONST[:radius] + geometric_alt)
|
54
|
+
CONST[:g_n] * temp * temp
|
55
|
+
end
|
56
|
+
|
57
|
+
def gravity_at_geopotential(geopotential_alt)
|
58
|
+
geometric_h = geometric_altitude_from_geopotential(geopotential_alt)
|
59
|
+
gravity_at_geometric(geometric_h)
|
60
|
+
end
|
61
|
+
|
62
|
+
# 2.4 Atmospheric composition and air molar mass
|
63
|
+
|
64
|
+
# 2.5 Physical characteristics of the atmosphere at mean sea level
|
65
|
+
|
66
|
+
# 2.6 Temperature and vertical temperature gradient
|
67
|
+
|
68
|
+
# Formula (11)
|
69
|
+
# T
|
70
|
+
def temperature_at_layer_from_H(geopotential_alt)
|
71
|
+
lower_layer_index = locate_lower_layer(geopotential_alt)
|
72
|
+
lower_layer = TEMPERATURE_LAYERS[lower_layer_index]
|
73
|
+
beta = lower_layer[:B]
|
74
|
+
capital_t_b = lower_layer[:T]
|
75
|
+
capital_h_b = lower_layer[:H]
|
76
|
+
|
77
|
+
capital_t_b + (beta * (geopotential_alt - capital_h_b))
|
78
|
+
end
|
79
|
+
|
80
|
+
def temperature_at_layer_celcius(geopotential_alt)
|
81
|
+
kelvin_to_celsius(temperature_at_layer_from_H(geopotential_alt))
|
82
|
+
end
|
83
|
+
|
84
|
+
def locate_lower_layer(geopotential_alt)
|
85
|
+
# Return first layer if lower than lowest
|
86
|
+
return 0 if geopotential_alt < TEMPERATURE_LAYERS[0][:H]
|
87
|
+
|
88
|
+
# Return second last layer if beyond last layer
|
89
|
+
i = TEMPERATURE_LAYERS.length - 1
|
90
|
+
return i - 1 if geopotential_alt >= TEMPERATURE_LAYERS[i][:H]
|
91
|
+
|
92
|
+
# find last layer with H larger than our H
|
93
|
+
TEMPERATURE_LAYERS.each_with_index do |layer, i|
|
94
|
+
return i if layer[:H] > geopotential_alt
|
95
|
+
end
|
96
|
+
|
97
|
+
nil
|
98
|
+
end
|
99
|
+
|
100
|
+
# Table 4 - Temperature and vertical temperature gradients
|
101
|
+
#
|
102
|
+
TEMPERATURE_LAYERS = [
|
103
|
+
# H is Geopotential altitude (base altitude) above mean sea level, m
|
104
|
+
# T is Temperature, K
|
105
|
+
# B is Temperature gradient, "beta", K m^-1
|
106
|
+
|
107
|
+
# This line is from ICAO 7488/3
|
108
|
+
# [H: -5000, T: 320.65, B: -0.0065 ],
|
109
|
+
|
110
|
+
# 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
|
+
|
122
|
+
|
123
|
+
# 2.7 Pressure
|
124
|
+
|
125
|
+
# Base pressure values given defined `TEMPERATURE_LAYERS` and constants
|
126
|
+
def pressure_layers
|
127
|
+
return @pressure_layers if @pressure_layers
|
128
|
+
|
129
|
+
# assuming TEMPERATURE_LAYERS index 1 base altitude is zero (mean sea level)
|
130
|
+
p = []
|
131
|
+
|
132
|
+
TEMPERATURE_LAYERS.each_with_index do |x, i|
|
133
|
+
last_i = (i == 0) ? 0 : i - 1
|
134
|
+
last_layer = TEMPERATURE_LAYERS[last_i]
|
135
|
+
beta = last_layer[:B]
|
136
|
+
|
137
|
+
if last_layer[:H] <= 0
|
138
|
+
pb = CONST[:p_n]
|
139
|
+
capital_h_b = 0
|
140
|
+
capital_t_b = CONST[:T_n]
|
141
|
+
else
|
142
|
+
pb = p[last_i]
|
143
|
+
capital_h_b = last_layer[:H]
|
144
|
+
capital_t_b = last_layer[:T]
|
145
|
+
end
|
146
|
+
|
147
|
+
current_layer = TEMPERATURE_LAYERS[i]
|
148
|
+
geopotential_alt = current_layer[:H]
|
149
|
+
temp = current_layer[:T]
|
150
|
+
|
151
|
+
p[i] = if beta != 0
|
152
|
+
# Formula (12)
|
153
|
+
pb * (1 + ((beta / capital_t_b) * (geopotential_alt - capital_h_b))) ** (-CONST[:g_n] / (beta * CONST[:R]))
|
154
|
+
else
|
155
|
+
# Formula (13)
|
156
|
+
pb * Math.exp(-(CONST[:g_n] / (CONST[:R] * temp)) * (geopotential_alt - capital_h_b))
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
@pressure_layers = p
|
161
|
+
end
|
162
|
+
|
163
|
+
# puts "PRE-CALCULATED PRESSURE LAYERS:"
|
164
|
+
# pp @pressure_layers
|
165
|
+
|
166
|
+
def pa_to_mmhg(pascal)
|
167
|
+
pascal * 0.007500616827
|
168
|
+
end
|
169
|
+
|
170
|
+
def pa_to_mbar(pascal)
|
171
|
+
pascal * 0.01
|
172
|
+
end
|
173
|
+
|
174
|
+
# Pressure for a given geopotential altitude `H` (m) above mean sea level
|
175
|
+
def pressure_from_H(geopotential_alt)
|
176
|
+
i = locate_lower_layer(geopotential_alt)
|
177
|
+
lower_temperature_layer = TEMPERATURE_LAYERS[i]
|
178
|
+
beta = lower_temperature_layer[:B]
|
179
|
+
capital_h_b = lower_temperature_layer[:H]
|
180
|
+
capital_t_b = lower_temperature_layer[:T]
|
181
|
+
temp = temperature_at_layer_from_H(geopotential_alt)
|
182
|
+
pb = pressure_layers[i]
|
183
|
+
|
184
|
+
if beta != 0
|
185
|
+
# Formula (12)
|
186
|
+
pb * (1 + ((beta / capital_t_b) * (geopotential_alt - capital_h_b))) ** (-CONST[:g_n] / (beta * CONST[:R]))
|
187
|
+
else
|
188
|
+
# Formula (13)
|
189
|
+
pb * Math.exp(-(CONST[:g_n] / (CONST[:R] * temp)) * (geopotential_alt - capital_h_b))
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
def pressure_from_H_mbar(geopotential_alt)
|
194
|
+
pa_to_mbar(pressure_from_H(geopotential_alt))
|
195
|
+
end
|
196
|
+
|
197
|
+
def pressure_from_H_mmhg(geopotential_alt)
|
198
|
+
pa_to_mmhg(pressure_from_H(geopotential_alt))
|
199
|
+
end
|
200
|
+
|
201
|
+
def p_p_n_from_H(geopotential_alt)
|
202
|
+
pressure_from_H(geopotential_alt) / CONST[:p_n]
|
203
|
+
end
|
204
|
+
|
205
|
+
# 2.8 Density and specific weight
|
206
|
+
|
207
|
+
# Calculate density for a given geopotential altitude `H` (m) above mean sea level
|
208
|
+
# Formula (14)
|
209
|
+
# rho
|
210
|
+
def density_from_H(geopotential_alt)
|
211
|
+
temp = temperature_at_layer_from_H(geopotential_alt)
|
212
|
+
p = pressure_from_H(geopotential_alt)
|
213
|
+
|
214
|
+
p / (CONST[:R] * temp)
|
215
|
+
end
|
216
|
+
|
217
|
+
def rho_rho_n_from_H(geopotential_alt)
|
218
|
+
density_from_H(geopotential_alt) / CONST[:rho_n]
|
219
|
+
end
|
220
|
+
|
221
|
+
def root_rho_rho_n_from_H(geopotential_alt)
|
222
|
+
Math.sqrt(rho_rho_n_from_H(geopotential_alt))
|
223
|
+
end
|
224
|
+
|
225
|
+
|
226
|
+
# Specific weight
|
227
|
+
# Formula (15)
|
228
|
+
# gamma
|
229
|
+
def specific_weight_from_H(geopotential_alt)
|
230
|
+
density_from_H(geopotential_alt) * gravity_at_geopotential(geopotential_alt)
|
231
|
+
end
|
232
|
+
|
233
|
+
# 2.9 Pressure scale height
|
234
|
+
# Formula (16)
|
235
|
+
# H_p
|
236
|
+
def pressure_scale_height_from_temp(temp)
|
237
|
+
(CONST[:R] * temp) / CONST[:g_n]
|
238
|
+
end
|
239
|
+
|
240
|
+
def pressure_scale_height_from_H(geopotential_alt)
|
241
|
+
temp = temperature_at_layer_from_H(geopotential_alt)
|
242
|
+
(CONST[:R] * temp) / gravity_at_geopotential(geopotential_alt)
|
243
|
+
end
|
244
|
+
|
245
|
+
# 2.10 Air number density
|
246
|
+
# Formula (17)
|
247
|
+
# n
|
248
|
+
def air_number_density_from_H(geopotential_alt)
|
249
|
+
temp = temperature_at_layer_from_H(geopotential_alt)
|
250
|
+
p = pressure_from_H(geopotential_alt)
|
251
|
+
|
252
|
+
CONST[:N_A] * p / (CONST[:R_star] * temp)
|
253
|
+
end
|
254
|
+
|
255
|
+
# 2.11 Mean air-particle speed
|
256
|
+
# Formula (18)
|
257
|
+
# v_bar
|
258
|
+
# CORRECT
|
259
|
+
def mean_air_particle_speed_from_temp(temp)
|
260
|
+
1.595769 * Math.sqrt(CONST[:R] * temp)
|
261
|
+
end
|
262
|
+
|
263
|
+
def mean_air_particle_speed_from_H(geopotential_alt)
|
264
|
+
temp = temperature_at_layer_from_H(geopotential_alt)
|
265
|
+
mean_air_particle_speed_from_temp(temp)
|
266
|
+
end
|
267
|
+
|
268
|
+
# 2.12 Mean free path of air particles
|
269
|
+
# Formula (19)
|
270
|
+
# l
|
271
|
+
def mean_free_path_of_air_particles_from_H(geopotential_alt)
|
272
|
+
1 / (1.414213562 * 3.141592654 * (0.365e-9 ** 2) * air_number_density_from_H(geopotential_alt))
|
273
|
+
end
|
274
|
+
|
275
|
+
# 2.13 Air-particle collision frequency
|
276
|
+
# Formula (20)
|
277
|
+
# omega
|
278
|
+
def air_particle_collision_frequency_from_temp(n, temp)
|
279
|
+
4 * (0.365e-9 ** 2) * ((3.141592654 / (CONST[:R_star] * CONST[:M])) ** 0.5) * n * CONST[:R_star] * (temp ** 0.5)
|
280
|
+
end
|
281
|
+
|
282
|
+
def air_particle_collision_frequency_from_H(geopotential_alt)
|
283
|
+
temp = temperature_at_layer_from_H(geopotential_alt)
|
284
|
+
n = air_number_density_from_H(geopotential_alt)
|
285
|
+
air_particle_collision_frequency_from_temp(n, temp)
|
286
|
+
end
|
287
|
+
|
288
|
+
# 2.14 Speed of sound
|
289
|
+
# Formula (21)
|
290
|
+
# a (ms-1)
|
291
|
+
# CORRECT
|
292
|
+
def speed_of_sound_from_temp(temp)
|
293
|
+
# `kappa` (ratio of c_p / c_v) = 1.4 (see 2.14)
|
294
|
+
kappa = 1.4
|
295
|
+
Math.sqrt(kappa * CONST[:R] * temp)
|
296
|
+
end
|
297
|
+
|
298
|
+
def speed_of_sound_from_H(geopotential_alt)
|
299
|
+
temp = temperature_at_layer_from_H(geopotential_alt)
|
300
|
+
speed_of_sound_from_temp(temp)
|
301
|
+
end
|
302
|
+
|
303
|
+
|
304
|
+
# 2.15 Dynamic viscosity
|
305
|
+
# Formula (22)
|
306
|
+
# mu (Pa s)
|
307
|
+
def dynamic_viscosity(temp)
|
308
|
+
# Sutherland's empirical constants in the equation for dynamic viscosity
|
309
|
+
capital_b_s = 1.458e-6
|
310
|
+
capital_s = 110.4
|
311
|
+
|
312
|
+
(capital_b_s * (temp ** (1.5))) / (temp + capital_s)
|
313
|
+
end
|
314
|
+
|
315
|
+
def dynamic_viscosity_from_H(geopotential_alt)
|
316
|
+
temp = temperature_at_layer_from_H(geopotential_alt)
|
317
|
+
dynamic_viscosity(temp)
|
318
|
+
end
|
319
|
+
|
320
|
+
# 2.16 Kinematic viscosity
|
321
|
+
# Formula (23)
|
322
|
+
# v
|
323
|
+
def kinematic_viscosity(temp)
|
324
|
+
dynamic_viscosity(temp) / CONST[:rho_n]
|
325
|
+
end
|
326
|
+
|
327
|
+
def kinematic_viscosity_from_H(geopotential_alt)
|
328
|
+
temp = temperature_at_layer_from_H(geopotential_alt)
|
329
|
+
dynamic_viscosity(temp) / density_from_H(geopotential_alt)
|
330
|
+
end
|
331
|
+
|
332
|
+
# 2.17 Thermal conductivity
|
333
|
+
# Formula (24)
|
334
|
+
# lambda
|
335
|
+
def thermal_conductivity_from_temp(temp)
|
336
|
+
(2.648151e-3 * (temp ** (1.5))) / (temp + (245.4 * (10 ** (-12.0/temp))))
|
337
|
+
end
|
338
|
+
|
339
|
+
def thermal_conductivity_from_H(geopotential_alt)
|
340
|
+
temp = temperature_at_layer_from_H(geopotential_alt)
|
341
|
+
thermal_conductivity_from_temp(temp)
|
342
|
+
end
|
343
|
+
|
344
|
+
def kelvin_to_celsius(kelvin)
|
345
|
+
kelvin - 273.15
|
346
|
+
end
|
347
|
+
|
348
|
+
end
|
349
|
+
end
|
350
|
+
end
|