model try
discrete Integer x(start = 1);
algorithm
when time >= 3 then
x:= x + 5;
end when;
x:= 5;
end try;
model try1
discrete Integer x(start = 1);
algorithm
x:= 5;
when time >= 3 then
x:= x + 5;
end when;
end try;
Both of the simulation result on OpenModelica is that x is always equal to 5. Why?
It seems that x in model try should be 5. But why x in model try1 is not 10 when time is equal to 3?
I have two comments. First, keep in mind that when dealing with
whenclauses, it is often prudent to utilize thepre(...)operator to make explicitly clear which value you are referring to, the new one or the previous. I don’t know if it is strictly necessary in this case (and even if I did know, I’m not sure if all developers of Modelica tools use consistent semantics), but it is a good idea if only to make it clear to readers of the code.The other issue is with the handling of algorithms. Normally, the statements are executed in the order they appear in the
algorithmsection. Butwhenclauses are a bit tricky since they have an asynchronous nature to them. Again, I’m not clear what the exact semantics are with regards to the interleaving ofwhenclauses with other assignment statements in the model, but writing analgorithmsection like you have is a bit ambiguous. Let’s assume thewhenstatement is evaluated andxis given a new value, how long do you expect it to keep that value? The compiler has latitude in repeatedly evaluating the algorithm section might be evaluated immediately after thewhenclause is invoked in which casexwill be given a new value of5(perhaps even without time advancing at all).I’m not sure what your intention really is with this model. But if you want it to start with one value and then, after time>3, take on a new value (based on the old value), I see two ways of achieving this in Modelica and both of them involve how you set the initial value. Consider the following model:
This model uses the
preoperator but, more importantly, it also uses theinitial()event to provide the initial value forx. In this way, this avoids the problem you were probably experiencing with the previous model of constantly overwriting the value ofxto5. Another way to do this could be:Although I confess that I suspect different tools might have different semantics for each of these versions. I’d say the
when initial()version is probably more universally consistent.Update:
I think your misunderstanding comes from not considering the implications of subsequent evaluations. In the case of
try1, at time==3 thewhenclause is evaluated andxis given a new value.But what happens on the next model evaluation? The algorithm section is evaluated again and
xis set back to 5. Thewhenclause does not get evaluated again until the condition expression turns false and then true again. So in this case, it triggers exactly once! If you want it to be evaluated for all times greater than 3, then you need to use anifstatement.And keep this question in mind…how much simulation time elapses between the execution of the
whenclause and the next model evaluation (whenxis reset)? Quite possibly none. You have no way of knowing when the algorithm section is executed (that depends on events, the integrator used, etc.). So if you wantxto be given a value once at the start of the simulation and once attime==3, then you need to state that in your model (as I did in my examples).