44"""Test the `turbulence` module."""
55
66import numpy as np
7- from numpy .testing import assert_almost_equal , assert_array_equal
87import pytest
8+ import xarray as xr
99
1010from 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+
3376def 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+
74123def 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 ()
338427def 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+
365460def 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