def test_get_plane_equation(self): point1 = Point(1, 0, 0) point2 = Point(1, 1, 2) point3 = Point(2, 1, 3) hypo = Point(0, 0, 0) nrm, dst = get_plane_equation(point1, point2, point3, hypo) # The value used for this test is computed using this website # http://keisan.casio.com/exec/system/1223596129 (first, # coverted to xyz coordinate) self.assertAlmostEqual(dst, -12361.172665611, delta=1) self.assertAlmostEqual(nrm[0], -111.16669652676, delta=0.1) self.assertAlmostEqual(nrm[1], -222.37855646024, delta=0.1) self.assertAlmostEqual(nrm[2], -12363.683697019, delta=0.1)
def hypocentre_patch_index(cls, hypocentre, rupture_top_edge, upper_seismogenic_depth, lower_seismogenic_depth, dip): """ This methods finds the index of the fault patch including the hypocentre. :param hypocentre: :class:`~openquake.hazardlib.geo.point.Point` object representing the location of hypocentre. :param rupture_top_edge: A instances of :class:`openquake.hazardlib.geo.line.Line` representing the rupture surface's top edge. :param upper_seismo_depth: Minimum depth ruptures can reach, in km (i.e. depth to fault's top edge). :param lower_seismo_depth: Maximum depth ruptures can reach, in km (i.e. depth to fault's bottom edge). :param dip: Dip angle (i.e. angle between fault surface and earth surface), in degrees. :return: An integer corresponding to the index of the fault patch which contains the hypocentre. """ totaln_patch = len(rupture_top_edge) indexlist = [] dist_list = [] for i, index in enumerate(range(1, totaln_patch)): p0, p1, p2, p3 = cls.get_fault_patch_vertices( rupture_top_edge, upper_seismogenic_depth, lower_seismogenic_depth, dip, index_patch=index) [normal, dist_to_plane] = get_plane_equation(p0, p1, p2, hypocentre) indexlist.append(index) dist_list.append(dist_to_plane) if numpy.allclose(dist_to_plane, 0., atol=25., rtol=0.): return index break index = indexlist[numpy.argmin(dist_list)] return index
def setUp(self): upper_seismogenic_depth = 0. lower_seismogenic_depth = 15. self.hypocentre = Point(10., 45.334898, 10.) dip = 90. self.delta_slip = 0. index_patch = 1 self.origin = Point(10., 45.2, 0.) fault_trace_start = Point(10., 45.2) fault_trace_end = Point(10., 45.919457) fault_trace = Line([fault_trace_start, fault_trace_end]) # E Plane Calculation self.p0, self.p1, self.p2, self.p3 = SimpleFaultSurface.get_fault_patch_vertices( fault_trace, upper_seismogenic_depth, lower_seismogenic_depth, dip=dip, index_patch=index_patch) [self.normal, self.dist_to_plane] = get_plane_equation( self.p0, self.p1, self.p2, self.origin)
def hypocentre_patch_index(cls, hypocentre, fault_trace, upper_seismogenic_depth, lower_seismogenic_depth, dip): """ This methods finds the index of the fault patch including the hypocentre. :param hypocentre: :class:`~openquake.hazardlib.geo.point.Point` object representing the location of hypocentre. :param openquake.hazardlib.geo.line.Line fault_trace: Geographical line representing the intersection between the fault surface and the earth surface. :param upper_seismo_depth: Minimum depth ruptures can reach, in km (i.e. depth to fault's top edge). :param lower_seismo_depth: Maximum depth ruptures can reach, in km (i.e. depth to fault's bottom edge). :param dip: Dip angle (i.e. angle between fault surface and earth surface), in degrees. :return: An integer corresponding to the index of the fault patch which contains the hypocentre. """ totaln_patch = len(fault_trace) for index in range(1, totaln_patch): p0, p1, p2, p3 = cls.get_fault_patch_vertices( fault_trace, upper_seismogenic_depth, lower_seismogenic_depth, dip, index_patch=index) [normal, dist_to_plane] = get_plane_equation(p0, p1, p2, hypocentre) if (numpy.allclose(dist_to_plane, 0., atol=20., rtol=0.)): return index
def get_dppvalue(self, site): """ Get the directivity prediction value, DPP at a given site as described in Spudich et al. (2013). :param site: :class:`~openquake.hazardlib.geo.point.Point` object representing the location of the target site :returns: A float number, directivity prediction value (DPP). """ origin = self.surface.get_resampled_top_edge()[0] dpp_multi = [] index_patch = self.surface.hypocentre_patch_index( self.hypocenter, self.surface.get_resampled_top_edge(), self.surface.mesh.depths[0][0], self.surface.mesh.depths[-1][0], self.surface.get_dip()) idx_nxtp = True hypocenter = self.hypocenter while idx_nxtp: # E Plane Calculation p0, p1, p2, p3 = self.surface.get_fault_patch_vertices( self.surface.get_resampled_top_edge(), self.surface.mesh.depths[0][0], self.surface.mesh.depths[-1][0], self.surface.get_dip(), index_patch=index_patch) [normal, dist_to_plane] = get_plane_equation(p0, p1, p2, origin) pp = projection_pp(site, normal, dist_to_plane, origin) pd, e, idx_nxtp = directp(p0, p1, p2, p3, hypocenter, origin, pp) pd_geo = origin.point_at((pd[0]**2 + pd[1]**2)**0.5, -pd[2], numpy.degrees(math.atan2(pd[0], pd[1]))) # determine the lower bound of E path value f1 = geodetic_distance(p0.longitude, p0.latitude, p1.longitude, p1.latitude) f2 = geodetic_distance(p2.longitude, p2.latitude, p3.longitude, p3.latitude) if f1 > f2: f = f1 else: f = f2 fs, rd, r_hyp = average_s_rad(site, hypocenter, origin, pp, normal, dist_to_plane, e, p0, p1, self.rupture_slip_direction) cprime = isochone_ratio(e, rd, r_hyp) dpp_exp = cprime * numpy.maximum(e, 0.1 * f) *\ numpy.maximum(fs, 0.2) dpp_multi.append(dpp_exp) # check if go through the next patch of the fault index_patch = index_patch + 1 if (len(self.surface.get_resampled_top_edge()) <= 2) and ( index_patch >= len(self.surface.get_resampled_top_edge())): idx_nxtp = False elif index_patch >= len(self.surface.get_resampled_top_edge()): idx_nxtp = False elif idx_nxtp: hypocenter = pd_geo idx_nxtp = True # calculate DPP value of the site. dpp = numpy.log(numpy.sum(dpp_multi)) return dpp
def get_dppvalue(self, site): """ Get the directivity prediction value, DPP at a given site as described in Spudich et al. (2013). :param site: :class:`~openquake.hazardlib.geo.point.Point` object representing the location of the target site :returns: A float number, directivity prediction value (DPP). """ origin = self.surface.get_resampled_top_edge()[0] dpp_multi = [] index_patch = self.surface.hypocentre_patch_index( self.hypocenter, self.surface.get_resampled_top_edge(), self.surface.mesh.depths[0][0], self.surface.mesh.depths[-1][0], self.surface.get_dip()) idx_nxtp = True hypocenter = self.hypocenter while idx_nxtp: # E Plane Calculation p0, p1, p2, p3 = self.surface.get_fault_patch_vertices( self.surface.get_resampled_top_edge(), self.surface.mesh.depths[0][0], self.surface.mesh.depths[-1][0], self.surface.get_dip(), index_patch=index_patch) [normal, dist_to_plane] = get_plane_equation( p0, p1, p2, origin) pp = projection_pp(site, normal, dist_to_plane, origin) pd, e, idx_nxtp = directp( p0, p1, p2, p3, hypocenter, origin, pp) pd_geo = origin.point_at( (pd[0] ** 2 + pd[1] ** 2) ** 0.5, -pd[2], numpy.degrees(math.atan2(pd[0], pd[1]))) # determine the lower bound of E path value f1 = geodetic_distance(p0.longitude, p0.latitude, p1.longitude, p1.latitude) f2 = geodetic_distance(p2.longitude, p2.latitude, p3.longitude, p3.latitude) if f1 > f2: f = f1 else: f = f2 fs, rd, r_hyp = average_s_rad(site, hypocenter, origin, pp, normal, dist_to_plane, e, p0, p1, self.rupture_slip_direction) cprime = isochone_ratio(e, rd, r_hyp) dpp_exp = cprime * numpy.maximum(e, 0.1 * f) *\ numpy.maximum(fs, 0.2) dpp_multi.append(dpp_exp) # check if go through the next patch of the fault index_patch = index_patch + 1 if (len(self.surface.get_resampled_top_edge()) <= 2) and (index_patch >= len(self.surface.get_resampled_top_edge())): idx_nxtp = False elif index_patch >= len(self.surface.get_resampled_top_edge()): idx_nxtp = False elif idx_nxtp: hypocenter = pd_geo idx_nxtp = True # calculate DPP value of the site. dpp = numpy.log(numpy.sum(dpp_multi)) return dpp