Skip to content

Commit 7c45c96

Browse files
authored
Update integral length scale function (#376)
Discovered a problem with the original function while conducting data analysis of ADV data from Puget Sound. Updating this function per the textbook definition of the integral time scale - it is listed as Equation 5.3 in this paper (http://dx.doi.org/10.1098/rsta.2012.0196). The code I'm replacing defined the integral time scale as when the autocorrelation function decays to 1/e of its original value, which is less robust than finding the first zero-crossing of the autocorrelation function, as is standard. The integral length scale [m] is simply the average flow speed [m/s] multiplied by the integral time scale [s].
1 parent 409822d commit 7c45c96

File tree

2 files changed

+21
-11
lines changed

2 files changed

+21
-11
lines changed
0 Bytes
Binary file not shown.

mhkit/dolfyn/adv/turbulence.py

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -619,13 +619,13 @@ def dissipation_rate_TE01(self, dat_raw, dat_avg, freq_range=[6.28, 12.57]):
619619

620620
def integral_length_scales(self, a_cov, U_mag, fs=None):
621621
"""
622-
Calculate integral length scales.
622+
Calculate integral length scales from the autocovariance (or autocorrelation).
623623
624624
Parameters
625625
----------
626-
a_cov : xarray.DataArray
627-
The auto-covariance array (i.e. computed using `autocovariance`).
628-
U_mag : xarray.DataArray
626+
a_cov : xarray.DataArray (..., time, lag)
627+
The autocovariance or autocorrelation array (i.e. computed using `autocovariance`).
628+
U_mag : xarray.DataArray (..., time)
629629
The bin-averaged horizontal velocity (from dataset shortcut)
630630
fs : numeric
631631
The raw sample rate
@@ -637,22 +637,32 @@ def integral_length_scales(self, a_cov, U_mag, fs=None):
637637
638638
Notes
639639
----
640-
The integral time scale (T_int) is the lag-time at which the
641-
auto-covariance falls to 1/e.
642-
643-
If T_int is not reached, L_int will default to '0'.
640+
The integral time scale (T_int) is integral of the normalized autocorrelation
641+
function, which theoretically decays to zero over time. Practically,
642+
T_int is the integral from zero to the first zero-crossing lag-time
643+
of the autocorrelation function. The integral length scale (L_int)
644+
then is the integral time scale multiplied by the bin speed.
644645
"""
645646

646647
if not isinstance(a_cov, xr.DataArray):
647648
raise TypeError("`a_cov` must be an instance of `xarray.DataArray`.")
648649
if len(a_cov["time"]) != len(U_mag["time"]):
649650
raise Exception("`U_mag` should be from ensembled-averaged dataset")
650651

651-
acov = a_cov.values
652652
fs = self._parse_fs(fs)
653+
# Normalize autocovariance/autocorrelation
654+
acov = a_cov / a_cov[..., 0]
655+
656+
# Calculate first zero crossing in auto-correlation
657+
zero_crossing = np.nanargmin(~(acov < 0), axis=-1)
658+
659+
# Calculate integral time scale
660+
T_int = np.zeros(acov.shape[:2])
661+
for i in range(3):
662+
for t in range(a_cov["time"].size):
663+
T_int[i, t] = np.trapz(acov[i, t][: zero_crossing[i, t]], dx=1 / fs)
653664

654-
scale = np.argmin((acov / acov[..., :1]) > (1 / np.e), axis=-1)
655-
L_int = U_mag.values / fs * scale
665+
L_int = U_mag.values * T_int
656666

657667
return xr.DataArray(
658668
L_int.astype("float32"),

0 commit comments

Comments
 (0)