functioneventsmodelicasmoothingdiscrete

Modelica and Event generation of Functions


I try to understand when events are generated in Modelica. In the context of functions I noticed behaviour I didn't expect: functions appear to suppress event generation.

I am surprised as this is, to my knowledge, not explicitly stated in the Modelica reference. For example, if I run this model in OMEdit of OpenModelica 1.17.0

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;

I get the following output in the solver window of 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.

Apart from the fact that the solver (I used dassl) interpreted the event at time=10 as a state event rather than a time event, the behaviour is as expected. However, if I instead run the (mathematically identical) model

model timeEventTest2

Real z(start=0);

equation

der(z) = myfunc(time-10); 

end timeEventTest2;

with myfunc defined as

function myfunc
input Real x;
output Real y;

algorithm

if x > 0 then

y := 1;

else 

y:= -1;

end if; 

end myfunc;

I obtain the following output in 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.

Not only is the event at time = 10 NOT detected, the solver even got into some trouble as indicated by the error test failures. This is a trivial example, however, I can imagine that the apparent suppression of events by function may result in mayor problems in larger models. What did I miss here? Can I enforce the strict triggering of events within functions? Some built-in functions also trigger events, e.g. div and mod (curiously, sign and abs don't).

Edit: Obviously, you need to run the examples at least to a time > 10s. I ran the simulations to 20s.


Solution

  • Functions in Modelica normally do not generate events.

    See 8.5 Events and Synchronization in the Modelica Spec.

    All equations and assignment statements within when-clauses and all assignment statements within function classes are implicitly treated with noEvent, i.e., relations within the scope of these operators never induce state or time events.

    But its possible to change this behavior: Add the annotation GenerateEvents=true to the function.

    However, it seems like this is not sufficient for some Modelica simulators (tested with OpenModelica v1.16.5 and Dymola 2021x).

    To make it work in OpenModelica and Dymola, you have add the Inline annotation or you have to assign the function output in one line.

    So if you re-write your function as follows and you will get a state event:

    function myfunc
      input Real x;
      output Real y;
    algorithm 
      y := if x > 0 then 1 else -1;
      annotation (GenerateEvents=true);
    end myfunc;
    

    or by additionally adding the Inline annotation:

    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;
    

    State event vs time event

    To turn the state event in timeEventTest into a time event, change the if-condition to

    if time > 10 then
    

    This is also covered in chapter 8.5 Events and Synchronization of the Modelica Spec. Only the following two cases trigger time events: