システムとモデリング

modelica, Julia, Design Structure Matrix, SysML, 他モデリング全般について。

Open ModelicaをJuliaで操作する

久々にOpen Modelicaに手を出してみました。 今回はJuliaを使ってOpen Modelicaを操作してシミュレーションする試みです。

今年になってOpen ModlicaのJulia APIが開発されために可能になりました。

www.openmodelica.org

手順

パッケージOMJuliaを使用します。 手順はおおよそ下記GithubのReadmeに書いてあります。

github.com

注意点としては

  • Open Modelica v1.14が必要(v1.12ではシミュレーション実行時にエラー。v1.13は未検証)
  • OMJuliaはJulia公式パッケージではないのでパッケージインストール時はGithubのアドレスを指定する必要あり
  • Open ModelicaのbinにPathを通しておくこと

検証

簡単な検証を行います。 電源のないRLC回路をmodelicaでモデリングした後、Juliaを使ってシミュレーションとプロットをします。

modelicaファイルの作成

RLC回路は以下のようなものをイメージしています

f:id:Otepipi:20190815121618p:plain

これをmodelicaで記述したファイルRLC.mo`をJuliaと同じディレクトリに置きます。

model RLC "A resistor-inductor-capacitor circuit model"
  type Voltage=Real(unit="V");
  type Current=Real(unit="A");
  type Resistance=Real(unit="Ohm");
  type Capacitance=Real(unit="F");
  type Inductance=Real(unit="H");
  parameter Inductance L = 1;
  parameter Capacitance C = 1/3;
  parameter Voltage V_in = 3;
  parameter Current i_in = 3;
  Voltage V_C;
  Voltage V_R;
  Voltage V_L;
  Current i_C;
  Current i_R;
  Current i_L;
initial equation
  V_C = V_in;
  i_C = i_in; 
equation
  C*der(V_C) = i_C;
  V_R = i_R^3 + 4*i_R;
  L * der(i_L) = V_L;
  i_C = i_R;
  i_R = i_L;
  V_C + V_L + V_R = 0;
end RLC;

なおこのファイル自体Visual Studio Codeのmodelica拡張機能で書いています。シンタックスハイライトや入力補助もありかなり書きやすいです。今回の検証はOpen Modelica自体を一切起動せずに実施できます。

f:id:Otepipi:20190815122244p:plain

Juliaで実行

Julia REPLでまず使用するパッケージを宣言します。

using OMJulia
using Plots

Plotsは描画用ですね。 次にRLC.moを読み込んでやります。

RLC = OMJulia.OMCSession() 
RLC.ModelicaSystem("RLC.mo","RLC")

ModelicaSystemの第一引数はmodelicaのファイル名、第二引数はそのファイル中で使用するmodel名称になります。

シミュレーションを実行するには

RLC.simulate()

を実行します。しかしこれは内部で処理するだけなので特に反応はありません。 シミュレーション結果を得るにはgetSolutions命令を使用します。他にも様々な命令がありますので、それについては上述したOMJuliaのサイトを確認してください。

t,i_C,V_C,di_C,dV_C = RLC.getSolutions(["time", "i_C", "V_C", "der(i_L)", "der(V_C)"]);

この結果をプロットしてみます。

plot(t, V_C)
xlabel!("time")
ylabel!("Voltage")
title!("RLC capacitor")

f:id:Otepipi:20190815123640p:plain

デフォルトのシミュレーション時間が1.0までなので中途半端なところで終わっています。 シミュレーションの設定を変更するにはsetSimulationOptionsを宣言して再度シミュレーションを実行する必要があります。

RLC.setSimulationOptions(["stopTime=10", "stepSize=0.01"])
RLC.simulate()
t,i_C,V_C,di_C,dV_C = RLC.getSolutions(["time", "i_C", "V_C", "der(i_L)", "der(V_C)"]);
plot(t, V_C)
xlabel!("time")
ylabel!("Voltage")
title!("RLC capacitor")

f:id:Otepipi:20190815124026p:plain

無事キャパシタの減衰を確認することができました。

ベクトル場の描画

modelicaをJuliaから使用する利点のひとつは、(Open Modelicaよりは)強力なグラフ描画機能が利用できることだと思います。Plots.jlを使用すればグラフの種類や軸のとり方など多彩です。折角なので最後にRLC回路のベクトル場の一部を描画します。

RLC.setSimulationOptions(["stopTime=10", "stepSize=0.1"])
RLC.simulate()
t,i_C,V_C,di_C,dV_C = RLC.getSolutions(["time", "i_C", "V_C", "der(i_L)", "der(V_C)"]);
r = 0.03
quiver(i_C, V_C, quiver=(r*di_C, r*dV_C))
xlabel!("Current")
ylabel!("Voltage")
title!("RLC ccapacitor")

f:id:Otepipi:20190815125852p:plain

modelicaの言語仕様は素晴らしいと思いながらもOpen Modelicaの操作性には辟易していました。Juliaから操作することでそこのところを改善できるのではないかなと思います。 もちろん、jupyterからも使用できます。

f:id:Otepipi:20190815130152p:plain

今回はここまでにします。