【问题标题】:Is it possible to build a "conditional" FMU using Modelica?是否可以使用 Modelica 构建“条件”FMU?
【发布时间】:2017-02-17 07:34:14
【问题描述】:

我有一个应用程序,我使用 Dymola 作为开发环境,但将以 FMU 形式导出模型以在另一个应用程序中使用。我正在建模的系统具有可互换的组件,使其非常适合在 Modelica 中建模。但是,当我想以 FMU 形式导出模型时,我不确定是否可以利用该功能。

考虑下面这个非常简单的包。该包的目标是定义两个非常简单的模型,并允许用户在执行模型时在可能的模型之间进行选择。虽然这在 Modelica IDE 中很容易做到,但我需要在 FMU 中实现类似的功能。

部分模型定义了一个模型,其中 y = p0 + p1*x。这两个扩展模型只是为参数 p0 和 p1 分配不同的值。最后,TestModel 添加了一个名为 modelIndex 的参数,用于定义两种可能的模型类型的条件表达式。在 Dymola 中这很有效,因为用户可以轻松设置参数 modelIndex 的值。我试图通过将 modelIndex 作为 FMU 的输入来确定是否可以通过 FMU 完成此操作。但是,如果我为 modelIndex 变量设置注释 Evaluate=false,编译将失败。声明的错误是: “当前版本的 Modelica 翻译器只能处理具有固定条件的条件组件......条件声明条件中使用的所有变量都必须声明为常量或参数。”

如果有人可以帮助提供有关如何创建条件 FMU 的指导,我们将不胜感激。这个简单的示例仅用于演示该问题。被建模的真实系统有 4-5 个主要组件,每个组件都有 5 种以上可能的不同模型,从而产生大量可能的排列。简单地批量导出所有配置可能不可行。

谢谢! 贾斯汀

package ConfigurableModel 
  "Package to test whether or not models can be configured by external inputs"
  partial model partialModel 
    "Partial model used to control selectable options in Dymola"

    Modelica.Blocks.Interfaces.RealInput x(start = 1) "input value";
    Modelica.Blocks.Interfaces.RealOutput y "output value";

    parameter Real p0 = 0;
    parameter Real p1 = 0;

  equation 
    y = p0 + p1*x;
      annotation (Icon(coordinateSystem(preserveAspectRatio=false)), Diagram(
      coordinateSystem(preserveAspectRatio=false)));
  end partialModel;

  model linearModel_NoOffset "Linear model with no offset"
    extends partialModel(p0 = 0, p1 = 1);
  end linearModel_NoOffset;

  model linearModel_Offset "Linear model with offset"
    extends partialModel(p0=1, p1=1);
  end linearModel_Offset;

  model TestModel "Model to test configurability"
    // parameter Integer modelIndex = 2 "1 = linear_NoOffset, 2 = linear_Offset" annotation(Evaluate=false);

    parameter Integer modelIndex = 2 "1 = linear_NoOffset, 2 = linear_Offset";

    // Conditional instances, only one model is created based upon value of modelIndex
    linearModel_NoOffset linear_NoOffset if modelIndex == 1;
    linearModel_Offset linear_Offset if modelIndex == 2;

    // Input and output blocks
    Modelica.Blocks.Sources.Constant xMaster(k=1) annotation (Placement(transformation(extent={{-100,-10},{-80,10}})));
    Modelica.Blocks.Interfaces.RealOutput yMaster annotation (Placement(transformation(extent={{100,-10},{120,10}})));

  equation 
    // Note that only the connections for the components that exist will be used

    // Connect input to each model instance
    connect(xMaster.y, linear_NoOffset.x);
    connect(xMaster.y, linear_Offset.x);

    // Connect output to each model instance
    connect(yMaster, linear_NoOffset.y);
    connect(yMaster, linear_Offset.y);

      annotation (Icon(coordinateSystem(preserveAspectRatio=false)), Diagram(
      coordinateSystem(preserveAspectRatio=false)));
  end TestModel;
    annotation (uses(Modelica(version="3.2.1")));
end ConfigurableModel;

【问题讨论】:

    标签: modelica dymola


    【解决方案1】:

    据我了解,这不可能直接使用 FMI。 Modelica 面向对象的特性,如条件实例化,在 Modelica 的符号处理期间处理,然后生成作为 FMU 一部分的 C 代码(作为 C 代码或编译形式)。通过条件实例化,可以更改导出的 FMU 的许多属性(例如,具有不同数量的状态)。因此,在 FMU 中不能有一个单独的 modeldescription.xml 文件来描述 FMU 的属性。 您可以考虑将模型拆分为多个 FMU,并通过交换其中的一些来处理子系统的可变性。但是,这可能会导致比使用原始整体 Modelica 模型更复杂的数值任务,因为无法像 Modelica 编译器对整体模型执行对整体模型的优化。您的示例中的一个优点是,您的部分模型已经具有因果接口(RealInput 和 RealOutput) 接近您预期的解决方案的解决方法可能是,您在模型中同时包含子模型 linear_NoOffset 和 linear_Offset(没有“如果 modelIndex == xy”),包括由 modelIndex 触发的开关以在信号之间切换两个子模型。由于两个子模型都存在并被评估,可能会导致一些计算开销。

    【讨论】:

    • 克里斯蒂安,感谢您的回复。不幸的是,你的反应是我所期望的。如果有人知道替代方案,我将不胜感激。我正在考虑以下内容: 1. 为每个所需的子组件排列导出多个 FMU。 2. 参数化每个子组件,以便它们可以用相同的结构指定,但参数值不同。不幸的是,对于我的真实系统来说,包含多个子模型可能会造成太大的损失,因为这些模型比简单的示例案例要复杂得多。谢谢,贾斯汀
    【解决方案2】:

    您的问题听起来可以使用Elmqvist (2014) 的方法解决,尽管从那以后我没有听到更多关于这个主题的信息。我不确定 Dymola 中是否添加了任何自动方法,但您可以尝试显式地切换模型。

    【讨论】:

    • 感谢您的参考。我已经审查了这篇论文,并同意它对我的情况很有用。我已向 Hilding Elmqvist 和 Dymola 技术支持提交了问题,以评论自论文发表以来实现了哪些功能。我将根据他们的反馈提供更新的 cmets。
    • Dymola 技术支持人员表示,Elmqvist (2014) 中概述的功能迄今尚未纳入 Dymola,也不在 Dymola 2018 的计划中。但他们正在继续进一步调查,看看是否他们可以找到解决方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-08-16
    • 1970-01-01
    • 2020-09-12
    • 2012-08-25
    • 1970-01-01
    • 2022-10-13
    • 2012-10-05
    相关资源
    最近更新 更多