def test_within_rupture_distance(self): """ Tests the function to select within Joyner-Boore distance """ self.catalogue.data["longitude"] = np.arange(4.0, 7.5, 0.5) self.catalogue.data["latitude"] = np.arange(4.0, 7.5, 0.5) self.catalogue.data["depth"] = np.ones(7, dtype=float) selector0 = CatalogueSelector(self.catalogue) # Construct Fault trace0 = np.array([[5.5, 6.0], [5.5, 5.0]]) fault_trace = Line([Point(trace0[i, 0], trace0[i, 1]) for i in range(0, 2)]) # Simple fault with vertical dip fault0 = SimpleFaultSurface.from_fault_data(fault_trace, 0.0, 20.0, 90.0, 1.0) # Within 100 km test_cat_100 = selector0.within_rupture_distance(fault0, 100.0) np.testing.assert_array_almost_equal(test_cat_100.data["longitude"], np.array([5.0, 5.5, 6.0])) np.testing.assert_array_almost_equal(test_cat_100.data["latitude"], np.array([5.0, 5.5, 6.0])) np.testing.assert_array_almost_equal(test_cat_100.data["depth"], np.array([1.0, 1.0, 1.0])) # Simple fault with 30 degree dip fault0 = SimpleFaultSurface.from_fault_data(fault_trace, 0.0, 20.0, 30.0, 1.0) # Within 100 km test_cat_100 = selector0.within_rupture_distance(fault0, 100.0) np.testing.assert_array_almost_equal(test_cat_100.data["longitude"], np.array([4.5, 5.0, 5.5, 6.0])) np.testing.assert_array_almost_equal(test_cat_100.data["latitude"], np.array([4.5, 5.0, 5.5, 6.0])) np.testing.assert_array_almost_equal(test_cat_100.data["depth"], np.array([1.0, 1.0, 1.0, 1.0]))
def __init__(self, source_id, name, tectonic_region_type, mfd, rupture_mesh_spacing, magnitude_scaling_relationship, rupture_aspect_ratio, # simple fault specific parameters upper_seismogenic_depth, lower_seismogenic_depth, fault_trace, dip, rake): super(SimpleFaultSource, self).__init__( source_id, name, tectonic_region_type, mfd, rupture_mesh_spacing, magnitude_scaling_relationship, rupture_aspect_ratio ) NodalPlane.check_rake(rake) SimpleFaultSurface.check_fault_data( fault_trace, upper_seismogenic_depth, lower_seismogenic_depth, dip, rupture_mesh_spacing ) self.fault_trace = fault_trace self.upper_seismogenic_depth = upper_seismogenic_depth self.lower_seismogenic_depth = lower_seismogenic_depth self.dip = dip self.rake = rake min_mag = self.mfd.get_min_mag() cols_rows = self._get_rupture_dimensions(float('inf'), float('inf'), min_mag) if 1 in cols_rows: raise ValueError('mesh spacing %s is too low to represent ' 'ruptures of magnitude %s' % (rupture_mesh_spacing, min_mag))
def iter_ruptures(self): """ See :meth: `openquake.hazardlib.source.base.BaseSeismicSource.iter_ruptures`. Generates a ruptures using the "floating" algorithm: for all the magnitude values of assigned MFD calculates the rupture size with respect to MSR and aspect ratio and then places ruptures of that size on the surface of the whole fault source. The occurrence rate of each of those ruptures is the magnitude occurrence rate divided by the number of ruptures that can be placed in a fault. """ whole_fault_surface = SimpleFaultSurface.from_fault_data( self.fault_trace, self.upper_seismogenic_depth, self.lower_seismogenic_depth, self.dip, self.rupture_mesh_spacing) whole_fault_mesh = whole_fault_surface.mesh mesh_rows, mesh_cols = whole_fault_mesh.shape fault_length = float((mesh_cols - 1) * self.rupture_mesh_spacing) fault_width = float((mesh_rows - 1) * self.rupture_mesh_spacing) for mag, mag_occ_rate in self.get_annual_occurrence_rates(): rup_cols, rup_rows = self._get_rupture_dimensions( fault_length, fault_width, mag) num_rup_along_length = mesh_cols - rup_cols + 1 num_rup_along_width = mesh_rows - rup_rows + 1 num_rup = num_rup_along_length * num_rup_along_width occurrence_rate = mag_occ_rate / float(num_rup) for first_row in range(num_rup_along_width): for first_col in range(num_rup_along_length): mesh = whole_fault_mesh[first_row: first_row + rup_rows, first_col: first_col + rup_cols] if not len(self.hypo_list) and not len(self.slip_list): hypocenter = mesh.get_middle_point() occurrence_rate_hypo = occurrence_rate surface = SimpleFaultSurface(mesh) yield ParametricProbabilisticRupture( mag, self.rake, self.tectonic_region_type, hypocenter, surface, occurrence_rate_hypo, self.temporal_occurrence_model) else: for hypo in self.hypo_list: for slip in self.slip_list: surface = SimpleFaultSurface(mesh) hypocenter = surface.get_hypo_location( self.rupture_mesh_spacing, hypo[:2]) occurrence_rate_hypo = occurrence_rate * \ hypo[2] * slip[1] rupture_slip_direction = slip[0] yield ParametricProbabilisticRupture( mag, self.rake, self.tectonic_region_type, hypocenter, surface, occurrence_rate_hypo, self.temporal_occurrence_model, rupture_slip_direction)
def test_upper_seismo_depth_range(self): self.assertRaises(ValueError, SimpleFaultSurface.check_fault_data, self.fault_trace, -0.1, 10.0, 90.0, 1.0) SimpleFaultSurface.check_fault_data(self.fault_trace, 0.0, 1.0, 90.0, 1.0) SimpleFaultSurface.check_fault_data(self.fault_trace, 1.0, 1.1, 90.0, 1.0)
def test_upper_seismo_depth_range(self): self.assertRaises(ValueError, SimpleFaultSurface.check_fault_data, self.fault_trace, -0.1, 10.0, 90.0, 1.0) SimpleFaultSurface.check_fault_data(self.fault_trace, 0.0, 1.0, 90.0, 1.0) SimpleFaultSurface.check_fault_data(self.fault_trace, 1.0, 1.1, 90.0, 1.0)
def test_mesh_spacing_range(self): SimpleFaultSurface.check_fault_data(self.fault_trace, 0.0, 1.0, 90.0, 1.0) self.assertRaises(ValueError, SimpleFaultSurface.check_fault_data, self.fault_trace, 0.0, 1.0, 90.0, 0.0) self.assertRaises(ValueError, SimpleFaultSurface.check_fault_data, self.fault_trace, 0.0, 1.0, 90.0, -1.0)
def test_mesh_spacing_range(self): SimpleFaultSurface.check_fault_data(self.fault_trace, 0.0, 1.0, 90.0, 1.0) self.assertRaises(ValueError, SimpleFaultSurface.check_fault_data, self.fault_trace, 0.0, 1.0, 90.0, 0.0) self.assertRaises(ValueError, SimpleFaultSurface.check_fault_data, self.fault_trace, 0.0, 1.0, 90.0, -1.0)
def modify_set_lower_seismogenic_depth(self, lsd): """ Modifies the lower seismogenic depth :param float lsd: New value of the lsd [km] """ SimpleFaultSurface.check_fault_data( self.fault_trace, self.upper_seismogenic_depth, lsd, self.dip, self.rupture_mesh_spacing) self.lower_seismogenic_depth = lsd
def modify_set_dip(self, dip): """ Modifies the dip to the specified value :param float dip: New value of dip (must still be within 0.0 to 90.0 degrees) """ SimpleFaultSurface.check_fault_data( self.fault_trace, self.upper_seismogenic_depth, self.lower_seismogenic_depth, dip, self.rupture_mesh_spacing) self.dip = dip
def modify_set_dip(self, dip): """ Modifies the dip to the specified value :param float dip: New value of dip (must still be within 0.0 to 90.0 degrees) """ SimpleFaultSurface.check_fault_data( self.fault_trace, self.upper_seismogenic_depth, self.lower_seismogenic_depth, dip, self.rupture_mesh_spacing) self.dip = dip
def modify_adjust_dip(self, increment): """ Modifies the dip by an incremental value :param float increment: Value by which to increase or decrease the dip (the resulting dip must still be within 0.0 to 90.0 degrees) """ SimpleFaultSurface.check_fault_data( self.fault_trace, self.upper_seismogenic_depth, self.lower_seismogenic_depth, self.dip + increment, self.rupture_mesh_spacing) self.dip += increment
def modify_adjust_dip(self, increment): """ Modifies the dip by an incremental value :param float increment: Value by which to increase or decrease the dip (the resulting dip must still be within 0.0 to 90.0 degrees) """ SimpleFaultSurface.check_fault_data( self.fault_trace, self.upper_seismogenic_depth, self.lower_seismogenic_depth, self.dip + increment, self.rupture_mesh_spacing) self.dip += increment
def __init__( self, source_id, name, tectonic_region_type, mfd, rupture_mesh_spacing, magnitude_scaling_relationship, rupture_aspect_ratio, temporal_occurrence_model, # simple fault specific parameters upper_seismogenic_depth, lower_seismogenic_depth, fault_trace, dip, rake, hypo_list=(), slip_list=()): super(SimpleFaultSource, self).__init__(source_id, name, tectonic_region_type, mfd, rupture_mesh_spacing, magnitude_scaling_relationship, rupture_aspect_ratio, temporal_occurrence_model) NodalPlane.check_rake(rake) SimpleFaultSurface.check_fault_data(fault_trace, upper_seismogenic_depth, lower_seismogenic_depth, dip, rupture_mesh_spacing) self.fault_trace = fault_trace self.upper_seismogenic_depth = upper_seismogenic_depth self.lower_seismogenic_depth = lower_seismogenic_depth self.dip = dip self.rake = rake min_mag, max_mag = self.mfd.get_min_max_mag() cols_rows = self._get_rupture_dimensions(float('inf'), float('inf'), min_mag) self.slip_list = slip_list self.hypo_list = hypo_list if (len(self.hypo_list) and not len(self.slip_list) or not len(self.hypo_list) and len(self.slip_list)): raise ValueError('hypo_list and slip_list have to be both given ' 'or neither given') if 1 in cols_rows: raise ValueError('mesh spacing %s is too high to represent ' 'ruptures of magnitude %s' % (rupture_mesh_spacing, min_mag))
def test_dip_inside_range(self): self.assertRaises(ValueError, SimpleFaultSurface.check_fault_data, self.fault_trace, 0.0, 1.0, 0.0, 1.0) self.assertRaises(ValueError, SimpleFaultSurface.check_fault_data, self.fault_trace, 0.0, 1.0, -0.1, 1.0) self.assertRaises(ValueError, SimpleFaultSurface.check_fault_data, self.fault_trace, 0.0, 1.0, 90.1, 1.0) SimpleFaultSurface.check_fault_data(self.fault_trace, 0.0, 1.0, 0.1, 1.0) SimpleFaultSurface.check_fault_data(self.fault_trace, 0.0, 1.0, 90.0, 1.0)
def test_dip_inside_range(self): self.assertRaises(ValueError, SimpleFaultSurface.check_fault_data, self.fault_trace, 0.0, 1.0, 0.0, 1.0) self.assertRaises(ValueError, SimpleFaultSurface.check_fault_data, self.fault_trace, 0.0, 1.0, -0.1, 1.0) self.assertRaises(ValueError, SimpleFaultSurface.check_fault_data, self.fault_trace, 0.0, 1.0, 90.1, 1.0) SimpleFaultSurface.check_fault_data(self.fault_trace, 0.0, 1.0, 0.1, 1.0) SimpleFaultSurface.check_fault_data(self.fault_trace, 0.0, 1.0, 90.0, 1.0)
def set_simple_fault_3D_geometry(w, src): """ Set simple fault surface coordinates as shapefile geometry. :parameter w: Writer :parameter src: NRML source object """ # Create an oq object for the source converter = sss.NrmlHazardlibConverter( investigation_time=50.0, rupture_mesh_spacing=1.0, width_of_mfd_bin=0.1, area_source_discretization=10.0 ) src_oq = converter(src) lon, lat = SimpleFaultSurface.get_surface_vertexes( src_oq.fault_trace, src_oq.upper_seismogenic_depth, src_oq.lower_seismogenic_depth, src_oq.dip ) # Reorder the vertexes lons = numpy.concatenate([lon[::2], numpy.flipud(lon[1::2])]) lats = numpy.concatenate([lat[::2], numpy.flipud(lat[1::2])]) depths = numpy.concatenate( [ numpy.ones_like(lon[::2]) * src_oq.upper_seismogenic_depth, numpy.ones_like(lon[::2]) * src_oq.lower_seismogenic_depth, ] ) # Create the 3D polygon w.poly(parts=[[[tlon, tlat, tdep] for tlon, tlat, tdep in zip(list(lons), list(lats), list(depths))]])
def count_ruptures(self): """ See :meth: `openquake.hazardlib.source.base.BaseSeismicSource.count_ruptures`. """ whole_fault_surface = SimpleFaultSurface.from_fault_data( self.fault_trace, self.upper_seismogenic_depth, self.lower_seismogenic_depth, self.dip, self.rupture_mesh_spacing) whole_fault_mesh = whole_fault_surface.mesh mesh_rows, mesh_cols = whole_fault_mesh.shape fault_length = float((mesh_cols - 1) * self.rupture_mesh_spacing) fault_width = float((mesh_rows - 1) * self.rupture_mesh_spacing) self._nr = [] n_hypo = len(self.hypo_list) or 1 n_slip = len(self.slip_list) or 1 for (mag, mag_occ_rate) in self.get_annual_occurrence_rates(): if mag_occ_rate == 0: continue rup_cols, rup_rows = self._get_rupture_dimensions( fault_length, fault_width, mag) num_rup_along_length = mesh_cols - rup_cols + 1 num_rup_along_width = mesh_rows - rup_rows + 1 self._nr.append(num_rup_along_length * num_rup_along_width * n_hypo * n_slip) counts = sum(self._nr) return counts
def set_simple_fault_3D_geometry(w, src): """ Set simple fault surface coordinates as shapefile geometry. :parameter w: Writer :parameter src: NRML source object """ # Create an oq object for the source hc = HC(1., 10., 0.1, 50.) converter = sss.NrmlHazardlibConverter(hc) src_oq = converter._nrml_source_to_hazardlib(src) lon, lat = \ SimpleFaultSurface.get_surface_vertexes(src_oq.fault_trace, src_oq.upper_seismogenic_depth, src_oq.lower_seismogenic_depth, src_oq.dip) # Reorder the vertexes print lon, lat lons = numpy.concatenate([lon[::2], numpy.flipud(lon[1::2])]) lats = numpy.concatenate([lat[::2], numpy.flipud(lat[1::2])]) depths = numpy.concatenate([numpy.ones_like(lon[::2]) * src_oq.upper_seismogenic_depth, numpy.ones_like(lon[::2]) * src_oq.lower_seismogenic_depth]) # Create the 3D polygon w.poly(parts=[[[tlon, tlat, tdep] for tlon, tlat, tdep in zip(list(lons), list(lats), list(depths))]])
def polygon(self): """ The underlying polygon `""" return SimpleFaultSurface.surface_projection_from_fault_data( self.fault_trace, self.upper_seismogenic_depth, self.lower_seismogenic_depth, self.dip)
def setUpClass(self): cfg = helpers.get_data_path('simple_fault_demo_hazard/job.ini') job = helpers.get_job(cfg) output = models.Output.objects.create(oq_job=job, display_name='test', output_type='ses') ses_coll = models.SESCollection.create(output=output) self.mesh_lons = numpy.array([0.1 * x for x in range(16)]).reshape( (4, 4)) self.mesh_lats = numpy.array([0.2 * x for x in range(16)]).reshape( (4, 4)) self.mesh_depths = numpy.array([0.3 * x for x in range(16)]).reshape( (4, 4)) sfs = SimpleFaultSurface( Mesh(self.mesh_lons, self.mesh_lats, self.mesh_depths)) ps = PlanarSurface(10, 20, 30, Point(3.9, 2.2, 10), Point(4.90402718, 3.19634248, 10), Point(5.9, 2.2, 90), Point(4.89746275, 1.20365263, 90)) self.fault_rupture = models.ProbabilisticRupture.objects.create( ses_collection=ses_coll, magnitude=5, rake=0, surface=sfs, is_from_fault_source=True, is_multi_surface=False) self.source_rupture = models.ProbabilisticRupture.objects.create( ses_collection=ses_coll, magnitude=5, rake=0, surface=ps, is_from_fault_source=False, is_multi_surface=False)
def make_rupture_fordpp(self, rupture_class, **kwargs): # Create the rupture surface. upper_seismogenic_depth = 0. lower_seismogenic_depth = 15. dip = 90. mesh_spacing = 1. fault_trace_start = Point(10., 45.2) fault_trace_end = Point(10., 45.919457) fault_trace = Line([fault_trace_start, fault_trace_end]) default_arguments = { 'mag': 7.2, 'rake': 0., 'tectonic_region_type': const.TRT.STABLE_CONTINENTAL, 'hypocenter': Point(10.0, 45.334898, 10), 'surface': SimpleFaultSurface.from_fault_data( fault_trace, upper_seismogenic_depth, lower_seismogenic_depth, dip=dip, mesh_spacing=mesh_spacing), 'rupture_slip_direction': 0. } default_arguments.update(kwargs) kwargs = default_arguments rupture = rupture_class(**kwargs) for key in kwargs: assert getattr(rupture, key) is kwargs[key] return rupture
def count_ruptures(self): """ See :meth: `openquake.hazardlib.source.base.BaseSeismicSource.count_ruptures`. """ whole_fault_surface = SimpleFaultSurface.from_fault_data( self.fault_trace, self.upper_seismogenic_depth, self.lower_seismogenic_depth, self.dip, self.rupture_mesh_spacing) whole_fault_mesh = whole_fault_surface.mesh mesh_rows, mesh_cols = whole_fault_mesh.shape fault_length = float((mesh_cols - 1) * self.rupture_mesh_spacing) fault_width = float((mesh_rows - 1) * self.rupture_mesh_spacing) self._nr = [] for (mag, mag_occ_rate) in self.get_annual_occurrence_rates(): if mag_occ_rate == 0: continue rup_cols, rup_rows = self._get_rupture_dimensions( fault_length, fault_width, mag) num_rup_along_length = mesh_cols - rup_cols + 1 num_rup_along_width = mesh_rows - rup_rows + 1 self._nr.append(num_rup_along_length * num_rup_along_width) counts = sum(self._nr) n_hypo = len(self.hypo_list) or 1 n_slip = len(self.slip_list) or 1 return counts * n_hypo * n_slip
def polygon(self): """ The underlying polygon `""" return SimpleFaultSurface.surface_projection_from_fault_data( self.fault_trace, self.upper_seismogenic_depth, self.lower_seismogenic_depth, self.dip)
def make_rupture_fordpp(self, rupture_class, **kwargs): # Create the rupture surface. upper_seismogenic_depth = 0. lower_seismogenic_depth = 15. dip = 90. mesh_spacing = 1. fault_trace_start = Point(10., 45.2) fault_trace_end = Point(10., 45.919457) fault_trace = Line([fault_trace_start, fault_trace_end]) default_arguments = { 'mag': 7.2, 'rake': 0., 'tectonic_region_type': const.TRT.STABLE_CONTINENTAL, 'hypocenter': Point(10.0, 45.334898, 10), 'surface': SimpleFaultSurface.from_fault_data( fault_trace, upper_seismogenic_depth, lower_seismogenic_depth, dip=dip, mesh_spacing=mesh_spacing), 'source_typology': object(), 'rupture_slip_direction': 0. } default_arguments.update(kwargs) kwargs = default_arguments rupture = rupture_class(**kwargs) for key in kwargs: assert getattr(rupture, key) is kwargs[key] return rupture
def test_get_resampled_top_edge_non_planar(self): upper_seismogenic_depth = 0. lower_seismogenic_depth = 40. dip = 90. mesh_spacing = 10. fault_trace = Line([Point(0.0, 0.0), Point(0.5, 0.5), Point(1.5, 1.0)]) whole_fault_surface = SimpleFaultSurface.from_fault_data( fault_trace, upper_seismogenic_depth, lower_seismogenic_depth, dip, mesh_spacing) ref = Line([Point(0., 0.), Point(0.5, 0.5), Point(1.5, 1.0)]) result = whole_fault_surface.get_resampled_top_edge() for ref_point, result_point in zip(ref.points, result.points): self.assertAlmostEqual(ref_point.longitude, result_point.longitude, delta=0.1) self.assertAlmostEqual(ref_point.latitude, result_point.latitude, delta=0.1) self.assertAlmostEqual(ref_point.depth, result_point.depth, delta=0.1)
def modify_set_geometry(self, fault_trace, upper_seismogenic_depth, lower_seismogenic_depth, dip, spacing): """ Modifies the current source geometry including trace, seismogenic depths and dip """ # Check the new geometries are valid SimpleFaultSurface.check_fault_data( fault_trace, upper_seismogenic_depth, lower_seismogenic_depth, dip, spacing ) self.fault_trace = fault_trace self.upper_seismogenic_depth = upper_seismogenic_depth self.lower_seismogenic_depth = lower_seismogenic_depth self.dip = dip self.rupture_mesh_spacing = spacing
def modify_set_geometry(self, fault_trace, upper_seismogenic_depth, lower_seismogenic_depth, dip, spacing): """ Modifies the current source geometry including trace, seismogenic depths and dip """ # Check the new geometries are valid SimpleFaultSurface.check_fault_data(fault_trace, upper_seismogenic_depth, lower_seismogenic_depth, dip, spacing) self.fault_trace = fault_trace self.upper_seismogenic_depth = upper_seismogenic_depth self.lower_seismogenic_depth = lower_seismogenic_depth self.dip = dip self.rupture_mesh_spacing = spacing
def test_get_dip_2(self): p1 = Point(0.0, 0.0) p2 = Point(0.0635916966572, 0.0635916574897) surface = SimpleFaultSurface.from_fault_data(Line([p1, p2]), 1.0, 6.0, 30.0, 1.0) self.assertAlmostEquals(30.0, surface.get_dip(), 1)
def test_get_strike_1(self): p1 = Point(0.0, 0.0) p2 = Point(0.0635916966572, 0.0635916574897) surface = SimpleFaultSurface.from_fault_data(Line([p1, p2]), 1.0, 6.0, 89.9, 1.0) self.assertAlmostEquals(45.0, surface.get_strike(), delta=1e-4)
def test_get_strike_1(self): p1 = Point(0.0, 0.0) p2 = Point(0.0635916966572, 0.0635916574897) surface = SimpleFaultSurface.from_fault_data(Line([p1, p2]), 1.0, 6.0, 89.9, 1.0) self.assertAlmostEquals(45.0, surface.get_strike(), delta=1e-4)
def test_inclined_non_planar_surface(self): p1 = Point(0.1, 0.1, 0.0) p2 = Point(0.1, 0.117986432118, 0.0) p3 = Point(0.117986470254, 0.117986426305, 0.0) p4 = Point(0.117986470254, 0.0999999941864, 0.0) surface = SimpleFaultSurface.from_fault_data(Line([p1, p2, p3, p4]), 2.0, 4.0, 30.0, 1.0) self.assertAlmostEqual(surface.get_width(), 4.0, places=2)
def test_get_dip_2(self): p1 = Point(0.0, 0.0) p2 = Point(0.0635916966572, 0.0635916574897) surface = SimpleFaultSurface.from_fault_data(Line([p1, p2]), 1.0, 6.0, 30.0, 1.0) self.assertAlmostEquals(30.0, surface.get_dip(), 1)
def test_inclined_non_planar_surface(self): p1 = Point(0.1, 0.1, 0.0) p2 = Point(0.1, 0.117986432118, 0.0) p3 = Point(0.117986470254, 0.117986426305, 0.0) p4 = Point(0.117986470254, 0.0999999941864, 0.0) surface = SimpleFaultSurface.from_fault_data(Line([p1, p2, p3, p4]), 2.0, 4.0, 30.0, 1.0) self.assertAlmostEqual(surface.get_width(), 4.0, places=2)
def test_get_strike_2(self): p1 = Point(0.0, 0.0) p2 = Point(0.0635916966572, 0.0635916574897) p3 = Point(0.0860747816618, 0.102533437776) surface = SimpleFaultSurface.from_fault_data(Line([p1, p2, p3]), 1.0, 6.0, 89.9, 1.0) self.assertAlmostEqual(40.0, surface.get_strike(), delta=0.02)
def test_get_mesh_5(self): p1 = Point(179.9, 0.0) p2 = Point(180.0, 0.0) p3 = Point(-179.9, 0.0) fault = SimpleFaultSurface.from_fault_data(Line([p1, p2, p3]), 1.0, 6.0, 90.0, 1.0) self.assert_mesh_is(fault, test_data.TEST_5_MESH)
def test_get_mesh_5(self): p1 = Point(179.9, 0.0) p2 = Point(180.0, 0.0) p3 = Point(-179.9, 0.0) fault = SimpleFaultSurface.from_fault_data(Line([p1, p2, p3]), 1.0, 6.0, 90.0, 1.0) self.assert_mesh_is(fault, test_data.TEST_5_MESH)
def test_get_dip_1(self): p1 = Point(0.0, 0.0) p2 = Point(0.0635916966572, 0.0635916574897) p3 = Point(0.0860747816618, 0.102533437776) surface = SimpleFaultSurface.from_fault_data(Line([p1, p2, p3]), 1.0, 6.0, 90.0, 1.0) self.assertAlmostEquals(90.0, surface.get_dip(), delta=1e-6)
def test_get_dip_1(self): p1 = Point(0.0, 0.0) p2 = Point(0.0635916966572, 0.0635916574897) p3 = Point(0.0860747816618, 0.102533437776) surface = SimpleFaultSurface.from_fault_data(Line([p1, p2, p3]), 1.0, 6.0, 90.0, 1.0) self.assertAlmostEquals(90.0, surface.get_dip(), delta=1e-6)
def test_get_fault_vertices_3d(self): p0, p1, p2, p3 = SimpleFaultSurface.get_fault_patch_vertices( Line([Point(10., 45.2), Point(10.5, 45.3), Point(10., 45.487783)]), upper_seismogenic_depth=0., lower_seismogenic_depth=14., dip=30, index_patch=1.) p4, p5, p6, p7 = SimpleFaultSurface.get_fault_patch_vertices( Line([Point(10., 45.2), Point(10.5, 45.3), Point(10., 45.487783)]), upper_seismogenic_depth=0., lower_seismogenic_depth=14., dip=30, index_patch=2.) # Test for the first patch self.assertAlmostEqual(p0.longitude, 10., delta=0.1) self.assertAlmostEqual(p0.latitude, 45.2, delta=0.1) self.assertAlmostEqual(p0.depth, 0., delta=0.1) self.assertAlmostEqual(p1.longitude, 10.5, delta=0.1) self.assertAlmostEqual(p1.latitude, 45.3, delta=0.1) self.assertAlmostEqual(p1.depth, 0., delta=0.1) self.assertAlmostEqual(p2.longitude, 10.81, delta=0.1) self.assertAlmostEqual(p2.latitude, 45.2995, delta=0.1) self.assertAlmostEqual(p2.depth, 14., delta=0.1) self.assertAlmostEqual(p3.longitude, 10.31, delta=0.1) self.assertAlmostEqual(p3.latitude, 45.1995, delta=0.1) self.assertAlmostEqual(p3.depth, 14., delta=0.1) # Test for the second patch self.assertAlmostEqual(p4.longitude, 10.5, delta=0.1) self.assertAlmostEqual(p4.latitude, 45.3, delta=0.1) self.assertAlmostEqual(p4.depth, 0., delta=0.1) self.assertAlmostEqual(p5.longitude, 10.0, delta=0.1) self.assertAlmostEqual(p5.latitude, 45.4877, delta=0.1) self.assertAlmostEqual(p5.depth, 0., delta=0.1) self.assertAlmostEqual(p6.longitude, 10.311, delta=0.1) self.assertAlmostEqual(p6.latitude, 45.4873, delta=0.1) self.assertAlmostEqual(p6.depth, 14., delta=0.1) self.assertAlmostEqual(p7.longitude, 10.81, delta=0.1) self.assertAlmostEqual(p7.latitude, 45.2995, delta=0.1) self.assertAlmostEqual(p7.depth, 14., delta=0.1)
def test_dip_90_three_points(self): polygon = SimpleFaultSurface.surface_projection_from_fault_data( Line([Point(1, -20), Point(1, -20.2), Point(2, -19.7)]), dip=90, upper_seismogenic_depth=30, lower_seismogenic_depth=50, ) elons = [1, 1, 2] elats = [-20.2, -20., -19.7] numpy.testing.assert_allclose(polygon.lons, elons) numpy.testing.assert_allclose(polygon.lats, elats)
def test_get_mesh_topo(self): p1 = Point(0.0, 0.0, -2.0) p2 = Point(0.0, 0.0359728811759, -2.0) p3 = Point(0.0190775080917, 0.0550503815182, -2.0) p4 = Point(0.03974514139, 0.0723925718856, -2.0) fault = SimpleFaultSurface.from_fault_data(Line([p1, p2, p3, p4]), -2.0, 2.0, 90.0, 1.0) self.assert_mesh_is(fault, test_data.TEST_TOPO_MESH)
def test_dip_90_self_intersection(self): polygon = SimpleFaultSurface.surface_projection_from_fault_data( Line([Point(1, -2), Point(2, -1.9), Point(3, -2.1), Point(4, -2)]), dip=90, upper_seismogenic_depth=10, lower_seismogenic_depth=20, ) elons = [3., 1., 2., 4.] elats = [-2.1, -2., -1.9, -2.] numpy.testing.assert_allclose(polygon.lons, elons) numpy.testing.assert_allclose(polygon.lats, elats)
def test_get_mesh_1(self): p1 = Point(0.0, 0.0, 0.0) p2 = Point(0.0, 0.0359728811759, 0.0) p3 = Point(0.0190775080917, 0.0550503815182, 0.0) p4 = Point(0.03974514139, 0.0723925718856, 0.0) fault = SimpleFaultSurface.from_fault_data( Line([p1, p2, p3, p4]), 0.0, 4.2426406871192848, 45.0, 1.0) self.assert_mesh_is(fault, test_data.TEST_1_MESH)
def test_dip_90_self_intersection(self): polygon = SimpleFaultSurface.surface_projection_from_fault_data( Line([Point(1, -2), Point(2, -1.9), Point(3, -2.1), Point(4, -2)]), dip=90, upper_seismogenic_depth=10, lower_seismogenic_depth=20, ) elons = [3., 1., 2., 4.] elats = [-2.1, -2., -1.9, -2.] numpy.testing.assert_allclose(polygon.lons, elons) numpy.testing.assert_allclose(polygon.lats, elats)
def test_get_mesh_1(self): p1 = Point(0.0, 0.0, 0.0) p2 = Point(0.0, 0.0359728811759, 0.0) p3 = Point(0.0190775080917, 0.0550503815182, 0.0) p4 = Point(0.03974514139, 0.0723925718856, 0.0) fault = SimpleFaultSurface.from_fault_data( Line([p1, p2, p3, p4]), 0.0, 4.2426406871192848, 45.0, 1.0) self.assert_mesh_is(fault, test_data.TEST_1_MESH)
def test_dip_90_three_points(self): polygon = SimpleFaultSurface.surface_projection_from_fault_data( Line([Point(1, -20), Point(1, -20.2), Point(2, -19.7)]), dip=90, upper_seismogenic_depth=30, lower_seismogenic_depth=50, ) elons = [1, 1, 2] elats = [-20.2, -20., -19.7] numpy.testing.assert_allclose(polygon.lons, elons) numpy.testing.assert_allclose(polygon.lats, elats)
def test_hypocentre_index_large_mesh_spacing(self): hypocentre = Point(10.443522, 45.379006, 20.0) upper_seismogenic_depth = 10. lower_seismogenic_depth = 28. dip = 30. mesh_spacing = 10. fault_trace = Line([Point(10., 45.2), Point(10., 45.487783)]) whole_fault_surface = SimpleFaultSurface.from_fault_data( fault_trace, upper_seismogenic_depth, lower_seismogenic_depth, dip, mesh_spacing) target_rupture_surface = whole_fault_surface.get_resampled_top_edge() index = SimpleFaultSurface.hypocentre_patch_index( hypocentre, target_rupture_surface, upper_seismogenic_depth, lower_seismogenic_depth, dip) # The value used for this test is by hand calculation self.assertEqual(index, 1)
def test_hypocentre_index_multi_segments(self): hypocentre = Point(0.588100, 0.479057, 7.1711) upper_seismogenic_depth = 0.5 lower_seismogenic_depth = 15. dip = 56.5 mesh_spacing = 2. fault_trace = Line([Point(0., 0.), Point(0.55, 0.5), Point(1.2, 1.2)]) whole_fault_surface = SimpleFaultSurface.from_fault_data( fault_trace, upper_seismogenic_depth, lower_seismogenic_depth, dip, mesh_spacing) target_rupture_surface = whole_fault_surface.get_resampled_top_edge() index = SimpleFaultSurface.hypocentre_patch_index( hypocentre, target_rupture_surface, upper_seismogenic_depth, lower_seismogenic_depth, dip) # The value used for this test is by hand calculation self.assertEqual(index, 2)
def test_get_mesh_topo(self): p1 = Point(0.0, 0.0, -2.0) p2 = Point(0.0, 0.0359728811759, -2.0) p3 = Point(0.0190775080917, 0.0550503815182, -2.0) p4 = Point(0.03974514139, 0.0723925718856, -2.0) fault = SimpleFaultSurface.from_fault_data(Line([p1, p2, p3, p4]), -2.0, 2.0, 90.0, 1.0) self.assert_mesh_is(fault, test_data.TEST_TOPO_MESH)
def test_hypocentre_index_large_mesh_spacing(self): hypocentre = Point(10.443522, 45.379006, 20.0) upper_seismogenic_depth = 10. lower_seismogenic_depth = 28. dip = 30. mesh_spacing = 10. fault_trace = Line([Point(10., 45.2), Point(10., 45.487783)]) whole_fault_surface = SimpleFaultSurface.from_fault_data( fault_trace, upper_seismogenic_depth, lower_seismogenic_depth, dip, mesh_spacing ) target_rupture_surface = whole_fault_surface.get_resampled_top_edge() index = SimpleFaultSurface.hypocentre_patch_index( hypocentre, target_rupture_surface, upper_seismogenic_depth, lower_seismogenic_depth, dip) # The value used for this test is by hand calculation self.assertEqual(index, 1)
def test_hypocentre_index_multi_segments(self): hypocentre = Point(0.588100, 0.479057, 7.1711) upper_seismogenic_depth = 0.5 lower_seismogenic_depth = 15. dip = 56.5 mesh_spacing = 2. fault_trace = Line([Point(0., 0.), Point(0.55, 0.5), Point(1.2, 1.2)]) whole_fault_surface = SimpleFaultSurface.from_fault_data( fault_trace, upper_seismogenic_depth, lower_seismogenic_depth, dip, mesh_spacing ) target_rupture_surface = whole_fault_surface.get_resampled_top_edge() index = SimpleFaultSurface.hypocentre_patch_index( hypocentre, target_rupture_surface, upper_seismogenic_depth, lower_seismogenic_depth, dip) # The value used for this test is by hand calculation self.assertEqual(index, 2)
def test_three_points(self): polygon = SimpleFaultSurface.surface_projection_from_fault_data( Line([Point(10, -20), Point(11, -20.2), Point(12, -19.7)]), dip=30, upper_seismogenic_depth=25.3, lower_seismogenic_depth=53.6, ) elons = [11.13560807, 10.1354272, 10.06374285, 12.06361991, 12.13515987] elats = [-21.02520738, -20.82520794, -20.3895235, -20.08952368, -20.52520878] numpy.testing.assert_allclose(polygon.lons, elons) numpy.testing.assert_allclose(polygon.lats, elats)
def test_dip_90_two_points(self): polygon = SimpleFaultSurface.surface_projection_from_fault_data( Line([Point(2, 2), Point(1, 1)]), dip=90, upper_seismogenic_depth=10, lower_seismogenic_depth=20, ) elons = [1.00003181, 0.99996821, 0.99996819, 1.99996819, 2.00003182, 2.00003181] elats = [0.99996822, 0.99996819, 1.00003178, 2.0000318, 2.0000318, 1.9999682] numpy.testing.assert_allclose(polygon.lons, elons) numpy.testing.assert_allclose(polygon.lats, elats)
def test_hypocentre_index_2ndpatch(self): hypocentre = Point(10.237155, 45.562761, 8.0) upper_seismogenic_depth = 0. lower_seismogenic_depth = 15. dip = 30. mesh_spacing = 1. fault_trace = Line([Point(10., 45.2), Point(10.0, 45.559729), Point(10.365145, 45.813659)]) whole_fault_surface = SimpleFaultSurface.from_fault_data( fault_trace, upper_seismogenic_depth, lower_seismogenic_depth, dip, mesh_spacing ) target_rupture_surface = whole_fault_surface.get_resampled_top_edge() index = SimpleFaultSurface.hypocentre_patch_index( hypocentre, target_rupture_surface, upper_seismogenic_depth, lower_seismogenic_depth, dip) # The value used for this test is by hand calculation self.assertEqual(index, 2)
def test_dip_90_two_points(self): polygon = SimpleFaultSurface.surface_projection_from_fault_data( Line([Point(2, 2), Point(1, 1)]), dip=90, upper_seismogenic_depth=10, lower_seismogenic_depth=20, ) elons = [1.00003181, 0.99996821, 0.99996819, 1.99996819, 2.00003182, 2.00003181] elats = [0.99996822, 0.99996819, 1.00003178, 2.0000318, 2.0000318, 1.9999682] numpy.testing.assert_allclose(polygon.lons, elons) numpy.testing.assert_allclose(polygon.lats, elats)
def test_hypocentre_index_2ndpatch(self): hypocentre = Point(10.237155, 45.562761, 8.0) upper_seismogenic_depth = 0. lower_seismogenic_depth = 15. dip = 30. mesh_spacing = 1. fault_trace = Line([Point(10., 45.2), Point(10.0, 45.559729), Point(10.365145, 45.813659)]) whole_fault_surface = SimpleFaultSurface.from_fault_data( fault_trace, upper_seismogenic_depth, lower_seismogenic_depth, dip, mesh_spacing ) target_rupture_surface = whole_fault_surface.get_resampled_top_edge() index = SimpleFaultSurface.hypocentre_patch_index( hypocentre, target_rupture_surface, upper_seismogenic_depth, lower_seismogenic_depth, dip) # The value used for this test is by hand calculation self.assertEqual(index, 2)
def test_three_points(self): polygon = SimpleFaultSurface.surface_projection_from_fault_data( Line([Point(10, -20), Point(11, -20.2), Point(12, -19.7)]), dip=30, upper_seismogenic_depth=25.3, lower_seismogenic_depth=53.6, ) elons = [11.13560807, 10.1354272, 10.06374285, 12.06361991, 12.13515987] elats = [-21.02520738, -20.82520794, -20.3895235, -20.08952368, -20.52520878] numpy.testing.assert_allclose(polygon.lons, elons) numpy.testing.assert_allclose(polygon.lats, elats)
def get_fault_surface_area(self): """ Computes the area covered by the surface of the fault. :returns: A float defining the area of the surface of the fault [km^2] """ sfc = SimpleFaultSurface.from_fault_data(self.fault_trace, self.upper_seismogenic_depth, self.lower_seismogenic_depth, self.dip, 1.0) return sfc.get_area()
def test_get_fault_vertices_3d(self): lons, lats, deps = SimpleFaultSurface.get_fault_vertices_3d( Line([Point(10, -20), Point(11, -20.2), Point(12, -19.7)]), upper_seismogenic_depth=25.3, lower_seismogenic_depth=53.6, dip=30, ) elons = [10, 11, 12, 12.13515987, 11.13560807, 10.1354272] elats = [-20, -20.2, -19.7, -20.52520878, -21.02520738, -20.82520794] edeps = [25.3, 25.3, 25.3, 53.6, 53.6, 53.6] numpy.testing.assert_allclose(lons, elons) numpy.testing.assert_allclose(lats, elats) numpy.testing.assert_allclose(deps, edeps)
def __init__(self, source_id, name, tectonic_region_type, mfd, rupture_mesh_spacing, magnitude_scaling_relationship, rupture_aspect_ratio, temporal_occurrence_model, # simple fault specific parameters upper_seismogenic_depth, lower_seismogenic_depth, fault_trace, dip, rake, hypo_list=(), slip_list=()): super(SimpleFaultSource, self).__init__( source_id, name, tectonic_region_type, mfd, rupture_mesh_spacing, magnitude_scaling_relationship, rupture_aspect_ratio, temporal_occurrence_model ) NodalPlane.check_rake(rake) SimpleFaultSurface.check_fault_data( fault_trace, upper_seismogenic_depth, lower_seismogenic_depth, dip, rupture_mesh_spacing ) self.fault_trace = fault_trace self.upper_seismogenic_depth = upper_seismogenic_depth self.lower_seismogenic_depth = lower_seismogenic_depth self.dip = dip self.rake = rake min_mag, max_mag = self.mfd.get_min_max_mag() cols_rows = self._get_rupture_dimensions(float('inf'), float('inf'), min_mag) self.slip_list = slip_list self.hypo_list = hypo_list if (len(self.hypo_list) and not len(self.slip_list) or not len(self.hypo_list) and len(self.slip_list)): raise ValueError('hypo_list and slip_list have to be both given ' 'or neither given') if 1 in cols_rows: raise ValueError('mesh spacing %s is too high to represent ' 'ruptures of magnitude %s' % (rupture_mesh_spacing, min_mag))