Skip to content

Commit 0417f5a

Browse files
Merge branch 'Unidata:main' into benchmarking
2 parents 0253fad + c880ce5 commit 0417f5a

2 files changed

Lines changed: 99 additions & 5 deletions

File tree

src/metpy/calc/turbulence.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ def get_perturbation(ts, axis=-1):
4646

4747

4848
@exporter.export
49-
@preprocess_and_wrap(wrap_like='u')
49+
@preprocess_and_wrap()
5050
def tke(u, v, w, perturbation=False, axis=-1):
5151
r"""Compute turbulence kinetic energy.
5252
@@ -180,7 +180,7 @@ def kinematic_flux(vel, b, perturbation=False, axis=-1):
180180

181181

182182
@exporter.export
183-
@preprocess_and_wrap(wrap_like='u')
183+
@preprocess_and_wrap()
184184
def friction_velocity(u, w, v=None, perturbation=False, axis=-1):
185185
r"""Compute the friction velocity from the time series of velocity components.
186186
@@ -245,5 +245,4 @@ def friction_velocity(u, w, v=None, perturbation=False, axis=-1):
245245
# the friction velocity is the 4th root of the kinematic momentum flux
246246
# As an optimization, first do inplace square root, then return the
247247
# square root of that. This is faster than np.power(..., 0.25)
248-
np.sqrt(kf, out=kf)
249-
return np.sqrt(kf)
248+
return np.sqrt(np.sqrt(kf))

tests/calc/test_turbulence.py

Lines changed: 96 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@
44
"""Test the `turbulence` module."""
55

66
import numpy as np
7-
from numpy.testing import assert_almost_equal, assert_array_equal
87
import pytest
8+
import xarray as xr
99

1010
from metpy.calc.turbulence import friction_velocity, get_perturbation, kinematic_flux, tke
11+
from metpy.testing import assert_almost_equal, assert_array_almost_equal, assert_array_equal
12+
from metpy.units import units
1113

1214

1315
#
@@ -30,6 +32,47 @@ def uvw_and_known_tke():
3032
return u, v, w, e_true
3133

3234

35+
@pytest.fixture()
36+
def uvw_and_known_tke_xarray():
37+
"""Provide a set of u, v, w with a known tke value as an xarray."""
38+
# Define coordinate values
39+
pressure = [1000, 850] # hPa
40+
lat = [10, 20] # degrees North
41+
lon = [30, 40] # degrees East
42+
time = np.array(['2025-01-01T00:00', '2025-01-01T06:00'], dtype='datetime64')
43+
44+
# Define dimensions
45+
dims = ('pressure', 'lat', 'lon', 'time')
46+
47+
# Generate 16 linearly spaced values between -30 and 30
48+
uwind_values = np.linspace(0, 30, num=16).reshape(2, 2, 2, 2)
49+
vwind_values = np.linspace(-30, 0, num=16).reshape(2, 2, 2, 2)
50+
wwind_values = np.linspace(-1, 2, num=16).reshape(2, 2, 2, 2)
51+
52+
# Apply units
53+
u = uwind_values * units('m/s')
54+
v = vwind_values * units('m/s')
55+
w = wwind_values * units('m/s')
56+
57+
# Create the Dataset
58+
ds = xr.Dataset(
59+
{
60+
'uwind': (dims, u),
61+
'vwind': (dims, v),
62+
'wwind': (dims, w),
63+
},
64+
coords={
65+
'pressure': pressure,
66+
'lat': lat,
67+
'lon': lon,
68+
'time': time
69+
}
70+
)
71+
72+
e_true = np.full((2, 2, 2), 1.005) * units('m^2/s^2')
73+
return ds, e_true
74+
75+
3376
def test_no_tke_1d():
3477
"""Test tke calculation where the expected value is 0."""
3578
observations = 5
@@ -71,6 +114,12 @@ def test_known_tke(uvw_and_known_tke):
71114
assert_array_equal(e_true, tke(u, v, w))
72115

73116

117+
def test_known_tke_xarray(uvw_and_known_tke_xarray):
118+
"""Test basic behavior of tke with known xarray values."""
119+
data, e_true = uvw_and_known_tke_xarray
120+
assert_array_almost_equal(tke(data.uwind, data.vwind, data.wwind), e_true)
121+
122+
74123
def test_known_tke_using_perturbation_velocities(uvw_and_known_tke):
75124
"""Test basic behavior of tke with known values."""
76125
u, v, w, e_true = uvw_and_known_tke
@@ -334,6 +383,46 @@ def uvw_and_known_u_star_zero_mean():
334383
return u, v, w, u_star_true
335384

336385

386+
@pytest.fixture()
387+
def uvw_and_known_friction_velocity_xarray():
388+
"""Provide a set of u, v, w with a known tke value as an xarray."""
389+
# Define coordinate values
390+
pressure = [1000, 850] # hPa
391+
lat = [10, 20] # degrees North
392+
lon = [30, 40] # degrees East
393+
time = np.array(['2025-01-01T00:00', '2025-01-01T06:00'], dtype='datetime64')
394+
395+
# Define dimensions
396+
dims = ('pressure', 'lat', 'lon', 'time')
397+
398+
# Generate 16 linearly spaced values between -30 and 30
399+
uwind_values = np.linspace(0, 30, num=16).reshape(2, 2, 2, 2)
400+
vwind_values = np.linspace(-30, 0, num=16).reshape(2, 2, 2, 2)
401+
wwind_values = np.linspace(-1, 2, num=16).reshape(2, 2, 2, 2)
402+
403+
# Apply units
404+
u = uwind_values * units('m/s')
405+
v = vwind_values * units('m/s')
406+
w = wwind_values * units('m/s')
407+
408+
# Create the Dataset
409+
ds = xr.Dataset(
410+
{
411+
'uwind': (dims, u),
412+
'vwind': (dims, v),
413+
'wwind': (dims, w),
414+
},
415+
coords={
416+
'pressure': pressure,
417+
'lat': lat,
418+
'lon': lon,
419+
'time': time
420+
}
421+
)
422+
expected = np.full((2, 2, 2), .3760603) * units('meter / second')
423+
return ds, expected
424+
425+
337426
@pytest.fixture()
338427
def uvw_and_known_u_star_nonzero_mean():
339428
"""Return components and friction velocity for a non-zero-mean time series."""
@@ -362,6 +451,12 @@ def test_u_star_1d_nonzero_mean(uvw_and_known_u_star_nonzero_mean):
362451
u_star_true['uwvw'])
363452

364453

454+
def test_friction_velocity_nonzero_xarray(uvw_and_known_friction_velocity_xarray):
455+
"""Test friction velocity in 1d with an xarray."""
456+
data, expected = uvw_and_known_friction_velocity_xarray
457+
assert_array_almost_equal(friction_velocity(data.uwind, data.wwind, data.vwind), expected)
458+
459+
365460
def test_u_star_2d_axis_last_zero_mean(uvw_and_known_u_star_zero_mean):
366461
"""Test friction velocity in 2D with a zero-mean time series along the last axis."""
367462
u, v, w, u_star_true = uvw_and_known_u_star_zero_mean

0 commit comments

Comments
 (0)