Completed
Push — master ( 62ca8d...3839f8 )
by Ryan
01:47
created

test_wet_psychrometric_rh_kwargs()   A

Complexity

Conditions 1

Size

Total Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
c 1
b 0
f 0
dl 0
loc 10
rs 9.4285
1
# Copyright (c) 2008-2015 MetPy Developers.
2
# Distributed under the terms of the BSD 3-Clause License.
3
# SPDX-License-Identifier: BSD-3-Clause
4
"""Test the `thermo` module."""
5
6
import numpy as np
7
import pytest
8
9
from metpy.calc import (density, dewpoint, dewpoint_rh, dry_lapse, el,
10
                        equivalent_potential_temperature, lcl, lfc, mixing_ratio, moist_lapse,
11
                        parcel_profile, potential_temperature,
12
                        psychrometric_vapor_pressure_wet, relative_humidity_wet_psychrometric,
13
                        saturation_mixing_ratio, saturation_vapor_pressure, vapor_pressure,
14
                        virtual_potential_temperature, virtual_temperature)
15
16
from metpy.testing import assert_almost_equal, assert_array_almost_equal
17
from metpy.units import units
18
19
20
def test_potential_temperature():
21
    """Test potential_temperature calculation."""
22
    temp = np.array([278., 283., 291., 298.]) * units.kelvin
23
    pres = np.array([900., 500., 300., 100.]) * units.mbar
24
    real_th = np.array([286.493, 344.961, 410.4335, 575.236]) * units.kelvin
25
    assert_array_almost_equal(potential_temperature(pres, temp), real_th, 3)
26
27
28
def test_scalar():
29
    """Test potential_temperature accepts scalar values."""
30
    assert_almost_equal(potential_temperature(1000. * units.mbar, 293. * units.kelvin),
31
                        293. * units.kelvin, 4)
32
    assert_almost_equal(potential_temperature(800. * units.mbar, 293. * units.kelvin),
33
                        312.2828 * units.kelvin, 4)
34
35
36
def test_fahrenheit():
37
    """Test that potential_temperature handles temperature values in Fahrenheit."""
38
    assert_almost_equal(potential_temperature(800. * units.mbar, 68. * units.degF),
39
                        (312.444 * units.kelvin).to(units.degF), 2)
40
41
42
def test_pot_temp_inhg():
43
    """Test that potential_temperature can handle pressure not in mb (issue #165)."""
44
    assert_almost_equal(potential_temperature(29.92 * units.inHg, 29 * units.degC),
45
                        301.019735 * units.kelvin, 4)
46
47
48
def test_dry_lapse():
49
    """Test dry_lapse calculation."""
50
    levels = np.array([1000, 900, 864.89]) * units.mbar
51
    temps = dry_lapse(levels, 303.15 * units.kelvin)
52
    assert_array_almost_equal(temps,
53
                              np.array([303.15, 294.16, 290.83]) * units.kelvin, 2)
54
55
56
def test_dry_lapse_2_levels():
57
    """Test dry_lapse calculation when given only two levels."""
58
    temps = dry_lapse(np.array([1000., 500.]) * units.mbar, 293. * units.kelvin)
59
    assert_array_almost_equal(temps, [293., 240.3723] * units.kelvin, 4)
60
61
62
def test_moist_lapse():
63
    """Test moist_lapse calculation."""
64
    temp = moist_lapse(np.array([1000., 800., 600., 500., 400.]) * units.mbar,
65
                       293. * units.kelvin)
66
    true_temp = np.array([293, 284.64, 272.81, 264.42, 252.91]) * units.kelvin
67
    assert_array_almost_equal(temp, true_temp, 2)
68
69
70
def test_moist_lapse_degc():
71
    """Test moist_lapse with Celsius temperatures."""
72
    temp = moist_lapse(np.array([1000., 800., 600., 500., 400.]) * units.mbar,
73
                       19.85 * units.degC)
74
    true_temp = np.array([293, 284.64, 272.81, 264.42, 252.91]) * units.kelvin
75
    assert_array_almost_equal(temp, true_temp, 2)
76
77
78
def test_parcel_profile():
79
    """Test parcel profile calculation."""
80
    levels = np.array([1000., 900., 800., 700., 600., 500., 400.]) * units.mbar
81
    true_prof = np.array([303.15, 294.16, 288.026, 283.073, 277.058, 269.402,
82
                          258.966]) * units.kelvin
83
84
    prof = parcel_profile(levels, 30. * units.degC, 20. * units.degC)
85
    assert_array_almost_equal(prof, true_prof, 2)
86
87
88
def test_parcel_profile_saturated():
89
    """Test parcel_profile works when LCL in levels (issue #232)."""
90
    levels = np.array([1000., 700., 500.]) * units.mbar
91
    true_prof = np.array([296.95, 284.381, 271.123]) * units.kelvin
92
93
    prof = parcel_profile(levels, 23.8 * units.degC, 23.8 * units.degC)
94
    assert_array_almost_equal(prof, true_prof, 2)
95
96
97
def test_sat_vapor_pressure():
98
    """Test saturation_vapor_pressure calculation."""
99
    temp = np.array([5., 10., 18., 25.]) * units.degC
100
    real_es = np.array([8.72, 12.27, 20.63, 31.67]) * units.mbar
101
    assert_array_almost_equal(saturation_vapor_pressure(temp), real_es, 2)
102
103
104
def test_sat_vapor_pressure_scalar():
105
    """Test saturation_vapor_pressure handles scalar values."""
106
    es = saturation_vapor_pressure(0 * units.degC)
107
    assert_almost_equal(es, 6.112 * units.mbar, 3)
108
109
110
def test_sat_vapor_pressure_fahrenheit():
111
    """Test saturation_vapor_pressure handles temperature in Fahrenheit."""
112
    temp = np.array([50., 68.]) * units.degF
113
    real_es = np.array([12.2717, 23.3695]) * units.mbar
114
    assert_array_almost_equal(saturation_vapor_pressure(temp), real_es, 4)
115
116
117
def test_basic_dewpoint_rh():
118
    """Test dewpoint_rh function."""
119
    temp = np.array([30., 25., 10., 20., 25.]) * units.degC
120
    rh = np.array([30., 45., 55., 80., 85.]) / 100.
121
122
    real_td = np.array([11, 12, 1, 16, 22]) * units.degC
123
    assert_array_almost_equal(real_td, dewpoint_rh(temp, rh), 0)
124
125
126
def test_scalar_dewpoint_rh():
127
    """Test dewpoint_rh with scalar values."""
128
    td = dewpoint_rh(10.6 * units.degC, 0.37)
129
    assert_almost_equal(td, 26. * units.degF, 0)
130
131
132
def test_dewpoint():
133
    """Test dewpoint calculation."""
134
    assert_almost_equal(dewpoint(6.112 * units.mbar), 0. * units.degC, 2)
135
136
137
def test_dewpoint_weird_units():
138
    """Test dewpoint using non-standard units.
139
140
    Revealed from odd dimensionless units and ending up using numpy.ma math
141
    functions instead of numpy ones.
142
    """
143
    assert_almost_equal(dewpoint(15825.6 * units('g * mbar / kg')),
144
                        13.8564 * units.degC, 4)
145
146
147
def test_mixing_ratio():
148
    """Test mixing ratio calculation."""
149
    p = 998. * units.mbar
150
    e = 73.75 * units.mbar
151
    assert_almost_equal(mixing_ratio(e, p), 0.04963, 2)
152
153
154
def test_vapor_pressure():
155
    """Test vapor pressure calculation."""
156
    assert_almost_equal(vapor_pressure(998. * units.mbar, 0.04963),
157
                        73.74925 * units.mbar, 5)
158
159
160
def test_lcl():
161
    """Test LCL calculation."""
162
    lcl_pressure, lcl_temperature = lcl(1000. * units.mbar, 30. * units.degC, 20. * units.degC)
163
    assert_almost_equal(lcl_pressure, 864.761 * units.mbar, 2)
164
    assert_almost_equal(lcl_temperature, 17.676 * units.degC, 2)
165
166
167
def test_lcl_convergence():
168
    """Test LCL calculation convergence failure."""
169
    with pytest.raises(RuntimeError):
170
        lcl(1000. * units.mbar, 30. * units.degC, 20. * units.degC, max_iters=2)
171
172
173
def test_lfc_basic():
174
    """Test LFC calculation."""
175
    levels = np.array([959., 779.2, 751.3, 724.3, 700., 269.]) * units.mbar
176
    temperatures = np.array([22.2, 14.6, 12., 9.4, 7., -49.]) * units.celsius
177
    dewpoints = np.array([19., -11.2, -10.8, -10.4, -10., -53.2]) * units.celsius
178
    l = lfc(levels, temperatures, dewpoints)
179
    assert_almost_equal(l[0], 727.468 * units.mbar, 2)
180
    assert_almost_equal(l[1], 9.705 * units.celsius, 2)
181
182
183
def test_no_lfc():
184
    """Test LFC calculation when there is no LFC in the data."""
185
    levels = np.array([959., 867.9, 779.2, 647.5, 472.5, 321.9, 251.]) * units.mbar
186
    temperatures = np.array([22.2, 17.4, 14.6, 1.4, -17.6, -39.4, -52.5]) * units.celsius
187
    dewpoints = np.array([9., 4.3, -21.2, -26.7, -31., -53.3, -66.7]) * units.celsius
188
    lfc_pressure, lfc_temperature = lfc(levels, temperatures, dewpoints)
189
    assert lfc_pressure is None
190
    assert lfc_temperature is None
191
192
193
def test_saturation_mixing_ratio():
194
    """Test saturation mixing ratio calculation."""
195
    p = 999. * units.mbar
196
    t = 288. * units.kelvin
197
    assert_almost_equal(saturation_mixing_ratio(p, t), .01068, 3)
198
199
200
def test_equivalent_potential_temperature():
201
    """Test equivalent potential temperature calculation."""
202
    p = 999. * units.mbar
203
    t = 288. * units.kelvin
204
    ept = equivalent_potential_temperature(p, t)
205
    assert_almost_equal(ept, 315.9548 * units.kelvin, 3)
206
207
208
def test_virtual_temperature():
209
    """Test virtual temperature calculation."""
210
    t = 288. * units.kelvin
211
    qv = .0016  # kg/kg
212
    tv = virtual_temperature(t, qv)
213
    assert_almost_equal(tv, 288.2796 * units.kelvin, 3)
214
215
216
def test_virtual_potential_temperature():
217
    """Test virtual potential temperature calculation."""
218
    p = 999. * units.mbar
219
    t = 288. * units.kelvin
220
    qv = .0016  # kg/kg
221
    theta_v = virtual_potential_temperature(p, t, qv)
222
    assert_almost_equal(theta_v, 288.3620 * units.kelvin, 3)
223
224
225
def test_density():
226
    """Test density calculation."""
227
    p = 999. * units.mbar
228
    t = 288. * units.kelvin
229
    qv = .0016  # kg/kg
230
    rho = density(p, t, qv).to(units.kilogram / units.meter ** 3)
231
    assert_almost_equal(rho, 1.2072 * (units.kilogram / units.meter ** 3), 3)
232
233
234
def test_el():
235
    """Test equilibrium layer calculation."""
236
    levels = np.array([959., 779.2, 751.3, 724.3, 700., 269.]) * units.mbar
237
    temperatures = np.array([22.2, 14.6, 12., 9.4, 7., -38.]) * units.celsius
238
    dewpoints = np.array([19., -11.2, -10.8, -10.4, -10., -53.2]) * units.celsius
239
    el_pressure, el_temperature = el(levels, temperatures, dewpoints)
240
    assert_almost_equal(el_pressure, 520.8420 * units.mbar, 3)
241
    assert_almost_equal(el_temperature, -11.7055 * units.degC, 3)
242
243
244
def test_no_el():
245
    """Test equilibrium layer calculation when there is no EL in the data."""
246
    levels = np.array([959., 867.9, 779.2, 647.5, 472.5, 321.9, 251.]) * units.mbar
247
    temperatures = np.array([22.2, 17.4, 14.6, 1.4, -17.6, -39.4, -52.5]) * units.celsius
248
    dewpoints = np.array([19., 14.3, -11.2, -16.7, -21., -43.3, -56.7]) * units.celsius
249
    el_pressure, el_temperature = el(levels, temperatures, dewpoints)
250
    assert el_pressure is None
251
    assert el_temperature is None
252
253
254
def test_wet_psychrometric_vapor_pressure():
255
    """Test calculation of vapor pressure from wet and dry bulb temperatures."""
256
    p = 1013.25 * units.mbar
257
    dry_bulb_temperature = 20. * units.degC
258
    wet_bulb_temperature = 18. * units.degC
259
    psychrometric_vapor_pressure = psychrometric_vapor_pressure_wet(dry_bulb_temperature,
260
                                                                    wet_bulb_temperature, p)
261
    assert_almost_equal(psychrometric_vapor_pressure, 19.3673 * units.mbar, 3)
262
263
264
def test_wet_psychrometric_rh():
265
    """Test calculation of relative humidity from wet and dry bulb temperatures."""
266
    p = 1013.25 * units.mbar
267
    dry_bulb_temperature = 20. * units.degC
268
    wet_bulb_temperature = 18. * units.degC
269
    psychrometric_rh = relative_humidity_wet_psychrometric(dry_bulb_temperature,
270
                                                           wet_bulb_temperature, p)
271
    assert_almost_equal(psychrometric_rh, 82.8747 * units.percent, 3)
272
273
274
def test_wet_psychrometric_rh_kwargs():
275
    """Test calculation of relative humidity from wet and dry bulb temperatures."""
276
    p = 1013.25 * units.mbar
277
    dry_bulb_temperature = 20. * units.degC
278
    wet_bulb_temperature = 18. * units.degC
279
    coeff = 6.1e-4 / units.kelvin
280
    psychrometric_rh = relative_humidity_wet_psychrometric(dry_bulb_temperature,
281
                                                           wet_bulb_temperature, p,
282
                                                           psychrometer_coefficient=coeff)
283
    assert_almost_equal(psychrometric_rh, 82.9701 * units.percent, 3)
284