use aphreco::prelude::*;
fn main() {
let model = Model::new();
let step_options = StepOptions::Dopri45 {
h0: 1e-3,
abstol: 1e-6,
reltol: 1e-6,
hmin: 1e-6,
hmax: 1e-3,
};
let stepper = Stepper::Dopri45(step_options);
let simulator = Simulator::new(model, stepper);
let sampling_time = sampling_time();
clock!(let simres = simulator.run(&sampling_time));
simres.save("./");
}
const LEN_Y: usize = 4;
const LEN_P: usize = 11;
const LEN_B: usize = 2;
#[allow(dead_code)]
pub struct Model {
p: [f64; LEN_P],
}
#[allow(dead_code)]
impl SimModelTrait<LEN_Y, LEN_P, LEN_B> for Model {
fn new() -> Self {
let p = [
0.2, 0.05, 0.0, 100000.0, 0.1, 1.0, 100000.0, 0.2, 2.0, 10.0, 500.0, ];
Self { p }
}
fn init(&self) -> (f64, [f64; LEN_Y]) {
let t0 = 0.0;
let y0 = [
100.0, 0.0, 10.0, 0.0, ];
let _b0 = ();
let _a0 = ();
(t0, y0)
}
#[allow(unused_variables)]
fn ode(&self, t: &f64, y: &[f64; LEN_Y], deriv_y: &mut [f64; LEN_Y]) {
deriv_y[0] = -self.p[0] * y[0] + self.p[1] * y[1];
deriv_y[1] = self.p[0] * y[0] - self.p[1] * y[1];
}
#[allow(unused_variables)]
fn rec(&self, t: &f64, y: &[f64; LEN_Y], delta_y: &mut [f64; LEN_Y], act: &[bool; LEN_B]) {
if act[0] {
delta_y[2] += self.p[8];
}
if act[1] {
delta_y[2] -= self.p[8];
}
}
#[allow(unused_variables)]
fn cond(
&self,
dec_t: &Decimal,
act: &mut [bool; LEN_B],
next_t: &[Decimal; LEN_B],
y: &[f64; LEN_Y],
) {
act[0] = if *dec_t == next_t[0] { true } else { false };
act[1] = if *dec_t == next_t[1] { true } else { false };
}
#[allow(unused_variables)]
fn beat(&self, t: &f64, y: &[f64; LEN_Y]) -> [[Decimal; 3]; LEN_B] {
[
beat![self.p[2], self.p[3], self.p[4]],
beat![self.p[5], self.p[6], self.p[7]],
]
}
#[allow(unused_variables)]
fn cre(&self, t: &f64, y: &mut [f64; LEN_Y]) {
y[3] = self.p[8] * t;
}
}
fn sampling_time() -> Vec<f64> {
let mut vec_smp_t = Vec::new();
for i in 0..=5000 {
vec_smp_t.push(i as f64 / 100.0);
}
vec_smp_t
}