# Modelling Physical Systems¶

We will do the following:

Model a water tank in Modelica;

Compile the Modelica model into an FMU;

Write a simple SMOL program that loads the FMU;

Simulate and control the system’s behavior over time

## Behavior of a Watertank¶

We will model a watertank with a pipe, such that turning on the pipe adds a constant amount of water per second to the current level of the tank. The tank also has a drain hole at the bottom; the rate of outflow is dependent on the current water level of the tank.

Mathematically, the behavior of the tank can be described by the following formula:

where

\(l\): current level in tank

\(d\): drain rate, “size of the hole”

\(f\): rate of inflow

\(v\): valve control (0: valve is closed, 1: valve is open)

## The Watertank in Modelica¶

The following Modelica model implements the watertank. Note that we use a Boolean variable to model the valve status, and introduce a second equation explicitly defining the current inflow from the valve.

```
model Tank
parameter Real d = 0.5 "drain rate / 'size of hole'";
parameter Real f = 1.0 "fill rate in l/s (constant)";
input Boolean v(start = true) "Valve closed / open";
output Real l(start = 5) "water level";
Real inFlow "Current fill rate";
equation
der(l) = inFlow - d * l;
if v then inFlow = f; else inFlow = 0.0; end if;
end Tank;
```

## Creating an FMU for the Watertank¶

OpenModelica can export Modelica models as FMUs. This can be done by opening
the model in the OMEdit application, or from the command line via the `omc`

program. To generate an FMU from the command line, save the above model in a
file `simple_tank.mo`

and create a file `generate_fmu.mos`

with the
following content:

```
installPackage(Modelica);
loadModel(Modelica);
loadFile("simple_tank.mo");
buildModelFMU(Tank, version="2.0", fmuType="me_cs");
getErrorString()
```

Then, run the command `omc generate_fmu.mos`

, which should result in a file
`Tank.fmu`

.

## Controlling the Watertank from SMOL¶

SMOL can instantiate an FMU and control it. Create a file `simple_tank.smol`

with the following contents:

```
main
FMO[in Boolean v, out Double l] de =
simulate("Tank.fmu", v = False, d = 0.5, f = 1.0);
print(de.l);
while de.l > 2 do
de.tick(1.0);
print(de.l);
end
de.v = True;
while de.l < 5 do
de.tick(1.0);
print(de.l);
end
end
```

This SMOL program creates an instance of the tank FMU and instantiates its parameters and inputs (Lines 2-3), advances time until the water level in the tank decreases below 2 (Lines 5-8), then turns on the valve (Line 9) and advances time until the water level increases above 5 (Lines 10-13).