def __init__(self, sp, pga=0.25, m_w=None, **kwargs): self.sp = sp assert isinstance(self.sp, sm.SoilProfile) self.inc = 0.01 self.sp.gen_split(target=self.inc, props=['csr_n15']) split_depths = np.cumsum(self.sp.split['thickness']) self.depth = np.arange(0, sp.height + self.inc, self.inc) self.npts = len(self.depth) self.s_g = kwargs.get("s_g", 2.65) self.s_g_water = kwargs.get("s_g_water", 1.0) saturation = kwargs.get("saturation", None) if m_w is None: self.m_w = 7.5 else: self.m_w = m_w self.gwl = sp.gwl self.pga = pga if saturation is None: self.saturation = np.where(self.depth < self.gwl, 0, 1) else: self.saturation = saturation self.sigma_v = sp.get_v_total_stress_at_depth(self.depth) / 1e3 self.pore_pressure = sp.get_hydrostatic_pressure_at_depth( self.depth) / 1e3 self.sigma_veff = self.sigma_v - self.pore_pressure if self.sigma_veff[0] == 0.0: self.sigma_veff[0] = 1.0e-10 self.rd = calc_rd(self.depth, self.m_w) crr_unlimited = np.interp(self.depth, split_depths, self.sp.split['csr_n15']) self.crr_m7p5 = np.where(self.depth <= self.gwl, 4, crr_unlimited) self.q_c1n_cs = calc_q_c1n_cs_from_crr_m7p5(self.crr_m7p5) self.k_sigma = calc_k_sigma(self.sigma_veff, self.q_c1n_cs) self.msf = calc_msf(self.m_w, self.q_c1n_cs) self.crr = crr_m(self.k_sigma, self.msf, self.crr_m7p5) # CRR at set magnitude self.csr = calc_csr(self.sigma_veff, self.sigma_v, pga, self.rd, self.gwl, self.depth) fs_unlimited = self.crr / self.csr self.factor_of_safety = np.where(fs_unlimited > 2, 2, fs_unlimited)
def compute_new_lsn_from_equivalent_profile(eq_profiler, new_pga, new_m_w, n=3): """ Computes the Liquefaction severity number (LSN) for an equivalent soil profile :param eq_profile: EquivalentSoilProfile object :param new_pga: float, peak ground acceleration to consider LSN at :param new_m_w: float, earthquake magnitude to consider LSN at :return: float, LSN """ depth = eq_profiler.depth gwl = eq_profiler.bi2014.gwl if n == 3: eq_qc1ncs = eq_profiler.e3_q_c1n_cs crr_7p5 = eq_profiler.e3_crr_7p5 elif n == 5: eq_qc1ncs = eq_profiler.e5_q_c1n_cs crr_7p5 = eq_profiler.e5_crr_7p5 else: raise ValueError # compute msf sigma_v = eq_profiler.bi2014.sigma_v sigma_v_eff = eq_profiler.bi2014.sigma_veff k_sigma = bi_functions.calc_k_sigma(sigma_v_eff, eq_qc1ncs) msf = bi_functions.calc_msf(new_m_w, eq_qc1ncs) rd = bi_functions.calc_rd(depth, new_m_w) # compute CSR csr = bi_functions.calc_csr(sigma_v_eff, sigma_v, new_pga, rd, gwl, depth) # using the CRR and q_c1n_cs values compute the new FoS eq_factor_of_safety = crr_7p5 / csr * k_sigma * msf # using the new FoS and q_c1n_cs values compute the volumetric strain eq_epsilon = lq.trigger.calculate_volumetric_strain( eq_factor_of_safety, eq_qc1ncs) lsn = lq.trigger.calculate_lsn(eq_epsilon, depth) # using the volumetric strain and new FoS compute new lsn return lsn
def test_calculate_k_sigma(): sigma_eff = 42.6 * np.ones(1) qc1ncs = 9.73 * np.ones(1) k_sigma = bim14.calc_k_sigma(sigma_eff, qc1ncs) expected_k_sigma = 1.038 assert np.isclose(expected_k_sigma, k_sigma[0], rtol=0.001) sigma_eff = 42.6 * np.ones(1) qc1ncs = 84. * np.ones(1) k_sigma = bim14.calc_k_sigma(sigma_eff, qc1ncs) expected_k_sigma = 1.080 assert np.isclose(expected_k_sigma, k_sigma[0], rtol=0.001) sigma_eff = 142.6 * np.ones(1) qc1ncs = 84. * np.ones(1) k_sigma = bim14.calc_k_sigma(sigma_eff, qc1ncs) expected_k_sigma = 0.9667 assert np.isclose(expected_k_sigma, k_sigma[0], rtol=0.001) sigma_eff = 142.6 * np.ones(1) qc1ncs = 130 * np.ones(1) k_sigma = bim14.calc_k_sigma(sigma_eff, qc1ncs) expected_k_sigma = 0.9521 assert np.isclose(expected_k_sigma, k_sigma[0], rtol=0.001) sigma_eff = 142.6 * np.ones(1) qc1ncs = 212 * np.ones(1) # Should hit maximum limit k_sigma = bim14.calc_k_sigma(sigma_eff, qc1ncs) expected_k_sigma = 0.8934 assert np.isclose(expected_k_sigma, k_sigma[0], rtol=0.001) sigma_eff = 142.6 * np.ones(1) qc1ncs = 220 * np.ones(1) # Should hit maximum limit k_sigma = bim14.calc_k_sigma(sigma_eff, qc1ncs) expected_k_sigma = 0.8934 assert np.isclose(expected_k_sigma, k_sigma[0], rtol=0.001)