FMI 3 (recommended)
taktwerk runs FMI 3 and FMI 2 co-simulation FMUs. Export from any tool that writes FMI 3
co-simulation for Linux; the FMU then runs unchanged in taktwerk and in every other FMI
importer. A kind = "fmi" model path is an .fmu archive (extracted to a private temporary
directory at load) or an already extracted FMU directory.
Sizes: structural parameters
A size-generic FMI 3 model declares each size as a structural parameter and sizes its arrays
with <Dimension valueReference="…"/>. Each structural parameter becomes a taktwerk dimension:
its name is the dimension’s name, start its default, min and max its bounds.
<ModelVariables>
<UInt64 name="n" valueReference="1" causality="structuralParameter"
variability="fixed" start="1" min="1" max="64"/>
<Float64 name="tau" valueReference="2" causality="parameter" variability="fixed"
start="1.0" unit="s">
<Dimension valueReference="1"/>
</Float64>
<Float64 name="gain" valueReference="3" causality="parameter" variability="tunable"
start="1.0"/>
<Float64 name="u" valueReference="4" causality="input" start="0">
<Dimension valueReference="1"/>
</Float64>
<Float64 name="y" valueReference="5" causality="output">
<Dimension valueReference="1"/>
</Float64>
</ModelVariables>
$ taktwerk inspect filter.fmu --kind fmi
dimension min max default
n 1 64 1
variable causality type shape unit description
tau parameter f64 [n] s
gain tunable f64 scalar -
u input f64 [n] -
y output f64 [n] -
- Structural parameters must have an integer type.
- A
<Dimension>takesstart="4"(a literal length), or avalueReferenceto a structural parameter or to a constant integer variable with astart. - At instantiation taktwerk enters configuration mode, sets every structural parameter to the instance’s bound length, and leaves it. Then it sets the instance’s parameters and tunables.
- Arrays are row-major, as FMI 3 defines them.
Variables and types
| FMI causality / variability | taktwerk causality |
|---|---|
input | input |
output | output |
parameter, fixed | parameter |
parameter, tunable | tunable |
structuralParameter | a dimension |
local, independent, calculatedParameter | not exposed |
| FMI 3 type | taktwerk type |
|---|---|
Float64, Float32 | f64, f32 |
Int64, Int32, Int16, Int8 | i64, i32, i16, i8 |
UInt64, UInt32, UInt16, UInt8 | u64, u32, u16, u8 |
Boolean | bool |
Enumeration | i64 |
String (FMI 3) | text, u8 [capacity] |
Binary, Clock | refused when exposed |
A String is text of a fixed capacity, NUL included: 256 bytes, or what a taktwerk
annotation gives (<Annotation type="taktwerk"><text capacity="32"/></Annotation>). It is
exchanged through fmi3SetString/fmi3GetString; a longer string from the FMU is cut to the
capacity. Connectors present it as a string, like raw text.
Units come from unit or the declared type’s unit; description is kept. Both show in
inspect and are informational.
FMI 2 FMUs are scalar only: Real is f64, Integer and Enumeration are i32, Boolean
is bool; other types are refused.
Calling sequence
Per instance: instantiate (co-simulation, no event mode, the FMU’s resources/ directory as
resource path), configuration mode for structural parameters, parameters set, initialization
mode at engine.start_time (no tolerance, no stop time) with the inputs described under
Init, outputs read back, then one DoStep per period of
every × tick_ms. Inputs are set before every step, changed tunables
before the next step; outputs are read after it. OK and Warning are success; any other
status, or a step that requests termination, stops the engine. Logging goes to the engine log
at debug level.
Single vs multiple instances
canBeInstantiatedOnlyOncePerProcess="true" marks a single-instance FMU. taktwerk still runs
several instances of it: each further instance loads a private copy of the shared library, since
one loaded file shares its globals. Without the flag, all instances share one loaded library.
Prefer FMUs that keep all state in the instance.
Platform binaries
taktwerk loads binaries/<platform>/<modelIdentifier>.so for the running architecture:
| FMI | x86_64 | aarch64 | 32-bit ARM |
|---|---|---|---|
| 3 | x86_64-linux | aarch64-linux | aarch32-linux |
| 2 | linux64, then x86_64-linux | aarch64-linux, linuxaarch64, linux-aarch64 | aarch32-linux |
An FMU without a binary for the target is refused at load, naming the platforms it has. Build the binary against a glibc no newer than the target’s (see cross-building).
Checklist
- FMI 3 (or FMI 2), with a
CoSimulationelement; model exchange alone is refused. - Every size is a structural parameter with an integer type, a
start, andmin/maxwhere the model has limits. - Exposed variables use numeric or Boolean types only.
- Parameters that may change while running are
variability="tunable". - A Linux binary for every target architecture, in the platform folder above.
- No allocation and no blocking I/O in
DoStep. -
taktwerk inspect model.fmu --kind fmishows the dimensions and variables you expect.