Skip to main content

carapace_core/analysis/
ground_motion.rs

1use crate::model::LoadSeries;
2
3/// Uniform ground-motion excitation in one direction — Xara/OpenSees's
4/// `UniformExcitation`. `TransientAnalysis` uses this to add the effective
5/// inertial force `-M·ι·ag(t)` (standard formulation, e.g. Chopra,
6/// "Dynamics of Structures") to each Newmark step's load, where `ι` is the
7/// unit influence vector selecting every free DOF in `direction`
8/// (`Domain::direction_incidence`) and `ag(t)` is this motion's
9/// acceleration at time `t`. An accelerogram is exactly a `LoadSeries::
10/// Path` (piecewise-linear interpolation over recorded points) — no
11/// separate series type needed; this reuses the same `LoadSeries` a static
12/// `LoadPattern` would.
13#[derive(Debug, Clone)]
14pub struct GroundMotion {
15    pub direction: usize,
16    pub series: LoadSeries,
17    pub scale_factor: f64,
18}
19
20impl GroundMotion {
21    /// `direction`: which DOF index (0 = x, 1 = y) the acceleration acts
22    /// along, applied uniformly to every node's mass in that direction.
23    pub fn new(direction: usize, series: LoadSeries) -> Self {
24        GroundMotion {
25            direction,
26            series,
27            scale_factor: 1.0,
28        }
29    }
30
31    /// E.g. a PGA scale on top of `series`'s own values.
32    pub fn with_scale_factor(mut self, scale_factor: f64) -> Self {
33        self.scale_factor = scale_factor;
34        self
35    }
36
37    pub(crate) fn acceleration(&self, time: f64) -> f64 {
38        self.series.factor(time) * self.scale_factor
39    }
40}