How do I define relations between multiple parameters in such a way that I can choose which parameters from the set to define, some equations defining the rest?
For example, I have a model with 3 parameters for the radius, height and volume of a cylinder, and they are related via the equation for volume V=r^2*h
.
I want to be able to choose on model instantiation if I define r
and h
(and V
is computed), r
, V
(and h
is computed), or h
, V
(and r
is computed).
In the following minimal example, I have tried the approaches 1-3, but none does what I need. I got the feeling that this has to be a common/solved problem, and I am just missing a certain modelling technique. Can you help?
model test_params "Model for a cylinder"
model Cylinder
parameter Real r;
parameter Real h;
parameter Real V;
//Approach 3: binding equation. Works, but what to do if I have V, h and want to know r??
//parameter Real V=r^2*Modelica.Constants.pi*h;
Real t;
initial equation
//Approach 2, apparently chooses V as 0 before getting to the initialisation equation
//V=r^2*Modelica.Constants.pi*h;
//Parameter cylinder.V has no value, and is fixed during initialization (fixed=true), using available start value (start=0.0) as default value.
// The initial conditions are over specified. The following 1 initial equations are redundant, so they are removed from the initialization sytem:
// cylinder.V = 3.141592653589793 * cylinder.r ^ 2.0 * cylinder.h.
equation
t = V;
// Approach 1
//V=r^2*Modelica.Constants.pi*h; //Leads to: Too many equations, over-determined system.
end Cylinder;
test_params.Cylinder cylinder(h = 1, r = 2) annotation(
Placement(visible = true, transformation(origin = {-44, 30}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
equation
end test_params;
This is on OpenModelica 1.14, if that should be relevant.
This can be done using your mentioned approach 2 if you set the dependent parameter as fixed=false parameter.
model TestParams "Model for a cylinder"
encapsulated model Cylinder
import Modelica.Constants.pi;
parameter Real r;
parameter Real h;
parameter Real V;
initial equation
V = r^2*pi*h "Cylinder volume";
end Cylinder;
TestParams.Cylinder cylinder_1(h=1, r=2, V(fixed=false)) "Compute cylinder V(h, r)"
annotation (Placement(transformation(origin={-70,50}, extent={{-10,-10},{10,10}})));
TestParams.Cylinder cylinder_2(h(start=0, fixed=false), r=2, V=13) "Compute cylinder h(r, V)"
annotation (Placement(transformation(origin={-30,50}, extent={{-10,-10},{10,10}})));
TestParams.Cylinder cylinder_3(h=1, r(start=0, fixed=false), V=13) "Compute cylinder r(h, V)"
annotation (Placement(transformation(origin={10,50}, extent={{-10,-10},{10,10}})));
end TestParams;