Opened 6 years ago
Last modified 5 years ago
#5462 assigned defect
Inaccurate simulation of systems with noEvent and saturations using the C runtime — at Version 3
Reported by: | Francesco Casella | Owned by: | Karim Adbdelhak |
---|---|---|---|
Priority: | blocker | Milestone: | 2.0.0 |
Component: | Run-time | Version: | |
Keywords: | Cc: | Lennart Ochel, Andreas Heuermann |
Description (last modified by )
When signal saturations are modelled using noEvent()
, the C runtime has some issues, as exemplified by the Modelica.Electrical.Analog.Examples.OpAmps.Multivibrator
model.
When simulating the model with OMEdit, some numerical errors are reported during the simulation, around some of the events. In fact, the simulation reaches stopTime
successfully, but for some reason the final solver statistics and the end message "The simulation finished successfully." are not displayed. This should be corrected.
The testsuite reports a verification failure, see, e.g., the plot of opAmp.out.v, which shows how the period of the OMC simulation is significantly shorter than the one of the reference plot.
The experiment annotation sets StopTime = 1, Tolerance = 1e-6, and Interval = 0.001.
If the simulation is run with these parameters (as Jenkins does), the last commutation of opAmp.out.v
takes place at time 0.975
, much earlier than the value of 0.9835
of the reference plot, which was computed by Dymola using the same parameters.
If I now decrease the Interval to 0.0002, the last commutation takes place at time 0.9826, which is much closer to the reference plot. However, the precision of the location of time events shouldn't really depend so much on the reporting interval length, so there is probably something fishy going on here.
On the other hand, if I turn off Equidistant time grid off, and keep the tolerance to 1e-6, the last commutation takes place even earlier than with 0.001 communication interval, at time 0.97266. Only if I decrease the tolerance to 1e-10 do I get the last commutation to take place at time 0.9843, which is probably very close to the exact result, and is the same that I get with Dymola using the same settings.
Summing up, even with a fairly tight tolerance setting (1e-6), it seems that the actual choice of communication interval (or the absence thereof) has an excessivly high impact on the accuracy of the solution of a simple system (it is a first-order ODE) that has state events. On the other hand, Dymola (which basically uses the same ODE solver, DASSL) doesn't show such a dependency, which probably means there is something wrong with our implementation.
This is immediately apparent if you check the plots of c.v, which is the only state variable of the system. If you zoom in around time = 0.034, it is apparent how the OMC solution change direction at a value of -7.4, much earlier than the correct value of -7.5 which is shown by the reference solution.
It looks like the event is not triggered at the zero-crossing time, but rather at the previous step (or communication interval). This seems quite a serious issue for the simulation of systems that heavily depend on state events.
Karim, Andreas, Lennart, can you please have a look?
Change History (3)
comment:1 by , 6 years ago
comment:2 by , 6 years ago
Never mind, I was using the Cpp runtime with the new frontend, not the C runtime.
Only for C runtime the error gets bigger over time. I'm not shure why though.
comment:3 by , 6 years ago
Description: | modified (diff) |
---|---|
Summary: | Sloppy event detection → Inaccurate simulation of systems with noEvent and saturations using the C runtime |
In fact you are right, with the current parameter settings, the opAmp model uses this equation to compute the output voltage:
v_out = smooth(0, noEvent(if V0*v_in>vps then vps else if V0*v_in<vns then vns else V0*v_in));
so there are in fact no events in this simulation. Unfortunately, the solver statistics are not shown (see issue 1.), so I didn't notice.
Anyway, it still seems that the C runtime deals with the if-expression in a somwhat wrong way, even in the presence of both smooth()
and noEven()
operators.
I tried to improve the description of the ticket.
If im not mistaken, there are no events in this model.
When setting both Dymola and OpenModelica to a tolerance of 1e-06 for DASSL and the same output interval (e.g. 0.001) I get the (nearly) exact same results.