Reputation: 33
The following simple model is correct and working in dymola:
model new_timer
Modelica.Blocks.Logical.Timer timer;
Real my_time( start=0);
equation
timer.u=true;
my_time=timer.y;
end new_timer;
However, the one below is correct during “checking” with dymola but does not work during simulation:
model new_timer
Modelica.Blocks.Logical.Timer timer;
Real my_time( start=0);
algorithm
timer.u:=true;
my_time:=timer.y;
end new_timer;
I wondered and looking for a way to make the latter working. The error reported by dymola is as follows:
Failed to generate code for an algebraic loop
involving when equations or algorithms with when parts.
Unknowns:
my_time
timer.entryTime
timer.u
timer.y
Equations:
when timer.u then
timer.entryTime = time;
end when;
timer.y = (if timer.u then time-timer.entryTime else 0.0);
algorithm
timer.u := true;
my_time := timer.y;
You may be able to cut the loop
by putting 'pre' around some of the references to
unknown continuous time variables in when parts or when conditions.
Translation aborted.
Upvotes: 3
Views: 525
Reputation: 3523
Well. It's a good example of why you should use equation-sections whenever possible.
The following...
algorithm timer.u:=true; my_time:=timer.y;
... is roughly equal to:
algorithm (timer.u,my_time) := f(timer.y);
And now it is more clear that timer.u looks like it depends on timer.y. So you get a loop.
The following creates two algorithm-section, which means the dependencies are more spread out (a little more like an equation section):
algorithm timer.u:=true; algorithm my_time:=timer.y;
Try to always use as short algorithm-sections as possible.
Upvotes: 3
Reputation: 9421
This is strange problem and I suspect this is a bug in Dymola (for reasons I will explain in a second).
It turns out you are running into this issue, although it isn't at all obvious in this situation why this should be the case.
So one solution is to use a slightly different implementation of the Timer
model, one that looks like this:
block Timer
"Timer measuring the time from the time instant where the Boolean input became true"
extends Modelica.Blocks.Interfaces.partialBooleanBlockIcon;
Modelica.Blocks.Interfaces.BooleanInput u "Connector of Boolean input signal"
annotation (extent=[-140,-20; -100,20]);
Modelica.Blocks.Interfaces.RealOutput y "Connector of Real output signal"
annotation (extent=[100,-10; 120,10]);
protected
discrete Modelica.SIunits.Time entryTime "Time instant when u became true";
initial equation
pre(entryTime) = 0;
equation
when pre(u) then
entryTime = time;
end when;
y = if u then time - entryTime else 0.0;
end Timer;
Note the presence of the pre
operator around the condition in the when
clause.
In general, the use of the pre
operator is a good idea (as I explain in that other issue). Why it is necessary in your specific case, I cannot explain. The conditional expression is simply true
in your case which means it should trigger the when
clause at the start of simulation. I don't see the algebraic loop that Dymola is talking about here. I suspect it has something to do with Dymola trying to organize all the things that should happen at the start of the simulation and running into some complication there. But it isn't obvious and it can all be avoided with the alternative Timer
model I mentioned.
Upvotes: 2