Set Parameter based on start/initial value of Continuous variable
Asked Answered
T

2

5

Task:

  • I have a variable y1 whose derivative is driven by some law
    e.g. y1 = sin(time)
    and for which I set the starting value
    e.g. y1 = 3.0
  • I have a second variable y2
    that is defined by y2 = y1 + offset
  • Now, I want this offset to be a Parameter (thus constant during the simulation) and to be evaluated based on starting/initial values of y1 and y2
    like offset = y2.start - y1.start

Code

Conceptually I want to achieve:

model SetParametersFromInitialValues

Real y1(start = 3.0, fixed = true);
Real y2(start = 3.0, fixed = true);
parameter Real offset(fixed = false);

initial equation
  offset = y2.start - y1.start;
equation
  der(y1) = sin(time);
  y2 = y1 + offset;

end SetParametersFromInitialValues;

and I thought it could work since start should be a parameter attribute of the built-in type Real, but it is not usable in this way.

I thought also of using a discrete instead of parameter, but I don't know if this will affect the performance.
However, even in this case, I get some dangerous warning (because of an algebraic loop), namely "It was not possible to check the given initialization system for consistency symbolically, because the relevant equations are part of an algebraic loop. This is not supported yet."

model SetParametersFromInitialValues

Real y1(start = 3.0, fixed = true);
discrete Real offset(fixed = false);
Real y2(start = 5.0, fixed = true);

equation
  when initial() then
    offset = y2 - y1;
  end when;
  der(y1) = sin(time);
  y2 = y1 + offset;

end SetParametersFromInitialValues;

Questions:

  • is there a way to achieve what I want with Parameter? Am I forced to use some more 'variable' variable?
  • are fixed attributes required? What if y1 and y2 values are fixed from other components? and what if they are not?

(please mind that I thinks it's different from Define Model Parameter as Variable since I need to evaluate parameters based specifically on initial values)

Tideway answered 6/6, 2019 at 10:26 Comment(0)
S
4

Initial values of variables are accessed using their names in an initial equation section. With some smaller modifications, your code works with Dymola an OpenModlica:

model SetParametersFromInitialValues
  Real y1(start=3.0, fixed=true);
  Real y2(start=2.0, fixed=true);
  final parameter Real offset(fixed=false);
equation 
  der(y1) = sin(time);
  y2 = y1 + offset;
end SetParametersFromInitialValues;

Note that no initial equation section is needed here, as equations are also valid during initialization. See the details below for further description.

Details about the removed initial equation

The Modelica Specification 3.40 writes in chapter 8.6 Initialization, initial equation, and initial algorithm:

The initialization uses all equations and algorithms that are utilized in the intended operation [such as simulation or linearization].

Since we specified y2 = y1 + offset in the equation section already, this equation must not be declared again in the initial equation section (offset = y2 - y1 is the same equation, just written in another way).

In fact, this example demonstrates very nicely, how Modelica enables you to describe models with equations instead of simple assignments.

During initialization the equation

y2 = y1 + offset

is solved as

offset := y2 - y1

by using the start values of y1 and y2.

During simulation the same equation is used to compute

y2 := y1 + offset.

Details about the fixed attribute

Modelica by Example gives a very nice explanation for the fixed attribute:

The fixed attribute changes the way the start attribute is used when the start attribute is used as an initial condition. Normally, the start attribute is considered a “fallback” initial condition and only used if there are insufficient initial conditions explicitly specified in the initial equation sections. However, if the fixed attribute is set to true, then the start attribute is treated as if it was used as an explicit initial equation (i.e., it is no longer used as a fallback, but instead treated as a strict initial condition).

So without using fixed=true we can reformulate the code above as follows:

model SetParametersFromInitialValues2
  Real y1;
  Real y2;
  final parameter Real offset(fixed=false);
initial equation 
  y1 = 3;
  y2 = 1;
equation 
  der(y1) = sin(time) + 1;
  y2 = y1 + offset;
end SetParametersFromInitialValues2;
Shadshadberry answered 6/6, 2019 at 10:47 Comment(4)
Oh, that's quite close to my "discrete" version! Nice. Unfortunately it will not properly work with OpenModelica (it returns the same error). With OpenModelica I suggest to use initial algorithm instead of initial equation so to help the symbolic manipulation. Unfortunately, even in this case, you will get a warning about "over-specified initial conditions". BTW, Dymola resolve the model with rising any issue.Tideway
Yes, OpenModelica can't solve it. Sorry, I only tried it in Dymola. But matth has posted a good solution which also works in OpenModelica.Shadshadberry
NOTE: Actually Dymola generates a warning message for this saying "Removed the following equations which are redundant and consistent: offset = y2-y1;". Removing the initial equation works fine - and generates the correct solution. That simpler model may work in OpeModelica. (It's quite obvious that the initial equation is redundant.)Tuberculosis
Thanks for the input Hans. I will update my answer.Shadshadberry
G
3

You could introduce parameters for setting the start values, might look less elegant, then calculating the offset is easy, and it introduces the possibility to set start values from the parameter dialog.

model SetParametersFromInitialValues

parameter Real y1_start = 3.0;
parameter Real y2_start = 3.1;
final parameter Real offset= y2_start - y1_start;

Real y1(start = y1_start, fixed = true);
Real y2(start = y2_start, fixed = true);

equation
  der(y1) = sin(time);
  y2 = y1 + offset;

end SetParametersFromInitialValues;
Garonne answered 6/6, 2019 at 20:20 Comment(1)
The fact is that I have to specifically avoid this as I mentioned in the very last lines of my post. I have to infer the starting value based on external models (e.g. position of bodies) thus I cannot fill the y1_start and y2_start values.Tideway

© 2022 - 2024 — McMap. All rights reserved.