Source code for openquake.hazardlib.gsim.mgmpe.nrcan15_site_term
# The Hazard Library# Copyright (C) 2012-2025 GEM Foundation## This program 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.## This program 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 this program. If not, see <http://www.gnu.org/licenses/>."""Module :mod:`openquake.hazardlib.mgmp.nrcan15_site_term` implements:class:`~openquake.hazardlib.mgmpe.NRCan15SiteTerm`"""importcopyimportnumpyasnpfromopenquake.hazardlibimportconstfromopenquake.hazardlib.gsim.baseimportCoeffsTablefromopenquake.hazardlib.gsim.baseimportGMPE,registryfromopenquake.hazardlib.gsim.atkinson_boore_2006import(_get_site_amplification_non_linear,_get_site_amplification_linear)fromopenquake.baselib.generalimportCallableDictBA08_AB06=CallableDict()
[docs]@BA08_AB06.add("base")defBA08_AB06_base(kind,C,C2,vs30,imt,pgar):""" Computes amplification factor similarly to what is done in the 2015 version of the Canada building code. An initial version of this code was kindly provided by Michal Kolaj - Geological Survey of Canada :param vs30: Can be either a scalar or a :class:`~numpy.ndarray` instance :param imt: The intensity measure type :param pgar: The value of hazard on rock (vs30=760). Can be either a scalar or a :class:`~numpy.ndarray` instance. Unit of measure is fractions of gravity acceleration. :return: A scalar or a :class:`~numpy.ndarray` instance with the amplification factor. """fa=np.ones_like(vs30)ifnp.isscalar(vs30):vs30=np.array([vs30])ifnp.isscalar(pgar):pgar=np.array([pgar])## Fixing vs30 for hard rock to 1999 m/s. Beyond this threshold the# motion will not be deamplified furthervs=copy.copy(vs30)vs[vs>=2000]=1999.## Computing motion on rockidx=np.where(vs30>760)ifnp.size(idx)>0:""" # This is the original implementation - Since this code is # experimental we keep it for possible further developments # For values of Vs30 greater than 760 a linear interpolation is # used between the gm factor at 2000 m/s and 760 m/s fa[idx] = 10**(np.interp(np.log10(vs[idx]), np.log10([760.0, 2000.0]), np.log10([1.0, C2['c']]))) """nl=_get_site_amplification_non_linear(vs[idx],pgar[idx],C)lin=_get_site_amplification_linear(vs[idx],C)tmp=np.exp(nl+lin)fa[idx]=tmp## For values of Vs30 lower than 760 the amplification is computed# using the site term of Boore and Atkinson (2008)idx=np.where(vs<760.)ifnp.size(idx)>0:nl=_get_site_amplification_non_linear(vs[idx],pgar[idx],C)lin=_get_site_amplification_linear(vs[idx],C)fa[idx]=np.exp(nl+lin)returnfa
[docs]@BA08_AB06.add("linear")defBA08_AB06_linear(kind,C,C2,vs30,imt,pgar):""" Computes amplification factor using an approach similar to the one used for the 2015 Canada Buiding code. Michal Kolaj's help is acknoledged. :param vs30: an be either a scalar or a :class:`~numpy.ndarray` instance :param imt: The intensity measure type :param pgar: The value of hazard on rock (vs30=760). Can be either a scalar or a :class:`~numpy.ndarray` instance. Unit of measure is fractions of gravity acceleration. :return: A scalar or a :class:`~numpy.ndarray` instance with the amplification factor. """fa=np.ones_like(vs30)ifnp.isscalar(vs30):vs30=np.array([vs30])ifnp.isscalar(pgar):pgar=np.array([pgar])## Fixing vs30 for hard rock to 1999 m/s. Beyond this threshold the# motion will not be modifiedvs=copy.copy(vs30)vs[vs>=2000]=2000.## Computing motion on rockidx=np.where(vs30>760)ifnp.size(idx)>0:fa[idx]=1./10**(np.interp(np.log10(vs[idx]),np.log10([760.0,2000.0]),np.log10([1.0,C2['c']])))## For values of Vs30 lower than 760 the amplification is computed# using the site term of Boore and Atkinson (2008)idx=np.where(vs<760.)ifnp.size(idx)>0:nl=_get_site_amplification_non_linear(vs[idx],pgar[idx],C)lin=_get_site_amplification_linear(vs[idx],C)fa[idx]=np.exp(nl+lin)returnfa
[docs]classNRCan15SiteTerm(GMPE):""" Implements a modified GMPE class that can be used to account for local soil conditions in the estimation of ground motion. :param gmpe_name: The name of a GMPE class """kind="base"# ParametersREQUIRES_SITES_PARAMETERS={'vs30'}#: Required distances are set on the underlying gmpeREQUIRES_DISTANCES=set()REQUIRES_RUPTURE_PARAMETERS=set()DEFINED_FOR_INTENSITY_MEASURE_COMPONENT=''DEFINED_FOR_INTENSITY_MEASURE_TYPES=set()DEFINED_FOR_STANDARD_DEVIATION_TYPES={const.StdDev.TOTAL}DEFINED_FOR_TECTONIC_REGION_TYPE=''DEFINED_FOR_REFERENCE_VELOCITY=Nonedef__init__(self,gmpe_name,**kwargs):self.gmpe=registry[gmpe_name](**kwargs)self.set_parameters()# Check if this GMPE has the necessary requirementsifnot(hasattr(self.gmpe,'DEFINED_FOR_REFERENCE_VELOCITY')or'vs30'inself.gmpe.REQUIRES_SITES_PARAMETERS):msg='{:s} does not use vs30 nor a defined reference velocity'raiseAttributeError(msg.format(str(self.gmpe)))if'vs30'notinself.gmpe.REQUIRES_SITES_PARAMETERS:self.REQUIRES_SITES_PARAMETERS=frozenset(self.gmpe.REQUIRES_SITES_PARAMETERS|{'vs30'})# Check compatibility of reference velocityifhasattr(self.gmpe,'DEFINED_FOR_REFERENCE_VELOCITY'):ok=760<=self.gmpe.DEFINED_FOR_REFERENCE_VELOCITY<=820ifnotok:name=self.gmpe.__class__.__name__raiseValueError(f'{name}.DEFINED_FOR_REFERENCE_VELOCITY ''is not in the range 760..800')
[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. """# compute mean and standard deviations on rockctx_rock=copy.copy(ctx)ctx_rock.vs30=np.full_like(ctx.vs30,760.)self.gmpe.compute(ctx_rock,imts,mean,sig,tau,phi)form,imtinenumerate(imts):C=self.COEFFS_BA08[imt]C2=self.COEFFS_AB06r[imt]fa=BA08_AB06(self.kind,C,C2,ctx.vs30,imt,np.exp(mean[m]))mean[m]=np.log(np.exp(mean[m])*fa)