fmi_export/fmi3/mod.rs
1//! ## Architecture
2//!
3//! The [`crate::export_fmu`] macro generates the necessary C-API bindings for the exported FMU.
4//! Many of these bindings operate on a [`::fmi::fmi3::binding::fmi3Instance`], which is an opaque
5//! pointer to an instance of [`instance::ModelInstance`].
6//!
7//! [`instance::ModelInstance`] implements the [`crate::fmi3::Fmi3Common`] trait, which provides
8//! the actual implementation of the FMI 3.0 API. All user-model-specific functions are delegated
9//! to the [`Model`] trait,
10//! which the user model must implement.
11
12// Disable coverage for the export module. Due to some bug in llvm-cov, the generated C functions
13// are never covered. This is ok since they are just thin wrappers around the Rust functions.
14#[cfg_attr(coverage_nightly, coverage(off))]
15mod export;
16
17mod instance;
18mod traits;
19mod types;
20mod variable_builder;
21
22use std::{fmt::Display, str::FromStr};
23
24// Re-exports
25pub use instance::{ModelInstance, context::BasicContext};
26pub use traits::{
27 CSDoStepResult, Context, Fmi3CoSimulation, Fmi3Common, Fmi3ModelExchange,
28 Fmi3ScheduledExecution, Model, ModelGetSet, ModelGetSetStates, ModelLoggingCategory, UserModel,
29};
30pub use types::{Binary, Clock, InitializeFromStart};
31pub use variable_builder::{FmiVariableBuilder, VariableBuilder};
32
33/// Specifies how Co-Simulation is implemented for a model
34/// Represents the current state of the model instance
35#[derive(Debug)]
36pub enum ModelState {
37 StartAndEnd,
38 ConfigurationMode,
39 /// In the state `Instantiated` the FMU can do one-time initializations and allocate memory.
40 ///
41 /// See <https://fmi-standard.org/docs/3.0.1/#Instantiated>
42 Instantiated,
43 /// The `InitializationMode` is used by the simulation algorithm to compute consistent initial
44 /// conditions for the overall system. Equations are active to determine the initial FMU state,
45 /// as well as all outputs (and optionally other variables exposed by the exporting tool).
46 /// Artificial or real algebraic loops over connected FMUs in Initialization Mode may be handled
47 /// by using appropriate numerical algorithms.
48 ///
49 /// See <https://fmi-standard.org/docs/3.0.1/#InitializationMode>
50 InitializationMode,
51 /// In `EventMode` all continuous-time, discrete-time equations and active model partitions are
52 /// evaluated. Algebraic loops active during Event Mode are solved by event iteration.
53 ///
54 /// See <https://fmi-standard.org/docs/3.0.1/#EventMode>
55 EventMode,
56 ContinuousTimeMode,
57 StepMode,
58 ClockActivationMode,
59 StepDiscarded,
60 ReconfigurationMode,
61 IntermediateUpdateMode,
62 Terminated,
63}
64
65/// Simple default logging category for models that don't need custom logging
66#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default)]
67pub enum DefaultLoggingCategory {
68 #[default]
69 LogAll,
70 /// Trace FMI API calls
71 Trace,
72}
73
74impl Display for DefaultLoggingCategory {
75 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
76 match self {
77 DefaultLoggingCategory::LogAll => f.write_str("logAll"),
78 DefaultLoggingCategory::Trace => f.write_str("trace"),
79 }
80 }
81}
82
83impl FromStr for DefaultLoggingCategory {
84 type Err = String;
85 fn from_str(s: &str) -> Result<Self, Self::Err> {
86 match s {
87 "logAll" => Ok(Self::LogAll),
88 "trace" => Ok(Self::Trace),
89 _ => Err(format!("Unknown logging category: {}", s)),
90 }
91 }
92}
93
94impl ModelLoggingCategory for DefaultLoggingCategory {
95 fn all_categories() -> impl Iterator<Item = Self> {
96 [Self::LogAll, Self::Trace].into_iter()
97 }
98 fn trace_category() -> Self {
99 Self::Trace
100 }
101 fn error_category() -> Self {
102 Self::LogAll
103 }
104}