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

时间:2017-04-05 13:41:49

标签: inheritance modelica

即使使用Modelica几个月,我也不熟悉继承和替换等高级功能。

我有一个标准模型(即池)和更复杂的变体(即包括蒸发计算):这两个模型有许多我想要“重用”的常见部分,但它们也有一些差异:一些方程式(即质量和能量平衡方程)是不同的(复杂模型有更多的术语),复杂模型包括更多的参数,变量和方程(即空气和蒸汽属性和定律)。

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

  1. 写下两个独立的模型(仅使用精彩的不同步复制粘贴文本功能) - 我不愿意。
  2. 使用继承(1)编写具有公共定义的部分模型和具有特定部分的两个继承模型。
  3. 使用继承(2)编写包含不同方程组(和其他特定定义)的两个部分模型,并编写包含公共定义的第三个模型并继承两个部分模型中的一个(例如通过布尔选择参数)。实际上我并不确定我能做到这一点:部分模型会包含带有未定义变量/参数的方程式(将在继承模型中定义):是吗?
  4. 编写标准模型并用新的方程替换方程式,同时添加其他定义。
  5. 我在(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项中的问题:我在定义部分模型时收到了错误消息,其中方程中使用的变量/参数未在类中定义。我通过略微修改我的想法解决了这个问题:我对两种情况使用相同的等式,但我有一个术语(在示例中为“额外”),它根据具体情况考虑使用的不同变量/参数。但是,看起来交互式地选择要扩展的模型是不可能的:此后的示例是错误的(没有“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回答后的编辑(感谢你们两位!)。 这些例子很有趣,但我仍然对你的例子中广泛使用“扩展”感到困惑。因此,我尝试简化您的代码,并从here学到了一些东西。

    斯科特的例子重新安排:

    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;
    

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

    • 两个示例/方法之间的区别。对于我想要的用途,我个人更喜欢Hans的方法(组件更换)。然而,为了立即执行多个组件更换,Scott的一个更加合适。
    • 使用'extends'不是强制性的。我发现的唯一用途就是允许使用'constrainedby',它必须引用一个〜普通母亲类〜(对不起我的不当措辞);这与Scott提供的“注释”相结合,允许在参数中有一个下拉菜单,这个菜单没有用处(也可以和汉斯的技术一起使用)。

    一个小问题仍未解决:根据the previous webpage,应该可以手动定义'annotation(choices())'列表,但是我没有成功(参见前面例子中的注释行)。这将允许正确的下拉菜单,而无需使用“common-mother-class”来“扩展”和“constrainedby”关键字。有人知道我错在哪里吗?

3 个答案:

答案 0 :(得分:3)

答案 1 :(得分:1)

您希望使用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;

更新:

添加了注释,以便从gui中有一个用于模型选择的下拉箭头。

更新2:

我已经用扩展示例替换了原始代码,该示例演示了一些基于海报附加问题使用可替换的不同方法。该代码现在还包括创建的模型的TestFinal),并且包含Variant_3,它不会从部分类扩展,以显示choices注释如何允许您还包含额外的模型如果这对你的情况有用。

答案 2 :(得分:0)

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;

这两种情况都适用。请注意,我也添加了选择注释 - 只是为了安全地使用类的全名(即使它应该工作)。

如果您拥有该模型的多个组件,则需要使用可替换模型,而在其他情况下,更需要使用样式。