I have a model where some parameters are functions of other parameters, which is OK. The particularity is that the formula to be used depend on a choice (another parameter). I.e. I have a pipes assembly and starting from some parameters (diameter, pitch and number of pipes), I want to characterise the external flow (hydraulic-diameter, ...). But the "character" depends on the assembly shape (triangular or square in my case). Here follows a code example:
parameter Modelica.SIunits.Diameter Dext=0.11 "Pipe external diameter";
parameter Integer Ntubes=1 "Number of pipes in parallel";
parameter Real P2D=1.3 "Pitch to diameter ratio";
parameter String pattern="square" "Pipes pattern" annotation(choices(choice="square",choice="triangle"));
if pattern=="square" then
parameter Modelica.SIunits.Area Asub = Dext^2 * (P2D^2 - Modelica.Constants.pi/4) "Subchannel Cross Section Area";
parameter Integer NtE = integer((Ntubes * Modelica.Constants.pi * Dext^2 / (4 * Asub)) + 0.5) "Number of pipes for same cross area";
parameter Real hcCorr = Dext*Ntubes/(Dh*NtE) "Heat Exchange Correction";
elseif pattern=="triangle" then
parameter Modelica.SIunits.Area Asub = Dext^2 * ((P2D^2 * sqrt(3)) - Modelica.Constants.pi/2)/2 "Subchannel Cross Section Area"; //2 (6/3rd) triangles for each pipe
parameter Integer NtE = integer((Ntubes * Modelica.Constants.pi * Dext^2 / (4 * Asub)) + 0.5) "Number of pipes for same cross area";
parameter Real hcCorr = Dext*Ntubes/(Dh*NtE) "Heat Exchange Correction";
end if;
parameter Modelica.SIunits.Diameter Dh = sqrt(Asub*Ntubes*4/(Modelica.Constants.pi*NtE)) "hydraulic diameter of external area";
I know I could do it parameter by parameter with an "inline" statement as follows:
parameter Modelica.SIunits.Area Asub = if pattern=="square" then Dext^2 * (P2D^2 - Modelica.Constants.pi/4) elseif pattern=="triangle" then Dext^2 * ((P2D^2 * sqrt(3)) - Modelica.Constants.pi/2)/2 else 0 "Subchannel Cross Section Area";
Since it is always the same condition, I would like to use a single if block (like in the example). However, the syntax is wrong and I do not understand why. I could also use repleaceble components, but I think that simpler approach (use of 'if') should exist...
If-statements can only occur in algorithms (and equation sections). There are conditional declarations - but they are so restricted that they cannot be used for this.
However, you can do it in another way, by having the computations in a function - and returning a parameter record.
record Geo
Modelica.SIunits.Area Asub;
Integer NtE;
Real hcCorr;
Modelica.SIunits.Diameter Dh;
end Geo;
function computeGeo
input String pattern;
input Modelica.SIunits.Diameter Dext;
input Integer Ntubes;
input Real P2D;
output Geo geo;
algorithm
if pattern=="square" then
geo.Asub :=Dext^2*(P2D^2 - Modelica.Constants.pi/4) "Subchannel Cross Section Area";
geo.NtE :=integer((Ntubes*Modelica.Constants.pi*Dext^2/(4*geo.Asub)) + 0.5) "Number of pipes for same cross area";
geo.Dh :=sqrt(geo.Asub*Ntubes*4/(Modelica.Constants.pi*geo.NtE));
geo.hcCorr :=Dext*Ntubes/(geo.Dh*geo.NtE) "Heat Exchange Correction";
elseif pattern == "triangle" then
geo.Asub :=Dext^2*((P2D^2*sqrt(3)) - Modelica.Constants.pi/2)/2 "Subchannel Cross Section Area"; //2 (6/3rd) triangles for each pipe
geo.NtE :=integer((Ntubes*Modelica.Constants.pi*Dext^2/(4*geo.Asub)) + 0.5) "Number of pipes for same cross area";
geo.Dh := sqrt(geo.Asub*Ntubes*4/(Modelica.Constants.pi*geo.NtE));
geo.hcCorr :=Dext*Ntubes/(geo.Dh*geo.NtE) "Heat Exchange Correction";
end if;
end computeGeo;
parameter Modelica.SIunits.Diameter Dext=0.11 "Pipe external diameter";
parameter Integer Ntubes=1 "Number of pipes in parallel";
parameter Real P2D=1.3 "Pitch to diameter ratio";
parameter String pattern="square" "Pipes pattern" annotation(choices(choice="square",choice="triangle"));
parameter Geo geo=computeGeo(pattern, Dext, Ntubes, P2D);
Assuming the two last statements of the if/else-branches should the same they could be moved after the end. You might also used named parameters for the function call - to reduce the risk of errors.
The downside is that the names are slightly longer, and that you have to manually order the statements in the function due to dependencies.
I would personally also change pattern to an enumeration.