Source code for wavespectra.construct.frequency

"""Frequency spectral shapes."""

import numpy as np
import xarray as xr
from scipy.constants import g, pi

from wavespectra.core.utils import scaled, check_same_coordinates, wavenuma, to_coords
from wavespectra.core.attributes import attrs
from wavespectra.core import npstats


[docs] def pierson_moskowitz(freq, fp, alpha=0.0081, hs=None, **kwargs): """Pierson and Moskowitz spectrum for fully developed seas (Pierson and Moskowitz, 1964). Args: - freq (DataArray, 1darray, list): Frequency array (Hz). - fp (DataArray, float): Peak wave frequency (Hz). - alpha (DataArray, float): Phillip's fetch-dependent scaling coefficient. - hs (DataArray, float): Significant wave height (m), if provided the spectra are scaled so that :math:`4\\sqrt{m_0} = hs`. Returns: - efth (SpecArray): Pierson-Moskowitz frequency spectrum E(f) (m2s). Note: - If `hs` is provided the spectra are scaled so that :math:`4\\sqrt{m_0} = hs` and the scaling parameter `alpha` becomes irrelevant. - If two or more input args other than `freq` are DataArrays, they must share the same coordinates. """ check_same_coordinates(fp, alpha) if not isinstance(freq, xr.DataArray): freq = to_coords(freq, "freq") dsout = alpha * g**2 / (2 * pi) ** 4 / freq**5 * np.exp(-1.25 * (freq / fp) ** -4) if hs is not None: dsout = scaled(dsout, hs) dsout.name = attrs.SPECNAME return dsout
[docs] def jonswap( freq, fp, alpha=0.0081, gamma=3.3, sigma_a=0.07, sigma_b=0.09, hs=None, **kwargs ): """Jonswap frequency spectrum for developing seas (Hasselmann et al., 1973). Args: - freq (DataArray, 1darray, list): Frequency array (Hz). - fp (DataArray, float): Peak wave frequency (Hz). - alpha (DataArray, float): Phillip's fetch-dependent scaling coefficient. - gamma (DataArray, float): Peak enhancement parameter. - sigma_a (DataArray, float): width of the peak enhancement parameter for f <= fp. - sigma_b (DataArray, float): width of the peak enhancement parameter for f > fp. - hs (DataArray, float): Significant wave height (m), if provided the Jonswap spectra are scaled so that :math:`4\\sqrt{m_0} = hs`. Returns: - efth (SpecArray): Jonswap spectrum E(f) (m2s). Note: - If `hs` is provided than the scaling parameter `alpha` becomes irrelevant. - If two or more input args other than `freq` are DataArrays, they must share the same coordinates. """ check_same_coordinates(fp, alpha, gamma, sigma_a, sigma_b, hs) if not isinstance(freq, xr.DataArray): freq = to_coords(freq, "freq") sigma = xr.where(freq <= fp, sigma_a, sigma_b) term1 = alpha * g**2 * (2 * pi) ** -4 * freq**-5 term2 = np.exp(-(5 / 4) * (freq / fp) ** -4) term3 = gamma ** np.exp(-((freq - fp) ** 2) / (2 * sigma**2 * fp**2)) dsout = term1 * term2 * term3 if hs is not None: dsout = scaled(dsout, hs) dsout.name = attrs.SPECNAME return dsout
[docs] def tma( freq, fp, dep, alpha=0.0081, gamma=3.3, sigma_a=0.07, sigma_b=0.09, hs=None, **kwargs, ): """TMA frequency spectrum for seas in water of finite depth (Bouws et al., 1985). Args: - freq (DataArray, 1darray, list): Frequency array (Hz). - fp (DataArray, float): Peak wave frequency (Hz). - dep (DataArray, float): Water depth (m). - alpha (DataArray, float): Phillip's fetch-dependent scaling coefficient. - gamma (DataArray, float): Peak enhancement parameter. - sigma_a (float): width of the peak enhancement parameter for f <= fp. - sigma_b (float): width of the peak enhancement parameter for f > fp. - hs (DataArray, float): Significant wave height (m), if provided the Jonswap spectra are scaled so that :math:`4\\sqrt{m_0} = hs`. Returns: - efth (SpecArray): TMA frequency spectrum E(f) (m2s). Note: - If `hs` is provided than the scaling parameter `alpha` becomes irrelevant. - If two or more input args other than freq are DataArrays, they must share the same coordinates. """ check_same_coordinates(fp, dep, alpha, gamma, sigma_a, sigma_b, hs) if not isinstance(freq, xr.DataArray): freq = to_coords(freq, "freq") dsout = jonswap(freq, fp, alpha, gamma, sigma_a, sigma_b, hs) k = wavenuma(freq, dep) phi = np.tanh(k * dep) ** 2 / (1 + (2 * k * dep) / np.sinh(2 * k * dep)) dsout = dsout * phi if hs is not None: dsout = scaled(dsout, hs) dsout.name = attrs.SPECNAME return dsout
[docs] def gaussian(freq, hs, fp, gw, **kwargs): """Gaussian frequency spectrum (Bunney et al., 2014). Args: - freq (DataArray): Frequency array (Hz). - hs (DataArray, float): Significant wave height (m). - fp (DataArray, float): Peak wave frequency (Hz). - gw (DataArray, float): Gaussian width parameter :math:`\sigma` (m2s). Returns: - efth (SpecArray): Gaussian frequency spectrum E(f) (m2s). Note: - The spectra are scaled so that :math:`4\\sqrt{m_0} = hs`. - If two or more input args other than `freq` are DataArrays, they must share the same coordinates. """ check_same_coordinates(hs, fp, gw) if not isinstance(freq, xr.DataArray): freq = to_coords(freq, "freq") mo = (hs / 4) ** 2 dsout = mo / (gw * np.sqrt(2 * pi)) * np.exp(-0.5 * ((freq - fp) / gw) ** 2) dsout = scaled(dsout, hs) dsout.name = attrs.SPECNAME return dsout
def conditional( freq, hs, fp, cond, when_true="jonswap", when_false="gaussian", **kwargs ): """Conditional frequency spectrum selecting a given shape based on a boolean array. Args: - freq (DataArray): Frequency array (Hz). - hs (DataArray, float): Significant wave height (m). - fp (DataArray, float): Peak wave frequency (Hz). - cond (DataArray, bool): . - when_true: spectral shape function when cond == True. - when_false: spectral shape function when cond == False. - kwargs: kwargs must have all arguments for both when_true and when_false functions. Returns: - efth (SpecArray): Conditional frequency spectrum E(f) (m2s). Note: - The spectra are scaled so that :math:`4\\sqrt{m_0} = hs`. - If two or more input args other than `freq` are DataArrays, they must share the same coordinates. """ check_same_coordinates(hs, fp, cond) if not isinstance(freq, xr.DataArray): freq = to_coords(freq, "freq") import inspect arg_vals = inspect.getargvalues(inspect.currentframe()) arguments = {a: arg_vals.locals[a] for a in arg_vals.args} arguments.update(arg_vals.locals["kwargs"]) true_func = globals()[when_true] false_func = globals()[when_false] ds_true = true_func(**arguments) ds_false = false_func(**arguments) dsout = xr.where(cond, ds_true, ds_false) dsout.name = attrs.SPECNAME return dsout