Source code for openquake.hazardlib.gsim.wang_2025_turkey

# -*- coding: utf-8 -*-
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
# Copyright (C) 2014-2026 GEM Foundation
#
# OpenQuake is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# OpenQuake is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with OpenQuake. If not, see <http://www.gnu.org/licenses/>.

import numpy as np

from openquake.hazardlib.gsim.base import GMPE, CoeffsTable
from openquake.hazardlib import const
from openquake.hazardlib.imt import IA, CAV, RSD575, RSD595


[docs]class WangEtAl2025(GMPE): """ Implements the GMM for Turkey developed by Mao-Xin Wang et al., published as "Ground-motion models for Arias intensity, cumulative absolute velocity, and duration parameters in Türkiye" (2025, Soil Dynam Earthq Eng). Wang, M. X., Leung, A. Y. F., Zhu, C., Güryuva, B., Sandıkkaya, M. A., Ji, K. (2025). Ground-motion models for Arias intensity, cumulative absolute velocity, and duration parameters in Türkiye. Soil Dynamics and Earthquake Engineering, 196, 109440. https://doi.org/10.1016/j.soildyn.2025.109440 """ DEFINED_FOR_TECTONIC_REGION_TYPE = const.TRT.ACTIVE_SHALLOW_CRUST DEFINED_FOR_INTENSITY_MEASURE_TYPES = {IA, CAV, RSD575, RSD595} DEFINED_FOR_INTENSITY_MEASURE_COMPONENT = const.IMC.GEOMETRIC_MEAN #: Supported standard deviation types are inter-event, intra-event DEFINED_FOR_STANDARD_DEVIATION_TYPES = { const.StdDev.TOTAL, const.StdDev.INTER_EVENT, const.StdDev.INTRA_EVENT, } #: Required site parameter is Vs30 REQUIRES_SITES_PARAMETERS = {"vs30"} #: Required rupture parameters are magnitude, rake, ztor REQUIRES_RUPTURE_PARAMETERS = {"mag", "rake", "ztor"} #: Required distance measure is Joyner-Boore distance REQUIRES_DISTANCES = {"rjb"}
[docs] def compute(self, ctx: np.recarray, imts, mean, sig, tau, phi): """ See :meth:`superclass method <.base.GroundShakingIntensityModel.compute>` for spec of input and result values. """ # Get mean and standard deviation for m, imt in enumerate(imts): C = self.COEFFS[imt] # Magnitude Scaling (fmag), see equation (8) f_mag = C["c0"] + C["c1"] * ctx.mag idx = ctx.mag > C["b1"] f_mag[idx] += C["c2"] * (ctx.mag[idx] - C["b1"]) idx = ctx.mag > C["b2"] f_mag[idx] += C["c3"] * (ctx.mag[idx] - C["b2"]) # Magnitude-Dependent Distance Scaling (fdis,mag), see equation (9) f_dis = (C["c4"] + C["c5"] * ctx.mag) * np.log(np.sqrt(ctx.rjb**2 + C["c6"]**2)) # Faulting Mechanism (fmech), see equation (10) frv = np.zeros_like(ctx.rake) fnm = np.zeros_like(ctx.rake) frv[(ctx.rake > 30.) & (ctx.rake < 150.)] = 1. fnm[(ctx.rake > -150.) & (ctx.rake < -30.)] = 1. f_mech = C["c7"] * (ctx.mag - C["b3"]) / (C["b4"] - C["b3"]) * fnm + C["c8"] * frv idx_smallMag = ctx.mag <= C["b3"] f_mech[idx_smallMag] = C["c8"] * frv[idx_smallMag] idx_largeMag = ctx.mag > C["b4"] f_mech[idx_largeMag] = C["c7"] * fnm[idx_largeMag] + C["c8"] * frv[idx_largeMag] # Source Depth (fdepth), see equation (11) f_depth = C["c9"] * np.log(ctx.ztor+1) # Assume No Aftershock Scaling, see equation (12) f_as = 0 # Site Response (fsite), see equation (13) f_site = C["c11"] * np.log(np.minimum(ctx.vs30, C["b6"]) / C["vref"]) # Anelastic Distance Scaling, see equation (14) f_anelas = C["c12"] * np.maximum(ctx.rjb-80, 0) # Final Mean Prediction, see equation (7) mean[m] = f_mag + f_dis + f_mech + f_depth + f_as + f_site + f_anelas # Compute Standard Deviations M_tau1 = 6 M_tau2 = 6.5 M_phi1 = 5 M_phi2 = 6.5 # between-event temp_tau = C["tau1"] + (C["tau2"] - C["tau1"]) * (ctx.mag - M_tau1) / (M_tau2 - M_tau1) temp_tau[ctx.mag <= M_tau1] = M_tau1 temp_tau[ctx.mag > M_tau2] = M_tau2 tau[m] = temp_tau # within-event temp_phi = C["phi1"] + (C["phi2"] - C["phi1"]) * (ctx.mag - M_phi1) / (M_phi2 - M_phi1) temp_phi[ctx.mag <= M_phi1] = M_phi1 temp_phi[ctx.mag > M_phi2] = M_phi2 phi[m] = temp_phi # total sig[m] = np.sqrt(tau[m] ** 2 + phi[m] ** 2)
# Coefficient table COEFFS = CoeffsTable( table="""\ IMT c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 b1 b2 b3 b4 b6 vref tau1 tau2 phi1 phi2 ia -11.1415 2.0755 -0.9198 0 -3.7481 0.2951 5.347 -0.4587 0 0.3435 -0.0146 -1.3411 -0.0084 6.3 999 4.6 5.5 800 760 0.746 0.564 1.006 1.006 cav -4.8074 1.1833 -0.3845 0 -1.5225 0.1191 6.2075 -0.178 0 0.1614 -0.0077 -0.7554 -0.0033 6.3 999 4.6 5.5 800 760 0.346 0.303 0.459 0.459 rsd575 -2.2988 0.3366 0.2848 2.2215 1.25 -0.1161 4.5577 0.2115 0.1011 -0.0557 0 -0.0999 0.0023 4.5 7.6 5.2 6 1200 370 0.236 0.164 0.429 0.362 rsd595 -0.3917 0.2813 0.1272 1.8806 0.8438 -0.0721 3.252 0.1817 0.0753 -0.0437 0 -0.1698 0.0021 4.5 7.6 5.1 5.9 1200 370 0.195 0.17 0.35 0.308 """, )