2

我正在使用 Dymola 2019 将我的 Modelica 模型转换为 FMU,然后我使用 JModelica 进行模拟(我从 2018 年 3 月 15 日开始使用 JModelica 2.2 版)。我的目标是能够模拟某个时期,分析结果,根据这些结果修改某些参数,然后在使用新参数值的同时从中断的地方继续之前的模拟。

我知道get_fmu_stateandset_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?. 但更重要的是,当在一个相对复杂的模型上尝试使用 Modelicasample()函数定期更改的离散实变量时,该离散变量的状态似乎在第二次模拟中变得不可变。它的初始值从第一次模拟结束时延续,但之后不再改变。因此,在前面的代码中,将产生与以下代码中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()正确使用吗?

还值得注意的是,我也看过这个问题,但这显然需要使用compile_fmu()而不是load_fmu()为了使用该"state_initial_equations": True选项(更不用说它似乎不适用于模拟中未包含的变量结果)。我也看过这个问题,但这是专门针对 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表明,虽然连续变量在使用 时表现如预期,但另一方面set_fmu_state()离散变量在整个第二次模拟中不会发生变化:

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
4

0 回答 0