#5831 closed defect (wontfix)
Asserts with "greater equal" conditions do not detect equals case
Reported by: | Owned by: | somebody | |
---|---|---|---|
Priority: | high | Milestone: | Future |
Component: | *unknown* | Version: | v.1.15.0-dev |
Keywords: | Cc: |
Description
A test model with an assert is implemented as follows:
model Model1 Modelica.Blocks.Interfaces.RealInput u annotation (Placement(transformation(extent={{-120,-20},{-80,20}}))); equation assert(u>=0.0,"Error u has to be greater or equal than zero"); annotation (Icon(coordinateSystem(preserveAspectRatio=false)), Diagram( coordinateSystem(preserveAspectRatio=false))); end Model1;
When connecting Model1.u with a ramp which goes down to zero the assert is falsely thrown.
Change History (4)
follow-up: 3 comment:1 by , 5 years ago
comment:2 by , 5 years ago
Resolution: | → wontfix |
---|---|
Status: | new → closed |
follow-up: 4 comment:3 by , 5 years ago
Replying to casella:
In general, relying on equality conditions on Real numbers is a numerical hazard. The output signal of the ramp is the difference between two numbers that mathematically gives zero, but numerically may end up being a small negative number. This is enough to trigger the assertion.
If you change the assert to
assert(u>=-1e-9,"Error u has to be greater or equal than zero");the assertion is never triggered.
Yep, there actually is no equality check for Real
numbers. The operator >=
directly translates to >
on Real
numbers and should only be used for Integer
or at least discrete
variables.
If you really want to have an equality check use Modelica.Math.isEqual
from the MSL, but you need to use an epsilon different to zero for it to properly work. There are some fringe cases where it also works with an epsilon of zero but i would not rely on that.
comment:4 by , 5 years ago
Replying to Karim.Abdelhak:
Yep, there actually is no true equality check for
Real
numbers. The operator>=
directly translates to>
onReal
numbers
While I agree in general with the first statement, I do not agree with the second, as far as parameters with simple binding equations are concerned. For example
model M parameter Real p = 0; equation assert(p >= 0, "p must be non-negative"); end M;
should simulate if p
is not changed by a modifier, while
model M parameter Real p = 0; equation assert(p > 0, "p must be positive"); end M;
shouldn't. In fact, this turns out to be the case with the current OMC implementation.
The point is that if I have an explicit equation assigning a variable or a parameter to zero, then there is no uncertainty there, the equality case makes sense, and there should be no need to introduce epsilons. If the zero value is instead the result of any finite precision mathematical operation, then it is not reliable and some tolerance should be allowed.
In general, relying on equality conditions on Real numbers is a numerical hazard. The output signal of the ramp is the difference between two numbers that mathematically gives zero, but numerically may end up being a small negative number. This is enough to trigger the assertion.
If you change the assert to
the assertion is never triggered.