ground_motion_lib/gmm.rs
1//! Ground Motion Prediction Equation (GMPE) definitions and traits.
2//!
3//! This module provides fundamental data structures and traits for representing
4//! seismic input points, earthquake parameters, and ground motion model outputs.
5//! It also defines the core trait for implementing specific GMPE models.
6
7use serde::{Deserialize, Serialize};
8
9/// Input point definition for which GMPE will be calculated.
10#[derive(Debug, Serialize, Deserialize)]
11pub struct Vs30Point {
12 /// Longitude in decimal degrees. Example: `142.23567`
13 pub lon: f64,
14 /// Latitude in decimal degrees. Example: `50.35927`
15 pub lat: f64,
16 /// Average shear-wave velocity (Vs, in m/s) in the top 30 meters of soil.
17 pub vs30: f64,
18 /// Depth (in meters) to the subsurface layer where Vs reaches 1400 m/s at the site.
19 #[serde(default)]
20 pub dl: Option<f64>,
21 /// Binary variable (0 or 1) indicating the site's position relative to the volcanic front
22 /// (specific to Japan).
23 #[serde(default)]
24 pub xvf: Option<u8>,
25}
26
27/// Magnitude type used in GMPE calculations.
28#[derive(Debug)]
29pub enum Magnitude {
30 /// Moment magnitude (Mw)
31 Mw,
32 /// Local magnitude (Ml)
33 Ml,
34}
35
36/// Represents an earthquake event with its source parameters.
37#[derive(Debug)]
38pub struct Earthquake {
39 /// Longitude in decimal degrees.
40 pub lon: f64,
41 /// Latitude in decimal degrees.
42 pub lat: f64,
43 /// Earthquake focal depth in kilometers.
44 pub depth: f64,
45 /// Magnitude value.
46 pub magnitude: f64,
47 /// Type of magnitude scale (Mw, Ml, etc.)
48 pub magnitude_kind: Magnitude,
49}
50
51/// Available GMPE output types.
52#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
53pub enum GmpePointKind {
54 /// Peak Ground Acceleration, expressed as a percentage of gravity (%g)
55 Pga,
56 /// Peak Spectral Acceleration, expressed as a percentage of gravity (%g)
57 Psa,
58 /// Peak Ground Velocity, expressed in cm/s
59 Pgv,
60}
61
62/// Struct representing a point with a computed GMPE value.
63#[derive(Debug, Serialize, Deserialize)]
64pub struct GmpePoint {
65 /// Longitude in decimal degrees.
66 pub lon: f64,
67 /// Latitude in decimal degrees.
68 pub lat: f64,
69 /// Computed ground motion value.
70 pub value: f64,
71 /// Type of GMPE output value.
72 pub kind: GmpePointKind,
73}
74
75/// Trait representing a Ground Motion Prediction Equation (GMPE).
76///
77/// Implementors of this trait can compute ground motion values at a site
78/// for a given earthquake scenario.
79pub trait GroundMotionModeling {
80 /// Compute ground motion value for a given input point and earthquake.
81 ///
82 /// # Arguments
83 ///
84 /// * `point` - Input site point parameters.
85 /// * `eq` - Earthquake source parameters.
86 ///
87 /// # Returns
88 ///
89 /// A `GmpePoint` containing the computed value and its location.
90 fn calc_from_point(&self, point: &Vs30Point, eq: &Earthquake) -> GmpePoint;
91}
92
93impl Vs30Point {
94 /// Create a new Vs30Point instance.
95 ///
96 /// # Arguments
97 ///
98 /// * `lon` - Longitude in decimal degrees.
99 /// * `lat` - Latitude in decimal degrees.
100 /// * `vs30` - Average Vs in the top 30 meters.
101 /// * `dl` - Depth to Vs=1400 m/s layer (optional).
102 /// * `xvf` - Binary volcanic front position indicator (optional).
103 ///
104 /// # Example
105 ///
106 /// ```
107 /// use ground_motion_lib::gmm::Vs30Point;
108 /// let vs30_point = Vs30Point::new(142.523, 52.913, 300., Some(250.), Some(1));
109 /// println!("Point is {vs30_point:?}");
110 /// ```
111 pub fn new(lon: f64, lat: f64, vs30: f64, dl: Option<f64>, xvf: Option<u8>) -> Self {
112 Self {
113 lon,
114 lat,
115 vs30,
116 dl,
117 xvf,
118 }
119 }
120
121 /// Calculate ground motion value for this point and given earthquake, using a GMPE.
122 ///
123 /// # Arguments
124 ///
125 /// * `gmpe` - Reference to a type implementing `GroundMotionModeling`.
126 /// * `eq` - Earthquake source parameters.
127 ///
128 /// # Returns
129 ///
130 /// A `GmpePoint` with the computed value.
131 pub fn get_gm<T: GroundMotionModeling>(&self, gmpe: &T, eq: &Earthquake) -> GmpePoint {
132 gmpe.calc_from_point(self, eq)
133 }
134}
135
136impl Earthquake {
137 /// Create a new Earthquake instance.
138 ///
139 /// # Arguments
140 ///
141 /// * `lon` - Longitude in decimal degrees.
142 /// * `lat` - Latitude in decimal degrees.
143 /// * `depth` - Focal depth in kilometers.
144 /// * `magnitude` - Magnitude value.
145 /// * `magnitude_kind` - Type of magnitude scale.
146 pub fn new(lon: f64, lat: f64, depth: f64, magnitude: f64, magnitude_kind: Magnitude) -> Self {
147 Self {
148 lon,
149 lat,
150 depth,
151 magnitude,
152 magnitude_kind,
153 }
154 }
155
156 /// Convenience constructor for Local magnitude (Ml).
157 pub fn new_ml(lon: f64, lat: f64, depth: f64, magnitude: f64) -> Self {
158 Self::new(lon, lat, depth, magnitude, Magnitude::Ml)
159 }
160
161 /// Convenience constructor for Moment magnitude (Mw).
162 pub fn new_mw(lon: f64, lat: f64, depth: f64, magnitude: f64) -> Self {
163 Self::new(lon, lat, depth, magnitude, Magnitude::Mw)
164 }
165}
166
167impl GmpePoint {
168 /// Create a new GmpePoint instance.
169 pub fn new(lon: f64, lat: f64, value: f64, kind: GmpePointKind) -> Self {
170 Self {
171 lon,
172 lat,
173 value,
174 kind,
175 }
176 }
177
178 /// Create a new Peak Ground Acceleration (PGA) point.
179 pub fn new_pga(lon: f64, lat: f64, value: f64) -> Self {
180 Self::new(lon, lat, value, GmpePointKind::Pga)
181 }
182
183 /// Create a new Peak Ground Velocity (PGV) point.
184 pub fn new_pgv(lon: f64, lat: f64, value: f64) -> Self {
185 Self::new(lon, lat, value, GmpePointKind::Pgv)
186 }
187
188 /// Create a new Peak Spectral Acceleration (PSA) point.
189 pub fn new_psa(lon: f64, lat: f64, value: f64) -> Self {
190 Self::new(lon, lat, value, GmpePointKind::Psa)
191 }
192}