【问题标题】:modelica: different results for equation section versus algorithm sectionmodelica:方程部分与算法部分的不同结果
【发布时间】:2014-01-26 13:57:03
【问题描述】:

以下简单模型是正确的并且在 dymola 中工作:

model new_timer

  Modelica.Blocks.Logical.Timer timer;
  Real my_time( start=0);

equation 
    timer.u=true;

    my_time=timer.y;

end new_timer;

但是,在使用 dymola 进行“检查”期间,以下一项是正确的,但在模拟期间却不起作用:

model new_timer

  Modelica.Blocks.Logical.Timer timer;
  Real my_time( start=0);

algorithm 
    timer.u:=true;
    my_time:=timer.y;

end new_timer;

我想知道并寻找一种使后者工作的方法。 dymola报错如下:

Failed to generate code for an algebraic loop
involving when equations or algorithms with when parts.
Unknowns:
my_time
timer.entryTime
timer.u
timer.y

Equations:
when timer.u then
timer.entryTime = time;
end when;
timer.y = (if timer.u then time-timer.entryTime else 0.0);
algorithm 
    timer.u := true;
    my_time := timer.y;

You may be able to cut the loop 
by putting 'pre' around some of the references to
unknown continuous time variables in when parts or when conditions.

Translation aborted.

【问题讨论】:

    标签: modelica dymola


    【解决方案1】:

    嗯。这是一个很好的例子,说明了为什么应该尽可能使用方程部分。

    以下...

    算法
        timer.u:=真;
        my_time:=timer.y;

    ... 大致等于:

    算法
        (timer.u,my_time) := f(timer.y);

    现在更清楚的是 timer.u 看起来依赖于 timer.y。所以你得到了一个循环。

    下面创建了两个算法部分,这意味着依赖关系更加分散(有点像方程部分):

    算法
        timer.u:=真;
    算法
        my_time:=timer.y;

    尽量使用尽可能短的算法部分。

    【讨论】:

      【解决方案2】:

      这是一个奇怪的问题,我怀疑这是 Dymola 中的一个错误(原因我稍后会解释)。

      事实证明你遇到了this issue,尽管在这种情况下根本不明显为什么会这样。

      因此,一种解决方案是使用 Timer 模型的稍微不同的实现,如下所示:

      block Timer 
        "Timer measuring the time from the time instant where the Boolean input became true" 
      
        extends Modelica.Blocks.Interfaces.partialBooleanBlockIcon;
        Modelica.Blocks.Interfaces.BooleanInput u "Connector of Boolean input signal"
          annotation (extent=[-140,-20; -100,20]);
        Modelica.Blocks.Interfaces.RealOutput y "Connector of Real output signal" 
          annotation (extent=[100,-10; 120,10]);
      protected 
        discrete Modelica.SIunits.Time entryTime "Time instant when u became true";
      initial equation 
        pre(entryTime) = 0;
      equation 
        when pre(u) then
          entryTime = time; 
        end when;
        y = if u then time - entryTime else 0.0;
      end Timer;
      

      注意pre 运算符在when 子句中的条件周围的存在。

      一般来说,使用pre 运算符是个好主意(正如我在that other issue 中解释的那样)。为什么在您的具体情况下有必要,我无法解释。在您的情况下,条件表达式只是 true,这意味着它应该在模拟开始时触发 when 子句。我没有看到 Dymola 在这里谈论的代数环。我怀疑这与 Dymola 试图组织在模拟开始时应该发生的所有事情并在那里遇到一些复杂情况有关。但这并不明显,并且可以通过我提到的替代 Timer 模型来避免。

      【讨论】:

        猜你喜欢
        • 2017-08-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-08-10
        • 2021-02-07
        • 1970-01-01
        • 2016-06-04
        • 1970-01-01
        相关资源
        最近更新 更多