fmi_export/fmi3/instance/
impl_cs.rs1use crate::fmi3::{
2 Model, ModelGetSetStates, ModelState, UserModel,
3 traits::{Context, ModelGetSet, ModelLoggingCategory},
4};
5use fmi::fmi3::{CoSimulation, Fmi3Error, Fmi3Res};
6
7use super::ModelInstance;
8
9impl<M, C> CoSimulation for ModelInstance<M, C>
10where
11 M: Model + UserModel + ModelGetSet<M> + ModelGetSetStates,
12 C: Context<M>,
13{
14 fn enter_step_mode(&mut self) -> Result<Fmi3Res, Fmi3Error> {
15 self.context.log(
16 Fmi3Res::OK.into(),
17 M::LoggingCategory::trace_category(),
18 format_args!("enter_step_mode()"),
19 );
20 self.assert_instance_type(fmi::InterfaceType::CoSimulation)?;
21
22 match self.state {
23 ModelState::EventMode => {
24 self.state = ModelState::StepMode;
25 Ok(Fmi3Res::OK)
26 }
27 ModelState::StepMode => Ok(Fmi3Res::OK),
28 _ => {
29 self.context.log(
30 Fmi3Error::Error.into(),
31 M::LoggingCategory::default(),
32 format_args!("enter_step_mode() called in invalid state {:?}", self.state),
33 );
34 Err(Fmi3Error::Error)
35 }
36 }
37 }
38
39 fn get_output_derivatives(
40 &mut self,
41 vrs: &[fmi::fmi3::binding::fmi3ValueReference],
42 orders: &[i32],
43 _values: &mut [f64],
44 ) -> Result<Fmi3Res, Fmi3Error> {
45 self.context.log(
46 Fmi3Error::Error.into(),
47 M::LoggingCategory::default(),
48 format_args!(
49 "get_output_derivatives(vrs: {:?}, orders: {:?}) not implemented",
50 vrs, orders
51 ),
52 );
53 Err(Fmi3Error::Error)
54 }
55
56 #[allow(clippy::too_many_arguments)]
57 fn do_step(
58 &mut self,
59 current_communication_point: f64,
60 communication_step_size: f64,
61 no_set_fmu_state_prior_to_current_point: bool,
62 event_handling_needed: &mut bool,
63 terminate_simulation: &mut bool,
64 early_return: &mut bool,
65 last_successful_time: &mut f64,
66 ) -> Result<Fmi3Res, Fmi3Error> {
67 self.context.log(
68 Fmi3Res::OK.into(),
69 M::LoggingCategory::trace_category(),
70 format_args!(
71 "do_step(t: {}, h: {}, no_set_state_prior: {})",
72 current_communication_point,
73 communication_step_size,
74 no_set_fmu_state_prior_to_current_point
75 ),
76 );
77 self.assert_instance_type(fmi::InterfaceType::CoSimulation)?;
78
79 match self.state {
80 ModelState::StepMode => {}
81 _ => {
82 self.context.log(
83 Fmi3Error::Error.into(),
84 M::LoggingCategory::default(),
85 format_args!("do_step() called in invalid state {:?}", self.state),
86 );
87 return Err(Fmi3Error::Error);
88 }
89 }
90
91 let result = self.model.do_step(
92 &mut self.context,
93 current_communication_point,
94 communication_step_size,
95 no_set_fmu_state_prior_to_current_point,
96 )?;
97
98 *event_handling_needed = result.event_handling_needed;
99 *terminate_simulation = result.terminate_simulation;
100 *early_return = self.context.early_return_allowed() && result.early_return;
101 *last_successful_time = result.last_successful_time;
102
103 self.is_dirty_values = true;
105
106 Ok(Fmi3Res::OK)
108 }
109}