准备FMU:交换模型输入的模型参数

时间:2014-08-14 10:24:02

标签: python-2.7 input parameters modelica fmi

我想使用Dymola 2014将Modelica模型导出为用于协同仿真的FMU。我计划使用pyfmi完成协同仿真。

为了测试这个,我试图模拟通过两个流体边界之间的管道的流体流动。我希望流体源的压力成为模型的输入。我的计划是从外部计算这个压力,并在每个时间步输入Modelica模型。

我的所有标准库组件的初始模型是:

model SE_BVP "BVP for stack exchange."
  inner Modelica.Fluid.System system;
  Modelica.Fluid.Pipes.StaticPipe pipe(
    redeclare package Medium = Modelica.Media.Air.MoistAir,
    length=1,
    diameter=1);
  Modelica.Fluid.Sources.Boundary_pT boundary1(nPorts=1, redeclare package
    Medium = Modelica.Media.Air.MoistAir);
  Modelica.Fluid.Sources.Boundary_pT boundary(nPorts=1, redeclare package Medium=
    Modelica.Media.Air.MoistAir, use_p_in=true);
  Modelica.Blocks.Interfaces.RealInput p_in1;

equation
   connect(pipe.port_b, boundary1.ports[1]);
   connect(boundary.ports[1], pipe.port_a);
   connect(boundary.p_in, p_in1);
end SE_BVP;

然后我将其包含在两个测试模型中:

model SE_BVP_test_1
 Real preVal = 101335;
 SE_BVP SE_BVP_1;

equation
 SE_BVP_1.p_in1 = preVal;

end SE_BVP_test_1; 

并使用参数类型,这是基于@Thierry

的建议完成的
model SE_BVP_test_2
  parameter Real preVal = 101335;
  SE_BVP SE_BVP_1;

equation
  SE_BVP_1.p_in1 = preVal;

end SE_BVP_test_2; 

运行这些模型会给我相同的结果:

No Variable typing.

With parameter typing

两种型号都在Dymola内工作。

现在我希望加载fmu并使用pyfmi进行模拟,所以我编写了这个脚本:

  import pyfmi
  import numpy as np
  import pylab as P
  import os

  # Define the FMU to test
  fmuDirNam = "SE_BVP_Test_1"  # CS 2.0 type FMU
  fmuNam = fmuDirNam + ".fmu"

  # Define the input var
  inVar = "preVal"

  # Get the path to the FMU
  curr_dir = os.path.dirname(os.path.abspath(__file__))
  par_dir = os.path.dirname(curr_dir)
  path_to_fmu = os.path.join(par_dir, "projectFMUs", fmuDirNam)

  # Load the model
  model = pyfmi.load_fmu(os.path.join(path_to_fmu, fmuNam))

哪个失败并给我以下错误:

FMIL: module = FMI2XML, log level = 2: XML element 
'Real': could not parse value for real attribute  
 'start'='pipMod.pipe.flowModel.states[1].p/(gasConstant_Unique7( 
      Modelica.Media.Air.MoistAir.ThermodynamicState(     
 p =

FMIL: module = FMI2XML, log level = 2: XML element 
'Real': could not parse value for   real attribute 
'start'='pipMod.pipe.flowModel.states[2].p/(gasConstant_Unique7(             
Modelica.Media.Air.MoistAir.ThermodynamicState(             
p =

FMIL: module = FMI2XML, log level = 2: XML element 
'Real': could not parse value for real attribute 
'start'='Modelica.Media.Incompressible.TableBased.Polynomials_Temp.evaluate({-4.96717436974791E-11, 5.06626785714286E-08, 1.72937731092437
FMIL: module = FMI2XML, log level = 2: XML element 'Real': could not parse value for real attribute 
'start'='Modelica.Media.Incompressible.TableBased.Polynomials_Temp.evaluate({-4.96717436974791E-11, 5.06626785714286E-08, 1.72937731092437

FMIL: module = FMI2XML, log level = 1: No model structure information available. 
Cannot continue.

FMIL: module = FMI2XML, log level = 1: Parse error at line 2703:
parsing aborted

来自追溯:

pyfmi.fmi.FMUException: The XML-could not be read. Parse error at line 2703:
parsing aborted

如果模型在Dymola中正确模拟,可能导致此解析错误的原因是什么?

  • 我也尝试使用CS 1.0导出并引发相同的异常,尽管这次读取fmu的模块不同。

  • 我认为通过删除inputparameter标签,出现了一些神秘的变量问题,但没有。即使使用parameter中的Test_2标记,也会引发相同的异常(CS 2.0)。

总结:Dymola 2014,python 2.7.x,CO-simulation 2.0的FMI

5 个答案:

答案 0 :(得分:4)

@RwardBound:如果你想在模拟过程中更改参数,那么我建议使用FMI 2.0而不是FMI 1.0 FMU。 FMI 2.0支持此功能。例如,最新版本的Dymola能够生成这样的FMU。我认为PyFMI也支持FMI 2.0。

一切顺利, 亨利

答案 1 :(得分:1)

测试Dymola模型以便作为FMU(或Modelica库)导出的最佳实践是构建顶级模型进行测试。然后,您可以构建专用于导出模型的模拟环境。

让我们采取简单的划分10 / u"模型示例:

model div10
  Modelica.Blocks.Math.Division division;
  Modelica.Blocks.Interfaces.RealInput u(start=10);
equation 
  division.u1 = 10;
  connect(division.u2, u);
end div10;

然后你必须创建这个顶级模型来测试 div10 模型:

   model div10_tester  
      parameter Real default_u = 2.0;
      div10 div10_1;
    equation 
      div10_1.u = default_u;
    end div10_tester;

另一种解决方案可能是使用" dsu.txt" (注意:如果单独模拟div10,则start = 10语句将无效,如错误日志所示:如果没有" dsu.txt" file =>所有输入都设置为0 )。 但这是非常有限的,因为它只指定起始值。

答案 2 :(得分:1)

在初始化时解决输入= 0的简单方法可能是添加一个max()块来比较输入和一些非常小的数字。

例如:

input = max(a very small positive number, input) if your input is always greater than zero. 

如果您的参数(输入)会切换标志,我相信您足够聪明,可以找到类似的方法。

答案 3 :(得分:1)

问题在于选择了媒体模型。 Modelica.Media.Air.MoistAir是空气状态的压力和温度耦合模型。因此,流体密度,焓等的初始值是边界压力的函数。在导出到FMU期间,管道中流体的状态变量的start值将作为表达式写入XML文件:

<ScalarVariable
   name="SE_BVP_1.pipe.flowModel.rhos[1]"
   valueReference="100663348"
   variability="constant">
<Real
  unit="kg/m3"
  min="0.0"
   start="SE_BVP_1.pipe.flowModel.states[1].p/(gasConstant_Unique7(
     Modelica.Media.Air.MoistAir.ThermodynamicState(
       p = SE_BVP_1.pipe.flowModel.states[1].p,
       T = SE_BVP_1.pipe.flowModel.states[1].T,
       X = {SE_BVP_1.pipe.flowModel.states[1].X[1],
                       SE_BVP_1.pipe.flowModel.states[1].X[2]}
            ))*SE_BVP_1.pipe.flowModel.states[1].T)"/>

将流体更改为Buildings.Media.GasesPTDecoupled.MoistAirUnsaturated会删除start值计算,XML会显示:

<ScalarVariable
   name="SE_BVP_1.pipe.flowModel.rhos[1]"
          valueReference="100663345"
   variability="fixed">
<Real
  unit="kg/m3"
  min="0.0"/>

pyfmi在解析期间不计算表达式,而是期望一个可以格式化为float的字符串。

答案 4 :(得分:1)

问题是由于Dymola生成的XML不正确。标量变量的start属性必须是值,而不是表达式,所有这些都根据规范。规范声明对于实数标量变量,起始值必须是浮点数,对于整数,起始值应该是int,依此类推。对于FMI 1.0和FMI 2.0也是如此(规范可以在https://fmi-standard.org/downloads读取。)

为了验证您获得的FMU是否符合标准,还有一个名为Compliance Checker的工具,该工具也可在上述站点获得。如果遇到这些类型的问题,这是一个很好的工具,可以排除导出工具导致问题的原因。

使用Dymola 2015,可以为模型SE_BVP_test_1正确生成XML,并且可以使用PyFMI进行模拟。