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(long = "init-values")]
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 = "step")]
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 /// Verbosity level. Use -v for info, -vv for debug, -vvv for trace. Also controls FMU log messages.
169 #[command(flatten)]
170 pub verbose: clap_verbosity_flag::Verbosity,
171}