"""Abrahamson and Silva (1996, :cite:`abrahamson96`) duration model."""
import numpy as np
from . import model
__author__ = "Albert Kottke"
[docs]
class AbrahamsonSilva1996(model.Model):
"""Abrahamson and Silva (1996, :cite:`abrahamson96`) duration model.
Parameters
----------
scenario : :class:`pygmm.model.Scenario`
earthquake scenario
"""
NAME = "Abrahamson Silva (1996)"
ABBREV = "AS96"
PARAMS = [
model.NumericParameter("mag", True, 4, 7.5),
model.NumericParameter("dist_rup", True, 0, 250),
# FIXME add site_cond to Scenario
model.CategoricalParameter("site_cond", True, ["soil", "rock"]),
]
[docs]
def __init__(self, scenario):
super().__init__(scenario)
s = self._scenario
stress_drop = np.exp(5.204 + 0.851 * (s.mag - 6))
moment = 10 ** (1.5 * s.mag + 16.05)
self._ln_dur = np.log(
(stress_drop / moment) ** (-1 / 3) / (4.9e6 * 3.2)
+ 0.805 * (1 if s.site_cond == "soil" else 0)
+ 0.063 * max(s.dist_rup - 10, 0)
) + self.calc_ln_dur_incr(0.75)
self._std_err = 0.55
@property
def duration(self):
return np.exp(self._ln_dur)
@property
def std_err(self):
return self._std_err
[docs]
@staticmethod
def calc_ln_dur_incr(nias):
# Mask out inappropriate values
nias = np.asarray(nias)
mask = (nias < 0.10) | (0.95 < nias)
nias[mask] = np.nan
# Compute the increment due to the difference in the normalized Arias
# intensity
ln_i_ratio = np.log((nias - 0.05) / (1 - nias))
ln_dur_incr = -0.532 + 0.552 * ln_i_ratio - 0.0262 * ln_i_ratio**2
return ln_dur_incr
[docs]
def interp(self, nias, stds=None):
# Mask out inappropriate values
nias = np.asarray(nias)
mask = (nias < 0.10) | (0.95 < nias)
nias[mask] = np.nan
ln_dur = self._ln_dur + self.calc_ln_dur_incr(nias)
if stds is not None:
std_errs = np.interp(
nias,
[
0.10,
0.15,
0.20,
0.25,
0.30,
0.35,
0.40,
0.45,
0.50,
0.55,
0.60,
0.65,
0.70,
0.75,
0.80,
0.85,
0.90,
0.95,
],
[
0.843,
0.759,
0.713,
0.691,
0.674,
0.660,
0.646,
0.636,
0.628,
0.616,
0.605,
0.594,
0.582,
0.565,
0.545,
0.528,
0.510,
0.493,
],
)
ln_dur = ln_dur + np.array(stds)[:, np.newaxis] * std_errs
return np.exp(ln_dur)