Python-Dymola接口:如何实时检查Dymola模型的进展?

huangapple go评论152阅读模式
英文:

Python-Dymola interface: How is it possible to check in real time the progress of a Dymola model?

问题

我开始使用Python来运行我的Dymola模型,因为我认为它比Dymola脚本“.mos”具有更多潜力。我已经设置了与“DymolaExample.py”相似的代码。

from dymola.dymola_interface import DymolaInterface
import os

# 实例化Dymola接口并启动Dymola
dymola = DymolaInterface()

# 调用Dymola中的函数并检查其返回值
result = dymola.simulateModel(
    "Modelica.Mechanics.Rotational.Examples.CoupledClutches",
    resultFile=r"N:\SOLAR.PROYECTOS.4 OTROS\GRUPO HIBRIDO CSP-FV\InterfacePythonDymola\python_interface\examples\nf")
if not result:
    print("Simulation failed. Below is the translation log.")
    log = dymola.getLastErrorLog()
    print(log)
    exit(1)

# dymola.plot(["J1.w", "J2.w", "J3.w", "J4.w"])
# plotPath = os.getcwd() + "/plot.png"
# dymola.ExportPlotAsImage(plotPath)

然而,我正在运行具有高计算成本的系统以评估其年度性能。在代码运行时是否有可能查看Dymola的结果?或者至少从Python中实时查看“模拟时间”,以确定模拟是否需要更多时间?

英文:

I am starting to use Python to run my Dymola models since I think that it has more potential than the Dymola scripts “.mos”. I’ve already set a similar code than the “DymolaExample.py”.

from dymola.dymola_interface import DymolaInterface
import os

# Instantiate the Dymola interface and start Dymola
dymola = DymolaInterface()

# Call a function in Dymola and check its return value
result = dymola.simulateModel(
    "Modelica.Mechanics.Rotational.Examples.CoupledClutches",
    resultFile=r"N:\SOLAR.PROYECTOS.4 OTROS\GRUPO HIBRIDO CSP-FV\InterfacePythonDymola\python_interface\examples\nf")
if not result:
    print("Simulation failed. Below is the translation log.")
    log = dymola.getLastErrorLog()
    print(log)
    exit(1)

# dymola.plot(["J1.w", "J2.w", "J3.w", "J4.w"])
# plotPath = os.getcwd() + "/plot.png"
# dymola.ExportPlotAsImage(plotPath)

However, I am running models to evaluate the annual performance of a system with high computational cost.
Is it possible to see the Dymola results while the code is running? Or at least see what is the Simulating Time in “real-time” from Python to see if the simulation is going to take much more time?

答案1

得分: 2

Dymola定期将正在运行的模拟的当前值写入结果文件。要实现您的目标,您可以读取结果文件并检查时间变量的最后一个值。为了做到这一点,我们必须异步运行模拟,例如在一个线程中(请参见https://stackoverflow.com/questions/1239035/asynchronous-method-call-in-python以获取更多解决方案)。

当线程仍然存活时,我们读取结果文件。这不能很容易地通过Dymola的Python接口完成,但SDF包使这成为一个简单的任务。
为了确保我们在模拟开始之前不尝试访问结果文件,首先显式地进行模型转换,只有实际模拟在线程中运行。

import os
import time
import threading
from pathlib import Path

import sdf
from dymola.dymola_interface import DymolaInterface


def sim():
    """在Dymola中模拟模型。"""
    ok = dymola.simulateModel(model, stopTime=stop_time,
                              resultFile=result_file.with_suffix('').as_posix())
    if ok:
        print("完成。")
    else:
        print("模拟失败。")


def get_time():
    """检查当前模拟时间。"""
    time = sdf.load(result_file.as_posix(), '/Time')
    print(f"time: {time.data[-1]:.1f}")


def create_slow_model():
    """创建包含近实时运行的模型的新包。"""
    dymola.setClassText("", """package MyPackage
end MyPackage;""")
    dymola.setClassText("MyPackage", """model SlowSim
  Modelica_DeviceDrivers.ClockedBlocks.OperatingSystem.SynchronizeRealtime synchronizeRealtime;
end SlowSim;"")


# 用户设置
model = "MyPackage.SlowSim"
stop_time = 10
check_interval = 1   # 以秒为单位

cwd = Path(os.getcwd())
result_file = cwd / f"{model.split('.')[-1]}.mat"

# 初始化
dymola = DymolaInterface()
create_slow_model()

# 转换模型
dymola.translateModel(model)

# 模拟
thr = threading.Thread(target=sim)
thr.start()
while thr.is_alive():
    get_time()
    time.sleep(check_interval)

英文:

Dymola periodically writes the current values of a running simulation to the result file. To achieve your goal, you can read the result file and check for the last value of the time variable. To do so, we have to run our simulation asynchronously, e.g. in a thread (see https://stackoverflow.com/questions/1239035/asynchronous-method-call-in-python for more solutions).

While the thread is alive, we read the result file. This can not be done easily with the dymola python interface, but the SDF package makes this a trivial task.
To make sure that we don't try to access the result file before the simulation is started, the model is explicitly translated first and only the actual simulation runs in the thread.

import os
import time
import threading
from pathlib import Path

import sdf
from dymola.dymola_interface import DymolaInterface


def sim():
    """Simulate model in Dymola."""
    ok = dymola.simulateModel(model, stopTime=stop_time,
                              resultFile=result_file.with_suffix('').as_posix())
    if ok:
        print("done.")
    else:
        print("simulation failed.")


def get_time():
    """Check current simulation time."""
    time = sdf.load(result_file.as_posix(), '/Time')
    print(f"time: {time.data[-1]:.1f}")


def create_slow_model():
    """Create new package with model that runs approximately in realtime."""
    dymola.setClassText("", """package MyPackage
end MyPackage;""")
    dymola.setClassText("MyPackage", """model SlowSim
  Modelica_DeviceDrivers.ClockedBlocks.OperatingSystem.SynchronizeRealtime synchronizeRealtime;
end SlowSim;""")


# user setup
model = "MyPackage.SlowSim"
stop_time = 10
check_interval = 1   # in seconds

cwd = Path(os.getcwd())
result_file = cwd / f"{model.split('.')[-1]}.mat"

# init
dymola = DymolaInterface()
create_slow_model()

# translate
dymola.translateModel(model)

# simulate
thr = threading.Thread(target=sim)
thr.start()
while thr.is_alive():
    get_time()
    time.sleep(check_interval)

huangapple
  • 本文由 发表于 2023年3月15日 20:20:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/75744612.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定