Task:
y1
whose derivative is driven by some lawy1 = sin(time)
y1 = 3.0
y2
y2 = y1 + offset
Parameter
(thus constant during the simulation) and to be evaluated based on starting/initial values of y1
and y2
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:
Parameter
? Am I forced to use some more 'variable' variable?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)
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.
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.
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;
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;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With