Function Modelica与函数的事件生成

Function Modelica与函数的事件生成,function,events,modelica,smoothing,discrete,Function,Events,Modelica,Smoothing,Discrete,我试图理解Modelica中何时生成事件。在函数的上下文中,我注意到了我没有预料到的行为:函数似乎抑制了事件的生成 据我所知,这一点并未在Modelica参考文献中明确说明,我对此感到惊讶。 例如,如果我在OpenModelica 1.17.0的OMEdit中运行此模型 model timeEventTest Real z(start=0); Real dummy(start=0); equation der(z) = dummy; algorithm if time > 10

我试图理解Modelica中何时生成事件。在函数的上下文中,我注意到了我没有预料到的行为:函数似乎抑制了事件的生成

据我所知,这一点并未在Modelica参考文献中明确说明,我对此感到惊讶。 例如,如果我在OpenModelica 1.17.0的OMEdit中运行此模型

model timeEventTest

Real z(start=0);
Real dummy(start=0);

equation

der(z) = dummy;

algorithm
 
if time > 10 then
dummy := 1;
else
dummy := -1.;
end if;

end timeEventTest;
我在OMEdit的解算器窗口中获得以下输出

    ### STATISTICS ###
    timer
    events
        1 state events
        0 time events
    solver: dassl
       46 steps taken
       46 calls of functionODE
       44 evaluations of jacobian
        0 error test failures
        0 convergence test failures
    0.000122251s time of jacobian evaluation
    The simulation finished successfully.
除了解算器(我使用dassl)将时间=10时的事件解释为状态事件而不是时间事件之外,该行为与预期的一样。 但是,如果我运行(数学上相同的)模型

将myfunc定义为

function myfunc
input Real x;
output Real y;

algorithm

if x > 0 then

y := 1;

else 

y:= -1;

end if; 

end myfunc;
我在OMEdit中获得以下输出

### STATISTICS ###
timer
events
    0 state events
    0 time events
solver: dassl
   52 steps taken
   79 calls of functionODE
   63 evaluations of jacobian
   13 error test failures
    0 convergence test failures
0.000185296s time of jacobian evaluation
The simulation finished successfully.
不仅没有检测到时间=10的事件,解算器甚至遇到了一些问题,错误测试失败表明了这一点。 这是一个微不足道的例子,但是,我可以想象,函数对事件的明显抑制可能会在更大的模型中导致严重的问题。 我错过了什么?我可以在函数中强制严格触发事件吗? 一些内置函数也会触发事件,例如div和mod(奇怪的是,sign和abs不会)


编辑:显然,您需要至少运行示例10秒以上。我将模拟运行到20秒。

Modelica中的函数通常不会生成事件

请参见Modelica规范中的

when子句中的所有方程和赋值语句以及函数类中的所有赋值语句都隐式地用noEvent处理,即,这些运算符范围内的关系从不引发状态或时间事件

但有可能改变这种行为: 将注释
GenerateEvents=true
添加到函数中

但是,对于某些Modelica模拟器(使用OpenModelica v1.16.5和Dymola 2021x进行测试),这似乎还不够

要使其在OpenModelica和Dymola中工作,您必须添加
内联
注释,或者必须在一行中分配函数输出

因此,如果您按照以下方式重新编写函数,您将得到一个状态事件:

function myfunc
  input Real x;
  output Real y;
algorithm 
  y := if x > 0 then 1 else -1;
  annotation (GenerateEvents=true);
end myfunc;
或者通过另外添加
内联
注释:

function myfunc
  input Real x;
  output Real y;
algorithm 
  if x > 0 then
    y := 1;
  else
    y := -1;
  end if;
  annotation (GenerateEvents=true, Inline=true);
end myfunc;
状态事件与时间事件 要将
timeEventTest
中的状态事件转换为时间事件,请将if条件更改为

if time > 10 then
Modelica规范第章也介绍了这一点。只有以下两种情况会触发时间事件:

  • 时间>=离散表达式
  • 时间<离散表达式

非常感谢!当我使用“Modelica 3.3的面向对象建模和仿真原理:网络物理方法,第二版”学习Modelica时,我不知道函数是用noEvent隐式处理的。我在章节中没有找到任何关于隐式noEvent处理或“GenerateEvents”注释的注释和函数。我猜这些是新功能。我还在OpenModelica中尝试了您对myfunc的建议,不幸的是,行为没有改变。OMEdit可以识别注释,但仍然没有生成任何事件。请尝试更新的建议,这两种建议对我都适用(添加内联或将函数重新写入单个语句)。我的第一个答案是指您提到“Inline=true”注释之前的答案的早期版本。通过“Inline=true”和“GenerateEvents=true”注释,我可以确认函数在OpenModelica 1.17.0中生成事件。因此,不管我是用if表达式在一行中编写算法,还是用if语句在几行中编写算法。非常感谢,这就把事情弄清楚了!我想我应该仔细阅读Modelica规范,因为Fritzson的书有点过时。相关:
if time > 10 then