Source code for pygmm.slope_displacement.watson_lamprey_abrahamson_2006

"""Watson-Lamprey and Abrahamson (2006) sliding-block displacement model."""

from __future__ import annotations

import numpy as np

from .._utils import dist_lognorm

__author__ = "Albert Kottke"


def _calc_wla06_ln_a_rms(pga):
    r"""Calculate :math:`\ln a_{rms}`, Equation (2)."""
    return -1.167 + 1.02 * np.log(pga)


def _calc_wla06_ln_dur_key(yield_coef: float, pga, psa_1s, mag: float):
    """Calculate the natural log of the duration the yield coefficient is exceeded."""
    ln_pga = np.log(pga)
    ln_pga_ky = np.log(pga / yield_coef)
    ln_psa_1s = np.log(psa_1s)

    return (
        -2.775
        + 0.956 * ln_pga_ky
        - 1.554 / (ln_pga_ky + 0.390)
        - 0.597 * ln_pga
        + 0.381 * ln_psa_1s
        + 0.334 * mag
    )


[docs] @dist_lognorm def calc_disp_wla06(yield_coef: float, pga, psa_1s, mag: float, **kwds): """Watson-Lamprey and Abrahamson (2006) slope displacement model. The model is not valid for PGA less than the yield coefficient, where NaN is returned. Parameters ---------- yield_coef : float Slope yield coefficient [g]. pga : float or array_like Peak ground acceleration [g]. psa_1s : float or array_like 5%-damped spectral acceleration at 1 s [g]. mag : float Moment magnitude. stats : bool, default False If True, return ``(ln_mean, ln_std)`` instead of the median. Returns ------- float or :class:`numpy.ndarray` Median displacement [cm], or ``(ln_mean, ln_std)`` if `stats` is True. """ # Constants from Table 1, with updated values provided by the authors. a1 = 5.463 b1 = 0.451 b2 = 0.0191 c1 = 0.591 d1 = 0.205 d2 = 0.0892 e1 = 1.039 e2 = 0.0427 f1 = -1.409 f2 = 0.1 ln_psa_1s = np.log(psa_1s) ln_dur_ky = _calc_wla06_ln_dur_key(yield_coef, pga, psa_1s, mag) ln_a_rms = _calc_wla06_ln_a_rms(pga) pga = np.asarray(pga) ln_pga_ky = np.log(pga / yield_coef) ln_psa_pga = np.log(psa_1s / pga) ln_mean = ( a1 + b1 * (ln_psa_1s + 0.45) + b2 * (ln_psa_1s + 0.45) ** 2 + c1 * (ln_a_rms - 1) + d1 * ln_psa_pga + d2 * ln_psa_pga**2 + e1 * (ln_dur_ky - 0.74) + e2 * (ln_dur_ky - 0.74) ** 2 + 1 / (f1 * (ln_pga_ky + f2)) ) # Equation not valid for PGA values less than the yield coefficient ln_mean = np.where(pga < yield_coef, np.nan, ln_mean) if ln_mean.ndim == 0: ln_mean = float(ln_mean) # From Figure 5 ln_std = 0.53 return ln_mean, ln_std