Opened 7 years ago
Closed 6 years ago
#4868 closed defect (fixed)
Issue with Integer-Real conversions in min/max functions with the NF
Reported by: | Francesco Casella | Owned by: | Per Östlund |
---|---|---|---|
Priority: | high | Milestone: | 2.0.0 |
Component: | New Instantiation | Version: | |
Keywords: | Cc: |
Description
Please check the simulation results of Modelica.Electrical.Analog.Examples.OpAmps.Comparator. The output of the comparator remains constant instead of being a square wave.
The root cause of the problem is that instead of having Rn = Rp = 500
we get Rp = 1000, Rn = 0
.
The equations in the source code are
Rp = R*(1 + alpha*(T_heatPort - T_ref))*(1 - min(1, max(0, rInt))); Rn = R*(1 + alpha*(T_heatPort - T_ref))*min(1, max(0, rInt));
The corresponding flattened equations with the NF are
potentiometer.Rp = potentiometer.R * (1.0 + potentiometer.alpha * (potentiometer.T_heatPort - potentiometer.T_ref)) * /*Real*/(1 - min(1, max(0, potentiometer.rInt))); potentiometer.Rn = potentiometer.R * (1.0 + potentiometer.alpha * (potentiometer.T_heatPort - potentiometer.T_ref)) * /*Real*/(min(1, max(0, potentiometer.rInt)));
while the old FE gives:
potentiometer.Rp = potentiometer.R * (1.0 + potentiometer.alpha * (potentiometer.T_heatPort - potentiometer.T_ref)) * (1.0 - min(1.0, max(0.0, potentiometer.rInt))); potentiometer.Rn = potentiometer.R * (1.0 + potentiometer.alpha * (potentiometer.T_heatPort - potentiometer.T_ref)) * min(1.0, max(0.0, potentiometer.rInt));
Apparently, the NF casts the Real argument of min and max to Integer rather casting the Integer argument to Real, and later casts the result back to Real, leading to a completely wrong result.
According to the specification 10.3.4, "min(x,y) returns the least element of the scalars x and y; as defined by <", so I guess when comparing a Real and an Integer, the latter should be cast to the former, and not the other way round.
Change History (3)
comment:2 by , 7 years ago
Current code:
function typeMinMaxCall input Call call; input ExpOrigin.Type origin; input SourceInfo info; output Expression callExp; output Type ty; output Variability var; protected Call argtycall; Function fn; list<TypedArg> args; TypedArg start,interval; algorithm argtycall as ARG_TYPED_CALL(_, args, _) := typeNormalCall(call, origin, info); argtycall := matchTypedNormalCall(argtycall, origin, info); callExp := Expression.CALL(unboxArgs(argtycall)); ty := Type.arrayElementType(Util.tuple32(listHead(args))); var := variability(argtycall); // TODO: check basic type in two argument overload. // check arrays of simple types in one argument overload. // fix return type. end typeMinMaxCall;
comment:3 by , 6 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
Fixed in fa177e77. The model also simulates and the comparator seems to be correct too as far as I can determine.
With this this commit the output changed to a runtime error because of division by zero
Rn
.