FMI 3.0 Export
Writing a model out as a Functional Mock-up Unit, for both interface types, and packaging a subsystem as a reusable component.
What gets written
FMI is an open standard for moving simulation models between tools. to_fmu writes an FMI 3.0 source FMU: the model is lowered to C, wrapped in the FMI C layer, and zipped with a generated modelDescription.xml and buildDescription.xml.
Source FMU means the archive carries C rather than binaries, so the importing tool compiles it for its own platform.
One archive offers both interfaces:
- Model Exchange — the FMU hands out MATHINLINE0ENDMATH and the importer integrates it.
- Co-Simulation — the FMU integrates itself, with the solver baked in at export time, and the importer just advances it.
Simulation.to_fmu() exports a whole model. A Subsystem has to_fmu too, which is how a component with input and output ports is packaged on its own.
The Model
A damped harmonic oscillator, which has a closed-form solution to check against:
MATHDISPLAY0ENDMATH
System Parameters
Block Diagram
Simulation
The reference run, before exporting anything.
Export
The keyword arguments become the default experiment in modelDescription.xml — what an importer uses when the user does not say otherwise.
What the Importer Sees
modelDescription.xml declares the interfaces on offer and the variables. Both <ModelExchange> and <CoSimulation> are there.
Running It Back
FMPy is an independent FMI implementation, so it is a good way to check that the FMU really is one. It builds the C for this platform first, since a source FMU ships none.
Model Exchange
FMPy integrates the FMU with its own solver — CVode here, which FastSim never runs.
Co-Simulation
The same archive, the other way round: the FMU steps itself and FMPy only advances the clock.
Results
Verification
Against the closed-form solution, which involves neither the FMU nor FastSim.
Exporting a Subsystem
A whole simulation is a closed model — no inputs, nothing to wire it to. A Subsystem is the other case: a component with ports, which becomes an FMU with real input and output variables that someone else can drop into their model.
The component here is a driven spring-mass-damper: force in, its state out.
MATHDISPLAY0ENDMATH
The exported component has an input variable — this FMU is not self-contained, it is meant to be connected. Its outputs are the plant's, position first.
Verification
Driven at its undamped natural frequency MATHINLINE1ENDMATH, the steady-state amplitude of such a component is known:
MATHDISPLAY0ENDMATH
Published FMUs
The two FMUs from this page are published in the repository under
fmus/, each with a
reference solution (_ref.csv / _ref.opt / _in.csv) so other tools can
import and compare. scripts/export_reference_fmus.py regenerates them, and
scripts/check_exported_fmus.py replays this page's comparison end to end.