model Valve "Simple valve"
extends Modelica.Thermal.FluidHeatFlow.Interfaces.Partials.TwoPort(m(start = 0), final tapT = 1);
parameter Boolean LinearCharacteristic(start = true) "Type of characteristic"
annotation (
Dialog(group = "Standard characteristic"),
choices(
choice = true "Linear",
choice = false "Exponential"));
parameter Real y1(min = small, start = 1) "Max. valve opening"
annotation (Dialog(group = "Standard characteristic"));
parameter Modelica.SIunits.VolumeFlowRate Kv1(min = small, start = 1) "Max. flow @ y = y1"
annotation (Dialog(group = "Standard characteristic"));
parameter Real kv0(min = small, max = 1 - small, start = 0.01) "Leakage flow / max.flow @ y = 0"
annotation (Dialog(group = "Standard characteristic"));
parameter Modelica.SIunits.Pressure dp0(start = 1) "Standard pressure drop"
annotation (Dialog(group = "Standard characteristic"));
parameter Modelica.SIunits.Density rho0(start = 10) "Standard medium's density"
annotation (Dialog(group = "Standard characteristic"));
parameter Real frictionLoss(min = 0, max = 1, start = 0) "Part of friction losses fed to medium";
protected
constant Modelica.SIunits.VolumeFlowRate unitVolumeFlowRate = 1;
constant Real small = Modelica.Constants.small;
constant Modelica.SIunits.VolumeFlowRate smallVolumeFlowRate = eps * unitVolumeFlowRate;
constant Real eps = Modelica.Constants.eps;
Real yLim = max(min(y, y1), 0) "Limited valve opening";
Modelica.SIunits.VolumeFlowRate Kv "Standard flow rate";
public
Modelica.Blocks.Interfaces.RealInput y annotation (Placement(transformation(
extent = {
{-20, -20},
{20, 20}},
rotation = 270,
origin = {0, 100})));
initial algorithm
assert(small < y1, "Valve characteristic: y1 has to be > 0 !");
assert(smallVolumeFlowRate < Kv1, "Valve characteristic: Kv1 has to be > 0 !");
assert(small < kv0, "Valve characteristic: kv0 has to be > 0 !");
assert(kv0 < 1 - eps, "Valve characteristic: kv0 has to be < 1 !");
equation
Kv / Kv1 = if LinearCharacteristic then kv0 + (1 - kv0) * yLim / y1 else kv0 * exp(Modelica.Math.log(kv0 ^ (-1)) * yLim / y1);
dp / dp0 = medium.rho / rho0 * (V_flow / Kv) * abs(V_flow / Kv);
Q_flow = frictionLoss * V_flow * dp;
annotation (
Documentation(info = "<html>\n<p>Simple controlled valve.</p>\n<p>\nStandard characteristic Kv=<em>f </em>(y) is given at standard conditions (dp0, rho0),\n</p>\n<ul>\n<li>either linear :<code> Kv/Kv1 = Kv0/Kv1 + (1-Kv0/Kv1) * y/Y1</code></li>\n<li>or exponential:<code> Kv/Kv1 = Kv0/Kv1 * exp[log(Kv1/Kv0) * y/Y1]</code></li>\n</ul>\n<p>\nwhere:\n</p>\n<ul>\n<li><code>Kv0 ... min. flow @ y = 0</code></li>\n<li><code>Y1 .... max. valve opening</code></li>\n<li><code>Kv1 ... max. flow @ y = Y1</code></li>\n</ul>\n<p>\nFlow resistance under real conditions is calculated by\n</p>\n<blockquote><pre>\nV_flow**2 * rho / dp = Kv(y)**2 * rho0 / dp0\n</pre></blockquote>\n</html>"),
Icon(
coordinateSystem(
preserveAspectRatio = true,
extent = {
{-100, -100},
{100, 100}}),
graphics = {
Polygon(
points = {
{-90, 10},
{-60, 10},
{-60, 60},
{0, 0},
{60, 60},
{60, 10},
{90, 10},
{90, -10},
{60, -10},
{60, -60},
{0, 0},
{-60, -60},
{-60, -10},
{-90, -10},
{-90, 10}},
lineColor = {255, 0, 0},
fillColor = {0, 0, 255},
fillPattern = FillPattern.Solid),
Line(
points = {
{0, 80},
{0, 0}},
color = {0, 0, 127}),
Text(
extent = {
{-150, -70},
{150, -110}},
textString = "%name",
lineColor = {0, 0, 255})}));
end Valve;