-
Notifications
You must be signed in to change notification settings - Fork 174
Description
While analyzing possible regressions from MSL 4.0.0 to 4.1.0 in OpenModelica, we found issues with several Spice3 model:
Modelica.Electrical.Spice3.Examples.Inverter
Modelica.Electrical.Spice3.Examples.FourInverters
Modelica.Electrical.Spice3.Examples.InvertersApartRecord
Modelica.Electrical.Spice3.Examples.InvertersExtendedModel
Modelica.Electrical.Spice3.Examples.Nor
Modelica.Electrical.Spice3.Examples.Spice3BenchmarkFourBitBinaryAdder
all failing at the beginning of the simulation with this runtime error:
division by zero at time 1.000000000300011, (a=inf) / (b=0), where divisor b expression is: v.Tfalling - v.Twidth
I checked the Inverter model more in depth. It contains an instance v
of the Modelica.Electrical.Spice3.Sources.V_pulse model:
ModelicaStandardLibrary/Modelica/Electrical/Spice3.mo
Lines 3129 to 3159 in 8e7876b
model V_pulse "Pulse voltage source" | |
extends Modelica.Electrical.Analog.Interfaces.OnePort; | |
parameter SI.Voltage V1 = 0 "Initial value"; | |
parameter SI.Voltage V2 = 0 "Pulsed value"; | |
parameter SI.Time TD = 0.0 "Delay time"; | |
parameter SI.Time TR(start=1) "Rise time"; | |
parameter SI.Time TF = TR "Fall time"; | |
parameter SI.Time PW = Modelica.Constants.inf "Pulse width"; | |
parameter SI.Time PER= Modelica.Constants.inf "Period"; | |
protected | |
parameter SI.Time Trising=TR "End time of rising phase within one period"; | |
parameter SI.Time Twidth=Trising + PW | |
"End time of width phase within one period"; | |
parameter SI.Time Tfalling=Twidth + TF | |
"End time of falling phase within one period"; | |
SI.Time T0(final start=TD, fixed=true) "Start time of current period"; | |
Integer counter(start=-1, fixed=true) "Period counter"; | |
Integer counter2(start=-1, fixed=true); | |
equation | |
when pre(counter2) <> 0 and sample(TD, PER) then | |
T0 = time; | |
counter2 = pre(counter); | |
counter = pre(counter) - (if pre(counter) > 0 then 1 else 0); | |
end when; | |
v = V1 + (if (time < TD or counter2 == 0 or time >= T0 + | |
Tfalling) then 0 else if (time < T0 + Trising) then (time - T0)* | |
(V2-V1)/Trising else if (time < T0 + Twidth) then V2-V1 else | |
(T0 + Tfalling - time)*(V2-V1)/(Tfalling - Twidth)); |
The component v is instantiated as:
Sources.V_pulse v(V2=5, TR=0.1e-12) annotation (Placement( |
so both
v.PW
and v.PER
retain their default value of Modelica.Constants.inf
. The resulting chain of parameter assignments is thus:
v.Trising := v.TR = 1e-13
v.Twidth := v.Trising + v.PW = 1e-13 + 1.7e308
v.Tfalling := v.Twidth + v.TF + v.TR = 1e-13 + 1.7e308 + 1e-13
it is then obvious that the computation of the denominator v.Tfalling - v.Twidth = 1e-13 + 1.7e308 + 1e-13 - (1e-13 + 1.7e308)
in the expression for v.v
is numerically ill-defined. In fact, it looks quite odd to me that this issue hasn't been raised before.
I also checked the documentation
of the component, which is not very clear as it states "All parameters of sources should be set explicitly"; if "set explicitly" meant "have explicit modifiers", then there should be no defaults.
In any case, if a MSL component has default values, it should work properly when those values are not changed, and this is obviously not the case with this component, so we should do something about it.