如何避免Modelica函数中assert()在每个时间步重复触发?
Modelica函数内assert()重复触发的解决方案
问题根源
方程段中的assert搭配noEvent使用时,仿真器会跟踪条件的状态变化,仅在条件真值从true切换为false的时刻触发一次告警(对应事件触发点)。但Modelica函数是纯无状态的,每个时间步调用时都会完整执行算法逻辑,包括assert检查,导致满足触发条件时每步都输出冗余告警。
可行解决方案
通过在模型中添加状态变量跟踪断言条件的历史状态,将“是否触发断言”的判断逻辑由模型控制,函数仅根据模型传入的状态信号执行断言,既保留函数的纯无状态特性,又实现与方程段一致的单次触发行为。
修改后的模型代码
model toto Real y; Real z; Boolean yWasNegative(start=true) "跟踪y上一步是否为负值"; equation y = sin(time); // 原方程段的assert保持不变 assert( noEvent(y > 0), "y smaller than 0", AssertionLevel.warning); // 更新状态变量,记录上一步y的正负状态 yWasNegative = pre(y < 0); // 将状态变量传入函数 z = function_titi(y, yWasNegative); annotation (experiment( StopTime=10, Interval=0.01, __Dymola_Algorithm="Dassl")); end toto;
修改后的函数代码
function function_titi input Real y; input Boolean yWasNegative; output Real z=1 "Dummy output"; algorithm // 仅当y从负值变为正值时触发断言(状态变化时刻) assert( noEvent(y < 0) or not yWasNegative, "y greater than 0", AssertionLevel.warning); end function_titi;
逻辑说明
- 模型中的
yWasNegative变量通过pre()函数记录上一步的y状态,跟踪状态变化。 - 函数内的
assert条件仅在y从负变正的时刻不满足,触发一次告警;后续y保持正值时,条件始终满足,不再重复触发。
内容的提问来源于stack exchange,提问作者Clement44
相关产品推荐
相关产品推荐

