我正在试图建立一个模型,可以在同一范围内使用两个不同的组件(取自现有的库):特别是一个带有换热器的系统;这种换热器可以基于不同的技术,例如管道或板。
然后,我想定义一个带有默认可替换交换机的模型,并说明可以使用哪些其他技术。
这是我尝试过的一个简单的例子:
package Test
// Component 1 original definition in the library
model COMP1
parameter Real p1=1 "";
Real v "";
equation
v=p1*time;
end COMP1;
// Component 2 original definition in the library
model COMP2
parameter Real p2=1 "";
Real v "";
equation
v=p2*time;
end COMP2;
// Main module (system)
model MAIN
parameter Real pm=100 "";
Real vm "";
// Redefinition of the component modifing the default values
model call1 = COMP1(p1=10);
model call2 = COMP2(p2=20);
replaceable call1 OBJ
annotation(choices(
choice(redeclare call1 OBJ "Default"),
choice(redeclare call2 OBJ "Variant")));
equation
vm = OBJ.v+pm;
end MAIN;
// Application model, using the main model
model APP
MAIN mAIN;
end APP;
end Test;
模型应用程序成功运行。但是,如果打开APP.mAIN的参数并更改OBJ (选择“默认”或“变体”),将导致修改APP模型如下:
model APP
MAIN mAIN(redeclare call1 OBJ "Default");
end APP;
我得到以下错误:
Component type specifier call1 not found
我不明白我做错了什么,请帮帮忙。
发布于 2019-01-22 08:29:00
出现与错误相关的问题,因为您没有在选项注释中使用正确的类路径。
如果在APP
中选择“默认”,将得到以下代码:
model APP
MAIN mAIN(redeclare call1 OBJ "Default");
end APP;
这里我们看到类路径call1
是无效的。APP只能通过使用相对类路径MAIN.call1
或绝对类路径Test.MAIN.call1
来访问Test.MAIN.call1
。因此,您可以使用以下注释解决此问题:
replaceable call1 OBJ
annotation(choices(
choice(redeclare MAIN.call1 OBJ "Default"),
choice(redeclare MAIN.call2 OBJ "Variant")));
但是,在Dymola中,由于MAIN
中的局部类定义,在修改默认值的组件的重新定义下,模型仍然不检查。在这里,您创建了新的类call1
和call2
。这可能是一个Dymola错误,因为它在OpenModelica中工作-但新的类是不必要的。相反,您可以使用原始类并在redeclare
语句中使用修饰符方程设置参数,如下所示:
model MAIN
parameter Real pm=100 "";
Real vm "";
replaceable COMP1 OBJ
annotation(choices(
choice(redeclare Test.COMP1 OBJ(p1=10) "Default"),
choice(redeclare Test.COMP2 OBJ(p2=10) "Variant")));
equation
vm = OBJ.v+pm;
end MAIN;
现在,该模型不适用于任何选择和“默认”,但当选择“variables”时,Dymola抱怨重新声明的类不包含与原始类相同的变量。这是使用可替换类时的限制之一(同样,OpenModelica对它没有问题,但Dymola警告您,这不符合Modelica语言规范)
替代方法:带有接口的MSL样式
我建议像Modelica库通常所做的那样创建一个接口模型(例如使用Modelica.Electrical.Analog.Interfaces.OnePort
):
partial
基模型,它包含所有变体所共有的所有内容,称为接口这就是你的例子的样子。第三方组件COMP1
和COMP2
被移动到包ReadOnlyLibrary
中。
package Test
// Original definition of Component 1 and 2 in the external library
package ReadOnlyLibrary
model COMP1
parameter Real p1=1 "";
Real v "";
equation
v=p1*time;
end COMP1;
model COMP2
parameter Real p2=1 "";
Real v "";
equation
v=p2*time;
end COMP2;
end ReadOnlyLibrary;
// Interface and variants with modified default values
partial model Call_Interface
Real v "";
end Call_Interface;
model Call1 "Default"
extends Call_Interface;
extends ReadOnlyLibrary.COMP1(p1=10);
end Call1;
model Call2 "Variant"
extends Call_Interface;
extends ReadOnlyLibrary.COMP2(p2=20);
end Call2;
// Main module (system)
model Main
parameter Real pm=100 "";
Real vm "";
replaceable Test.Call1 OBJ constrainedby Test.Call_Interface annotation (choicesAllMatching);
equation
vm = OBJ.v+pm;
end Main;
// Application model, using the main model
model App
Main main annotation (Placement(transformation(extent={{-12,10},{8,30}})));
end App;
end Test;
https://stackoverflow.com/questions/54298679
复制相似问题