FMI¶
The Functional Mock-up Interface (FMI) is a standard that defines a container and an interface to exchange dynamic models using a combination of XML files, binaries and C code zipped into a single file.
For further detail, please look at the official website: https://fmi-standard.org/
The goal of the standard is to allow the co-simulation of models from different tools. This notebook presents how to package a CoSApp model as a Functional Mock-up Unit (FMU).
System without iterative¶
Case description¶
Creating the elements¶
First, you need to export your CoSApp system code into a separate file.
[1]:
from exprampode_fmu import ExpRampOde
# Trick to display nicely the class code
from IPython.display import Markdown
import inspect
Markdown(f"```py\n{inspect.getsource(ExpRampOde)}```")
[1]:
class ExpRampOde(System):
"""
System representing function f(t) = a * (1 - exp(-t / tau)),
through ODE: tau * f' + f = a
f is then apply on an input signal x to produce y.
"""
def setup(self):
self.add_inward('a', 1.0)
self.add_inward('tau', 1.0)
self.add_inward('x', 1.0)
self.add_outward('y', 1.0)
self.add_outward('df_dt', 0.0)
self.add_transient('f', der='df_dt', max_time_step='tau / 5')
def compute(self):
self.df_dt = (self.a - self.f) / self.tau
self.y = self.x * self.f
Export to FMU¶
Exporting a CoSApp system is done using function cosapp.tools.to_fmu
.
When this function is called, actual system parameters will be used as default values in the FMU.
[2]:
import os
import tempfile
import shutil
from cosapp.tools import to_fmu
syst = ExpRampOde('fmu1')
# Customize parameters
syst.a = 5
if not os.path.exists('fmus'):
os.mkdir('fmus')
# Export the FMU in a temporary directory
with tempfile.TemporaryDirectory() as tmp_dir:
fmu_file = to_fmu(syst, dest=tmp_dir, locals=['f', 'df_dt'])
shutil.copy2(fmu_file, 'fmus')
Use the FMU¶
[3]:
import pyfmi
fmu = pyfmi.load_fmu('fmus/ExpRampOde.fmu')
results = fmu.simulate(final_time=10.)
Simulation interval : 0.0 - 10.0 seconds.
Elapsed simulation time: 0.1522242160026508 seconds.
[4]:
# Plot results
import plotly.graph_objs as go
layout = go.Layout(
height = 450,
xaxis = dict(title="time"),
yaxis = dict(title = "f")
)
go.Figure(
data=go.Scatter(
x = results['time'],
y = results['f'],
),
layout=layout)