利用FMU进行FMU在线灵敏度分析

2024-10-03 11:16:36 发布

您现在位置:Python中文网/ 问答频道 /正文

主要目标

区域供热管网灵敏度分析。在

方法

  1. 使用AixLib和构建系统库的系统的Modelica模型(在Dymola中)

  2. 将模型导出为FMU协同仿真

  3. 使用SALib(敏感度分析python库)定义样本(参数扫描)

  4. 使用PyFMI在Python中的for循环中为所有单个样本运行模型(并并行化for循环,可能使用joblib在多个处理器上执行模拟)

  5. SALib将执行基于方差的敏感性分析(http://salib.readthedocs.io/en/latest/basics.html#an-example

第一步

Ishigami函数的简单modelica模型(不依赖时间)。此函数通常用于测试灵敏度分析方法(https://www.sfu.ca/~ssurjano/ishigami.html)。在

python代码(包括用PyFMI加载FMU和参数sweep)工作正常。在

问题

经过一定数量的模拟,我们得到了一个错误。错误输出看起来并不总是相同的。有时候我们

FMUException: Error loading the binary. Could not load the DLL: Eine DLL-Initialisierungsroutine ist fehlgeschlagen.

转换:DLL初始化例程失败。在

有时我们得到:

FMUException: Error loading the binary. Could not load the DLL: Für diesen Befehl ist nicht genügend Speicher verfügbar.

翻译:没有足够的内存来执行这个命令。在

错误发生在大约650次模拟运行之后。 如果在一个或多个循环中的一个或多个模拟都是在一个或多个循环中执行的,则为一个或多个循环执行的模拟。通过重新启动python控制台/进程,可以再次运行新的模拟。在

工作环境:

Windows10,Python2.7,使用pip(不是JModelica)安装的PyFMI,Jupyther笔记本电脑上的Python编码(在Mozilla Firefox上)

我们只有python和PyFMI的基本知识,并且正在努力解决这个错误!在

附件

下面你可以找到

  • 用于从Dymola导出协同仿真FMU的Modelica模型(使用CVode)

  • Python代码为py文件

  • 输出python代码的散点图。

我还在JModelica论坛上发了一个帖子,你可以直接下载这些文件(FMU、Jupyter笔记本等): http://www.jmodelica.org/27925

Modelica模型

model IshigamiFunction

  final parameter Real a = 7;

  final parameter Real b = 0.05;

  parameter Real x1 = 1;

  parameter Real x2 = 1;

  parameter Real x3 = 1;

  Real f;

equation

  f = sin(x1) + a * sin(x2)^2 + b * x3^4 * sin(x1);

end IshigamiFunction;

Python代码

^{pr2}$

从python脚本输出绘图enter image description here

更新

我又做了一些测试,我发现:

根据FMU是从Dymola导出还是从JModelica导出,其行为不同:

使用从Dymola导出的FMU:

  • load_fmu行从for循环中取出似乎是可行的
  • 即使load_fmu不在for循环中,有时也有 崩溃
  • model.set(...)命令之前添加新行model.reset() 似乎工作得很好
  • 无论有无模拟结果都是不同的 model.reset()->;为什么??
  • model.instantiate()而不是{}->;不起作用。这个 任务管理器中的内存使用量增加到大约350MB,然后

    FMUException: Failed to instantiate the model. See the log for possibly more information.

日志级别为4的日志文件:

FMIL: module = FMILIB, log level = 4: XML specifies FMI standard version 2.0
FMIL: module = FMILIB, log level = 4: Loading 'win32' binary with 'default' platform types
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiInstantiateModel completed
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiInstantiateSlave
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiInstantiateModel completed
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiInstantiateSlave
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiSetReal: x1 = -1.76101
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiSetReal: x2 = -2.53414
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiSetReal: x3 = 0.116583
FMIL: module = Model, log level = 4: [][FMU status:OK] fmi2SetupExperiment: startTime is set to 0
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiEnterSlaveInitializationMode...
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiSetTime to 0
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiEnterSlaveInitializationMode completed
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiExitSlaveInitializationMode...
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiExitSlaveInitializationMode completed
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiGetReal: x1 = -1.76101
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiGetReal: x2 = -2.53414
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiGetReal: x3 = 0.116583
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiGetReal: a = 7
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiGetReal: b = 0.05
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiGetReal: f = 1.29856
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiGetDerivatives
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiGetDerivatives
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiGetDerivatives
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiGetDerivatives
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiGetDerivatives
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiGetDerivatives
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiGetDerivatives
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiGetDerivatives
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiSetTime to 0.002
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiDoStep
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiSetTime to 0.004
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiDoStep
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiSetTime to 0.006
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiDoStep
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiGetDerivatives
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiSetTime to 0.008
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiDoStep
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiSetTime to 0.01
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiDoStep
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiSetTime to 0.012
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiDoStep
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiSetTime to 0.014
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiDoStep
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiSetTime to 0.016
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiDoStep
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiSetTime to 0.018
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiDoStep
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiSetTime to 0.02
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiDoStep

...

FMIL: module = Model, log level = 4: [][FMU status:OK] fmiDoStep
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiSetTime to 0.99
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiDoStep
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiSetTime to 0.992
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiDoStep
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiSetTime to 0.994
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiDoStep
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiSetTime to 0.996
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiDoStep
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiSetTime to 0.998
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiDoStep
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiSetTime to 1
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiDoStep
FMIL: module = Model, log level = 1: [][FMU status:Fatal] The license file was not found. Use the environment variable "DYMOLA_RUNTIME_LICENSE" to specify your Dymola license file.

FMIL: module = Model, log level = 1: [][FMU status:Fatal] Instantiation failed
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiFreeModelInstance

使用从JModelica导出的FMU:

  • 即使load_fmu在for循环中也能正常工作(但速度较慢)
  • 这种经验与第5.4.2章(http://www.jmodelica.org/api-docs/usersguide/2.1/ch05s04.html#d0e1854)JModelica文档中给出的示例不符,其中load_fmu命令是在for循环中给出的
  • 命令model.reset()model.instatiate()在中是必需的 for循环(与Dymola FMU相反)->;为什么??

我的问题:

什么是正确的为什么要执行一个循环,它用不同的参数多次模拟一个FMU模型?在

使用^{}、model.instatiate()还是一个都没有?在

附件

下面是一个显示有model.reset()的for循环与没有它的for循环之间的区别。 enter image description here

从JModelica导出的FMU(不需要任何许可证)可以在这里下载:http://www.jmodelica.org/27925#comment-6668


Tags: to模型logformodelstatusoklevel
2条回答

对我来说这是个记忆问题。在Win任务管理器中运行时,您能观察到分配的内存吗? 顺便说一句,你的FMU(来自你的交叉帖子)需要DYMOLA_RUNTIME_许可证,这限制了只允许DYMOLA用户复制。在

Dymola FMU的正确方法是在for循环外调用fmi/fmi2instantate。如果在没有二进制输出许可证的情况下导出FMU,这些功能将分配内存并执行许可证检查。通过调用fmiResetSlave/fmi2Reset,您可以在不分配新内存的情况下将FMU重置为实例化状态。在

  • fmiinstantateslave/fmi2安装

    创建一个可用于模拟的FMU实例,多个调用将创建多个实例,每个实例都需要新的内存分配和适当的删除。

  • F导线

    将实例重置为实例化之后和调用fmiInitializeSlave/fmi2itilize之前的状态。这样更快,不需要新的动态内存分配,应该在您的案例中使用。

此外,在调用fmifreeselveinstance/fmi2FreeInstance时,Dymola FMU的未导出二进制文件的许可证检查可能会泄漏旧版本Dymola中的内存。这在大多数情况下都不是问题,因为你通常在终止FMU时终止程序。通过在for循环中实例化你的FMU,这会变得很严重,你的内存将最终结束。 如果您联系Dymola支持部门,则应提供修复包。在

相关问题 更多 >