Search code examples
modelicaopenmodelica

Set Parameter based on start/initial value of Continuous variable


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)


Solution

  • 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;