什么时候在 Modelica 语言中使用 noEvent 运算符?

When to use noEvent operator in Modelica language?

Modelica 中的 noEvent 运算符不使用迭代来查找触发事件的精确时刻。

这好像会导致计算错误,这里是我在下面的网站上找到的例子 https://mbe.modelica.university/behavior/discrete/decay/ 那么在使用 noEvent 运算符时是否必须确保功能流畅? noEvent算子如果不能保证准确性还有什么用?

我认为 Modelica Language Specification Version 3.4 第 3.7.3.2 节。和第 8.5 节。会在这里帮助你(如果你还没有检查过)。

据我所知,它应该只用于效率原因,在大多数情况下应该使用 smooth() 代替或结合使用。

基于两种不同的事件处理方式。如果使用 noEvent 运算符,积分不会停止,但数值求解器假定函数应该是平滑的,如果函数不平​​滑,则会出现数值错误。

虽然问题已经回答了,但我想补充几点,因为我认为它对很多人都有用。

使用 noEvent() 语句有一些常见原因:

  1. 保护表达式:这用于防止在其有效范围之外评估函数。一个典型的例子是 der(x) = if x>=0 then sqrt(x) else 0;,它可以在大多数常见的编程语言中完美运行。由于以下原因,这在 Modelica 中并不总是有效:当搜索条件 x>=0 变为假的时间时,两个分支的评估值 x 可能在 0 左右变化。 marvel 发布的屏幕截图中提到了同样的事实,如果计算负数 x 的平方根,则会导致崩溃。因此 der(x) = if noEvent(x>=0) then -sqrt(x) else 0; 用于抑制搜索交叉时间的迭代,将不连续性的处理留给求解器(通常称为 "expressions are taken literally instead of generating crossing functions")。在使用可变步长求解器的情况下,这会使求解器减小步长以满足其相对误差容限,这可能会导致性能下降。此外,如果所描述的函数不够平滑导致模拟不精确甚至不稳定,这可能很关键。

  2. 连续表达式:当函数是连续的时,实际上不需要事件。这归结为一个事实,即事件用于描述不连续性。因此,如果存在 none,通常事件只是多余的,因此可以被抑制。这实际上由 Modelica 中的 smooth() 运算符涵盖,但规范说,工具仍然可以免费生成事件。根据我的经验,如果对功能的更改相对较大,工具会生成事件。因此,在 smooth().

  3. 中设置 noEvent() 是有意义的
  4. 避免喋喋不休noEvent在这里可以提供帮助,但实际上喋喋不休是一个更普遍的问题。因此,我建议通过重新构建模型来解决与抖动相关的问题。

如果上述 none 为真,则应仔细考虑 noEvent 的使用。