Question

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.
Was it helpful?

Solution 2

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.

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top