即使使用Modelica几个月,我也不熟悉继承和替换等高级功能。
我有一个标准模型(即池)和更复杂的变体(即包括蒸发计算):这两个模型有许多我想要“重用”的常见部分,但它们也有一些差异:一些方程式(即质量和能量平衡方程)是不同的(复杂模型有更多的术语),复杂模型包括更多的参数,变量和方程(即空气和蒸汽属性和定律)。
我认为我在Modelica中有一些可能性来做到这一点:
我在(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;
我理解(或者至少我认为):
一个小问题仍未解决:根据the previous webpage,应该可以手动定义'annotation(choices())'列表,但是我没有成功(参见前面例子中的注释行)。这将允许正确的下拉菜单,而无需使用“common-mother-class”来“扩展”和“constrainedby”关键字。有人知道我错在哪里吗?
答案 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:
我已经用扩展示例替换了原始代码,该示例演示了一些基于海报附加问题使用可替换的不同方法。该代码现在还包括创建的模型的Test
(Final
),并且包含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;
这两种情况都适用。请注意,我也添加了选择注释 - 只是为了安全地使用类的全名(即使它应该工作)。
如果您拥有该模型的多个组件,则需要使用可替换模型,而在其他情况下,更需要使用样式。