我正在尝试根据某些组件是否存在(在我的情况下,流体端口)构建一个稍微不同的公式的模型。
以下代码无效:
parameter Boolean use_component=false;
Component component if use_component;
equation
if use_component then
component.x = 0;
end if;
我该如何解决这个问题?
答案 0 :(得分:9)
如果您想使用条件组件,则需要注意一些限制。 Modelica 3.3规范的4.4.5节很好地总结了它。它说“如果条件是假的,那么组件,它的修饰符和任何连接方程 包含该组件,将被删除“。我将在一秒钟内向您展示如何使用它来解决您的问题,但首先我要解释为什么您的解决方案不起作用。
问题与检查模型有关。在您的情况下,显而易见的是,等式component.x
和组件component
都存在或两者都不存在。那是因为你已将它们绑定到相同的布尔变量。但如果你不这样做会怎么样:
parameter Real some_number;
Component component if some_number*some_number>4.0;
equation
if some_number>=-2 and some_number<=2 then
component.x = 0;
end if;
我们可以看到这与您的案例在逻辑上完全相同。 component.x
缺席时,component
无法存在。但是,我们可以证明一般这样的事情吗?否。
因此,当引入条件组件时,实现了保守语义,这些语义总是可以很容易地确保所涉及的变量和方程组永远不会“不同步”。
让我们回到规范所说的内容:“如果条件为假,则组件,其修饰符和任何连接方程式 涉及组件,被删除“
对于您的情况,解决方案可能非常简单。根据您声明“x”的方式,您可以添加对component
的修改,即
parameter Boolean use_component=false;
Component component(x=0) if use_component;
这样做的优雅之处在于修改仅适用于component
,如果component
不存在,则修改(等式)也不适用。因此变量x
及其相关方程是“同步的”。但是这并不适用于所有情况(IIRC,x
必须有一个input
限定符才能使用......也许这可以在你的情况下实现?)。
还有两种选择。首先,将等式component.x
放在component
内。第二种是在component
上引入连接器,如果连接,将生成您想要的等式。与修改案例一样(这不是巧合),您可以将x
与某种输入连接器关联,然后执行此操作:
parameter Boolean use_component;
Component component if use_component;
Constant zero(k=0);
equation
connect(k.y, component.x);
现在,我可以想象在考虑了所有三种情况(修改,内化方程并使用connect
)之后,你得出的结论是它们都不会起作用。如果是这种情况,那么我会谦虚地建议您在如何设计组件时遇到问题。出现这些限制的原因与必须自行检查组件的正确性有关。这要求组件完整(在规范的术语中“平衡”)。
如果您无法通过我上面提到的方法解决问题,那么我怀疑您确实存在一个平衡问题,并且您可能需要以某种方式重新定义组件的边界。如果是这种情况,我建议你在这里打开另一个问题,详细说明你要做的事情。
答案 1 :(得分:1)
我认为这不起作用的原因是解析器将查找变量“component.x”的声明,如果该组件不活动,则该声明不存在。即使在注释中插入“Evaluate = true”,它也不起作用。 在我看来,最干净的解决方案是在方程水平上工作,并在同一个区块中启用不同的方程组。您可以使用正确的连接器和参数创建包装器模型,然后如果它是因果模型,您可以使用可替换类来将模型参数化为函数,或者,如果是非因果模型,则将方程式置于内部如果声明。 另一种可能的解决方法是在一个块中放置两个不同的模型,因此您可以将它们的变量用于方程式部分,然后构建条件连接,以便使用具有选择行为的块。换句话说,您可以构建一个内部有两个块的“包装模型”,然后将连接方程放在if语句中的包装模型的连接器中。请记住构建模型,以便即使对于未使用的块,也会有一致的符号系统。 但这不是最好的解决方案,因为如果块很大,你将不得不等待更长的时间进行编译,因为所有内容都将被编译。
我希望这会有所帮助,
马
答案 2 :(得分:0)
您还可以制作在图形图层中不可见的虚拟组件:
connector DummyHeatPort
"Dummy heatport to facilitate optional heatport. Use this with a conditional heatport by connecting it to the heatport. Then use the -DummyHeatPort.Q_flow in the thermal energy balance."
Modelica.SIunits.Temperature T "Port temperature";
flow Modelica.SIunits.HeatFlowRate Q_flow
"Heat flow rate (positive if flowing from outside into the component)";
end DummyHeatPort;
然后当它在双端口模型中使用时
Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a heatport if use_heat_port;
DummyHeatPort dummy_heatport;
...
equation
flowport_a.H_flow + flowport_b.H_flow - dummy_heatport.Q_flow = storage
"thermal energy balance";
connect(dummy_heatport, heatport);
这样一来,如果存在热量运动,它会被使用,但不会引起错误。