Modelica 意外的断言行为

Modelica unexpected behaviour of assertion

我需要断言一个变量(下面 MWE 中的 a)大于另一个变量(b)。

我注意到导入模型中的断言 a>b 表现得像 a>=b。 我试图解决该问题以改为断言 a>(b+Constants.small) 。 更改断言,即使在断言 a>(b+someBiggerNumber) 时仍然不能像预期的那样为 a=b 工作。如果 a!=b 断言按预期工作。

这是一个错误还是我做错了什么?如果是错误,是否有解决方法?

MWE:

model MWE

  model SomeModel
    parameter Real a(start=1);
    parameter Real b(start=1);
  protected
    Real c=5/(a-b);
  equation
    assert(a > b, "a has to be bigger than b. However, a (=" + String(a) +") < b (=" + String(b) + ")");
    //assert(a > (b + 1), "a has to be bigger than b+1. However, a (=" + String(a) +") < b (=" + String(b) + ")");
  end SomeModel;

  SomeModel sm(a = 5, b = 5);
  Real var;

equation
  var = sm.c;

end MWE;

// assert a > b
// a=5, b=4 no fail, as expected, same for b<4
// a=5, b=5 no fail
// a=5, b=6 fail, as expected, same for b>3

// assert a > (b + 1)
// a=5, b=3 no fail, as expected, same for b<3
// a=5, b=4 fail, as expected
// a=5, b=5 no fail
// a=5, b=6 fail, as expected, same for b>3

您可以检查 Real 变量是否与 Modelica.Math.isEqual(a,b) 相等,并像这样组合它:(a > b) or Modelica.Math.isEqual(a,b)

和往常一样,问题出在键盘前:/

我无法通过在脑海中逐步解决问题来解决问题。 断言工作正常,但 Modelica 不会像大多数编程语言那样按顺序逐步执行方程式,因此 运行 在断言任何事情之前进入被零错误除法。

像这样改变顺序

  protected
    Real c;
  initial equation
    assert(a > b, "a has to be bigger than b. However, a (=" + String(a) +") < b (=" + String(b) + ")");
  algorithm
    assert(a > b, "a has to be bigger than b. However, a (=" + String(a) +") < b (=" + String(b) + ")");
  equation
    assert(a > b, "a has to be bigger than b. However, a (=" + String(a) +") < b (=" + String(b) + ")");
    c=5/(a-b);

不会改变这一点。

如果有人知道如何首先 运行 断言以获得更清晰的错误消息,欢迎您输入:)

如果你想得到一个可预测的顺序,使用一个算法:

  protected
    Real c;
algorithm
    assert(a > b, "a has to be bigger than b. However, a (=" + String(a) +") <= b (=" + String(b) + ")");
    c:=5/(a-b);

或者将其转换为函数并将断言放入函数中。

你必须在算法部分做你想控制的部分,例如:

model MWE

  model SomeModel
    parameter Real a(start=1);
    parameter Real b(start=1);
  protected
    Real c;
  algorithm
      assert(a > b, "a has to be bigger than b. However, a (=" + String(a) +") < b (=" + String(b) + ")");
    //assert(a > (b + 1), "a has to be bigger than b+1. However, a (=" + String(a) +") < b (=" + String(b) + ")");
    c := 5/(a-b);
  end SomeModel;

  SomeModel sm(a = 5, b = 5);
  Real var;

equation
  var = sm.c;

end MWE;

如果您在一个算法中放置两个赋值,它们肯定会按正确的顺序执行。编译器可以自由更改其他方程式的顺序,如果我没记错的话,断言将被视为 "removed equations",它没有任何对模拟有贡献的输出值,这些是在完整步骤之后计算的。所以它总是在方程式被评估之后。这样做是因为断言通常在步骤结束时进行测试,以防止下一个步骤发生。

编辑:啊,我刚刚看到@Hans Olson 发布了相同的解决方案,抱歉!