def parse_planar_surface(rupture): """ """ mag = Node("magnitude", text=rupture["magnitude"]) rake = Node("rake", text=rupture["rake"]) top_left = Point(float(rupture.planarSurface.topLeft["lon"]), float(rupture.planarSurface.topLeft["lat"]), float(rupture.planarSurface.topLeft["depth"])) top_right = Point(float(rupture.planarSurface.topRight["lon"]), float(rupture.planarSurface.topRight["lat"]), float(rupture.planarSurface.topRight["depth"])) bottom_left = Point(float(rupture.planarSurface.bottomLeft["lon"]), float(rupture.planarSurface.bottomLeft["lat"]), float(rupture.planarSurface.bottomLeft["depth"])) bottom_right = Point(float(rupture.planarSurface.bottomRight["lon"]), float(rupture.planarSurface.bottomRight["lat"]), float(rupture.planarSurface.bottomRight["depth"])) planar_surface = PlanarSurface(1.0, float(rupture["strike"]), float(rupture["dip"]), top_left, top_right, bottom_right, bottom_left) hypocentre = planar_surface.get_middle_point() hypo = Node("hypocenter", { "lon": str(hypocentre.longitude), "lat": str(hypocentre.latitude), "depth": str(hypocentre.depth)}) surface = Node("planarSurface", {"strike": rupture["strike"], "dip": rupture["dip"]}, nodes=rupture.planarSurface.nodes) return Node("singlePlaneRupture", nodes=[mag, rake, hypo, surface])
def test_middle_point_multi_surfaces(self): surf = MultiSurface([ PlanarSurface(1.0, 0.0, 90.0, Point(0.0, -1.0, 0.0), Point(0.0, 1.0, 0.0), Point(0.0, 1.0, 10.0), Point(0.0, -1.0, 10.0)), PlanarSurface(1.0, 135.0, 90.0, Point(0.0, -1.0, 0.0), Point(1.0, 1.0, 0.0), Point(1.0, 1.0, 10.0), Point(0.0, -1.0, 10.0)) ]) middle_point = surf.get_middle_point() self.assertTrue(Point(0.5, 0.0, 5.0) == middle_point)
def planar_fault_surface_from_dict(data, mesh_spacing=1.): """ Builds a planar fault surface from the json load """ assert "PlanarSurface" in data top_left = Point(data["top_left"][0], data["top_left"][1], data["top_left"][2]) top_right = Point(data["top_right"][0], data["top_right"][1], data["top_right"][2]) bottom_left = Point(data["bottom_left"][0], data["bottom_left"][1], data["bottom_left"][2]) bottom_right = Point(data["bottom_right"][0], data["bottom_right"][1], data["bottom_right"][2]) return PlanarSurface.from_corner_points(mesh_spacing, top_left, top_right, bottom_right, bottom_left)
def _make_rupture(self, width, length, dip): mid_left = self.hypocenter.point_at(length / 2.0, 0, azimuth=270) mid_right = self.hypocenter.point_at(length / 2.0, 0, azimuth=90) hwidth = width * numpy.cos(numpy.radians(dip)) / 2.0 vwidth = width * numpy.sin(numpy.radians(dip)) / 2.0 top_left = mid_left.point_at(hwidth, -vwidth, azimuth=0) bottom_left = mid_left.point_at(hwidth, vwidth, azimuth=180) top_right = mid_right.point_at(hwidth, -vwidth, azimuth=0) bottom_right = mid_right.point_at(hwidth, vwidth, azimuth=180) surface = PlanarSurface(1, 2, dip, top_left, top_right, bottom_right, bottom_left) rupture = ParametricProbabilisticRupture( mag=1, rake=2, tectonic_region_type=TRT.VOLCANIC, hypocenter=self.hypocenter, surface=surface, source_typology=PointSource, occurrence_rate=3, temporal_occurrence_model=PoissonTOM(1) ) return rupture
def create_planar_surface(top_centroid, strike, dip, area, aspect): """ Given a central location, create a simple planar rupture :param top_centroid: Centroid of trace of the rupture, as instance of :class: openquake.hazardlib.geo.point.Point :param float strike: Strike of rupture(Degrees) :param float dip: Dip of rupture (degrees) :param float area: Area of rupture (km^2) :param float aspect: Aspect ratio of rupture :returns: Rupture as an instance of the :class: openquake.hazardlib.geo.surface.planar.PlanarSurface """ rad_dip = dip * pi / 180. width = sqrt(area / aspect) length = aspect * width # Get end points by moving the top_centroid along strike top_right = top_centroid.point_at(length / 2., 0., strike) top_left = top_centroid.point_at(length / 2., 0., (strike + 180.) % 360.) # Along surface width surface_width = width * cos(rad_dip) vertical_depth = width * sin(rad_dip) dip_direction = (strike + 90.) % 360. bottom_right = top_right.point_at(surface_width, vertical_depth, dip_direction) bottom_left = top_left.point_at(surface_width, vertical_depth, dip_direction) # Create the rupture return PlanarSurface(strike, dip, top_left, top_right, bottom_right, bottom_left)
def _setup_peer_test_bending_fault_config(): """ The GC2 tests will be based on variations of the PEER bending fault test case: (Fault is dipping east north east Point 5 (-65.0, 0.0, 0.0) o | | | o Point 4 (-65.0, -0.16188, 0) \ \ \ \ \ o Point 3 (-64.90498, -0.36564, 0.0) \__ \__ \__ \__ \__Point 2 (-64.80164, -0.45236, 0.0) \o---o Point 1 (-64.78365, -0.45236, 0.0) """ # Build separate faults # Get down-dip points - dipping east-noth-east strike1 = PNT1.azimuth(PNT2) dipdir1 = (strike1 + 90.) % 360.0 strike2 = PNT2.azimuth(PNT3) dipdir2 = (strike2 + 90.) % 360.0 strike3 = PNT3.azimuth(PNT4) dipdir3 = (strike3 + 90.) % 360.0 strike4 = PNT4.azimuth(PNT5) dipdir4 = (strike4 + 90.) % 360.0 global_strike = PNT1.azimuth(PNT5) global_dipdir = (global_strike + 90.) % 360.0 # Get lower trace usd = 0.0 lsd = 12.0 dip = 60.0 as_length = lsd / numpy.tan(numpy.radians(dip)) PNT1b = PNT1.point_at(as_length, lsd, global_dipdir) PNT2b = PNT2.point_at(as_length, lsd, global_dipdir) PNT3b = PNT3.point_at(as_length, lsd, global_dipdir) PNT4b = PNT4.point_at(as_length, lsd, global_dipdir) PNT5b = PNT5.point_at(as_length, lsd, global_dipdir) # As simple fault dipping east mesh_spacing = 0.5 simple_fault1 = SimpleFaultSurface.from_fault_data( Line([PNT1, PNT2, PNT3, PNT4, PNT5]), usd, lsd, dip, mesh_spacing) # As a set of planes describing a concordant "Stirling fault" stirling_planes = [ PlanarSurface.from_corner_points(PNT1, PNT2, PNT2b, PNT1b), PlanarSurface.from_corner_points(PNT2, PNT3, PNT3b, PNT2b), PlanarSurface.from_corner_points(PNT3, PNT4, PNT4b, PNT3b), PlanarSurface.from_corner_points(PNT4, PNT5, PNT5b, PNT4b) ] stirling_fault1 = MultiSurface(stirling_planes) # As a set of planes describing a concordant "Frankel Fault" # In the Frankel fault each segment is projected to the local dip direction dipdir2b = (dipdir2 + 180.) % 360.0 frankel_planes = [ PlanarSurface.from_corner_points( PNT1, PNT2, PNT2.point_at(as_length, lsd, dipdir1), PNT1.point_at(as_length, lsd, dipdir1)), PlanarSurface.from_corner_points( PNT2, PNT3, PNT3.point_at(as_length, lsd, dipdir2), PNT2.point_at(as_length, lsd, dipdir2)), PlanarSurface.from_corner_points( PNT3, PNT4, PNT4.point_at(as_length, lsd, dipdir3), PNT3.point_at(as_length, lsd, dipdir3)), PlanarSurface.from_corner_points( PNT4, PNT5, PNT5.point_at(as_length, lsd, dipdir4), PNT4.point_at(as_length, lsd, dipdir4)) ] frankel_fault1 = MultiSurface(frankel_planes) # Test the case of a discordant Frankel plane # Swapping the strike of the second segment to change the dip direction # Also increasing the dip from 60 degrees to 75 degrees as_length_alt = lsd / numpy.tan(numpy.radians(75.0)) frankel_discordant = [ PlanarSurface.from_corner_points( PNT1, PNT2, PNT2.point_at(as_length, lsd, dipdir1), PNT1.point_at(as_length, lsd, dipdir1)), PlanarSurface.from_corner_points( PNT3, PNT2, PNT2.point_at(as_length_alt, lsd, dipdir2b), PNT3.point_at(as_length_alt, lsd, dipdir2b)), PlanarSurface.from_corner_points( PNT3, PNT4, PNT4.point_at(as_length, lsd, dipdir3), PNT3.point_at(as_length, lsd, dipdir3)), PlanarSurface.from_corner_points( PNT4, PNT5, PNT5.point_at(as_length, lsd, dipdir4), PNT4.point_at(as_length, lsd, dipdir4)) ] frankel_fault2 = MultiSurface(frankel_discordant) return simple_fault1, stirling_fault1, frankel_fault1, frankel_fault2
def _setup_peer_test_bending_fault_config(): """ The GC2 tests will be based on variations of the PEER bending fault test case: (Fault is dipping east north east Point 5 (-65.0, 0.0, 0.0) o | | | o Point 4 (-65.0, -0.16188, 0) \ \ \ \ \ o Point 3 (-64.90498, -0.36564, 0.0) \__ \__ \__ \__ \__Point 2 (-64.80164, -0.45236, 0.0) \o---o Point 1 (-64.78365, -0.45236, 0.0) """ # Build separate faults # Get down-dip points - dipping east-noth-east strike1 = PNT1.azimuth(PNT2) dipdir1 = (strike1 + 90.) % 360.0 strike2 = PNT2.azimuth(PNT3) dipdir2 = (strike2 + 90.) % 360.0 strike3 = PNT3.azimuth(PNT4) dipdir3 = (strike3 + 90.) % 360.0 strike4 = PNT4.azimuth(PNT5) dipdir4 = (strike4 + 90.) % 360.0 global_strike = PNT1.azimuth(PNT5) global_dipdir = (global_strike + 90.) % 360.0 # Get lower trace usd = 0.0 lsd = 12.0 dip = 60.0 as_length = lsd / numpy.tan(numpy.radians(dip)) PNT1b = PNT1.point_at(as_length, lsd, global_dipdir) PNT2b = PNT2.point_at(as_length, lsd, global_dipdir) PNT3b = PNT3.point_at(as_length, lsd, global_dipdir) PNT4b = PNT4.point_at(as_length, lsd, global_dipdir) PNT5b = PNT5.point_at(as_length, lsd, global_dipdir) # As simple fault dipping east mesh_spacing = 0.5 simple_fault1 = SimpleFaultSurface.from_fault_data( Line([PNT1, PNT2, PNT3, PNT4, PNT5]), usd, lsd, dip, mesh_spacing) # As a set of planes describing a concordant "Stirling fault" stirling_planes = [ PlanarSurface.from_corner_points(1.0, PNT1, PNT2, PNT2b, PNT1b), PlanarSurface.from_corner_points(1.0, PNT2, PNT3, PNT3b, PNT2b), PlanarSurface.from_corner_points(1.0, PNT3, PNT4, PNT4b, PNT3b), PlanarSurface.from_corner_points(1.0, PNT4, PNT5, PNT5b, PNT4b) ] stirling_fault1 = MultiSurface(stirling_planes) # As a set of planes describing a concordant "Frankel Fault" # In the Frankel fault each segment is projected to the local dip direction dipdir2b = (dipdir2 + 180.) % 360.0 frankel_planes = [ PlanarSurface.from_corner_points( 1.0, PNT1, PNT2, PNT2.point_at(as_length, lsd, dipdir1), PNT1.point_at(as_length, lsd, dipdir1) ), PlanarSurface.from_corner_points( 1.0, PNT2, PNT3, PNT3.point_at(as_length, lsd, dipdir2), PNT2.point_at(as_length, lsd, dipdir2) ), PlanarSurface.from_corner_points( 1.0, PNT3, PNT4, PNT4.point_at(as_length, lsd, dipdir3), PNT3.point_at(as_length, lsd, dipdir3) ), PlanarSurface.from_corner_points( 1.0, PNT4, PNT5, PNT5.point_at(as_length, lsd, dipdir4), PNT4.point_at(as_length, lsd, dipdir4) ) ] frankel_fault1 = MultiSurface(frankel_planes) # Test the case of a discordant Frankel plane # Swapping the strike of the second segment to change the dip direction # Also increasing the dip from 60 degrees to 75 degrees as_length_alt = lsd / numpy.tan(numpy.radians(75.0)) frankel_discordant = [ PlanarSurface.from_corner_points( 1.0, PNT1, PNT2, PNT2.point_at(as_length, lsd, dipdir1), PNT1.point_at(as_length, lsd, dipdir1) ), PlanarSurface.from_corner_points( 1.0, PNT3, PNT2, PNT2.point_at(as_length_alt, lsd, dipdir2b), PNT3.point_at(as_length_alt, lsd, dipdir2b) ), PlanarSurface.from_corner_points( 1.0, PNT3, PNT4, PNT4.point_at(as_length, lsd, dipdir3), PNT3.point_at(as_length, lsd, dipdir3) ), PlanarSurface.from_corner_points( 1.0, PNT4, PNT5, PNT5.point_at(as_length, lsd, dipdir4), PNT4.point_at(as_length, lsd, dipdir4) ) ] frankel_fault2 = MultiSurface(frankel_discordant) return simple_fault1, stirling_fault1, frankel_fault1, frankel_fault2
def build_ruptures(self, centroid, strikes, dips, lengths, widths, hypo_locs): """ Builds the rupture set """ ruptures = [] rstrikes = strikes * np.pi / 180. rdips = dips * np.pi / 180. for (strike, rstrike, dip, rdip, length, width, hypo_loc) in zip(strikes, rstrikes, dips, rdips, lengths, widths, hypo_locs): # Deal with the dip part first area = length * width updip_width = hypo_loc[1] * width downdip_width = (1.0 - hypo_loc[1]) * width updip_depth_change = updip_width * np.sin(rdip) downdip_depth_change = downdip_width * np.sin(rdip) if centroid.depth < updip_depth_change: # This would move the rupture above the top surface # readjust offset = updip_depth_change - centroid.depth updip_depth_change = centroid.depth downdip_depth_change += offset if downdip_depth_change > (self.lsd - centroid.depth): if (updip_depth_change + downdip_depth_change) >\ self.thickness: # Determine excess width offset = (centroid.depth + downdip_depth_change) - self.lsd offset_area = length * (offset / np.sin(rdip)) rw_max = self.thickness / np.sin(rdip) length += (offset_area / rw_max) updip_depth_change = centroid.depth downdip_depth_change = self.lsd - centroid.depth else: # This would move the rupture below the lower surface offset = (centroid.depth + downdip_depth_change) - self.lsd downdip_depth_change = self.lsd - centroid.depth updip_depth_change += offset updip_surface_length = updip_depth_change / np.tan(rdip) downdip_surface_length = downdip_depth_change / np.tan(rdip) # Now deal with strike parts left_length = hypo_loc[0] * length right_length = (1.0 - hypo_loc[0]) * length # Build corner points downdip_dir = (dip + 90.0) % 360 updip_dir = (dip - 90.0) % 360 mid_left = centroid.point_at(left_length, 0.0, (strike + 180.) % 360.) mid_right = centroid.point_at(right_length, 0.0, strike) top_left = mid_left.point_at(updip_surface_length, -updip_depth_change, updip_dir) top_right = mid_right.point_at(updip_surface_length, -updip_depth_change, updip_dir) bottom_left = mid_left.point_at(downdip_surface_length, downdip_depth_change, downdip_dir) bottom_right = mid_right.point_at(downdip_surface_length, downdip_depth_change, downdip_dir) try: surface = PlanarSurface.from_corner_points( top_left, top_right, bottom_right, bottom_left) except: print(strike, dip, length, width, hypo_loc) print(top_left, top_right, bottom_right, bottom_left) raise ValueError ruptures.append(surface) return ruptures