fmi_export/fmi3/instance/
common.rs1use super::ModelInstance;
2use crate::fmi3::{
3 Model, ModelState, UserModel,
4 traits::{Context, ModelGetSet, ModelLoggingCategory},
5};
6use fmi::{
7 EventFlags, InterfaceType,
8 fmi3::{Common, Fmi3Error, Fmi3Res, binding},
9};
10
11impl<M, C> Common for ModelInstance<M, C>
12where
13 M: Model + UserModel + ModelGetSet<M>,
14 C: Context<M>,
15{
16 fn get_version(&self) -> &str {
17 unsafe { str::from_utf8_unchecked(binding::fmi3Version) }
19 }
20
21 fn set_debug_logging(
22 &mut self,
23 logging_on: bool,
24 categories: &[&str],
25 ) -> Result<Fmi3Res, Fmi3Error> {
26 for &cat in categories.iter() {
27 if let Some(cat) = cat.parse::<M::LoggingCategory>().ok() {
28 self.context.set_logging(cat, logging_on);
29 } else {
30 self.context.log(
31 Fmi3Error::Error.into(),
32 M::LoggingCategory::default(),
33 format_args!("Unknown logging category {cat}"),
34 );
35 return Err(Fmi3Error::Error);
36 }
37 }
38 Ok(Fmi3Res::OK)
39 }
40
41 fn enter_initialization_mode(
42 &mut self,
43 tolerance: Option<f64>,
44 start_time: f64,
45 stop_time: Option<f64>,
46 ) -> Result<Fmi3Res, Fmi3Error> {
47 self.context.log(
48 Fmi3Res::OK.into(),
49 Default::default(),
50 format_args!(
51 "enter_initialization_mode(tolerance: {tolerance:?}, start_time: {start_time:?}, stop_time: {stop_time:?})",
52 ),
53 );
54
55 match self.state {
56 ModelState::Instantiated => {
57 self.context.initialize(start_time, stop_time);
58 self.state = ModelState::InitializationMode;
59 Ok(Fmi3Res::OK)
60 }
61 _ => {
62 self.context.log(
63 Fmi3Error::Error.into(),
64 M::LoggingCategory::default(),
65 format_args!(
66 "enter_initialization_mode() called in invalid state {:?}",
67 self.state
68 ),
69 );
70 Err(Fmi3Error::Error)
71 }
72 }
73 }
74
75 fn exit_initialization_mode(&mut self) -> Result<Fmi3Res, Fmi3Error> {
76 self.context.log(
77 Fmi3Res::OK.into(),
78 Default::default(),
79 format_args!("exit_initialization_mode()"),
80 );
81
82 if self.is_dirty_values {
84 self.model.calculate_values(&self.context)?;
85 self.is_dirty_values = false;
86 }
87
88 match self.instance_type {
89 InterfaceType::ModelExchange => {
90 self.state = ModelState::EventMode;
91 }
92 InterfaceType::CoSimulation => {
93 let event_mode_used = false;
95 if event_mode_used {
96 self.state = ModelState::EventMode;
97 } else {
98 self.state = ModelState::StepMode;
99 }
100 }
101 InterfaceType::ScheduledExecution => {
102 self.state = ModelState::ClockActivationMode;
103 }
104 }
105
106 self.model.configurate(&self.context)?;
107
108 Ok(Fmi3Res::OK)
109 }
110
111 fn terminate(&mut self) -> Result<Fmi3Res, Fmi3Error> {
112 self.context.log(
113 Fmi3Res::OK.into(),
114 Default::default(),
115 format_args!("terminate()"),
116 );
117 self.state = ModelState::Terminated;
118 Ok(Fmi3Res::OK)
119 }
120
121 fn reset(&mut self) -> Result<Fmi3Res, Fmi3Error> {
122 self.state = ModelState::Instantiated;
123 self.context.initialize(0.0, None);
124 self.model.set_start_values();
125 Ok(Fmi3Res::OK)
126 }
127
128 fn enter_configuration_mode(&mut self) -> Result<Fmi3Res, Fmi3Error> {
129 self.context.log(
130 Fmi3Res::OK.into(),
131 M::LoggingCategory::trace_category(),
132 format_args!("enter_configuration_mode()"),
133 );
134
135 match self.state {
136 ModelState::Instantiated => {
137 self.state = ModelState::ConfigurationMode;
138 }
139 _ => {
140 self.state = ModelState::ReconfigurationMode;
141 }
142 }
143
144 Ok(Fmi3Res::OK)
145 }
146
147 fn exit_configuration_mode(&mut self) -> Result<Fmi3Res, Fmi3Error> {
148 self.context.log(
149 Fmi3Res::OK.into(),
150 M::LoggingCategory::trace_category(),
151 format_args!("exit_configuration_mode()"),
152 );
153
154 match self.state {
155 ModelState::ConfigurationMode => {
156 self.state = ModelState::Instantiated;
157 }
158
159 ModelState::ReconfigurationMode => {
160 match self.instance_type {
161 InterfaceType::ModelExchange => {
162 self.state = ModelState::EventMode;
163 }
164 InterfaceType::CoSimulation => {
165 let event_mode_used = false;
167 if event_mode_used {
168 self.state = ModelState::EventMode;
169 } else {
170 self.state = ModelState::StepMode;
171 }
172 }
173 InterfaceType::ScheduledExecution => {
174 self.state = ModelState::ClockActivationMode;
175 }
176 }
177 }
178
179 _ => {
180 self.context.log(
181 Fmi3Error::Error.into(),
182 M::LoggingCategory::default(),
183 format_args!(
184 "exit_configuration_mode() called in invalid state {:?}",
185 self.state
186 ),
187 );
188 return Err(Fmi3Error::Error);
189 }
190 }
191
192 Ok(Fmi3Res::OK)
193 }
194
195 fn enter_event_mode(&mut self) -> Result<Fmi3Res, Fmi3Error> {
196 self.context.log(
197 Fmi3Res::OK.into(),
198 M::LoggingCategory::trace_category(),
199 format_args!("enter_event_mode()"),
200 );
201 self.state = ModelState::EventMode;
202 Ok(Fmi3Res::OK)
203 }
204
205 fn update_discrete_states(
206 &mut self,
207 event_flags: &mut EventFlags,
208 ) -> Result<Fmi3Res, Fmi3Error> {
209 self.context.log(
210 Fmi3Res::OK.into(),
211 M::LoggingCategory::trace_category(),
212 format_args!("update_discrete_states()"),
213 );
214 self.model.event_update(&self.context, event_flags)
216 }
217
218 fn get_number_of_variable_dependencies(
219 &mut self,
220 _vr: binding::fmi3ValueReference,
221 ) -> Result<usize, Fmi3Error> {
222 Ok(0)
224 }
225
226 fn get_variable_dependencies(
227 &mut self,
228 _dependent: binding::fmi3ValueReference,
229 ) -> Result<Vec<fmi::fmi3::VariableDependency>, Fmi3Error> {
230 Ok(Vec::new())
232 }
233}