Source code for openquake.hazardlib.gsim.yenier_atkinson_2015
# -*- coding: utf-8 -*-# vim: tabstop=4 shiftwidth=4 softtabstop=4## Copyright (C) 2021 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/>."""Module exports :class:`YenierAtkinson2015BSSA`"""importnumpyasnpfromopenquake.hazardlibimportconstfromopenquake.hazardlib.imtimportPGA,PGV,SAfromopenquake.hazardlib.gsim.baseimportCoeffsTable,GMPEfromopenquake.hazardlib.gsim.boore_2014importBooreEtAl2014,CONSTS
[docs]defget_sof_adjustment(rake,imt):""" Computes adjustment factor for style-of-faulting following the scheme proposed by Bommer et al. (2003). :param rake: Rake value :param imt: The intensity measure type :return: The adjustment factor """im2=imt.string[:2]ifimt.string=='PGA'or(im2=='SA'andimt.period<=0.4):f_r_ss=1.2elifim2=='SA'andimt.period>0.4andimt.period<3.0:f_r_ss=1.2-(0.3/np.log10(3.0/0.4))*np.log10(imt.period/0.4)elifim2=='SA'andimt.period>=3.0:f_r_ss=1.2-(0.3/np.log10(3.0/0.4))*np.log10(3.0/0.4)else:raiseValueError('Unsupported IMT')# Set coefficientsf_n_ss=0.95p_r=0.68p_n=0.02# Normal - F_N:EQif-135<rake<=-45:famp=f_r_ss**(-p_r)*f_n_ss**(1-p_n)# Reverse - F_R:EQelif45<rake<=135:famp=f_r_ss**(1-p_r)*f_n_ss**(-p_n)# Strike-Slip - F_SS:EQelif(-30<rake<=30)or(150<rake<=180)or(-180<rake<=-150):famp=f_r_ss**(-p_r)*f_n_ss**(-p_n)else:raiseValueError('Unrecognised rake value')returnfamp
def_get_c_e(region,imt):""" Implements the Ce calibration term. - For 'CENA' See eq. 23 at page 2003 """ifregion=='CENA':# See equation 23 page 2003 of Yenier and Atkinsonifimt.string=='PGA':return-0.25elifimt.string=='PGV':return-0.21elifimt.period<=10.:return-0.25+np.max([0,0.39*np.log(imt.period/2)])else:fmt='This IMT is not supported by the Ce calibration term'msg=fmt.format(region)raiseValueError(msg)else:fmt='{:s} region does not have Ce calibration term'msg=fmt.format(region)raiseValueError(msg)def_get_c_p(region,imt,rrup,m):""" Implements the Cp calibration term """ifregion=='CENA':# See equations 24 and 25 page 2003 of Yenier and Atkinsonifimt.string=='PGA':delta_b3=0.030elifimt.string=='PGV':delta_b3=0.052elifimt.period<=10.:tmp=0.095*np.log(imt.period/0.065)delta_b3=np.min([0.095,0.030+np.max([0,tmp])])else:msg='This region is not supported by the Ce calibration term'raiseValueError(msg)# Compute the calibration termpseudo_depth=10**(-0.405+0.235*m)reff=(rrup**2+pseudo_depth**2)**0.5cp=np.zeros_like(rrup)# cp[rrup <= 150] = delta_b3 * np.log(rrup[rrup <= 150]/150.)cp[reff<=150]=delta_b3*np.log(reff[reff<=150]/150.)returncpelse:fmt='{:s} region does not have Cp calibration term'msg=fmt.format(region)raiseValueError(msg)def_get_edelta(C,m,stress_drop):edelta=(C['s0']+C['s1']*m+C['s2']*m**2+C['s3']*m**3+C['s4']*m**4)m=m[stress_drop>100]edelta[stress_drop>100]=(C['s5']+C['s6']*m+C['s7']*m**2+C['s8']*m**3+C['s9']*m**4)returnedeltadef_get_f_gamma(region,C,imt,rrup):""" Implements """ifregion=='CENA':returnrrup*C['gCENA']elifregion=='CA':returnrrup*C['gCalifornia']else:fmt='{:s} is a key not supported for region definition'msg=fmt.format(region)raiseValueError(msg)def_get_f_m(C,imt,m):""" Implements eq. 3 at page 1991 """mh=C['Mh']res=C['e0']+C['e1']*(m-mh)+C['e2']*(m-mh)**2res[m>mh]=C['e0']+C['e3']*(m[m>mh]-mh)returnresdef_get_f_z(C,imt,rrup,m):""" Implements eq. 7 and eq. 8 at page 1991 """# Pseudo depth - see eq. 6 at page 1991pseudo_depth=10**(-0.405+0.235*m)# Effective distance - see eq. 5 at page 1991reff=(rrup**2+pseudo_depth**2)**0.5# The transition_distance is 50 km as defined just below eq. 8transition_dst=50.# Geometrical spreading ratesb1=-1.3b2=-0.5# Geometrical attenuationz=reff**b1ratio_a=reff/transition_dstz[reff>transition_dst]=(transition_dst**b1*(ratio_a[reff>transition_dst])**b2)# Compute geometrical spreading functionratio_b=reff/(1.+pseudo_depth**2)**0.5returnnp.log(z)+(C['b3']+C['b4']*m)*np.log(ratio_b)def_get_mean_on_rock(region,focal_depth,C2,C3,C4,ctx,imt):# Get coefficients# Magnitude effectf_m=_get_f_m(C2,imt,ctx.mag)# Stress adjustmentf_delta_sigma=_get_stress_drop_adjstment(region,focal_depth,C3,imt,ctx.mag)# Geometrical spreadingf_z=_get_f_z(C2,imt,ctx.rrup,ctx.mag)# Anelastic attenuation functionf_gamma=_get_f_gamma(region,C4,imt,ctx.rrup)# Regional term for stress dropc_e=_get_c_e(region,imt)# Regional term for path durationc_p=_get_c_p(region,imt,ctx.rrup,ctx.mag)# Compute mean using equation 26mean=f_m+f_delta_sigma+f_z+f_gamma+c_e+c_preturnmeandef_get_mean_on_soil(adapted,region,focal_depth,gmm,C2,C3,C4,ctx,imt):# Get PGA on rocktmp=PGA()pga_rock=_get_mean_on_rock(region,focal_depth,C2,C3,C4,ctx,tmp)pga_rock=np.exp(pga_rock)ifadapted:# in acme_2019# Site-effect model: always evaluated for 760 (see HID 2.6.2)vs30=np.ones_like(ctx.vs30)*760.else:vs30=ctx.vs30# Compute the mean on soilmean=_get_mean_on_rock(region,focal_depth,C2,C3,C4,ctx,imt)# coefficients of BooreEtAl2014C=gmm.COEFFS[imt]mean+=get_fs_SeyhanStewart2014(C,imt,pga_rock,vs30)ifadapted:# acme_2019 considers the SoF correctionfamp=[get_sof_adjustment(rake,imt)forrakeinctx.rake]mean+=np.log(famp)returnmeandef_get_stress_drop_adjstment(region,focal_depth,C,imt,m):""" Implements eq. 4 at page 1991 and eq. 17 at page 1994. For CENA we use eq. 21 at page 2001 """ifregion=='CENA':d=focal_deptht1=np.clip(0.290*(d-10.),None,0)t2=np.clip(0.229*(m-5.),None,0)delta_sigma=np.exp(5.704+t1+t2)edelta=_get_edelta(C,m,delta_sigma)returnedelta*np.log(delta_sigma/100.)else:fmt='{:s} is a region not supported for stress drop adjustment'msg=fmt.format(region)raiseValueError(msg)
[docs]defget_fs_SeyhanStewart2014(C,imt,pga_rock,vs30):""" Implements eq. 11 and 12 at page 1992 in Yenier and Atkinson (2015) :param pga_rock: Median peak ground horizontal acceleration for reference :param vs30: """# Linear termflin=vs30/CONSTS['Vref']flin[vs30>C['Vc']]=C['Vc']/CONSTS['Vref']fl=C['c']*np.log(flin)# Non-linear termv_s=np.copy(vs30)v_s[vs30>760.]=760.# parameter (equation 8 of BSSA 2014)f_2=C['f4']*(np.exp(C['f5']*(v_s-360.))-np.exp(C['f5']*400.))fnl=CONSTS['f1']+f_2*np.log((pga_rock+CONSTS['f3'])/CONSTS['f3'])returnfl+fnl
[docs]classYenierAtkinson2015BSSA(GMPE):""" Implements the GMM of Yenier and Atkinson (2015) as described in the paper titled "Regionally Adjustable Generic Ground-Motion Prediction Equation to Central and Eastern North America" published on BSSA, vol 105. Note that this model does not provide a standard deviation, hence, in order to use it for PSHA calculations if must be combined with a model for ground motion aleatory uncertainty such as, for example, the one proposed by Al Atik (2014). :param focal_depth: A float defining focal depth [km]. :param region: A string specifying a region. Admitted values are 'CENA' (Central and East North America) and 'CA' (California). Default is 'CENA' """#: Supported tectonic region type is active shallow crust, see title!DEFINED_FOR_TECTONIC_REGION_TYPE=const.TRT.ACTIVE_SHALLOW_CRUST#: Supported intensity measure types are spectral acceleration, peak#: ground velocity and peak ground acceleration, see tables 4#: pages 1036DEFINED_FOR_INTENSITY_MEASURE_TYPES={PGA,PGV,SA}#: Supported intensity measure component is orientation-independent#: average horizontal :attr:`~openquake.hazardlib.const.IMC.RotD50`,#: see page 1025.DEFINED_FOR_INTENSITY_MEASURE_COMPONENT=const.IMC.GEOMETRIC_MEAN#: Supported standard deviation types are inter-event, intra-event#: and total, see paragraph "Equations for standard deviations", page#: 1046.DEFINED_FOR_STANDARD_DEVIATION_TYPES={const.StdDev.TOTAL}#: Required site parameter is Vs30REQUIRES_SITES_PARAMETERS={'vs30'}#: Required rupture parameters are magnitude and hypocenter depthREQUIRES_RUPTURE_PARAMETERS={'mag','hypo_depth'}#: Required distance measures is RrupREQUIRES_DISTANCES={'rrup'}REQUIRES_ATTRIBUTES={'adapted','region','focal_depth'}adapted=Falsedef__init__(self,focal_depth=None,region='CENA',**kwargs):super().__init__(focal_depth=focal_depth,region=region,**kwargs)self.focal_depth=focal_depthself.region=regionself.gmpe=BooreEtAl2014()
[docs]defcompute(self,ctx:np.recarray,imts,mean,sig,tau,phi):form,imtinenumerate(imts):C2=self.COEFFS_TAB2[imt]C3=self.COEFFS_TAB3[imt]C4=self.COEFFS_TAB4[imt]# Compute focal depth if not set at the initialization levelifself.focal_depthisNone:focal_depth=ctx.hypo_depthelse:focal_depth=np.full_like(ctx.hypo_depth,self.focal_depth)# Compute mean and stdmean[m]=_get_mean_on_soil(self.adapted,self.region,focal_depth,self.gmpe,C2,C3,C4,ctx,imt)