fmi_sim/
options.rs

1use std::fmt::Display;
2
3#[derive(Default, Debug, Clone, clap::ValueEnum)]
4pub enum SolverArg {
5    /// Euler solver
6    #[clap(name = "euler")]
7    #[default]
8    Euler,
9}
10
11#[derive(Default, Debug, clap::Args)]
12/// Perform a ModelExchange simulation
13pub struct ModelExchangeOptions {
14    #[command(flatten)]
15    pub common: CommonOptions,
16
17    /// The solver to use
18    #[arg(long, default_value = "euler")]
19    pub solver: SolverArg,
20}
21
22#[derive(Default, Debug, clap::Args)]
23/// Perform a CoSimulation simulation
24pub struct CoSimulationOptions {
25    #[command(flatten)]
26    pub common: CommonOptions,
27
28    /// Use event mode
29    #[arg(long)]
30    pub event_mode_used: bool,
31
32    /// Support early-return in Co-Simulation.
33    #[arg(long)]
34    pub early_return_allowed: bool,
35}
36
37#[derive(Debug, clap::Subcommand)]
38pub enum Interface {
39    #[cfg(feature = "me")]
40    #[command(alias = "me")]
41    ModelExchange(ModelExchangeOptions),
42
43    #[cfg(feature = "cs")]
44    #[command(alias = "cs")]
45    CoSimulation(CoSimulationOptions),
46
47    /// Perform a ScheduledExecution simulation
48    #[cfg(feature = "se")]
49    ScheduledExecution(CommonOptions),
50}
51
52impl Default for Interface {
53    fn default() -> Self {
54        // if only CS is enabled, use CS as default
55        #[cfg(all(not(feature = "me"), feature = "cs"))]
56        {
57            Self::CoSimulation(Default::default())
58        }
59
60        // if both ME and CS are enabled, use CS as default
61        #[cfg(all(feature = "me", feature = "cs"))]
62        {
63            Self::CoSimulation(Default::default())
64        }
65
66        // if only ME is enabled, use ME as default
67        #[cfg(all(feature = "me", not(feature = "cs")))]
68        {
69            Self::ModelExchange(Default::default())
70        }
71    }
72}
73
74impl Display for Interface {
75    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
76        match self {
77            #[cfg(feature = "me")]
78            Self::ModelExchange(_) => write!(f, "ModelExchange"),
79            #[cfg(feature = "cs")]
80            Self::CoSimulation(_) => write!(f, "CoSimulation"),
81            #[cfg(feature = "se")]
82            Self::ScheduledExecution(_) => write!(f, "ScheduledExecution"),
83        }
84    }
85}
86
87#[derive(Default, Debug, clap::Args)]
88pub struct CommonOptions {
89    /// File containing initial serialized FMU state.
90    #[arg(long)]
91    pub initial_fmu_state_file: Option<std::path::PathBuf>,
92
93    /// File to write final serialized FMU state.
94    #[arg(long)]
95    pub final_fmu_state_file: Option<std::path::PathBuf>,
96
97    /// List of initial values to set before simulation starts. The format is
98    /// "variableName=value", where variableName is the name of the variable and value is the
99    /// value to set. The value must be of the same type as the variable. The variable name must
100    /// be a valid FMI variable name, i.e. it must be a valid identifier and it must be unique.
101    #[arg(short = 'v')]
102    pub initial_values: Vec<String>,
103
104    /// Print also left limit values at event points to the output file to investigate event
105    /// behaviour. Default is to only print values after event handling.
106    #[arg(short = 'd')]
107    pub print_left_limit: bool,
108
109    /// Print all variables to the output file. Default is to only print outputs.
110    #[arg(long = "print-all")]
111    pub print_all_variables: bool,
112
113    /// For ME simulation: Decides step size to use in forward Euler.
114    /// For CS simulation: Decides communication step size for the stepping.
115    /// Observe that if a small stepSize is used the number of saved outputs will still be limited
116    /// by the number of output points. Default is to calculated a step size from the number of
117    /// output points. See the -n option for how the number of outputs is set.
118    #[arg(long = "ss")]
119    pub step_size: Option<f64>,
120
121    #[arg(long = "output-interval")]
122    pub output_interval: Option<f64>,
123
124    /// Maximum number of output points. "-n 0" means output at every step and the number of
125    /// outputs are decided by the -h option. Observe that no interpolation is used, output points
126    /// are taken at the steps.
127    #[arg(short = 'n', default_value = "500")]
128    pub num_steps: usize,
129
130    /// Simulation start time, default is to use information from 'DefaultExperiment' as specified
131    /// in the model description XML.
132    #[arg(short = 's')]
133    pub start_time: Option<f64>,
134
135    /// Simulation stop time, default is to use information from 'DefaultExperiment' as specified
136    /// in the model description XML.
137    #[arg(short = 'f')]
138    pub stop_time: Option<f64>,
139
140    /// Relative tolerance
141    #[arg(long)]
142    pub tolerance: Option<f64>,
143}
144
145/// Simulate an FMU
146#[derive(Default, Debug, clap::Parser)]
147#[command(version, about)]
148pub struct FmiSimOptions {
149    /// Which FMI interface to use
150    #[command(subcommand)]
151    pub interface: Interface,
152    /// The FMU model to read
153    #[arg(long)]
154    pub model: std::path::PathBuf,
155    /// Name of the CSV file name with input data.
156    #[arg(short = 'i', long)]
157    pub input_file: Option<std::path::PathBuf>,
158    /// Simulation result output CSV file name. Default is to use standard output.
159    #[arg(short = 'o', long)]
160    pub output_file: Option<std::path::PathBuf>,
161    /// Separator to be used in CSV input/output.
162    #[arg(short = 'c', default_value = ",")]
163    pub separator: char,
164    /// Mangle variable names to avoid quoting (needed for some CSV importing applications, but not
165    /// according to the CrossCheck rules).
166    #[arg(short = 'm')]
167    pub mangle_names: bool,
168}