Source code for openquake.hazardlib.gsim.campbell_bozorgnia_2008
# -*- coding: utf-8 -*-# vim: tabstop=4 shiftwidth=4 softtabstop=4## Copyright (C) 2013-2025 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:`CampbellBozorgnia2008`, and:class:'CampbellBozorgnia2008Arbitrary'"""importnumpyasnpfrommathimportlog,expfromopenquake.hazardlib.gsim.baseimportGMPE,CoeffsTablefromopenquake.hazardlibimportconstfromopenquake.hazardlib.imtimportPGA,PGV,PGD,CAV,SAdef_get_basin_term(C,ctx,region=None):""" Returns the basin response term (equation 12, page 146) """z2pt5=ctx.z2pt5fsed=np.zeros_like(z2pt5,dtype=float)idx=z2pt5<1.0ifnp.any(idx):fsed[idx]=C['c11']*(z2pt5[idx]-1.0)idx=z2pt5>3.0ifnp.any(idx):fsed[idx]=(C['c12']*C['k3']*exp(-0.75))*\
(1.0-np.exp(-0.25*(z2pt5[idx]-3.0)))returnfseddef_compute_distance_term(C,ctx):""" Returns the distance scaling factor (equation (3), page 145) """return(C['c4']+C['c5']*ctx.mag)* \
np.log(np.sqrt(ctx.rrup**2.+C['c6']**2.))def_compute_hanging_wall_term(C,ctx):""" Returns the hanging wall scaling term, the product of the scaling coefficient and four separate scaling terms for distance, magnitude, rupture depth and dip (equations 6 - 10, page 146). Individual scaling terms defined in separate functions """return(C['c9']*_get_hanging_wall_distance_term(ctx)*_get_hanging_wall_magnitude_term(ctx.mag)*_get_hanging_wall_depth_term(ctx.ztor)*_get_hanging_wall_dip_term(ctx.dip))def_compute_imt1100(C,ctx,get_pga_site=False):""" Computes the PGA on reference (Vs30 = 1100 m/s) rock. """# Calculates simple site response term assuming all sites 1100 m/sfsite=(C['c10']+(C['k2']*C['n']))*log(1100./C['k1'])# Calculates the PGA on rockpga1100=np.exp(_compute_magnitude_term(C,ctx.mag)+_compute_distance_term(C,ctx)+_compute_style_of_faulting_term(C,ctx)+_compute_hanging_wall_term(C,ctx)+_get_basin_term(C,ctx)+fsite)# If PGA at the site is needed then remove factor for rock and# re-calculate on correct site conditionifget_pga_site:pga_site=np.exp(np.log(pga1100)-fsite)fsite=_compute_shallow_site_response(C,ctx,pga1100)pga_site=np.exp(np.log(pga_site)+fsite)else:pga_site=Nonereturnpga1100,pga_sitedef_compute_intra_event_alpha(C,vs30,pga1100):""" Returns the linearised functional relationship between fsite and pga1100, determined from the partial derivative defined on equation 17 on page 148 """alpha=np.zeros_like(vs30,dtype=float)idx=vs30<C['k1']ifnp.any(idx):temp1=(pga1100[idx]+C['c']*(vs30[idx]/C['k1'])**C['n'])**-1.temp1=temp1-((pga1100[idx]+C['c'])**-1.)alpha[idx]=C['k2']*pga1100[idx]*temp1returnalphadef_compute_intra_event_std(C,vs30,pga1100,sigma_pga):""" Returns the intra-event standard deviation at the site, as defined in equation 15, page 147 """# Get intra-event standard deviation at the base of the site profilesig_lnyb=np.sqrt(C['s_lny']**2.-C['s_lnAF']**2.)sig_lnab=np.sqrt(sigma_pga**2.-C['s_lnAF']**2.)# Get linearised relationship between f_site and ln PGAalpha=_compute_intra_event_alpha(C,vs30,pga1100)returnnp.sqrt((sig_lnyb**2.)+(C['s_lnAF']**2.)+((alpha**2.)*(sig_lnab**2.))+(2.0*alpha*C['rho']*sig_lnyb*sig_lnab))def_compute_magnitude_term(C,mag):""" Returns the magnitude scaling factor (equation (2), page 144) """fmag=C['c0']+C['c1']*magterm=C['c2']*(mag-5.5)term[mag<=5.5]=0.term[mag>6.5]=C['c2']*(mag[mag>6.5]-5.5)+(C['c3']*(mag[mag>6.5]-6.5))returnfmag+termdef_compute_shallow_site_response(C,ctx,pga1100):""" Returns the shallow site response term (equation 11, page 146) """stiff_factor=C['c10']+(C['k2']*C['n'])# Initially default all sites to intermediate rock valuefsite=stiff_factor*np.log(ctx.vs30/C['k1'])# Check for soft soil ctxidx=ctx.vs30<C['k1']ifnp.any(idx):pga_scale=np.log(pga1100[idx]+(C['c']*((ctx.vs30[idx]/C['k1'])**C['n'])))-np.log(pga1100[idx]+C['c'])fsite[idx]=C['c10']*np.log(ctx.vs30[idx]/C['k1'])+ \
(C['k2']*pga_scale)# Any very hard rock ctx are rendered to the constant amplification# factoridx=ctx.vs30>=1100.ifnp.any(idx):fsite[idx]=stiff_factor*log(1100./C['k1'])returnfsitedef_compute_style_of_faulting_term(C,ctx):""" Returns the style of faulting factor, depending on the mechanism (rake) and top of rupture depth (equations (4) and (5), pages 145 - 146) """frv,fnm=_get_fault_type_dummy_variables(ctx.rake)ffltz=np.zeros_like(ctx.rake)# Top of rupture depth term only applies to reverse faultsffltz[(frv>0.)&(ctx.ztor<1)]=ctx.ztor[(frv>0.)&(ctx.ztor<1)]ffltz[(frv>0.)&(ctx.ztor>=1)]=1.returnC['c7']*frv*ffltz+C['c8']*fnmdef_get_fault_type_dummy_variables(rake):""" Returns the coefficients FRV and FNM, describing if the rupture is reverse (FRV = 1.0, FNM = 0.0), normal (FRV = 0.0, FNM = 1.0) or strike-slip/oblique-slip (FRV = 0.0, FNM = 0.0). Reverse faults are classified as those with a rake in the range 30 to 150 degrees. Normal faults are classified as having a rake in the range -150 to -30 degrees :returns: FRV, FNM """frv,fnm=np.zeros_like(rake),np.zeros_like(rake)frv[(rake>30.0)&(rake<150.)]=1.fnm[(rake>-150.)&(rake<-30.)]=1.returnfrv,fnmdef_get_hanging_wall_depth_term(ztor):""" Returns the hanging wall depth scaling term (equation 9, page 146) """returnnp.where(ztor>=20.0,0.,(20.-ztor)/20.0)def_get_hanging_wall_dip_term(dip):""" Returns the hanging wall dip scaling term (equation 10, page 146) """returnnp.where(dip>70.0,(90.0-dip)/20.0,1.0)def_get_hanging_wall_distance_term(ctx):""" Returns the hanging wall distance scaling term (equation 7, page 146) """fhngr=np.ones_like(ctx.rjb,dtype=float)idx=(ctx.rjb>0.)&(ctx.ztor<1)temp_rjb=np.sqrt(ctx.rjb[idx]**2.+1.)r_max=np.max(np.column_stack([ctx.rrup[idx],temp_rjb]),axis=1)fhngr[idx]=(r_max-ctx.rjb[idx])/r_maxidx=(ctx.rjb>0.)&(ctx.ztor>=1)fhngr[idx]=(ctx.rrup[idx]-ctx.rjb[idx])/ctx.rrup[idx]returnfhngrdef_get_hanging_wall_magnitude_term(mag):""" Returns the hanging wall magnitude scaling term (equation 8, page 146) """returnnp.clip(2.*(mag-6.0),0.,1.)def_get_stddevs(kind,C,ctx,pga1100,sigma_pga):""" Returns the standard deviations as described in the "ALEATORY UNCERTAINTY MODEL" section of the paper. Equations 13 to 19, pages 147 to 151 """std_intra=_compute_intra_event_std(C,ctx.vs30,pga1100,sigma_pga)std_inter=C['t_lny']*np.ones_like(ctx.vs30)return[_get_total_sigma(kind,C,std_intra,std_inter),std_inter,std_intra]def_get_total_sigma(kind,C,std_intra,std_inter):""" Returns the total sigma term as defined by equation 16, page 147 This method is defined here as the Campbell & Bozorgnia (2008) model can also be applied to the "arbitrary" horizontal component definition, in which case the total sigma is modified (see equation 18, page 150). """tot2=std_intra**2.+std_inter**2.ifkind=='arbitrary':returnnp.sqrt(tot2+C['c_lny']**2.)returnnp.sqrt(tot2)
[docs]classCampbellBozorgnia2008(GMPE):""" Implements GMPE developed by Kenneth W. Campbell and Yousef Bozorgnia, published as "NGA Ground Motion Model for the Geometric Mean Horizontal Component of PGA, PGV, PGD and 5 % Damped Linear Elastic Response Spectra for Periods Ranging from 0.01 to 10s" (2008, Earthquake Spectra, Volume 24, Number 1, pages 139 - 171). This class implements the model for the Geometric Mean of the elastic spectra. Included in the coefficient set are the coefficients for the Campbell & Bozorgnia (2010) GMPE for predicting Cumulative Absolute Velocity (CAV), published as "A Ground Motion Prediction Equation for the Horizontal Component of Cumulative Absolute Velocity (CSV) Based on the PEER-NGA Strong Motion Database" (2010, Earthquake Spectra, Volume 26, Number 3, 635 - 650). """kind="base"#: Supported tectonic region type is active shallow crustDEFINED_FOR_TECTONIC_REGION_TYPE=const.TRT.ACTIVE_SHALLOW_CRUST#: Supported intensity measure types are spectral acceleration, peak#: ground velocity, peak ground displacement and peak ground acceleration#: Additional model for cumulative absolute velocity defined in#: Campbell & Bozorgnia (2010)DEFINED_FOR_INTENSITY_MEASURE_TYPES={PGA,PGV,PGD,CAV,SA}#: Supported intensity measure component is orientation-independent#: average horizontal :attr:`~openquake.hazardlib.const.IMC.GMRotI50`DEFINED_FOR_INTENSITY_MEASURE_COMPONENT=const.IMC.GMRotI50#: Supported standard deviation types are inter-event, intra-event#: and total, see section "Aleatory Uncertainty Model", page 147.DEFINED_FOR_STANDARD_DEVIATION_TYPES={const.StdDev.TOTAL,const.StdDev.INTER_EVENT,const.StdDev.INTRA_EVENT}#: Required site parameters are Vs30, Vs30 type (measured or inferred),#: and depth (km) to the 2.5 km/s shear wave velocity layer (z2pt5)REQUIRES_SITES_PARAMETERS={'vs30','z2pt5'}#: Required rupture parameters are magnitude, rake, dip, ztorREQUIRES_RUPTURE_PARAMETERS={'mag','rake','dip','ztor'}#: Required distance measures are Rrup and Rjb.REQUIRES_DISTANCES={'rrup','rjb'}
[docs]defcompute(self,ctx:np.recarray,imts,mean,sig,tau,phi):""" See :meth:`superclass method <.base.GroundShakingIntensityModel.compute>` for spec of input and result values. """C_PGA=self.COEFFS[PGA()]form,imtinenumerate(imts):C=self.COEFFS[imt]# compute median pga on rock (vs30=1100), needed for site response# term calculation# For spectral accelerations at periods between 0.0 and 0.25 s,# Sa (T) cannot be less than PGA on soil, therefore if the IMT is# in this period range it is necessary to calculate PGA on soilget_pga_site=imt.period>0.0andimt.period<0.25pga1100,pga_site=_compute_imt1100(C_PGA,ctx,get_pga_site)# Get the median ground motionmean[m]=(_compute_magnitude_term(C,ctx.mag)+_compute_distance_term(C,ctx)+_compute_style_of_faulting_term(C,ctx)+_compute_hanging_wall_term(C,ctx)+_compute_shallow_site_response(C,ctx,pga1100)+_get_basin_term(C,ctx))# If it is necessary to ensure that Sa(T) >= PGA# (see previous comment)ifget_pga_site:idx=mean[m]<np.log(pga_site)mean[m,idx]=np.log(pga_site[idx])sig[m],tau[m],phi[m]=_get_stddevs(self.kind,C,ctx,pga1100,C_PGA['s_lny'])
[docs]classCampbellBozorgnia2008Arbitrary(CampbellBozorgnia2008):""" Implements the Campbell & Bozorgnia (2008) GMPE as modified to represent the arbitrary horizontal component of ground motion, instead of the Rotationally Independent Geometric Mean (GMRotI) originally defined in the paper. """kind="arbitrary"#: Supported intensity measure component is arbitrary horizontal#: :attr:`~openquake.hazardlib.const.IMC.HORIZONTAL`,DEFINED_FOR_INTENSITY_MEASURE_COMPONENT=const.IMC.HORIZONTAL