This notebook shows how to
The source code of the model is
model HelloWorld "The simplest differential equation ever"
Real x
"The unknown variable";
constant Real a = -2.0
"Constant that characterizes the model";
parameter Real x_start = 5.0
"Initial value of the variable x";
initial equation
// Define initial conditions here...
x = x_start;
equation
// Write the equations here...
der(x) = a*x;
end HelloWorld;
and it's locatios is the repository ModelicaInAction is ModelicaInAction/modelica/HelloWorld.mo
.
When starting the docker container using the command make start
# Excerpt from ModelicaInAction/Makefile
start: ## Starts the container in detached mode and exposes an ipython notebook server listening on port 8888.
docker run -d -v $(shell pwd)/modelica:/home/docker/modelica \
-v $(shell pwd)/ipynotebooks:/home/docker/ipynotebooks \
-p 127.0.0.1:8888:8888 jmodelica:1.0 \
sh -c 'ipython notebook --no-browser --matplotlib=inline --ip=0.0.0.0 --port=8888 --notebook-dir=/home/docker/ipynotebooks'
the option -v $(shell pwd)/modelica:/home/docker/modelica
attaches the folder
ModelicaInAction/modelica/
to the folder /home/docker/modelica
inside the container.
In this way we can modify/create Modelica files on the host, compile and simulate them on the guest (the docker container).
In [1]:
from pymodelica import compile_fmu
from pyfmi import load_fmu
from pylab import rcParams
rcParams['figure.figsize'] = 12, 6
from matplotlib import pyplot as plt
import numpy as np
In [2]:
# Specify Modelica model and model file (.mo or .mop)
model_name = 'HelloWorld'
mo_file = '/home/docker/modelica/HelloWorld.mo'
# Compile the model and save the return argument, which is the file name of the FMU
my_fmu = compile_fmu(model_name, mo_file)
JModelica.org starts by opening the Modelica model named HelloWorld located in file /home/docker/modelica/HelloWorld.mo
.
Once the .mo
file is loaded JModelica.org parses and compiles it. The result of the compilation
is an FMU file.
An FMU (Functional Mock-up Unit) is a file compliant with the Functional Mock-up Interface (FMI). FMI is a tool independent standard to support both model exchange and co-simulation of dynamic models using a combination of xml-files and compiled C-code.
Long story short, JModelica.org generates C-code and an xml representation of the model. Both the C-code and the xml-files are packaged inside the FMU.
In [3]:
# Load the model and simulate
hello_world = load_fmu(my_fmu)
res = hello_world.simulate(final_time=5.0)
In [4]:
plt.plot(res["time"], res['x'], label="$x(t)$")
plt.xlabel("Time [s]")
plt.ylabel("State variable x")
plt.legend()
Out[4]:
The model has a parameter called x_init
that is the initial value of the state variable x
at the beginning of the simulation time.
We'll now run multiple simulations that start from different initial conditions.
The model has already been simulated, therefore in order to run a new simulation we need to reset the model.
To reset the model we use the reset()
method
hello_world.reset()
To change the value of a parameter we use the set()
method
hello_world.set(<PARAMETER_NAME>, <NEW_VALUE>)
In [5]:
x_init = np.linspace(5.0, 10.0, 10)
results = []
for xi in x_init:
hello_world.reset()
hello_world.set("x_start", xi)
results.append(hello_world.simulate(final_time=5.0))
In [6]:
for i, res in enumerate(results):
plt.plot(res["time"], res['x'], 'b', label="$x(t)$" if i==0 else None)
plt.xlabel("Time [s]")
plt.ylabel("State variable x")
plt.legend()
Out[6]: