【问题标题】:conditional component declaration and a following if equation条件组件声明和以下 if 等式
【发布时间】:2013-01-18 01:46:35
【问题描述】:

我正在尝试构建一个模型,该模型将根据是否存在某些组件(在我的情况下为流体端口)具有略微不同的方程。

下面的代码不起作用:

parameter Boolean use_component=false;
Component component if use_component;
equation
if use_component then
  component.x = 0;
end if;

我该如何解决这个问题?

【问题讨论】:

    标签: conditional declaration modelica


    【解决方案1】:

    您还可以制作一个在图形层中不可见的虚拟组件:

    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);  
    

    这样,如果存在热端口,就会使用该热端口,否则不会导致错误。

    【讨论】:

      【解决方案2】:

      如果您想使用条件组件,则需要注意一些限制。 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 不存在时,component.x 就没有机会存在。但是我们能一般地证明这些事情吗?没有。

      因此,当引入条件组件时,实现了保守语义,它始终可以轻松确保所涉及的变量和方程组永远不会“不同步”。

      让我们回到规范所说的内容:“如果条件为假,则组件、其修饰符和任何连接方程 涉及该组件,被删除”

      对于您的情况,解决方案可能非常简单。根据您声明“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)之后,您得出的结论是它们都不起作用。如果是这种情况,那么我会谦虚地建议您对如何设计组件有疑问。出现这些限制的原因与检查组件自身的正确性的必要性有关。这要求组件是完整的(规范术语中的“平衡”)。

      如果您无法使用我上面提到的方法解决问题,那么我怀疑您确实存在平衡问题,并且您可能需要以某种方式重新定义组件的边界。如果是这种情况,我建议您在此处打开另一个问题,详细说明您正在尝试做什么。

      【讨论】:

        【解决方案3】:

        我认为这不起作用的原因是解析器将查找变量“component.x”的声明,如果组件不活动,则该声明不存在。即使您在注释中插入“Evaluate=true”,它也不起作用。 在我看来,最干净的解决方案是在方程级别工作,并在同一块中启用不同的方程组。您可以使用正确的连接器和参数创建一个包装模型,然后如果它是一个因果模型,例如,您可以使用可替换的类来将模型参数化为函数,或者在非因果模型的情况下,将方程放入其中if 语句。 另一种可能的解决方法是将两个不同的模型放在一个块中,这样您就可以在方程部分使用它们的变量,然后建立条件连接,以便使用具有所选行为的块。换句话说,您可以建立一个内部有两个块的“包装模型”,然后将连接方程放置在 if 语句中的包装模型的连接器上。请记住建立模型,以便即使对于未使用的块也会有一个一致的方程系统。 但这不是最好的解决方案,因为如果块很大,您将不得不等待更长的时间进行编译,因为所有内容都会被编译。

        我希望这会有所帮助,

        马可

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-05-27
          • 1970-01-01
          • 1970-01-01
          • 2014-04-30
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多