使用PyFMI多次仿真Dymola FMU时重置初始化失败的问题求助
看起来你遇到的问题核心是FMU状态残留加上初始化流程顺序错误,导致第二次初始化时模型变量处于异常状态(比如NaN),非线性求解器无法处理。我之前也碰到过Dymola生成的FMU在PyFMI中重复运行的类似问题,给你几个可行的解决方案:
1. 修正FMU仿真的标准流程顺序
你的初始代码里调用initialize()的顺序错了!按照FMU的官方规范,正确的流程应该是:
加载FMU → 设置实验(setup_experiment) → 初始化(initialize) → 执行仿真步(do_step)
你之前先调用了initialize()再setup_experiment(),这会导致FMU的初始状态没有被正确配置,第一次仿真可能侥幸运行,但后续重置时必然出问题。先把这个顺序改过来:
# 正确的初始化流程 model = load_fmu(r'path', kind="CS", log_level=4) model.setup_experiment(start_time=start_time) # 先设置实验 model.initialize() # 再初始化
2. 每次仿真后重置FMU状态(而非仅重新初始化)
很多Dymola生成的FMU不会仅通过initialize()就完全重置内部状态(比如离散状态、代数变量的残留值),需要调用标准的reset()方法来回到初始状态。修改你的循环代码:
model = load_fmu(r'path', kind="CS", log_level=4) for run in range(2): model.setup_experiment(start_time=start_time) model.initialize() for step in steps: status = model.do_step([:], new_step=True) # 完成一轮仿真后,先重置再准备下一轮 model.reset()
reset()方法会清除所有仿真过程中产生的状态变量值,将FMU恢复到刚加载后的初始状态,这样下一轮的setup_experiment和initialize就能正常执行。
3. 若reset仍无效,尝试每次循环重新加载FMU
如果某些特殊的Dymola FMU不支持reset()(比如模型中有自定义的非重置状态),可以在每次循环中重新加载FMU实例,彻底避免状态残留:
for run in range(2): # 每轮都重新加载FMU,确保完全干净的初始状态 model = load_fmu(r'path', kind="CS", log_level=4) model.setup_experiment(start_time=start_time) model.initialize() for step in steps: status = model.do_step([:], new_step=True) # 仿真结束后可以调用terminate()释放资源(可选) model.terminate()
这种方法虽然会增加一点加载开销,但能100%避免状态残留问题,适合对稳定性要求高的场景。
4. 检查Dymola导出FMU的设置
你可以回到Dymola中检查FMU导出的配置:
- 确保勾选了Support Reset选项(在FMU导出对话框的Advanced设置里)
- 检查模型中是否有使用
noReset修饰的变量,这类变量不会在reset时被重置,可能导致异常状态残留 - 尝试将FMU的导出版本设置为2.0或2.1(PyFMI对新版本FMU的状态重置支持更好)
为什么FMpy能正常运行?
FMpy内部在每次仿真循环时会自动处理FMU的状态重置,甚至可能重新加载FMU实例,所以不会出现状态残留问题,但代价就是速度变慢——这也侧面验证了你的问题根源是状态没有被正确重置。
内容的提问来源于stack exchange,提问作者Phil




