JModelica User Guide - Version.2.10 の 5.4.3. Simulation of an Engine model with input のシミュレーションを実行します。
このモデルは Modelica.Mechanics.MultiBody.Examples.Loops.EngineV6_analytic のエンジンの負荷となるトルクコンポーネントを、回転数から計算する QuadraticSpeedDependentTorque から、入力信号として設定可能な Torque に変更したものです。トルクは入力信号 u で設定します。
モデルのソースコードを作成します。
%%writefile EngineV6.mo
model EngineV6_analytic_with_input
output Real engineSpeed_rpm= Modelica.SIunits.Conversions.to_rpm(load.w);
output Real engineTorque = filter.u;
output Real filteredEngineTorque = filter.y;
input Real u;
import Modelica.Mechanics.*;
inner MultiBody.World world;
MultiBody.Examples.Loops.Utilities.EngineV6_analytic engine(
redeclare model Cylinder = MultiBody.Examples.Loops.Utilities.Cylinder_analytic_CAD
);
Rotational.Components.Inertia load(
phi(start=0,fixed=true),
w(start=10,fixed=true),
stateSelect=StateSelect.always,J=1
);
Rotational.Sensors.TorqueSensor torqueSensor;
Rotational.Sources.Torque torque;
Modelica.Blocks.Continuous.CriticalDamping filter(
n=2,initType=Modelica.Blocks.Types.Init.SteadyState,f=5
);
equation
torque.tau = u;
connect(world.frame_b, engine.frame_a);
connect(torque.flange, load.flange_b);
connect(torqueSensor.flange_a, engine.flange_b);
connect(torqueSensor.flange_b, load.flange_a);
connect(torqueSensor.tau, filter.u);
annotation (experiment(StopTime=1.01));
end EngineV6_analytic_with_input;
Overwriting EngineV6.mo
コンパイルして FMU を作成します。
from pymodelica import compile_fmu
name = compile_fmu("EngineV6_analytic_with_input", "EngineV6.mo")
入力信号を未設定 (u = 0) のままシミュレーションを実行します。
from pyfmi import load_fmu
model = load_fmu(name)
opts = model.simulate_options()
opts["ncp"] = 1000
res = model.simulate(options=opts)
Final Run Statistics: --- Number of steps : 1789 Number of function evaluations : 3615 Number of Jacobian evaluations : 274 Number of function eval. due to Jacobian eval. : 1096 Number of error test failures : 28 Number of nonlinear iterations : 2519 Number of nonlinear convergence failures : 0 Number of state function evaluations : 4230 Number of state events : 273 Solver options: Solver : CVode Linear multistep method : BDF Nonlinear solver : Newton Linear solver type : DENSE Maximal order : 5 Tolerances (absolute) : 1e-06 Tolerances (relative) : 0.0001 Simulation interval : 0.0 - 1.01 seconds. Elapsed simulation time: 1.02757716179 seconds.
シミュレーション結果をプロットします。
%matplotlib notebook
import matplotlib.pyplot as plt
plt.figure(1)
plt.subplot(3,1,1)
plt.plot(res["time"],res["u"])
plt.legend(["Load Torque"], loc='lower right')
plt.ylabel("Torque [N.m]")
plt.grid(b=True, linestyle="--")
plt.subplot(3,1,2)
plt.plot(res["time"],res["filteredEngineTorque"])
plt.legend(["Filtered Engine Torque"], loc='lower right')
plt.ylabel("Torque [N.m]")
plt.grid(b=True, linestyle="--")
plt.subplot(3,1,3)
plt.plot(res["time"],res["engineSpeed_rpm"])
plt.legend(["Engine Speed"], loc='lower right')
plt.ylabel("Speed [1/min]")
plt.grid(b=True, linestyle="--")
plt.xlabel("Time [s]")
plt.show()
入力信号を表す Python の関数を作成します。
def input_func(t):
return -100.0*t
入力信号を設定してシミュレーションを実行します。
model = load_fmu(name)
opts = model.simulate_options()
opts["ncp"] = 1000
res = model.simulate(options=opts, input=("u",input_func))
Final Run Statistics: --- Number of steps : 1619 Number of function evaluations : 3268 Number of Jacobian evaluations : 246 Number of function eval. due to Jacobian eval. : 984 Number of error test failures : 29 Number of nonlinear iterations : 2284 Number of nonlinear convergence failures : 0 Number of state function evaluations : 3782 Number of state events : 245 Solver options: Solver : CVode Linear multistep method : BDF Nonlinear solver : Newton Linear solver type : DENSE Maximal order : 5 Tolerances (absolute) : 1e-06 Tolerances (relative) : 0.0001 Simulation interval : 0.0 - 1.01 seconds. Elapsed simulation time: 1.10802078247 seconds.
シミュレーション結果をプロットします。
plt.figure(2)
plt.subplot(3,1,1)
plt.plot(res["time"],res["u"])
plt.legend(["Load Torque"], loc='upper right')
plt.ylabel("Torque [N.m]")
plt.grid(b=True, linestyle="--")
plt.subplot(3,1,2)
plt.plot(res["time"],res["filteredEngineTorque"])
plt.legend(["Filtered Engine Torque"], loc='lower right')
plt.ylabel("Torque [N.m]")
plt.grid(b=True, linestyle="--")
plt.subplot(3,1,3)
plt.plot(res["time"],res["engineSpeed_rpm"])
plt.legend(["Engine Speed"], loc='lower right')
plt.ylabel("Speed [1/min]")
plt.grid(b=True, linestyle="--")
plt.xlabel("Time [s]")
plt.show()