Modelica - 模型变体(标准的一种和更复杂的一种)

Modelica - Model variants (Standard one and more complex one)

即使几个月以来一直在使用 Modelica,我对继承和替换等高级功能还是陌生的。

我有一个标准模型(即游泳池)和一个更复杂的变体(即包括蒸发计算):这两个模型有许多我想要的共同部分 "reuse" 但它们也有一些差异: 一些方程(即质量和能量平衡方程)不同(复杂模型有更多项)并且复杂模型包括更多参数、变量和方程(即空气和蒸汽性质和定律)。

我认为我在 Modelica 中有一些可能性可以做到这一点:

  1. 写下两个独立的模型(只用了精彩的不同步复制粘贴文本功能)--我不想。
  2. 使用继承(1)编写一个具有公共定义的部分模型和两个具有特定部分的继承模型。
  3. 使用继承 (2) 编写包含不同方程组(和其他特定定义)的两个部分模型,并编写包含通用定义并继承两个部分模型之一的第三个模型(例如选择通过一个布尔参数)。实际上我不太确定我能做到这一点:部分模型将包含未定义 variables/parameters 的方程(将在继承模型中定义):可以吗?
  4. 编写标准模型并用新方程替换方程,同时添加附加定义。

我在(2)中实现了,见下面的示例1。但是我不明白如何使用替换机制(参见我在示例 2 中的失败尝试)。我哪里错了?

下面的例子是我为了理解如何去做而写的简化模型。

示例 1

package Inherited_base

  partial model Base
    parameter Real a=1;
    parameter Real b=2;
    Real c;
    Real d;
  equation 
    c+d = b;
  end Base;

  model Variant_1
    extends Base;
  equation 
    c = time*a;
  end Variant_1;

  model Variant_2
    extends Base;
    parameter Real e=0.5;
    Real d;
  equation 
    c+d*e = time*a;
  end Variant_2;

end Inherited_base;

示例 2

  model Base
    parameter Real a=1;
    parameter Real b=2;

    class Eqs
    Real c;
    Real d;
    equation 
        c = time*a;
    end Eqs;


  equation 

    replaceble Eqs bouclage;
    bouclage.c+bouclage.d = b;

  end Base;

编辑:我试图回答项目符号 3 中的问题:我在定义部分模型时收到错误消息,其中方程中使用的 variables/parameters 未在 class 中定义。我通过稍微修改我的想法解决了这个问题:我在两种情况下使用相同的方程式但是我有一个术语(示例中的'extra')考虑到根据情况使用不同的variables/parameters .但是,似乎无法交互式地选择要扩展的模型:下面的示例是错误的(没有 "if" 并且只有一个 'extends' 没问题)。

示例 3

package Inherited_variants

  model Final
    parameter Real a=1;
    parameter Real b=2;
    Real c;
    Real d;
    parameter Boolean complexmodel = false;
    if complexmodel then
      extends Variant_2;
    else
      extends Variant_1;
    end if;
  equation 
    c+d = b;
    c+extra = time*a;
  end Final;

  partial model Variant_1
    parameter Real extra=0;
  end Variant_1;

  partial model Variant_2
    parameter Real e=0.5;
    Real d;
    Real extra;
  equation 
    extra = d*e;
  end Variant_2;

end Inherited_variants;

在 Scott G 和 Hans Olsson 回答后进行编辑(感谢你们!)。 这些例子很有趣,但我仍然对你的例子中 "extends" 的广泛使用感到困惑。所以我试着简化你的代码,也从 here.

那里学到了一些东西

重新排列了 Scott 的示例:

package Example

  partial model FinalTerm
  end FinalTerm;

  model Final

    model Variant_1
       extends FinalTerm;
       parameter Real extra=0;
    end Variant_1;

    parameter Real a=1;
    parameter Real b=2;
    Real c;
    Real d;

    replaceable model VarType = Variant_1 constrainedby FinalTerm annotation(choicesAllMatching=true);

    //replaceable model VarType = Variant_1 constrainedby FinalTerm annotation(choices(choice=redeclare Variant_2 VarType,
    //                                                                                  choice=redeclare Variant_1 VarType));

    VarType varType;

  equation 

     c+d = b;
     c+varType.extra*d = time*a;

  end Final;

  model Variant_2
      extends FinalTerm;
      parameter Real e=0.5;
      Real extra;
  equation 
      extra = e;
  end Variant_2;

end Example;

汉斯的例子重新排列:

package Example_2

  partial model FinalTerm
  end FinalTerm;

  model Final

    model Variant_1
       extends FinalTerm;
       parameter Real extra=0;
    end Variant_1;

    parameter Real a=1;
    parameter Real b=2;
    Real c;
    Real d;

    replaceable Variant_1 test constrainedby FinalTerm annotation(choicesAllMatching=true);
    //replaceable Variant_1 test constrainedby FinalTerm annotation(choices(choice=redeclare Variant_2 test "NEW",
    //                                                                      choice=redeclare Variant_1 test "OLD"));

  equation 

     c+d = b;
     c+test.extra*d = time*a;

  end Final;

  model Variant_2
      extends FinalTerm;
      parameter Real e=0.5;
      Real extra;
  equation 
      extra = e;
  end Variant_2;

end Example_2;

我的理解(或者至少我认为):

一个小问题仍然悬而未决:根据 the previous webpage 应该可以手动定义 'annotation(choices())' 列表,但我没有成功(参见前面示例中的注释行)。这将允许适当的下拉菜单,而无需使用 "common-mother-class" 到 'extend' 和 'constrainedby' 关键字。有人知道我哪里错了吗?

您想使用 replaceable model 在模型之间切换而不是 if 语句。下面是一个基于您的示例的示例。我将留给您重新考虑如何正确地表述您的问题以正确使用可替换功能。希望对你有帮助。

在 Dymola 2017 FD01 中测试...

不确定 OMEdit 是否会处理 replaceable 正确使用,因为似乎存在一些仍在解决的长期问题: https://trac.openmodelica.org/OpenModelica/ticket/2079.

package Example

  model Test
  // Simple test of the component "Final"

    Final Final1(
      redeclare model VarType = Variant_1,
      redeclare Variant_2 varType2,
      redeclare Example.Variant_3 varType3 "Test")
      annotation (Placement(transformation(extent={{-10,-10},{10,10}})));
  end Test;

  model Final
  // Model demonstrating difference ways to use "replaceable"

    extends ReplaceableModels.PartialModel;

    replaceable model VarType = ReplaceableModels.Variant_1 constrainedby 
      ReplaceableModels.PartialVariants
                              annotation(choicesAllMatching=true);

    VarType varType1;

    replaceable ReplaceableModels.Variant_1 varType2 constrainedby 
      ReplaceableModels.PartialVariants annotation (choicesAllMatching=true);

    replaceable ReplaceableModels.Variant_1 varType3 constrainedby 
      ReplaceableModels.PartialVariants annotation (choices(
        choice(redeclare Example.Variant_1 varType3 "OLD"),
        choice(redeclare Example.Variant_2 varType3 "NEW"),
        choice(redeclare Example.Variant_3 varType3 "Test")));

  equation 
       result1 = varType1.extra;
       result2 = varType2.extra;
       result3 = varType3.extra;

  end Final;

  model Variant_1

      extends ReplaceableModels.PartialVariants;

      parameter Real extra0=0;

  equation 
    extra = extra0;

  end Variant_1;

  model Variant_2

      extends ReplaceableModels.PartialVariants;

      parameter Real a=1;
      Real b;
      Real c;
      parameter Real e=0.5;
      parameter Real d = 0.1;

  equation 

      c+d = b;
      c+extra = time*a;
      extra = d*e;

  end Variant_2;

  model Variant_3

      Real extra;

      parameter Real a=1;
      Real b;
      Real c;
      parameter Real e=0.5;
      parameter Real d = 0.1;

  equation 

      c+d = b;
      c+extra = time*a;
      extra = d*e;

  end Variant_3;

  partial model PartialModel

    Real result1;
    Real result2;
    Real result3;

  end PartialModel;

  partial model PartialVariants

    Real extra;

  end PartialVariants;
end Example;

更新:

添加了注释,以便在图形用户界面中有一个用于模型选择的下拉箭头。

更新 2:

我已将原始代码替换为一个扩展示例,该示例根据发布者的附加问题演示了使用可替换的几种不同方法。该代码现在还包括创建的模型的 Test (Final) 和不从部分 class 扩展的 Variant_3 以显示 choices如果对您的情况有用,注释还允许您包含额外的模型。

Scott G 解决方案的替代方案是使用可替换组件(以他的代码为基础):

package ReplaceableComponentTest
  model Test2 "Showing how to change it"
    extends Final(redeclare Example.Variant_2 varType);
  end Test2;

  model Final
    extends Example.PartialModel;
    replaceable Example.Variant_1 varType constrainedby 
      Example.PartialVariants annotation(choices(
             choice(redeclare Example.Variant_2 test "NEW"),
             choice(redeclare Example.Variant_1 test "OLD")));
  equation 
       result = varType.extra;
  end Final;
end ReplaceableComponentTest;

package Example

  model Variant_1
      extends Example.PartialVariants;
      parameter Real extra0=0;
  equation 
    extra = extra0;
  end Variant_1;

  model Variant_2
      extends Example.PartialVariants;

      parameter Real a=1;
      Real b;
      Real c;
      parameter Real e=0.5;
      parameter Real d = 0.1;

  equation 
      c+d = b;
      c+extra = time*a;
      extra = d*e;
  end Variant_2;

  partial model PartialModel

    Real result;

  end PartialModel;

  partial model PartialVariants

    Real extra;

  end PartialVariants;
end Example;

两者都适用于这种情况。请注意,我也添加了选择注释 - 为了安全起见,使用了 类 的全名(即使它应该有效)。

如果您有该模型的多个组件,则需要使用可替换模型,而在其他情况下,它更多的是风格问题。

我仍然可以推荐 https://modelica.org/events/Conference2003/Modelica03-AdvancedTutorial.pdf 的第五部分。