Modelica 中的 noEvent 运算符不使用迭代来查找触发事件的精确时刻。
似乎这会导致计算错误,这是我在以下网站上找到的示例 https://mbe.modelica.university/behavior/discrete/decay/ 那么我是否必须确保在使用 noEvent 运算符时函数是平滑的?如果不能确保准确性,使用 noEvent 运算符的目的是什么?
虽然问题已经回答了,但我想补充几点,因为我认为它对许多人有用。
使用该noEvent()语句有一些常见的原因:
保护表达式:这用于防止函数在其有效性范围之外进行评估。一个典型的例子是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;用于抑制迭代以搜索交叉时间,将不连续性的处理留给求解器(通常称为“从字面上获取表达式而不是生成交叉函数”)。在使用可变步长求解器的情况下,这会使求解器减小步长以满足其相对误差容限,这可能会导致性能下降。此外,如果所描述的函数不够平滑导致不精确甚至不稳定的模拟,这可能是至关重要的。
连续表达式:当函数是连续的时,实际上不需要事件。这归结为一个事实,即事件用于描述不连续性。因此,如果没有,通常该事件只是多余的,因此可以被抑制。这实际上由smooth()Modelica 中的操作符涵盖,但规范说,工具仍然可以免费生成事件。根据我的经验,如果功能的变化相对较大,工具会生成事件。因此,noEvent()在 a 中包含 a是有意义的smooth()。
避免喋喋不休:noEvent在这里可以提供帮助,但实际上喋喋不休是一个更普遍的问题。因此,我建议通过重新构建模型来解决与抖动相关的问题。
如果以上都不是真的,noEvent则应仔细考虑使用。