sciforge_hub/engine/simulation/
model.rs1pub trait DynamicalSystem {
3 fn dimension(&self) -> usize;
5 fn derivatives(&self, t: f64, state: &[f64], out: &mut [f64]);
7 fn initial_state(&self) -> Vec<f64>;
9 fn time_span(&self) -> (f64, f64);
11}
12
13pub type SystemFn = Box<dyn Fn(f64, &[f64], &mut [f64])>;
15
16pub struct SimpleModel {
18 y0: Vec<f64>,
19 t_span: (f64, f64),
20 f: SystemFn,
21}
22
23impl SimpleModel {
24 pub fn new(y0: Vec<f64>, t_span: (f64, f64), f: SystemFn) -> Self {
26 Self { y0, t_span, f }
27 }
28}
29
30impl DynamicalSystem for SimpleModel {
31 fn dimension(&self) -> usize {
32 self.y0.len()
33 }
34 fn derivatives(&self, t: f64, state: &[f64], out: &mut [f64]) {
35 (self.f)(t, state, out);
36 }
37 fn initial_state(&self) -> Vec<f64> {
38 self.y0.clone()
39 }
40 fn time_span(&self) -> (f64, f64) {
41 self.t_span
42 }
43}
44
45pub struct HarmonicOscillator {
47 pub omega: f64,
49 pub x0: f64,
51 pub v0: f64,
53 pub t_span: (f64, f64),
55}
56
57impl DynamicalSystem for HarmonicOscillator {
58 fn dimension(&self) -> usize {
59 2
60 }
61 fn derivatives(&self, _t: f64, state: &[f64], out: &mut [f64]) {
62 out[0] = state[1];
63 out[1] = -self.omega * self.omega * state[0];
64 }
65 fn initial_state(&self) -> Vec<f64> {
66 vec![self.x0, self.v0]
67 }
68 fn time_span(&self) -> (f64, f64) {
69 self.t_span
70 }
71}
72
73pub struct LotkaVolterra {
75 pub alpha: f64,
77 pub beta: f64,
79 pub delta: f64,
81 pub gamma: f64,
83 pub prey0: f64,
85 pub pred0: f64,
87 pub t_span: (f64, f64),
89}
90
91impl DynamicalSystem for LotkaVolterra {
92 fn dimension(&self) -> usize {
93 2
94 }
95 fn derivatives(&self, _t: f64, state: &[f64], out: &mut [f64]) {
96 let x = state[0];
97 let y = state[1];
98 out[0] = self.alpha * x - self.beta * x * y;
99 out[1] = self.delta * x * y - self.gamma * y;
100 }
101 fn initial_state(&self) -> Vec<f64> {
102 vec![self.prey0, self.pred0]
103 }
104 fn time_span(&self) -> (f64, f64) {
105 self.t_span
106 }
107}