def test_vskappa_scaling(self): vskappa_dict = {"PGA": 1.2, "SA(0.2)": 1.3, "SA(1.0)": 1.4} gsim_1 = self.gsim("BindiEtAl2014Rjb", branch="central", vskappa=vskappa_dict) gsim_2 = self.gsim("BindiEtAl2014Rjb", branch="central") # PGA self._compare_arrays( gsim_1.get_mean_and_stddevs(self.sctx, self.rctx, self.dctx, PGA(), [const.StdDev.TOTAL])[0], gsim_2.get_mean_and_stddevs(self.sctx, self.rctx, self.dctx, PGA(), [const.StdDev.TOTAL])[0], 1.2) # SA(0.2) self._compare_arrays( gsim_1.get_mean_and_stddevs(self.sctx, self.rctx, self.dctx, SA(0.2), [const.StdDev.TOTAL])[0], gsim_2.get_mean_and_stddevs(self.sctx, self.rctx, self.dctx, SA(0.2), [const.StdDev.TOTAL])[0], 1.3) # SA(1.0) self._compare_arrays( gsim_1.get_mean_and_stddevs(self.sctx, self.rctx, self.dctx, SA(1.0), [const.StdDev.TOTAL])[0], gsim_2.get_mean_and_stddevs(self.sctx, self.rctx, self.dctx, SA(1.0), [const.StdDev.TOTAL])[0], 1.4)
def get_mean_and_stddevs(self, sites, rup, dists, imt, stddev_types): """ See :meth:`superclass method <.base.GroundShakingIntensityModel.get_mean_and_stddevs>` for spec of input and result values. """ assert all(stddev_type in self.DEFINED_FOR_STANDARD_DEVIATION_TYPES for stddev_type in stddev_types) # Compute SA with primed coeffs and PGA with both unprimed and # primed coeffs C = self.COEFFS_PRIMED[imt] C_PGA = self.COEFFS_PRIMED[PGA()] C_PGA_unprimed = self.COEFFS_UNPRIMED[PGA()] # Get S term to determine if consider site term is applied S = self._get_site_class(sites.vs30) # Abrahamson and Silva (1997) hanging wall term. This is not used # in the latest version of GMPE but is defined in functional form in # the paper so we keep it here as a placeholder f4HW = self._compute_f4(C, rup.mag, dists.rrup) # Flags for rake angles CN, CR = self._get_fault_mechanism_flags(rup.rake) # Get volcanic path distance which Rvol=0 for current implementation # of McVerry2006Asc, but kept here as placeholder for future use rvol = self._get_volcanic_path_distance(dists.rrup) # Get delta_C and delta_D terms for site class delta_C, delta_D = self._get_deltas(sites.vs30) # Compute lnPGA_ABCD primed lnPGAp_ABCD = self._compute_mean(C_PGA, S, rup.mag, dists.rrup, rvol, rup.hypo_depth, CN, CR, f4HW, delta_C, delta_D) # Compute lnPGA_ABCD unprimed lnPGA_ABCD = self._compute_mean(C_PGA_unprimed, S, rup.mag, dists.rrup, rvol, rup.hypo_depth, CN, CR, f4HW, delta_C, delta_D) # Compute lnSA_ABCD lnSAp_ABCD = self._compute_mean(C, S, rup.mag, dists.rrup, rvol, rup.hypo_depth, CN, CR, f4HW, delta_C, delta_D) # Stage 3: Equation 6 SA_ABCD(T). This is lnSA_ABCD # need to calculate final lnSA_ABCD from non-log values but return log mean = np.log(np.exp(lnSAp_ABCD) * (np.exp(lnPGA_ABCD) / np.exp(lnPGAp_ABCD))) # Compute standard deviations C_STD = self.COEFFS_STD[imt] stddevs = self._get_stddevs( C_STD, rup.mag, stddev_types, sites.vs30.size ) return mean, stddevs
def test_mag_greater_8pt5(self): gmpe = SadighEtAl1997() sctx = SitesContext() rctx = RuptureContext() dctx = DistancesContext() rctx.rake = 0.0 dctx.rrup = numpy.array([0., 1.]) sctx.vs30 = numpy.array([800., 800.]) rctx.mag = 9.0 mean_rock_9, _ = gmpe.get_mean_and_stddevs(sctx, rctx, dctx, PGA(), [StdDev.TOTAL]) rctx.mag = 8.5 mean_rock_8pt5, _ = gmpe.get_mean_and_stddevs(sctx, rctx, dctx, PGA(), [StdDev.TOTAL]) numpy.testing.assert_allclose(mean_rock_9, mean_rock_8pt5) sctx.vs30 = numpy.array([300., 300.]) rctx.mag = 9.0 mean_soil_9, _ = gmpe.get_mean_and_stddevs(sctx, rctx, dctx, PGA(), [StdDev.TOTAL]) rctx.mag = 8.5 mean_soil_8pt5, _ = gmpe.get_mean_and_stddevs(sctx, rctx, dctx, PGA(), [StdDev.TOTAL]) numpy.testing.assert_allclose(mean_soil_9, mean_soil_8pt5)
def get_mean_and_stddevs(self, sites, rup, dists, imt, stddev_types): """ See :meth:`superclass method <.base.GroundShakingIntensityModel.get_mean_and_stddevs>` for spec of input and result values. """ assert all(stddev_type in self.DEFINED_FOR_STANDARD_DEVIATION_TYPES for stddev_type in stddev_types) F, HW = self._get_fault_type_hanging_wall(rup.rake) S = self._get_site_class(sites.vs30) # compute pga on rock (used then to compute site amplification factor) C = self.COEFFS[PGA()] pga_rock = np.exp( self._compute_mean_on_rock(C, rup.mag, dists.rrup, F, HW)) # compute mean for the given imt (do not repeat the calculation if # imt is PGA, just add the site amplification term) if imt == PGA(): mean = np.log(pga_rock) + S * self._compute_f5(C, pga_rock) else: C = self.COEFFS[imt] mean = (self._compute_mean_on_rock(C, rup.mag, dists.rrup, F, HW) + S * self._compute_f5(C, pga_rock)) C_STD = self.COEFFS_STD[imt] stddevs = self._get_stddevs(C_STD, rup.mag, stddev_types, sites.vs30.size) return mean, stddevs
def compute(self, ctx, imts, mean, sig, tau, phi): """ See :meth:`superclass method <.base.GroundShakingIntensityModel.compute>` for spec of input and result values. """ F, HW = _get_fault_type_hanging_wall(ctx.rake) S = _get_site_class(ctx.vs30) # compute pga on rock (used then to compute site amplification factor) C = self.COEFFS[PGA()] pga_rock = np.exp(_compute_mean_on_rock(C, ctx.mag, ctx.rrup, F, HW)) for m, imt in enumerate(imts): # compute mean for the given imt (do not repeat the calculation if # imt is PGA, just add the site amplification term) if imt == PGA(): mean[m] = np.log(pga_rock) + S * _compute_f5(C, pga_rock) else: C = self.COEFFS[imt] mean[m] = (_compute_mean_on_rock(C, ctx.mag, ctx.rrup, F, HW) + S * _compute_f5(C, pga_rock)) C_STD = self.COEFFS_STD[imt] # standard deviation as defined in eq.13 page 106. if ctx.mag <= 5: sig[m] += C_STD['b5'] elif 5.0 < ctx.mag < 7.0: sig[m] += C_STD['b5'] - C_STD['b6'] * (ctx.mag - 5) else: sig[m] += C_STD['b5'] - 2 * C_STD['b6']
def get_mean_and_stddevs(self, sites, rup, dists, imt, stddev_types): """ See :meth:`superclass method <.base.GroundShakingIntensityModel.get_mean_and_stddevs>` for spec of input and result values. """ # extract dictionaries of coefficients specific to required # intensity measure type and for PGA C = self.COEFFS[imt] C_PGA = self.COEFFS[PGA()] # compute median pga on rock (vs30=1100), needed for site response # term calculation pga1100 = np.exp(self._compute_imt1100(PGA(), sites, rup, dists)) mean = (self._compute_base_term(C, rup, dists) + self._compute_faulting_style_term(C, rup) + self._compute_site_response_term(C, imt, sites, pga1100) + self._compute_hanging_wall_term(C, dists, rup) + self._compute_top_of_rupture_depth_term(C, rup) + self._compute_large_distance_term(C, dists, rup) + self._compute_soil_depth_term(C, imt, sites.z1pt0, sites.vs30)) stddevs = self._get_stddevs(C, C_PGA, pga1100, rup, sites, stddev_types) return mean, stddevs
def compute(self, ctx, imts, mean, sig, tau, phi): """ See :meth:`superclass method <.base.GroundShakingIntensityModel.compute>` for spec of input and result values. """ C_PGA = self.COEFFS[PGA()] dc1_pga = self.delta_c1 or self.COEFFS_MAG_SCALE[PGA()]["dc1"] # compute median pga on rock (vs30=1000), needed for site response # term calculation pga1000 = np.exp( _compute_pga_rock(self.kind, self.trt, self.theta6_adj, self.faba_model, C_PGA, dc1_pga, ctx)) for m, imt in enumerate(imts): C = self.COEFFS[imt] dc1 = self.delta_c1 or self.COEFFS_MAG_SCALE[imt]["dc1"] mean[m] = (_compute_magnitude_term(self.kind, C, dc1, ctx.mag) + _compute_distance_term(self.kind, self.trt, self.theta6_adj, C, ctx) + _compute_focal_depth_term(self.trt, C, ctx) + _compute_forearc_backarc_term(self.trt, self.faba_model, C, ctx) + _compute_site_response_term(C, ctx, pga1000)) if self.sigma_mu_epsilon: sigma_mu = get_stress_factor( imt, self.DEFINED_FOR_TECTONIC_REGION_TYPE == const.TRT.SUBDUCTION_INTRASLAB) mean[m] += sigma_mu * self.sigma_mu_epsilon sig[m] = C["sigma"] if self.ergodic else C["sigma_ss"] tau[m] = C['tau'] phi[m] = C["phi"] if self.ergodic else np.sqrt(C["sigma_ss"]**2. - C["tau"]**2.)
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. """ # cap magnitude values at 8.5, see page 1709 mag = np.clip(ctx.mag, 0, 8.5) if self.kind == 'SInter2008': ctx = copy.copy(ctx) ctx.hypo_depth = 20. # compute PGA on rock (needed for site amplification calculation) G = 10**(1.2 - 0.18 * mag) pga_rock = _compute_mean( self.kind, self.COEFFS_SINTER[PGA()], G, mag, ctx.hypo_depth, ctx.rrup, ctx.vs30, # by passing pga_rock > 500 the soil # amplification is 0 np.zeros_like(ctx.vs30) + 600, PGA()) pga_rock = 10**pga_rock for m, imt in enumerate(imts): C = self.COEFFS_SINTER[imt] # periods 0.4 s (2.5 Hz) and 0.2 s (5 Hz) need a special case # because of the erratum. SA for 0.4s and 0.2s is computed and a # weighted sum is returned if imt.period in (0.2, 0.4): C04 = self.COEFFS_SINTER[SA(period=0.4, damping=5.0)] C02 = self.COEFFS_SINTER[SA(period=0.2, damping=5.0)] mean04 = _compute_mean(self.kind, C04, G, mag, ctx.hypo_depth, ctx.rrup, ctx.vs30, pga_rock, imt) mean02 = _compute_mean(self.kind, C02, G, mag, ctx.hypo_depth, ctx.rrup, ctx.vs30, pga_rock, imt) if imt.period == 0.2: mean[m] = 0.333 * mean02 + 0.667 * mean04 else: mean[m] = 0.333 * mean04 + 0.667 * mean02 else: mean[m] = _compute_mean(self.kind, C, G, mag, ctx.hypo_depth, ctx.rrup, ctx.vs30, pga_rock, imt) # convert from log10 to ln and units from cm/s**2 to g mean[m] = np.log((10**mean[m]) * 1e-2 / g) if imt.period == 4.0: mean[m] /= 0.550 sig[m] = np.log(10**C['sigma']) if 's2' in C.dtype.names: # in the Gupta subclass tau[m] = np.log(10**C['s2']) phi[m] = np.log(10**C['s1'])
def get_mean_and_stddevs(self, sites, rup, dists, imt, stddev_types): """ See :meth:`superclass method <.base.GroundShakingIntensityModel.get_mean_and_stddevs>` for spec of input and result values. """ # extracting dictionary of coefficients specific to required # intensity measure type. C = self.COEFFS_SINTER[imt] # cap magnitude values at 8.5, see page 1709 mag = rup.mag if mag > 8.5: mag = 8.5 # compute PGA on rock (needed for site amplification calculation) G = 10**(1.2 - 0.18 * mag) pga_rock = self._compute_mean( self.COEFFS_SINTER[PGA()], G, mag, rup.hypo_depth, dists.rrup, sites.vs30, # by passing pga_rock > 500 the soil # amplification is 0 np.zeros_like(sites.vs30) + 600, PGA()) pga_rock = 10**(pga_rock) # periods 0.4 s (2.5 Hz) and 0.2 s (5 Hz) need a special case because # of the erratum. SA for 0.4s and 0.2s is computed and a weighted sum # is returned if imt.period in (0.2, 0.4): C04 = self.COEFFS_SINTER[SA(period=0.4, damping=5.0)] C02 = self.COEFFS_SINTER[SA(period=0.2, damping=5.0)] mean04 = self._compute_mean(C04, G, mag, rup.hypo_depth, dists.rrup, sites.vs30, pga_rock, imt) mean02 = self._compute_mean(C02, G, mag, rup.hypo_depth, dists.rrup, sites.vs30, pga_rock, imt) if imt.period == 0.2: mean = 0.333 * mean02 + 0.667 * mean04 else: mean = 0.333 * mean04 + 0.667 * mean02 else: mean = self._compute_mean(C, G, mag, rup.hypo_depth, dists.rrup, sites.vs30, pga_rock, imt) # convert from log10 to ln and units from cm/s**2 to g mean = np.log((10**mean) * 1e-2 / g) if imt.period == 4.0: mean /= 0.550 stddevs = self._get_stddevs(C, stddev_types, sites.vs30.shape[0]) return mean, stddevs
def test_scaling_factors(self): gsim_1 = self.gsim("BindiEtAl2014Rjb", branch="central", scaling_factor=1.2) gsim_2 = self.gsim("BindiEtAl2014Rjb", branch="central") mean_1 = gsim_1.get_mean_and_stddevs(self.sctx, self.rctx, self.dctx, PGA(), [const.StdDev.TOTAL])[0] mean_2 = gsim_2.get_mean_and_stddevs(self.sctx, self.rctx, self.dctx, PGA(), [const.StdDev.TOTAL])[0] self._compare_arrays(mean_1, mean_2, 1.2)
def test_sigma_mu_scaling(self): gsim_1 = self.gsim("BindiEtAl2014Rjb", branch="central", sigma_mu_epsilon=1.0) gsim_2 = self.gsim("BindiEtAl2014Rjb", branch="central") mean_1 = gsim_1.get_mean_and_stddevs(self.sctx, self.rctx, self.dctx, PGA(), [const.StdDev.TOTAL])[0] mean_2 = gsim_2.get_mean_and_stddevs(self.sctx, self.rctx, self.dctx, PGA(), [const.StdDev.TOTAL])[0] self._compare_arrays(mean_1, mean_2, np.exp(0.083))
def compute(self, ctx, imts, mean, sig, tau, phi): """ See :meth:`superclass method <.base.GroundShakingIntensityModel.compute>` for spec of input and result values. """ # Compute SA with primed coeffs and PGA with both unprimed and # primed coeffs C_PGA = self.COEFFS_PRIMED[PGA()] C_PGA_unprimed = self.COEFFS_UNPRIMED[PGA()] for m, imt in enumerate(imts): C = self.COEFFS_PRIMED[imt] # Get S term to determine if consider site term is applied S = _get_site_class(self.kind, ctx) # Abrahamson and Silva (1997) hanging wall term. This is not used # in the latest version of GMPE but is defined in functional form # in the paper so we keep it here as a placeholder f4HW = _compute_f4(C, ctx.mag, ctx.rrup) # Flags for rake angles CN, CR = _get_fault_mechanism_flags(ctx.rake) # Get volcanic path distance rvol = ctx.rrup if self.kind.startswith("vol") else 0. # Get delta_C and delta_D terms for site class delta_C, delta_D = _get_deltas(self.kind, ctx) # Compute lnPGA_ABCD primed lnPGAp_ABCD = _compute_mean(self.kind, C_PGA, S, ctx.mag, ctx.rrup, rvol, ctx.hypo_depth, CN, CR, f4HW, delta_C, delta_D) # Compute lnPGA_ABCD unprimed lnPGA_ABCD = _compute_mean(self.kind, C_PGA_unprimed, S, ctx.mag, ctx.rrup, rvol, ctx.hypo_depth, CN, CR, f4HW, delta_C, delta_D) # Compute lnSA_ABCD lnSAp_ABCD = _compute_mean(self.kind, C, S, ctx.mag, ctx.rrup, rvol, ctx.hypo_depth, CN, CR, f4HW, delta_C, delta_D) # Stage 3: Equation 6 SA_ABCD(T). This is lnSA_ABCD # need to calculate final lnSA_ABCD from non-log values but # return log mean[m] = np.log( np.exp(lnSAp_ABCD) * (np.exp(lnPGA_ABCD) / np.exp(lnPGAp_ABCD))) # Compute standard deviations C_STD = self.COEFFS_STD[imt] sig[m], tau[m], phi[m] = _get_stddevs(self.kind, C_STD, ctx)
def compute(self, ctx, imts, mean, sig, tau, phi): """ See :meth:`superclass method <.base.GroundShakingIntensityModel.compute>` for spec of input and result values. """ # horrible hack to fix the distance parameters; needed for the can15 # subclasses; extra distances are add in can15.eastern # this also affects generic_gmpe_avgsa_test.py vars(ctx).update(contexts.get_dists(ctx)) # compute PGA on rock conditions - needed to compute non-linear # site amplification term pga4nl = _get_pga_on_rock(self.COEFFS[PGA()], ctx) for m, imt in enumerate(imts): C = self.COEFFS[imt] C_SR = self.COEFFS_SOIL_RESPONSE[imt] # equation 1, pag 106, without sigma term, that is only the first 3 # terms. The third term (site amplification) is computed as given # in equation (6), that is the sum of a linear term - equation (7) # - and a non-linear one - equations (8a) to (8c). # Mref, Rref values are given in the caption to table 6, pag 119. if imt == PGA(): # avoid recomputing PGA on rock, just add site terms mean[m] = np.log(pga4nl) + \ _get_site_amplification_linear(ctx.vs30, C_SR) + \ _get_site_amplification_non_linear(ctx.vs30, pga4nl, C_SR) else: mean[m] = _compute_magnitude_scaling(ctx, C) + \ _compute_distance_scaling(ctx, C) + \ _get_site_amplification_linear(ctx.vs30, C_SR) + \ _get_site_amplification_non_linear(ctx.vs30, pga4nl, C_SR) if self.kind in ('2011', 'prime'): # correction factor (see Atkinson and Boore, 2011; equation 5 # at page 1126 and nga08_gm_tmr.for line 508 corr_fact = 10.0**(np.max([0, 3.888 - 0.674 * ctx.mag]) - (np.max([0, 2.933 - 0.510 * ctx.mag]) * np.log10(ctx.rjb + 10.))) mean[m] = np.log(np.exp(mean[m]) * corr_fact) if self.kind == 'hawaii': hawaii_adjust(mean[m], ctx, imt) elif self.kind == 'prime': # Implements the Boore & Atkinson (2011) adjustment to the # Atkinson (2008) GMPE A08 = self.COEFFS_A08[imt] f_ena = 10.0 ** (A08["c"] + A08["d"] * ctx.rjb) mean[m] = np.log(np.exp(mean[m]) * f_ena) set_sig(self.kind, C, sig[m], tau[m], phi[m])
def test_homoskedastic_tau_branches(self): mags = self.expected_hetero_pga[:, 0] central = [] lower = [] upper = [] for mag in mags: central.append(HOMOSKEDASTIC_TAU["central"](PGA())) lower.append(HOMOSKEDASTIC_TAU["lower"](PGA())) upper.append(HOMOSKEDASTIC_TAU["upper"](PGA())) np.testing.assert_array_almost_equal(np.array(lower), np.array(central) - 0.075) np.testing.assert_array_almost_equal(np.array(upper), np.array(central) + 0.075)
def test_homoskedastic_phi_branches(self): mags = self.expected_hetero_pga[:, 0] central = [] lower = [] upper = [] for mag in mags: central.append(HOMOSKEDASTIC_PHI["central"](PGA())) lower.append(HOMOSKEDASTIC_PHI["lower"](PGA())) upper.append(HOMOSKEDASTIC_PHI["upper"](PGA())) np.testing.assert_array_almost_equal( np.array(lower) / np.array(central), 0.84 * np.ones(len(mags))) np.testing.assert_array_almost_equal( np.array(upper) / np.array(central), 1.16 * np.ones(len(mags)))
def setUp(self): fname = gettemp(ampl_func) df = read_csv(fname, { 'ampcode': ampcode_dt, None: numpy.float64 }, index='ampcode') self.df = AmplFunction(df) # Set GMMs gmmA = BooreAtkinson2008() # Set parameters dsts = [10., 15., 20., 30., 40.] dsts = [10.] imts = [PGA(), SA(1.0)] sites = Dummy.get_site_collection(len(dsts), vs30=760.0) self.mag = 5.5 rup = Dummy.get_rupture(mag=self.mag) ctx = full_context(sites, rup) ctx.rjb = numpy.array(dsts) ctx.rrup = numpy.array(dsts) self.rrup = ctx.rrup # Compute GM on rock self.cmaker = ContextMaker('TRT', [gmmA], dict(imtls={str(im): [0] for im in imts})) [self.meastd] = self.cmaker.get_mean_stds([ctx], const.StdDev.TOTAL)
def get_mean_and_stddevs(self, sites, rup, dists, imt, stddev_types): """ See :meth:`superclass method <.base.GroundShakingIntensityModel.get_mean_and_stddevs>` for spec of input and result values. """ # extracting dictionary of coefficients specific to required # intensity measure type. C = self.COEFFS[imt] C_SR = self.COEFFS_SOIL_RESPONSE[imt] # compute PGA on rock conditions - needed to compute non-linear # site amplification term pga4nl = self._get_pga_on_rock(rup, dists, C) # equation 1, pag 106, without sigma term, that is only the first 3 # terms. The third term (site amplification) is computed as given in # equation (6), that is the sum of a linear term - equation (7) - and # a non-linear one - equations (8a) to (8c). # Mref, Rref values are given in the caption to table 6, pag 119. if imt == PGA(): # avoid recomputing PGA on rock, just add site terms mean = np.log(pga4nl) + \ self._get_site_amplification_linear(sites.vs30, C_SR) + \ self._get_site_amplification_non_linear(sites.vs30, pga4nl, C_SR) else: mean = self._compute_magnitude_scaling(rup, C) + \ self._compute_distance_scaling(rup, dists, C) + \ self._get_site_amplification_linear(sites.vs30, C_SR) + \ self._get_site_amplification_non_linear(sites.vs30, pga4nl, C_SR) stddevs = self._get_stddevs(C, stddev_types, num_sites=len(sites.vs30)) return mean, stddevs
def get_mean_and_stddevs(self, sites, rup, dists, imt, stddev_types): """ Using a frequency dependent correction for the mean ground motion. Standard deviation is fixed. """ mean, stddevs = super().get_mean_and_stddevs(sites, rup, dists, imt, stddev_types) # Defining frequency if imt == PGA(): freq = 50.0 elif imt == PGV(): freq = 2.0 else: freq = 1./imt.period # Equation 3 of Atkinson (2010) x1 = np.min([-0.18+0.17*np.log10(freq), 0]) # Equation 4 a-b-c of Atkinson (2010) if rup.hypo_depth < 20.0: x0 = np.max([0.217-0.321*np.log10(freq), 0]) elif rup.hypo_depth > 35.0: x0 = np.min([0.263+0.0924*np.log10(freq), 0.35]) else: x0 = 0.2 # Limiting calculation distance to 1km # (as suggested by C. Bruce Worden) rjb = [d if d > 1 else 1 for d in dists.rjb] # Equation 2 and 5 of Atkinson (2010) mean += (x0 + x1*np.log10(rjb))/np.log10(np.e) return mean, stddevs
def test_compute_gmf(self): hc = mock.Mock() hc.ground_motion_correlation_model = None hc.truncation_level = None hc.maximum_distance = 200. gsim = get_available_gsims()['AkkarBommer2010']() site_coll = make_site_coll(-78, 15.5, n=5) params = dict(truncation_level=3, correl_model=None, maximum_distance=200) trt = 'Subduction Interface' rupture_ids = range(2) ruptures = [FakeRupture(i, trt) for i in rupture_ids] rupture_seeds = rupture_ids gmv_dict, rup_dict = core._compute_gmf( params, PGA(), {trt: gsim}, site_coll, ruptures, rupture_seeds) expected_rups = { 0: rupture_ids, 1: rupture_ids, 2: rupture_ids, 3: rupture_ids, 4: rupture_ids, } expected_gmvs = { 0: [0.122149047040728, 0.0813899249039753], 1: [0.0541662667863476, 0.02136369236082], 2: [0.0772246502768338, 0.0226182956091826], 3: [0.166062666449449, 0.0164127269047494], 4: [0.133588538354143, 0.0529987707352876] } numpy.testing.assert_equal(rup_dict, expected_rups) for i, gmvs in expected_gmvs.iteritems(): numpy.testing.assert_allclose(gmvs, expected_gmvs[i])
def get_mean_and_stddevs(self, sctx, rctx, dctx, imt, stddev_types): """ Returns the mean and standard deviations calling the input GMPE for the mean acceleration for PGA and Sa (1.0) on the reference rock, defining the amplification factors and code spectrum to return the mean ground motion at the desired period, before the calling the input GMPE once more in order to return the standard deviations for the required IMT. """ sctx_r = deepcopy(sctx) sctx_r.vs30 = self.rock_vs30 * np.ones_like(sctx_r.vs30) # Get PGA and Sa (1.0) from GMPE pga_r = self.gmpe.get_mean_and_stddevs(sctx_r, rctx, dctx, PGA(), stddev_types)[0] s_1_rp = self.gmpe.get_mean_and_stddevs(sctx_r, rctx, dctx, SA(1.0), stddev_types)[0] s_s_rp = self.CONSTANTS["F0"] * np.exp(pga_r) s_1_rp = np.exp(s_1_rp) # Get the short and long period amplification factors f_s, f_l = self.get_amplification_factor(s_s_rp, s_1_rp, sctx) s_1 = f_l * s_1_rp s_s = f_s * s_s_rp # Get the mean ground motion at the IMT using the design code spectrum mean = self.get_amplified_mean(s_s, s_1, s_1_rp, imt) # Call the original GMPE to return the standard deviation for the # IMT in question stddevs = self.gmpe.get_mean_and_stddevs(sctx, rctx, dctx, imt, stddev_types)[1] return mean, stddevs
def compute(self, ctx, imts, mean, sig, tau, phi): """ See :meth:`superclass method <.base.GroundShakingIntensityModel.compute>` for spec of input and result values. """ # extract dictionaries of coefficients specific to IM type trt = self.DEFINED_FOR_TECTONIC_REGION_TYPE C_PGA = self.COEFFS[PGA()] s = self.CONSTANTS for m, imt in enumerate(imts): C = self.COEFFS[imt] f_mag = _fmag(self.region, C, ctx.mag) f_ztor = _fztor(trt, C, ctx.ztor) # path term f_p = _fp(trt, self.region, s, C, ctx.mag, ctx.rrup) # PGA at rock with Vs30 = 1000 m/s pga_1000 = pga_rock(trt, self.region, self.CONSTANTS, C_PGA, ctx.mag, ctx.rrup, ctx.ztor, 1000) # site effect vs30 = np.minimum(ctx.vs30, 1000) # non-linear component f_site = _fsite(s, self.region, C, vs30, pga_1000) # basin depth term f_z1pt0 = _fz1pt0(self.region, C, vs30, ctx.z1pt0) # median total and stddev mean[m] = f_mag + f_p + f_ztor + f_site + f_z1pt0 sig[m], tau[m], phi[m] = _get_stddevs(self.region, C)
def test_gm_calculation_hard_rock(self): """ Test mean and std calculation - on hard rock using AB06""" # Modified gmpe mgmpe = NRCan15SiteTermLinear(gmpe_name='AtkinsonBoore2006') # Set parameters sites = Dummy.get_site_collection(2, vs30=[760, 2010]) rup = Dummy.get_rupture(mag=7.0) dists = DistancesContext() dists.rrup = np.array([15., 15.]) stdt = [const.StdDev.TOTAL] gmpe = AtkinsonBoore2006() for imt in [PGA(), SA(1.0), SA(5.0)]: # # Computes results mean, stds = mgmpe.get_mean_and_stddevs(sites, rup, dists, imt, stdt) # Compute the expected results mean_expected, stds_expected = gmpe.get_mean_and_stddevs( sites, rup, dists, imt, stdt) # Test that for reference soil conditions the modified GMPE gives # the same results of the original gmpe np.testing.assert_allclose(np.exp(mean), np.exp(mean_expected), rtol=1.0e-1) np.testing.assert_allclose(stds, stds_expected)
def get_mean_and_stddevs(self, sctx, rctx, dctx, imt, stddev_types): """ Returns the mean and standard deviations """ # Get the PGA on the reference rock condition if PGA in self.DEFINED_FOR_INTENSITY_MEASURE_TYPES: rock_imt = PGA() else: rock_imt = SA(0.01) pga_r = self.get_hard_rock_mean(rctx, dctx, rock_imt, stddev_types) # Get the desired spectral acceleration on rock if not str(imt) == "PGA": # Calculate the ground motion at required spectral period for # the reference rock mean = self.get_hard_rock_mean(rctx, dctx, imt, stddev_types) else: # Avoid re-calculating PGA if that was already done! mean = np.copy(pga_r) mean += self.get_site_amplification(imt, np.exp(pga_r), sctx) # Get standard deviation model nsites = getattr(dctx, self.distance_type).shape stddevs = self.get_stddevs(rctx.mag, imt, stddev_types, nsites) return mean, stddevs
def get_mean_and_stddevs(self, sites, rup, dists, imt, stddev_types): """ See :meth:`superclass method <.base.GroundShakingIntensityModel.get_mean_and_stddevs>` for spec of input and result values. """ # extract dictionaries of coefficients specific to required # intensity measure type and for PGA C = self.COEFFS[imt] C_PGA = self.COEFFS[PGA()] # Get mean and standard deviation of PGA on rock (Vs30 1100 m/s^2) pga1100 = np.exp(self.get_mean_values(C_PGA, sites, rup, dists, None)) # Get mean and standard deviations for IMT mean = self.get_mean_values(C, sites, rup, dists, pga1100) if imt.name == "SA" and imt.period <= 0.25: # According to Campbell & Bozorgnia (2013) [NGA West 2 Report] # If Sa (T) < PGA for T < 0.25 then set mean Sa(T) to mean PGA # Get PGA on soil pga = self.get_mean_values(C_PGA, sites, rup, dists, pga1100) idx = mean <= pga mean[idx] = pga[idx] # Get standard deviations stddevs = self._get_stddevs(C, C_PGA, rup, sites, pga1100, stddev_types) return mean, stddevs
def test_table_string_instantiation(self): # Check that the table instantiates in the conventional way table1 = CoeffsTable(sa_damping=5, table=self.coefficient_string) self.assertDictEqual(table1.non_sa_coeffs, { PGV(): { "a": 0.1, "b": 0.2 }, PGA(): { "a": 0.05, "b": 0.1 } }) self.assertDictEqual( table1.sa_coeffs, { SA(period=0.1, damping=5): { "a": 1.0, "b": 2.0 }, SA(period=1.0, damping=5): { "a": 5.0, "b": 10.0 }, SA(period=10.0, damping=5): { "a": 10.0, "b": 20.0 } })
def test(self): numpy.random.seed(13) cormo = JB2009CorrelationModel(vs30_clustering=False) intra_residuals_sampled = numpy.random.normal(size=(3, 100000)) intra_residuals_correlated = cormo.apply_correlation( self.SITECOL, PGA(), intra_residuals_sampled) inferred_corrcoef = numpy.corrcoef(intra_residuals_correlated) mean = intra_residuals_correlated.mean() std = intra_residuals_correlated.std() self.assertAlmostEqual(mean, 0, delta=0.002) self.assertAlmostEqual(std, 1, delta=0.002) actual_corrcoef = cormo._get_correlation_matrix(self.SITECOL, PGA()) numpy.testing.assert_almost_equal(inferred_corrcoef, actual_corrcoef, decimal=2)
def get_mean_and_stddevs(self, sites, rup, dists, imt, stddev_types): """ See :meth:`superclass method <.base.GroundShakingIntensityModel.get_mean_and_stddevs>` for spec of input and result values. """ # extract dictionaries of coefficients specific to required # intensity measure type and for PGA C = self.COEFFS[imt] C_PGA = self.COEFFS[PGA()] # compute median pga on rock (vs30=1000), needed for site response # term calculation pga1000 = np.exp( self._compute_pga_rock(C_PGA, rup, dists) + C_PGA[self.CASCADIA_ADJUSTMENT]) # Get full model mean = (self.compute_base_term(C) + self.compute_magnitude_term(C, rup.mag) + self.compute_depth_term(C, rup) + self.compute_distance_term(C, dists.rrup, rup.mag) + self.compute_site_term(C, sites.vs30, pga1000)) stddevs = self.get_stddevs(C, C_PGA, pga1000, sites.vs30, stddev_types) if self.EPISTEMIC_ADJUSTMENT: adjustment = C[self.CASCADIA_ADJUSTMENT] +\ C[self.EPISTEMIC_ADJUSTMENT] return mean + adjustment, stddevs else: return mean + C[self.CASCADIA_ADJUSTMENT], stddevs
def get_mean_and_stddevs(self, sites, rup, dists, imt, stddev_types): """ See :meth:`superclass method <.base.GroundShakingIntensityModel.get_mean_and_stddevs>` for spec of input and result values. """ # extract dictionaries of coefficients specific to required # intensity measure type and for PGA C = self.COEFFS[imt] C_PGA = self.COEFFS[PGA()] m_b = self._get_mb() c0, c0_pga = self._c0(C, C_PGA) fm, fm_pga = self._magnitude_scaling(C, C_PGA, rup.mag, m_b) fp, fp_pga = self._path_term(C, C_PGA, rup.mag, dists.rrup, m_b) fd = self._depth_scaling(C, rup) fd_pga = self._depth_scaling(C_PGA, rup) fb = self._basin_term(C, sites) flin = self._linear_amplification(C, sites.vs30) fnl = self._non_linear_term(C, imt, sites.vs30, fp_pga, fm_pga, c0_pga, fd_pga) # The output is the desired median model prediction in LN units # Take the exponential to get PGA, PSA in g or the PGV in cm/s mean = fp + fnl + fb + flin + fm + c0 + fd stddevs = self.get_stddevs(C, dists.rrup, sites.vs30, stddev_types) return mean, stddevs
def get_mean_and_stddevs(self, sctx, rctx, dctx, imt, stddev_types): """ As with the :class:`PitilakisEtal2018`, the mean ground motion is determined by construction of the Eurocode 8 design spectrum from the short- and long-period acceleration coefficients amplified to the desired site class, with the standard deviations taken from the original GMPE at the desired IMT """ sctx_r = deepcopy(sctx) sctx_r.vs30 = self.rock_vs30 * np.ones_like(sctx_r.vs30) # Get PGA and Sa (1.0) from GMPE pga_r = self.gmpe.get_mean_and_stddevs(sctx_r, rctx, dctx, PGA(), stddev_types)[0] s_1_rp = self.gmpe.get_mean_and_stddevs(sctx_r, rctx, dctx, SA(1.0), stddev_types)[0] s_s_rp = self.CONSTANTS["F0"] * np.exp(pga_r) s_1_rp = np.exp(s_1_rp) ec8 = self.get_ec8_class(sctx.vs30, sctx.h800) f_s, f_l = self.get_amplification_factor(s_s_rp, s_1_rp, ec8, sctx) s_1 = f_l * s_1_rp s_s = f_s * s_s_rp mean = self.get_amplified_mean(s_s, s_1, s_1_rp, imt) stddevs = self.gmpe.get_mean_and_stddevs(sctx, rctx, dctx, imt, stddev_types)[1] return mean, stddevs
def get_mean_and_stddevs(self, sctx, rctx, dctx, imt, stddev_types): """ Returns the mean and standard deviations """ C = self.COEFFS[imt] C_ROCK = self.COEFFS[PGA()] pga_r = self.get_hard_rock_mean(C_ROCK, rctx, dctx) # Get the desired spectral acceleration on rock if not str(imt) == "PGA": # Calculate the ground motion at required spectral period for # the reference rock mean = self.get_hard_rock_mean(C, rctx, dctx) else: # Avoid re-calculating PGA if that was already done! mean = np.copy(pga_r) mean += self.get_site_amplification(imt, np.exp(pga_r), sctx) # Get standard deviation model nsites = dctx.rrup.shape stddevs = self.get_stddevs(rctx.mag, imt, sctx, stddev_types, nsites) if self.epsilon: # If requested, apply epistemic uncertainty mean += (self.epsilon * C["sigma_mu"]) return mean, stddevs