在Modelica语言中何时使用noEvent运算符?
Modelica中的noEvent操作符不使用迭代来查找触发事件的精确时间。 这似乎会导致计算错误,下面是我在以下网站上找到的一个例子 因此,在使用noEvent操作符时,我是否必须确保功能顺畅? 如果无法确保准确性,使用noEvent操作符的目的是什么 我认为第3.7.3.2节。和第8.5节。将在这里帮助您(如果您尚未检查此项)在Modelica语言中何时使用noEvent运算符?,modelica,Modelica,Modelica中的noEvent操作符不使用迭代来查找触发事件的精确时间。 这似乎会导致计算错误,下面是我在以下网站上找到的一个例子 因此,在使用noEvent操作符时,我是否必须确保功能顺畅? 如果无法确保准确性,使用noEvent操作符的目的是什么 我认为第3.7.3.2节。和第8.5节。将在这里帮助您(如果您尚未检查此项) 据我所知,它应该只用于效率的原因,在大多数情况下应该使用smooth(),而不是结合使用 基于处理事件的两种不同方式。如果使用noEvent运算符,积分不会停止,但
据我所知,它应该只用于效率的原因,在大多数情况下应该使用
smooth()
,而不是结合使用 基于处理事件的两种不同方式。如果使用noEvent运算符,积分不会停止,但数值解算器假设函数应平滑,如果函数不平滑,则会出现数值错误
虽然这个问题已经得到了回答,但我想补充几点,因为我认为这对很多人都有用 使用
noEvent()
语句有一些常见的原因:
der(x)=如果x>=0,那么sqrt(x)否则为0
在大多数常见编程语言中都能完美工作。这在Modelica中并不总是有效,原因如下:当搜索条件x>=0
变为false的时间时,两个分支的值都可能在0左右变化。marvel发布的屏幕截图中也提到了同样的事实,如果计算负x
的平方根,则会导致崩溃。因此der(x)=如果无事件(x>=0),则-sqrt(x)否则为0代码>用于抑制迭代以搜索交叉时间,将不连续性的处理留给解算器(通常称为“按字面理解表达式,而不是生成交叉函数”)。在使用可变步长解算器的情况下,这会使解算器减小步长以满足其相对误差容限,这可能会导致性能下降。此外,如果所描述的功能不够平滑,导致模拟不精确甚至不稳定,则这可能是至关重要的
smooth()
操作符实际上涵盖了这一点,但该规范指出,工具仍然可以自由生成事件。根据我的经验,如果对函数的更改相对较大,工具会生成事件。因此,在smooth()
中使用noEvent()
是有意义的noEvent
在这里有帮助,但实际上喋喋不休是一个更普遍的问题。因此,我建议通过重新构建模型来解决与聊天相关的问题如果上述任何一项都不正确,则应仔细考虑使用
noEvent
。能否为您添加的第一个屏幕截图添加参考/链接?“另外,noEvent()
…”前面的部分对我来说似乎有点奇怪。我想了解更多的上下文…这是一本免费电子书的238页,你可以从下载,这是一本MOOC()的教科书。我想如果我能找到noEvent操作符如何找到从一个分支到另一个分支的正确点的详细过程,解决这个问题就会更清楚。有人能告诉我在哪里可以找到相关信息吗?以下设置不会出错。我认为,阅读包含“事件抑制”链接的文章,应该可以很好地了解何时使用noEvent
以及可能的smooth()
。我已经阅读了这两部分,但我对用noEvent处理数学的所谓方法感到困惑,我的意思是noEvent是否需要数学函数足够平滑,这样就不会出现像我上面的问题那样的错误。我想说noEvent应该只在需要时使用,例如,如果noEvent(d>0,那么d^0.5 else-(-d)^0.5;在没有noEvent的情况下,当d开关出现故障时,将评估错误的分支;并且不是出于效率原因。从技术上讲,它不必平滑-因此,如果noEvent(d>0),您可以编写然后是d^0.5 else 2;但我不推荐它。我的主要困惑是,如果noEvent没有精确计算触发事件的正确时间,积分器如何确保以下代码中的准确性如果noEvent(d>0,那么d^0.5 else-(-d)^0.5)
?它没有,这就是问题所在。使用noEvent()
意味着这可以以草率的方式处理,如果事件发生在稍微错误的时间,则不会产生太大的影响。Hans是对的,但关于他的使用示例,我没有想到这种情况(括号是错误的,如果没有事件(d>0),那么d^0.5,否则-(-d)^0.5)在这种特殊情况下,这并不重要,因为不连续性的结果仍然是平滑的,在这种情况下,可以使用类似于符号(d)*abs(d)的东西^0.5,但这并不总是容易找到或根本不存在。你有截图的来源吗?我记不清在哪里可以找到这张图片,我会努力找出它。