断言触发太迟

assert triggered too late

请考虑以下 Modelica 示例模型:

model Detection2
  Real x = (1-2*time)*1e5;
  parameter Real x_min=0.1;
  Real y;

equation 
  y = max(x,x_min);
  assert(y>x_min, "(assert) triggered at t = " + String(time), level=AssertionLevel.warning);
  when y <= x_min then
      Modelica.Utilities.Streams.print("(when) triggered at t = " + String(time));
  end when;
  annotation (experiment(StopTime=1));
end Detection2;

当我模拟它时(在 Dymola 2019FD01 中),我得到以下结果:

结果看起来和预期的一样,但是断言消息和打印语句都打印了错误的时间,它们总是打印停止时间,而不是我预期的时间!?

这有两部分:

  1. 为什么还没结束就触发了?原因是由于数值原因,求解器为此类关系创建事件,并且不想要太多事件,因此只要 "almost true" 就认为 y>x_min 为真,即 y>x_min-eps , 对于一些小的 epsilon。这在规范的第 8.5 节事件和同步中进行了解释。 https://specification.modelica.org/v3.4/Ch8.html#events-and-synchronization
  2. 为什么最后触发了?原因是在仿真结束时有一个事件,因为模型可能包含 terminal 运算符。在一个事件中,比较被更字面地对待。

如果您使用的是 x>x_minx<=x_min,它会如您所愿地工作。

或者,如果您使用了 y = if x>=x_min then x else x_min,则 y 可能略低于 x_min,但会触发消息。