def iter_ruptures(self): """ See :meth: `openquake.hazardlib.source.base.BaseSeismicSource.iter_ruptures`. Uses :func:`_float_ruptures` for finding possible rupture locations on the whole fault surface. """ whole_fault_surface = ComplexFaultSurface.from_fault_data( self.edges, self.rupture_mesh_spacing) whole_fault_mesh = whole_fault_surface.mesh cell_center, cell_length, cell_width, cell_area = ( whole_fault_mesh.get_cell_dimensions()) for mag, mag_occ_rate in self.get_annual_occurrence_rates(): rupture_area = self.magnitude_scaling_relationship.get_median_area( mag, self.rake) rupture_length = numpy.sqrt( rupture_area * self.rupture_aspect_ratio) rupture_slices = _float_ruptures( rupture_area, rupture_length, cell_area, cell_length) occurrence_rate = mag_occ_rate / float(len(rupture_slices)) for rupture_slice in rupture_slices[self.start:self.stop]: mesh = whole_fault_mesh[rupture_slice] # XXX: use surface centroid as rupture's hypocenter # XXX: instead of point with middle index hypocenter = mesh.get_middle_point() try: surface = ComplexFaultSurface(mesh) except ValueError as e: raise ValueError("Invalid source with id=%s. %s" % ( self.source_id, str(e))) yield ParametricProbabilisticRupture( mag, self.rake, self.tectonic_region_type, hypocenter, surface, occurrence_rate, self.temporal_occurrence_model)
def modify_set_geometry(self, edges, spacing): """ Modifies the complex fault geometry """ ComplexFaultSurface.check_fault_data(edges, spacing) self.edges = edges self.rupture_mesh_spacing = spacing
def __init__( self, source_id, name, tectonic_region_type, mfd, rupture_mesh_spacing, magnitude_scaling_relationship, rupture_aspect_ratio, temporal_occurrence_model, # complex fault specific parameters edges, rake, ): super(ComplexFaultSource, 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) ComplexFaultSurface.check_fault_data(edges, rupture_mesh_spacing) self.edges = edges self.rake = rake
def test_mesh_spacing_more_than_two_widthss(self): edge1 = Line([Point(0, 0, 0), Point(0, 0.2, 0)]) edge2 = Line([Point(0, 0, 10), Point(0, 0.2, 20)]) with self.assertRaises(ValueError) as ar: ComplexFaultSurface.from_fault_data([edge1, edge2], mesh_spacing=30.1) self.assertEqual( str(ar.exception), 'mesh spacing 30.1 km is too big for mean width 15.0 km')
def test_mesh_spacing_more_than_two_widthss(self): edge1 = Line([Point(0, 0, 0), Point(0, 0.2, 0)]) edge2 = Line([Point(0, 0, 10), Point(0, 0.2, 20)]) with self.assertRaises(ValueError) as ar: ComplexFaultSurface.from_fault_data([edge1, edge2], mesh_spacing=30.1) self.assertEqual( str(ar.exception), 'mesh spacing 30.1 km is too big for mean width 15.0 km' )
def test_invalid_surface_polygon_topo(self): # intermediate edge has opposite strike than top and bottom edges = [ Line([Point(0, 0, -5), Point(0, 2, -5)]), Line([Point(0, 2, 5), Point(0, 0, 5)]) ] with self.assertRaises(ValueError) as cm: ComplexFaultSurface.from_fault_data(edges, mesh_spacing=1) self.assertEqual('Edges points are not in the right order', str(cm.exception))
def test_invalid_surface_polygon_case2(self): # inclined complex fault with top and bottom edges inverted edges = [ Line([Point(0, 0), Point(0, 2)]), Line([Point(0.2, 2, 10), Point(0.6, 0, 10)]) ] with self.assertRaises(ValueError) as cm: ComplexFaultSurface.from_fault_data(edges, mesh_spacing=10) self.assertEqual('Edges points are not in the right order', str(cm.exception))
def test_invalid_surface_polygon_case2(self): # inclined complex fault with top and bottom edges inverted edges = [Line([Point(0, 0), Point(0, 2)]), Line([Point(0.2, 2, 10), Point(0.6, 0, 10)])] with self.assertRaises(ValueError) as cm: ComplexFaultSurface.from_fault_data(edges, mesh_spacing=10) self.assertEqual( 'Edges points are not in the right order', str(cm.exception) )
def test_invalid_surface_polygon_topo(self): # intermediate edge has opposite strike than top and bottom edges = [Line([Point(0, 0, -5), Point(0, 2, -5)]), Line([Point(0, 2, 5), Point(0, 0, 5)])] with self.assertRaises(ValueError) as cm: ComplexFaultSurface.from_fault_data(edges, mesh_spacing=1) self.assertEqual( 'Edges points are not in the right order', str(cm.exception) )
def test_dip_left_of_fault_strike_topo(self): # when the fault is above sea level edges = [ Line([Point(0, 1, -1), Point(0, 0, -1)]), Line([Point(1, 1, 0), Point(1, 0, 0)]) ] with self.assertRaises(ValueError) as cm: ComplexFaultSurface.from_fault_data(edges, mesh_spacing=1) self.assertEqual( 'Surface does not conform with Aki & Richards convention', str(cm.exception))
def __init__(self, source_id, name, tectonic_region_type, mfd, rupture_mesh_spacing, magnitude_scaling_relationship, rupture_aspect_ratio, temporal_occurrence_model, # complex fault specific parameters edges, rake): super().__init__( source_id, name, tectonic_region_type, mfd, rupture_mesh_spacing, magnitude_scaling_relationship, rupture_aspect_ratio, temporal_occurrence_model) NodalPlane.check_rake(rake) ComplexFaultSurface.check_fault_data(edges, rupture_mesh_spacing) self.edges = edges self.rake = rake
def test_dip_left_of_fault_strike_case1(self): # checks that an error is raised when fault surface dips left of # fault strike (i.e. does not obey to Aki & Richards convention) # simple case of planar surface with strike 0 (pointing towards # north) but with surface dipping to the west edges = [Line([Point(0, 0), Point(0, 1)]), Line([Point(-1, 0, 10), Point(-1, 1, 10)])] with self.assertRaises(ValueError) as cm: ComplexFaultSurface.from_fault_data(edges, mesh_spacing=10) self.assertEqual( 'Surface does not conform with Aki & Richards convention', str(cm.exception) )
def test_2(self): # this is a regression test. Reference values have been obtained # by extracting mesh from complex surface. edge1 = Line([Point(0, 0, 1), Point(0, 0.02, 1)]) edge2 = Line([Point(0.02, 0, 1.5), Point(0.02, 0.01, 1.5)]) edge3 = Line([Point(0, 0, 2), Point(0, 0.02, 2)]) surface = ComplexFaultSurface.from_fault_data([edge1, edge2, edge3], mesh_spacing=1) self.assert_mesh_is(surface=surface, expected_mesh=[ [(0.0, 0.0, 1.0), (0.0, 0.01, 1.0), (0.0, 0.02, 1.0)], [(0.008, 0.0, 1.2), (0.008, 0.008, 1.2), (0.008, 0.016, 1.2)], [(0.016, 0.0, 1.4), (0.016, 0.006, 1.4), (0.016, 0.012, 1.4)], [(0.016, 0.0, 1.6), (0.016, 0.006, 1.6), (0.016, 0.012, 1.6)], [(0.008, 0, 1.8), (0.008, 0.008, 1.8), (0.008, 0.016, 1.8)], [(0.0, 0.0, 2.0), (0.0, 0.01, 2.0), (0.0, 0.02, 2.0)], ])
def test_2(self): edge1 = Line([Point(0, 0, 1), Point(0, 0.02, 1)]) edge2 = Line([Point(0.02, 0, 0.5), Point(0.02, 0.01, 0.5)]) edge3 = Line([Point(0, 0, 2), Point(0, 0.02, 2)]) surface = ComplexFaultSurface.from_fault_data([edge1, edge2, edge3], mesh_spacing=1) self.assert_mesh_is(surface=surface, expected_mesh=[ [(0.00000000e+00, 0.00000000e+00, 1.00000000e+00), (0.00000000e+00, 1.00000000e-02, 1.00000000e+00), (0.00000000e+00, 2.00000000e-02, 1.00000000e+00)], [(8.70732572e-03, 5.33152318e-19, 7.82316857e-01), (8.67044753e-03, 7.83238825e-03, 7.83238813e-01), (8.57984833e-03, 1.57100762e-02, 7.85503798e-01)], [(1.74146514e-02, 1.06630462e-18, 5.64633714e-01), (1.73408950e-02, 5.66477632e-03, 5.66477626e-01), (1.71596963e-02, 1.14201520e-02, 5.71007595e-01)], [(1.47979150e-02, 3.18525318e-19, 8.90156376e-01), (1.48515919e-02, 6.28710212e-03, 8.86130608e-01), (1.49871315e-02, 1.25064345e-02, 8.75965152e-01)], [(7.39895749e-03, 7.71565830e-19, 1.44507819e+00), (7.42579599e-03, 8.14355113e-03, 1.44306530e+00), (7.49356586e-03, 1.62532174e-02, 1.43798258e+00)], [(0.00000000e+00, 0.00000000e+00, 2.00000000e+00), (0.00000000e+00, 1.00000000e-02, 2.00000000e+00), (0.00000000e+00, 2.00000000e-02, 2.00000000e+00)], ])
def test_2(self): edge1 = Line([Point(0, 0, 1), Point(0, 0.02, 1)]) edge2 = Line([Point(0.02, 0, 0.5), Point(0.02, 0.01, 0.5)]) edge3 = Line([Point(0, 0, 2), Point(0, 0.02, 2)]) surface = ComplexFaultSurface.from_fault_data([edge1, edge2, edge3], mesh_spacing=1) self.assert_mesh_is( surface=surface, expected_mesh=[ [(0.00000000e+00, 0.00000000e+00, 1.00000000e+00), (0.00000000e+00, 1.00000000e-02, 1.00000000e+00), (0.00000000e+00, 2.00000000e-02, 1.00000000e+00)], [(8.70732572e-03, 5.33152318e-19, 7.82316857e-01), (8.67044753e-03, 7.83238825e-03, 7.83238813e-01), (8.57984833e-03, 1.57100762e-02, 7.85503798e-01)], [(1.74146514e-02, 1.06630462e-18, 5.64633714e-01), (1.73408950e-02, 5.66477632e-03, 5.66477626e-01), (1.71596963e-02, 1.14201520e-02, 5.71007595e-01)], [(1.47979150e-02, 3.18525318e-19, 8.90156376e-01), (1.48515919e-02, 6.28710212e-03, 8.86130608e-01), (1.49871315e-02, 1.25064345e-02, 8.75965152e-01)], [(7.39895749e-03, 7.71565830e-19, 1.44507819e+00), (7.42579599e-03, 8.14355113e-03, 1.44306530e+00), (7.49356586e-03, 1.62532174e-02, 1.43798258e+00)], [(0.00000000e+00, 0.00000000e+00, 2.00000000e+00), (0.00000000e+00, 1.00000000e-02, 2.00000000e+00), (0.00000000e+00, 2.00000000e-02, 2.00000000e+00)], ])
def test(self): edges = [Line([Point(-3.4, 5.5, 0), Point(-3.9, 5.3, 0)]), Line([Point(-2.4, 4.6, 10), Point(-3.6, 4.9, 20)])] polygon = ComplexFaultSurface.surface_projection_from_fault_data(edges) elons = [-2.4, -3.6, -3.9, -3.4] elats = [4.6, 4.9, 5.3, 5.5] numpy.testing.assert_allclose(polygon.lons, elons) numpy.testing.assert_allclose(polygon.lats, elats)
def test_surface_with_variable_width(self): edges = [Line([Point(0.1, 0.1, 0), Point(0.459729190252, 0.0999980290582, 0.0), Point(0.819458380482, 0.0999960581553, 0.0)]), Line([Point(0.1, 0.1, 20.0), Point(0.459729190252, 0.0999980290582, 20.0), Point(0.819458380482, 0.0999960581553, 43.0940107676)])] surface = ComplexFaultSurface.from_fault_data(edges, mesh_spacing=5.0) self.assertAlmostEqual(surface.get_width(), 26.0, places=0)
def test_surface_crossing_international_date_line(self): edge1 = Line([Point(179.95, 0., 0.), Point(-179.95, 0., 0.)]) edge2 = Line([Point(179.95, 0., 10.), Point(-179.95, 0., 10.)]) surface = ComplexFaultSurface.from_fault_data([edge1, edge2], mesh_spacing=10.) self.assert_mesh_is(surface=surface, expected_mesh=[ [(179.95, 0., 0.), (-179.95, 0., 0.)], [(179.95, 0., 10.), (-179.95, 0., 10.)] ])
def test_dip_left_of_fault_strike_topo(self): # when the fault is above sea level edges = [ Line([ Point(0, 1, -1), Point(0, 0, -1) ]), Line([ Point(1, 1, 0), Point(1, 0, 0)] )] with self.assertRaises(ValueError) as cm: ComplexFaultSurface.from_fault_data(edges, mesh_spacing=1) self.assertEqual( 'Surface does not conform with Aki & Richards convention', str(cm.exception) )
def test_dip_90_three_points(self): edges = [Line([Point(1, -20, 30), Point(1, -20.2, 30), Point(2, -19.7, 30)]), Line([Point(1, -20, 50), Point(1, -20.2, 50), Point(2, -19.7, 50)])] polygon = ComplexFaultSurface.surface_projection_from_fault_data(edges) 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_dip_90_two_points(self): edges = [Line([Point(2, 2, 10), Point(1, 1, 10)]), Line([Point(2, 2, 20), Point(1, 1, 20)])] polygon = ComplexFaultSurface.surface_projection_from_fault_data(edges) 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_dip_90_self_intersection(self): edges = [Line([Point(1, -2, 10), Point(2, -1.9, 10), Point(3, -2.1, 10), Point(4, -2, 10)]), Line([Point(1, -2, 20), Point(2, -1.9, 20), Point(3, -2.1, 20), Point(4, -2, 20)])] polygon = ComplexFaultSurface.surface_projection_from_fault_data(edges) 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_edges_with_nonuniform_length(self): edges = [Line([Point(1, -20, 30), Point(1, -20.2, 30), Point(2, -19.7, 30), Point(3, -19.5, 30)]), Line([Point(1, -20, 50), Point(1, -20.2, 50), Point(2, -19.7, 50)])] polygon = ComplexFaultSurface.surface_projection_from_fault_data(edges) elons = [1, 1, 2, 3] elats = [-20.2, -20., -19.7, -19.5] numpy.testing.assert_allclose(polygon.lons, elons) numpy.testing.assert_allclose(polygon.lats, elats)
def test_dip_left_of_fault_strike_case2(self): # real example taken from wrong fault for japan model # ('Kanto earthquake') edges = [ Line([ Point(139.268, 35.3649682834, 10.6), Point(139.579014512, 35.1780000001, 10.6) ]), Line([ Point(139.541937161, 35.378, 19.5999999911), Point(139.867999999, 35.2135133354, 19.6000000095)] )] with self.assertRaises(ValueError) as cm: ComplexFaultSurface.from_fault_data(edges, mesh_spacing=10) self.assertEqual( 'Surface does not conform with Aki & Richards convention', str(cm.exception) )
def test_dip_left_of_fault_strike_case2(self): # real example taken from wrong fault for japan model # ('Kanto earthquake') edges = [ Line([ Point(139.268, 35.3649682834, 10.6), Point(139.579014512, 35.1780000001, 10.6) ]), Line([ Point(139.541937161, 35.378, 19.5999999911), Point(139.867999999, 35.2135133354, 19.6000000095) ]) ] with self.assertRaises(ValueError) as cm: ComplexFaultSurface.from_fault_data(edges, mesh_spacing=10) self.assertEqual( 'Surface does not conform with Aki & Richards convention', str(cm.exception))
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] """ # The mesh spacing is hardcoded to guarantee stability in the values # computed sfc = ComplexFaultSurface.from_fault_data(self.edges, 2.0) return sfc.get_area()
def __init__(self, id, trt, mag=5.0, rake=90.): hypocenter = Point(17.788328, -77.219496, 7.8125) lons = numpy.array( [-78.18106621, -78.18013243, -78.17919864, -78.15399318, -78.15305962, -78.15212606]) lats = numpy.array( [15.615, 15.615, 15.615, 15.56553731, 15.56553731, 15.56553731]) surface = ComplexFaultSurface(Mesh(lons, lats, None)) self.rupture = Rupture(mag, rake, trt, hypocenter, surface, ComplexFaultSource) self.id = id
def test_1(self): edge1 = Line([Point(0, 0), Point(0.03, 0)]) edge2 = Line([Point(0, 0, 2.224), Point(0.03, 0, 2.224)]) surface = ComplexFaultSurface.from_fault_data([edge1, edge2], mesh_spacing=1.112) self.assertIsInstance(surface, ComplexFaultSurface) self.assert_mesh_is(surface=surface, expected_mesh=[ [(0, 0, 0), (0.01, 0, 0), (0.02, 0, 0), (0.03, 0, 0)], [(0, 0, 1.112), (0.01, 0, 1.112), (0.02, 0, 1.112), (0.03, 0, 1.112)], [(0, 0, 2.224), (0.01, 0, 2.224), (0.02, 0, 2.224), (0.03, 0, 2.224)], ])
def __init__(self, id, trt, mag=5.0, rake=90.): self.hypocenter = Point(17.788328, -77.219496, 7.8125) lons = numpy.array( [-78.18106621, -78.18013243, -78.17919864, -78.15399318, -78.15305962, -78.15212606]) lats = numpy.array( [15.615, 15.615, 15.615, 15.56553731, 15.56553731, 15.56553731]) self.surface = ComplexFaultSurface(Mesh(lons, lats, None)) self.mag = mag self.rake = rake self.id = id self.site_indices = None
def count_ruptures(self): """ See :meth: `openquake.hazardlib.source.base.BaseSeismicSource.count_ruptures`. """ whole_fault_surface = ComplexFaultSurface.from_fault_data(self.edges, self.rupture_mesh_spacing) whole_fault_mesh = whole_fault_surface.get_mesh() cell_center, cell_length, cell_width, cell_area = whole_fault_mesh.get_cell_dimensions() counts = 0 for (mag, mag_occ_rate) in self.get_annual_occurrence_rates(): rupture_area = self.magnitude_scaling_relationship.get_median_area(mag, self.rake) rupture_length = numpy.sqrt(rupture_area * self.rupture_aspect_ratio) rupture_slices = _float_ruptures(rupture_area, rupture_length, cell_area, cell_length) counts += len(rupture_slices) return counts
def get_rupture_enclosing_polygon(self, dilation=0): """ Uses :meth:`openquake.hazardlib.geo.surface.complex_fault.ComplexFaultSurface.surface_projection_from_fault_data` for getting the fault's surface projection and then calls its :meth:`~openquake.hazardlib.geo.polygon.Polygon.dilate` method passing in ``dilation`` parameter. See :meth:`superclass method <openquake.hazardlib.source.base.BaseSeismicSource.get_rupture_enclosing_polygon>` for parameter and return value definition. """ polygon = ComplexFaultSurface.surface_projection_from_fault_data(self.edges) if dilation: return polygon.dilate(dilation) else: return polygon
def get_rupture_enclosing_polygon(self, dilation=0): """ Uses :meth:`openquake.hazardlib.geo.surface.complex_fault.ComplexFaultSurface.surface_projection_from_fault_data` for getting the fault's surface projection and then calls its :meth:`~openquake.hazardlib.geo.polygon.Polygon.dilate` method passing in ``dilation`` parameter. See :meth:`superclass method <openquake.hazardlib.source.base.BaseSeismicSource.get_rupture_enclosing_polygon>` for parameter and return value definition. """ polygon = ComplexFaultSurface.surface_projection_from_fault_data( self.edges) if dilation: return polygon.dilate(dilation) else: return polygon
def __init__(self, traces, mesh_spacing=1.0): ''' Set up function an creates complex fault surface :param list traces: Edges of the complex fault as a list of :class: openquake.hazardlib.geo.line.Line. Please refer to documentation of openquake.hazardlib.geo.surface.complex_fault.ComplexFaultSurface for details. :param float mesh_spacing: Spacing (km) of the fault surface mesh ''' self.typology = 'Complex' self.trace = traces self.upper_depth = None self.lower_depth = None self.surface = ComplexFaultSurface.from_fault_data(self.trace, mesh_spacing) self.dip = self.surface.get_dip()
def __init__(self, traces, mesh_spacing=1.0): ''' Set up function an creates complex fault surface :param list traces: Edges of the complex fault as a list of :class: openquake.hazardlib.geo.line.Line. Please refer to documentation of openquake.hazardlib.geo.surface.complex_fault.ComplexFaultSurface for details. :param float mesh_spacing: Spacing (km) of the fault surface mesh ''' self.typology = 'Complex' self.trace = traces self.upper_depth = None self.lower_depth = None self.surface = ComplexFaultSurface.from_fault_data( self.trace, mesh_spacing) self.dip = self.surface.get_dip()
def iter_ruptures(self): """ See :meth: `openquake.hazardlib.source.base.BaseSeismicSource.iter_ruptures`. Uses :func:`_float_ruptures` for finding possible rupture locations on the whole fault surface. """ whole_fault_surface = ComplexFaultSurface.from_fault_data( self.edges, self.rupture_mesh_spacing ) whole_fault_mesh = whole_fault_surface.get_mesh() cell_center, cell_length, cell_width, cell_area = ( whole_fault_mesh.get_cell_dimensions() ) for (mag, mag_occ_rate) in self.get_annual_occurrence_rates(): rupture_area = self.magnitude_scaling_relationship.get_median_area( mag, self.rake ) rupture_length = numpy.sqrt( rupture_area * self.rupture_aspect_ratio) rupture_slices = _float_ruptures( rupture_area, rupture_length, cell_area, cell_length ) occurrence_rate = mag_occ_rate / float(len(rupture_slices)) for rupture_slice in rupture_slices[self.start:self.stop]: mesh = whole_fault_mesh[rupture_slice] # XXX: use surface centroid as rupture's hypocenter # XXX: instead of point with middle index hypocenter = mesh.get_middle_point() try: surface = ComplexFaultSurface(mesh) except ValueError as e: raise ValueError("Invalid source with id=%s. %s" % ( self.source_id, str(e))) yield ParametricProbabilisticRupture( mag, self.rake, self.tectonic_region_type, hypocenter, surface, type(self), occurrence_rate, self.temporal_occurrence_model )
def count_ruptures(self): """ See :meth: `openquake.hazardlib.source.base.BaseSeismicSource.count_ruptures`. """ whole_fault_surface = ComplexFaultSurface.from_fault_data( self.edges, self.rupture_mesh_spacing) whole_fault_mesh = whole_fault_surface.get_mesh() cell_center, cell_length, cell_width, cell_area = ( whole_fault_mesh.get_cell_dimensions()) counts = 0 for (mag, mag_occ_rate) in self.get_annual_occurrence_rates(): rupture_area = self.magnitude_scaling_relationship.get_median_area( mag, self.rake) rupture_length = numpy.sqrt(rupture_area * self.rupture_aspect_ratio) rupture_slices = _float_ruptures(rupture_area, rupture_length, cell_area, cell_length) counts += len(rupture_slices[self.start:self.stop]) return counts
def create_geometry(self, input_geometry, mesh_spacing=1.0): ''' If geometry is defined as a numpy array then create instance of nhlib.geo.line.Line class, otherwise if already instance of class accept class :param input_geometry: List of at least two fault edges of the fault source from shallowest to deepest. Each edge can be represented as as either i) instance of nhlib.geo.polygon.Polygon class ii) numpy.ndarray [Longitude, Latitude, Depth] :param float mesh_spacing: Spacing of the fault mesh (km) {default = 1.0} ''' if not isinstance(input_geometry, list) or len(input_geometry) < 2: raise ValueError('Complex fault geometry incorrectly defined') self.fault_edges = [] for edge in input_geometry: if not isinstance(edge, Line): if not isinstance(edge, np.ndarray): raise ValueError('Unrecognised or unsupported geometry ' 'definition') else: self.fault_edges.append(Line([Point(row[0], row[1], row[2]) for row in edge])) else: self.fault_edges.append(edge) # Updates the upper and lower sesmogenic depths to reflect geometry self._get_minmax_edges(edge) # Build fault surface self.geometry = ComplexFaultSurface.from_fault_data(self.fault_edges, mesh_spacing) # Get a mean dip self.dip = self.geometry.get_dip()
def create_geometry(self, input_geometry, mesh_spacing=1.0): ''' If geometry is defined as a numpy array then create instance of nhlib.geo.line.Line class, otherwise if already instance of class accept class :param input_geometry: List of at least two fault edges of the fault source from shallowest to deepest. Each edge can be represented as as either i) instance of nhlib.geo.polygon.Polygon class ii) numpy.ndarray [Longitude, Latitude, Depth] :param float mesh_spacing: Spacing of the fault mesh (km) {default = 1.0} ''' if not isinstance(input_geometry, list) or len(input_geometry) < 2: raise ValueError('Complex fault geometry incorrectly defined') self.fault_edges = [] for edge in input_geometry: if not isinstance(edge, Line): if not isinstance(edge, np.ndarray): raise ValueError('Unrecognised or unsupported geometry ' 'definition') else: self.fault_edges.append( Line([Point(row[0], row[1], row[2]) for row in edge])) else: self.fault_edges.append(edge) # Updates the upper and lower sesmogenic depths to reflect geometry self._get_minmax_edges(edge) # Build fault surface self.geometry = ComplexFaultSurface.from_fault_data( self.fault_edges, mesh_spacing) # Get a mean dip self.dip = self.geometry.get_dip()
def polygon(self): """ The underlying polygon `""" return ComplexFaultSurface.surface_projection_from_fault_data( self.edges)