FMI2.0 CS のCo-Simulation Master 機能を使ってみる

JModelica.org には、FMI2.0CS の規格の FMU を読み込んで Co-Simulation モデルを構築するMasterツールの機能があります。 この機能を使用して FMI10CS_BouncingBall.ipynb と同様の Co-Simulation モデルを作成します。

BouncingBall モデル

BouncingBall モデルのソースコードを作成します。入力信号は反発係数$e$、出力信号は高さ$y=h$です。

In [1]:
%%writefile BouncingBall.mo
model BouncingBall
  import SI = Modelica.SIunits;
  Modelica.Blocks.Interfaces.RealInput e(start=0.8);
  Modelica.Blocks.Interfaces.RealOutput y;
  SI.Length h;
  SI.Velocity v;
  parameter SI.Acceleration g = Modelica.Constants.g_n;
  parameter SI.Height h0 = 1.0;
initial equation
  h = h0;
equation
  v = der(h);
  der(v) = -g;
  y = h;
  when h < 0 then
    reinit(v, -e * pre(v));
  end when;
end BouncingBall;

FMI2.0 for Co-Simualtion の規格に従う BouncingBall モデルの FMU を生成します。

In [2]:
from pymodelica import compile_fmu
fmu = compile_fmu("BouncingBall","BouncingBall.mo", version='2.0', target='cs',compile_to = "BouncingBallCS20.fmu")

反発係数を出力するモデル

同様に、Modelica.Blocks.Souces.Step から入力信号モデルの FMU を生成します。

In [3]:
fmu = compile_fmu("Modelica.Blocks.Sources.Step", version='2.0', target='cs', compile_to = "StepCS20.fmu")

Co-Simulation モデル

2つのサブシステムモデルをロードし、パラメータを設定します。

In [4]:
from pyfmi import load_fmu
restitution = load_fmu("StepCS20.fmu")
bouncingBall = load_fmu("BouncingBallCS20.fmu")
restitution.set("height",-0.3)
restitution.set("offset", 1.0)
restitution.set("startTime",1.0)

Co-Simulation モデルを構成するサブシステムモデルのリストと接続関係のリストを作成します。

In [5]:
models = [restitution, bouncingBall]
connections = [(restitution, "y", bouncingBall,"e")]

Co-Simulation モデルを作ります。

In [6]:
from pyfmi.master import Master
coupled_simulation = Master(models, connections)
WARNING:root:No dependency information for the outputs was found in the model description. Assuming complete dependency with the exception if the output is a state by itself.

Co-Simulation の実行

シミュレーションの開始時刻、終了時刻、communication step を決めてシミュレーションを実行します。 オプションの linear_correction 機能は、FMUの directional derivatives 機能が使えるときのみサポートされるようです。

In [7]:
t_start = 0.0
t_end = 3.0
dt = (t_end - t_start)/500
opts = coupled_simulation.simulate_options()
opts["step_size"] = dt
opts["linear_correction"] = False
res = coupled_simulation.simulate(start_time = t_start, final_time = t_end, options = opts)
Elapsed initialization time: 0.000314950942993 seconds.
Master Algorithm options:
 Algorithm             : Jacobi (fixed-step)
  Execution            : Serial
 Extrapolation Order   : 0
 Step-size             : 0.006
 Algebraic loop        : False
  Linear Correction    : False

Statistics: 
 Number of global steps        : 500

Simulation interval      : 0.0 - 3.0 seconds.
Elapsed simulation time  : 0.270776987076 seconds.
 0.003081 seconds spent in StepCS20.
 0.003817 seconds spent in BouncingBallCS20.
 0.239775 seconds spent saving simulation result.

シミュレーション結果をプロットします。

In [8]:
%matplotlib inline
import matplotlib.pyplot as plt
t = res[restitution]["time"]
e = res[restitution]["y"]
h = res[bouncingBall]["y"]
plt.figure(1)
plt.plot(t,e,t,h)
Out[8]:
[<matplotlib.lines.Line2D at 0x7f28ad8b03d0>,
 <matplotlib.lines.Line2D at 0x7f28ad8b0510>]
In [ ]: