fmi_sim/sim/solver/
mod.rs

1mod euler;
2
3pub use euler::Euler;
4use fmi::traits::FmiModelExchange;
5
6pub trait Model {
7    fn get_continuous_states(&mut self, x: &mut [f64]);
8    fn set_continuous_states(&mut self, states: &[f64]);
9    fn get_continuous_state_derivatives(&mut self, dx: &mut [f64]);
10    fn get_event_indicators(&mut self, z: &mut [f64]);
11}
12
13impl<Inst: FmiModelExchange> Model for Inst {
14    fn get_continuous_states(&mut self, x: &mut [f64]) {
15        let _ = FmiModelExchange::get_continuous_states(self, x);
16    }
17
18    fn set_continuous_states(&mut self, states: &[f64]) {
19        let _ = FmiModelExchange::set_continuous_states(self, states);
20    }
21
22    fn get_continuous_state_derivatives(&mut self, dx: &mut [f64]) {
23        let _ = FmiModelExchange::get_continuous_state_derivatives(self, dx);
24    }
25
26    fn get_event_indicators(&mut self, z: &mut [f64]) {
27        let _ = FmiModelExchange::get_event_indicators(self, z);
28    }
29}
30
31#[derive(Debug, thiserror::Error)]
32pub enum SolverError {
33    #[error("Step error")]
34    StepError,
35}
36
37pub trait Solver<M> {
38    /// Solver parameters
39    type Params;
40
41    /// Create a new Solver instance.
42    /// # Arguments
43    /// * `nx` - The number of continuous states.
44    /// * `nz` - The number of event indicators.
45    fn new(start_time: f64, tolerance: f64, nx: usize, nz: usize, params: Self::Params) -> Self;
46
47    /// Perform a single step of the solver.
48    ///
49    /// # Arguments
50    /// * `model` - The model to be simulated.
51    /// * `next_time` - The time at which the simulation should stop.
52    ///
53    /// # Returns
54    /// A tuple of (`time_reached`, `state_event`)
55    fn step(&mut self, model: &mut M, next_time: f64) -> Result<(f64, bool), SolverError>;
56
57    /// Reset the solver
58    fn reset(&mut self, model: &mut M, time: f64) -> Result<(), SolverError>;
59}
60
61/// A dummy solver that does nothing.
62pub struct DummySolver;
63
64impl<M> Solver<M> for DummySolver {
65    type Params = ();
66    fn new(
67        _start_time: f64,
68        _tolerance: f64,
69        _nx: usize,
70        _nz: usize,
71        _params: Self::Params,
72    ) -> Self {
73        Self
74    }
75
76    fn step(&mut self, _model: &mut M, _next_time: f64) -> Result<(f64, bool), SolverError> {
77        Ok((0.0, false))
78    }
79
80    fn reset(&mut self, _model: &mut M, _time: f64) -> Result<(), SolverError> {
81        Ok(())
82    }
83}