PyFMI / JModelica-暂停仿真并使用修改后的参数从状态重启

时间:2018-11-28 18:14:45

标签: modelica fmi jmodelica

我正在使用Dymola 2019将我的Modelica模型转换为FMU,然后使用JModelica模拟(我使用的是2018-03-15的JModelica 2.2版)。我的目标是能够模拟一个特定的时期,分析结果,基于这些结果修改某些参数,然后在使用新参数值的同时从中断处继续进行先前的模拟。

我知道从技术上讲get_fmu_stateset_fmu_state可以做到这一点,但是当我尝试实现它时,我并没有设法使其起作用,而且似乎没有是使用这些功能之一的PyFMI目录中的任何示例。我尝试了以下操作:

from pyfmi import load_fmu
model = load_fmu("FMU_generated_by_Dymola.fmu")
res1 = model.simulate(final_time=5.0)
state = model.get_fmu_state()
#Here I would ideally like to use res1 to vary some parameters

model = load_fmu("FMU_generated_by_Dymola.fmu")
model.initialize()
opts = model.simulate_options()
opts['initialize'] = False
model.set_fmu_state(state)
res2 = model.simulate(start_time=5.0,final_time=10.0,options=opts)

上面的代码在不引发任何异常的范围内起作用,尽管它确实在末尾打印以下警告:WARNING:root:The simulation start time (5.000000) and the current time in the model (0.000000) is different. Is the simulation start time correctly set?。但是更重要的是,当在相对复杂的模型上使用离散的Real变量(通过Modelica的sample()函数定期更改)尝试进行此操作时,该离散变量的状态在第二次仿真中似乎变得不可变。它的初始值从第一个模拟结束时开始保留,但之后不再更改。因此,先前代码中的res2与下面代码中的res3会产生实质上不同的结果:

from pyfmi import load_fmu
model = load_fmu("FMU_generated_by_Dymola.fmu")
res3 = model.simulate(final_time=10.0)

即使将res3的通信点数量加倍以更准确地反映res2,仍然存在差异。我迷茫了,为什么在使用set_fmu_state()后启动仿真时,我的真实离散变量似乎变成常量。有人有什么想法吗?我没有正确使用set_fmu_state()吗?

值得注意的是,我也曾经研究过this question,但这显然需要使用compile_fmu()而不是load_fmu()才能使用"state_initial_equations": True选项(更不用说它似乎不适用于仿真结果中未包含的变量)。我也看过this question,但这是专门针对Dymola而不是JModelica的,并且依赖于结果文件中存在的所需状态,并非总是如此。

编辑

为使我的问题更清楚,我在下面提供了一个示例模型。

model DiscreteContinuous
  discrete Real discr "Discrete variable";
  Real cont "Continuous variable";

initial equation 
  discr=0;
  cont=0;

equation 
  when sample(0,2) then
    discr=pre(discr)+1;
  end when;
  der(cont)=1;

end DiscreteContinuous;

之后,Dymola 2019用于将该模型转换为FMU格式,然后使用JModelica运行我所问的Python。首先,来自res3的以下结果符合预期:

In [1]: res3['discr'][-1]
Out [1]: 6.0

In [2]: res3['discr'][0]
Out [2]: 1.0

但是,来自res2的以下结果表明,尽管 continuous 变量在使用set_fmu_state()时的行为符合预期,但 discrete 变量在在第二次仿真中,另一只手不变:

In [3]: res2['discr'][-1]
Out [3]: 3.0

In [4]: res2['discr'][0]
Out [4]: 3.0

In [5]: res2['cont'][-1]
Out [5]: 9.9999999999999929

In [6]: res2['cont'][0]
Out [6]: 4.9999999999999964

0 个答案:

没有答案