Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clocked algorithm variables: Unspecified behavior in case of missing equations #3107

Open
d-model opened this issue Feb 1, 2022 · 12 comments · May be fixed by #3602
Open

Clocked algorithm variables: Unspecified behavior in case of missing equations #3107

d-model opened this issue Feb 1, 2022 · 12 comments · May be fixed by #3602
Labels
clocked Clocked parts of Modelica; synchronous and state-machines
Milestone

Comments

@d-model
Copy link

d-model commented Feb 1, 2022

For algorithm sections the Modelica Specification requires in general all variables, which are assigned somewhere in the algorithm section, to be initialized always when the algorithm is called (Modelica specification 3.5, Section 11.1.2). Concretely:

  • Continuous signals: Initialise to start value
  • Discrete signals: Initialise to pre value

However variables of clocked variability are not listed here.

Note, that clocked variability is different to discrete variability: Modelica specification 3.5, Section 16.8.1:

If not explicitly stated otherwise, an expression with a variability such as continuous-time or discrete-time means that the expression is inside a partition that is not associated to a clock. If an expression is present in a partition that is not a continuous-time partition, it is a clocked expression and has clocked variability.

Natural suggestions for initialization would be the previous value or the start value.

Our Questions:

  • Are we right, that the Modelica Specification in fact leaves the initialization of clocked variables during calls to clocked algorithms unspecified?
  • If we are wrong:
    • What is then the correct understanding of initial values during calls to the clocked algorithm section?
    • According to the Modelica Specification, how is a clocked algorithm required to treat variables, which are not assigned during the clocked algorithm (as in examples Model1, Model2, Model3 below).
  • If we are right, and the Modelica Specification in fact leaves this unspecified:
    • Has this issue stayed unspecified on purpose?
    • Is there any intent to close this gap?
    • Which choices for the initial values inside a clocked algorithm are allowed? (previous value / start value?)

For the follwing three examples, the behavior of signal ‘internal’ seems not to be specified:

Model1: Missing equations for ‘internal’ after first tick.

model model1
  parameter Real p = 5;
  Real internal (start = 2);
  parameter Real Ts = 0.001;
  Clock cl = Clock(Ts);
algorithm
  if firstTick(cl) then
    internal := 5;
  end if;
end model1;

or

Model2: Missing equation for ‘internal’ at first tick.

model model2
  parameter Real p = 5;
  Real internal (start = 2);
  parameter Real Ts = 0.001;
  Clock cl = Clock(Ts);
algorithm
  if not firstTick(cl) then
   internal := 5;
  end if;
end model2;

Model3: Missing equations for ‘internal’ at first tick and after time 0.5

model model3
  parameter Real p = 5;
  Real internal (start = 2);
  parameter Real Ts = 0.001;
  Clock cl = Clock(Ts);
algorithm
  if not firstTick(cl) then
   if time < 0.5 then
      internal := 5;
    end if;
  end if;
end model3;
@casella
Copy link
Collaborator

casella commented Feb 1, 2022

Are we right, that the Modelica Specification in fact leaves the initialization of clocked variables during calls to clocked algorithms unspecified?

I think so, good point.

Has this issue stayed unspecified on purpose?

I think this was probably an oversight. Clocked variable semantics is based on synchronous system theory, which is based on equations, algorithms were probably not considered back then, when Modelica 3.3 was written. Maybe @HildingElmqvist, @MartinOtter and @HansOlsson who worked on the original proposal and its implementation can comment on that.

Clocked variables can describe the behaviour of digital controllers where algorithms are run at each clock tick, so algorithms in clocked models are probably useful. For sure a lot more useful than algorithms for continuous variables, which I find pretty confusing. If algorithms involving continuous variables are allowed, it would be odd not to do so for algorithms including clocked variables.

In this case the obvious semantics is that any clocked variable v is initialized at its previous(v) value, similarly to discrete variables, and we could add this to Section 1.11.2.

@MartinOtter
Copy link
Member

You are right, this should be clarified in the spec, something like:

  • If a clocked discrete-time variable is not assigned at a clock tick, it is implicitly assigned to its previous value. [Note, at the first clock tick, the previous-value is the start value of the variable.]

@d-model
Copy link
Author

d-model commented Feb 1, 2022

Dear all,

thank you very much for your quick response. And we will be glad if this is added to the upcoming version of the specification.

We are as well convinced, that the previous value will be the best choice for this purpose:

  • It is inline with the ‘pre’ for continuous time discrete variables,
  • for discrete controls, it is usually the expectation of the user, that the variable stays with the previous value, if it is untouched.

Let us also hint to the circumstance, that several Modelica tools behave unconsistently in this situation. (Some using the start value, others using previous value.)

Clocked variables can describe the behaviour of digital controllers where algorithms are run at each clock tick, so algorithms in clocked models are probably useful. For sure a lot more useful than algorithms for continuous variables, which I find pretty confusing. If algorithms involving continuous variables are allowed, it would be odd not to do so for algorithms including clocked variables.

We agree on this. Clocked systems are quite a useful way for modelling discrete controls.

@casella
Copy link
Collaborator

casella commented Feb 1, 2022

Let us also hint to the circumstance, that several Modelica tools behave unconsistently in this situation. (Some using the start value, others using previous value.)

That's too bad, but consistent with the current status of unspecified behaviour 😄

@HansOlsson I guess this could be processed by the MAP-LANG group without too much effort.

@HansOlsson
Copy link
Collaborator

This is a bit more complicated.

If the model is just a normal clocked model I agree that previous(...) seems like the best choice (see also #3014 for the difference to pre(...)).

However, if the model was continuous and is then clocked discretized (see #3091 for a discussion of having better names for that) it becomes less clear. Since the goal is that clocked discretization should be possible for every continuous model (and obviously give a result close to the original), it seems that we should preserve that semantics and in those cases initialize to the start-value. However, I am not sure if there's a simple definition of those cases (as we also want to clock discretization of discrete parts of that model).

Related to that the clarification in #3090 requires some minor changes in model3.

It is also unclear how much this will matter in practice for a continuous variable.
For a discrete variable doing x:=a*x+u; (as a short-hand for x:=a*pre(x)+u;) makes sense, but for a truly continuous equation it doesn't make sense to re-use the previous value as the equation will not converge, and it is more that you can write something like:

   Real mySum1=sum(cos(i*time) for i in 0:10);
   Real mySum(start=1.0); // Using algorithm to get same result as mySum1
algorithm
   for i in 1:10 loop
      mySum:=mySum+cos(i*time);
   end for;
   // The value for i=0 is handled by the start-value of mySum

@casella
Copy link
Collaborator

casella commented Feb 2, 2022

However, if the model was continuous and is then clocked discretized (see #3091 for a discussion of having better names for that) it becomes less clear. Since the goal is that clocked discretization should be possible for every continuous model (and obviously give a result close to the original), it seems that we should preserve that semantics and in those cases initialize to the start-value.

I agree. I remain with my personal conviction that algorithms in continuous time models are fishy, and that algorithms in continuous time models that do not initialize all their variables explicitly are even more fishy. You can imagin what I think of the case where the latter ones are turned into clocked models, maybe using an implicit integration algorithm that required iterations. My head spins... 😄

Maybe would could at least bar this specific case. Honestly, I can't think of any sensible application of it.

However, I am not sure if there's a simple definition of those cases (as we also want to clock discretization of discrete parts of that model).

And therein lies the rub.

It is also unclear how much this will matter in practice for a continuous variable. For a discrete variable doing x:=a*x+u; (as a short-hand for x:=a*pre(x)+u;) makes sense, but for a truly continuous equation it doesn't make sense to re-use the previous value as the equation will not converge, and it is more that you can write something like:

   Real mySum1=sum(cos(i*time) for i in 0:10);
   Real mySum(start=1.0); // Using algorithm to get same result as mySum1
algorithm
   for i in 1:10 loop
      mySum:=mySum+cos(i*time);
   end for;
   // The value for i=0 is handled by the start-value of mySum

With my proposal, one would be forced to write

algorithm
   mySum := 0;
   for i in 1:10 loop
      mySum:=mySum+cos(i*time);
   end for;

which IMHO is way clearer and less ambiguous than relying on a start value, which is declared elsewhere.

@HansOlsson
Copy link
Collaborator

Note that I explicitly did set the start-value of mySum to 1.0 - to skip adding cos(0*time).

@casella
Copy link
Collaborator

casella commented Feb 2, 2022

That's precisely what I mean, this formulation is fishy 😄

@casella
Copy link
Collaborator

casella commented Feb 2, 2022

It's a bit like writing

a = ++b + (c = d / b) – 1;

in C. For sure it is legal C code, but why would one want to write something that is deliberately obscure?

@sjoelund
Copy link
Member

sjoelund commented Feb 2, 2022

For sure it is legal C code, but why would one want to write something that is deliberately obscure?

Code golf

@HansOlsson
Copy link
Collaborator

It's a bit like writing

a = ++b + (c = d / b) – 1;

in C. For sure it is legal C code, but why would one want to write something that is deliberately obscure?

Such C-code would likely be the result of using macros - especially if the code pre-dates proper inline functions; I've seen similar one. Not very relevant for Modelica.

@casella
Copy link
Collaborator

casella commented Feb 2, 2022

Yeah, what I mean is that the initialization with the start attribute is a bit tricky and not very easily readable.

@HansOlsson HansOlsson added this to the Phone 2022-1 milestone Feb 7, 2022
@HansOlsson HansOlsson added the clocked Clocked parts of Modelica; synchronous and state-machines label Jul 1, 2022
HansOlsson added a commit to HansOlsson/ModelicaSpecification that referenced this issue Nov 6, 2024
@HansOlsson HansOlsson linked a pull request Nov 6, 2024 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clocked Clocked parts of Modelica; synchronous and state-machines
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants