From c35a1c526f44da87b3e52c8a6200a7bf6be7a9a3 Mon Sep 17 00:00:00 2001
From: Dietmar Winkler
Date: Thu, 27 Jun 2024 15:05:27 +0200
Subject: [PATCH] Equation of Tainter Gate implementation after Bollrich2019
---
OpenHPL/Examples/Gate.mo | 94 +++++++++++++++++++
OpenHPL/Examples/TainterGate.mo | 38 --------
OpenHPL/Examples/TainterGate3.mo | 42 +++++++++
OpenHPL/Examples/package.order | 3 +-
OpenHPL/Icons/{TainterGate.mo => Gate.mo} | 29 ++++--
OpenHPL/Icons/package.order | 2 +-
OpenHPL/Waterway/{TainterGate3.mo => Gate.mo} | 81 +++++++++-------
.../Waterway/{TainterGate.mo => Gate_HR.mo} | 6 +-
OpenHPL/Waterway/TainterGate_old.mo | 37 --------
OpenHPL/Waterway/package.order | 5 +-
10 files changed, 213 insertions(+), 124 deletions(-)
create mode 100644 OpenHPL/Examples/Gate.mo
delete mode 100644 OpenHPL/Examples/TainterGate.mo
create mode 100644 OpenHPL/Examples/TainterGate3.mo
rename OpenHPL/Icons/{TainterGate.mo => Gate.mo} (71%)
rename OpenHPL/Waterway/{TainterGate3.mo => Gate.mo} (71%)
rename OpenHPL/Waterway/{TainterGate.mo => Gate_HR.mo} (97%)
delete mode 100644 OpenHPL/Waterway/TainterGate_old.mo
diff --git a/OpenHPL/Examples/Gate.mo b/OpenHPL/Examples/Gate.mo
new file mode 100644
index 0000000..b5a992b
--- /dev/null
+++ b/OpenHPL/Examples/Gate.mo
@@ -0,0 +1,94 @@
+within OpenHPL.Examples;
+model Gate "Usage of the tainter gate"
+ extends Modelica.Icons.Example;
+ inner Data data(SteadyState = true, Vdot_0 = 75) annotation (
+ Placement(transformation(extent = {{-100, 80}, {-80, 100}})));
+ Modelica.Blocks.Sources.Ramp gateOpening(
+ height=0,
+ duration=1000,
+ offset=1,
+ startTime=500) annotation (Placement(transformation(extent={{-90,-10},{-70,10}})));
+ Waterway.Reservoir upstream(
+ h_0=5,
+ constantLevel=true,
+ L=10,
+ W=10) annotation (Placement(transformation(extent={{-40,38},{-20,58}})));
+ Waterway.Reservoir downstream(
+ h_0=4,
+ constantLevel=false,
+ useLevel=true,
+ L=10,
+ W=10) annotation (Placement(transformation(
+ extent={{-10,10},{10,-10}},
+ rotation=180,
+ origin={30,48})));
+ Waterway.Gate_HR gate_HR(W=16.5, T=5.6) annotation (Placement(transformation(extent={{-10,38},{10,58}})));
+ Modelica.Blocks.Sources.Ramp level(
+ height=4.89,
+ duration=1000,
+ offset=0.01,
+ startTime=500) annotation (Placement(transformation(extent={{80,38},{60,58}})));
+ Waterway.Reservoir upstream1(
+ h_0=5,
+ constantLevel=true,
+ L=10,
+ W=10) annotation (Placement(transformation(extent={{-40,-10},{-20,10}})));
+ Waterway.Reservoir downstream1(
+ h_0=4,
+ constantLevel=false,
+ useLevel=true,
+ L=10,
+ W=10) annotation (Placement(transformation(
+ extent={{-10,10},{10,-10}},
+ rotation=180,
+ origin={32,0})));
+ Waterway.Gate gate(
+ sluice=false,
+ b=16.5,
+ r=8.5,
+ h_h=5.6) annotation (Placement(transformation(extent={{-8,-10},{12,10}})));
+ Modelica.Blocks.Sources.Ramp level1(
+ height=4.89,
+ duration=1000,
+ offset=0.01,
+ startTime=500) annotation (Placement(transformation(extent={{82,-10},{62,10}})));
+ Waterway.Reservoir upstream2(
+ h_0=5,
+ constantLevel=true,
+ L=10,
+ W=10) annotation (Placement(transformation(extent={{-40,-50},{-20,-30}})));
+ Waterway.Reservoir downstream2(
+ h_0=4,
+ constantLevel=false,
+ useLevel=true,
+ L=10,
+ W=10) annotation (Placement(transformation(
+ extent={{-10,10},{10,-10}},
+ rotation=180,
+ origin={30,-40})));
+ Waterway.Gate gate_sluice(
+ sluice=true,
+ b=16.5,
+ r=8.5,
+ h_h=5.6) annotation (Placement(transformation(extent={{-10,-50},{10,-30}})));
+ Modelica.Blocks.Sources.Ramp level2(
+ height=4.89,
+ duration=1000,
+ offset=0.01,
+ startTime=500) annotation (Placement(transformation(extent={{80,-50},{60,-30}})));
+equation
+ connect(upstream.o, gate_HR.i) annotation (Line(points={{-20,48},{-10,48}}, color={0,128,255}));
+ connect(gate_HR.o, downstream.o) annotation (Line(points={{10,48},{20,48}}, color={0,128,255}));
+ connect(gateOpening.y, gate_HR.B) annotation (Line(points={{-69,0},{-44,0},{-44,70},{0,70},{0,60}}, color={0,0,127}));
+ connect(level.y, downstream.level) annotation (Line(points={{59,48},{50,48},{50,54},{42,54}}, color={0,0,127}));
+ connect(upstream1.o, gate.i) annotation (Line(points={{-20,0},{-8,0}}, color={0,128,255}));
+ connect(gate.o, downstream1.o) annotation (Line(points={{12,0},{22,0}}, color={0,128,255}));
+ connect(level1.y, downstream1.level) annotation (Line(points={{61,0},{52,0},{52,6},{44,6}}, color={0,0,127}));
+ connect(gateOpening.y, gate.a) annotation (Line(points={{-69,0},{-44,0},{-44,22},{2,22},{2,12}}, color={0,0,127}));
+ connect(upstream2.o, gate_sluice.i) annotation (Line(points={{-20,-40},{-10,-40}}, color={0,128,255}));
+ connect(gate_sluice.o, downstream2.o) annotation (Line(points={{10,-40},{20,-40}}, color={0,128,255}));
+ connect(level2.y, downstream2.level) annotation (Line(points={{59,-40},{50,-40},{50,-34},{42,-34}}, color={0,0,127}));
+ connect(gateOpening.y, gate_sluice.a) annotation (Line(points={{-69,0},{-44,0},{-44,-18},{0,-18},{0,-28}}, color={0,0,127}));
+ annotation (
+ experiment(StopTime=2000, Interval=0.4));
+end Gate;
diff --git a/OpenHPL/Examples/TainterGate.mo b/OpenHPL/Examples/TainterGate.mo
deleted file mode 100644
index 918fba7..0000000
--- a/OpenHPL/Examples/TainterGate.mo
+++ /dev/null
@@ -1,38 +0,0 @@
-within OpenHPL.Examples;
-model TainterGate "Usage of the tainter gate"
- extends Modelica.Icons.Example;
- inner Data data(SteadyState = true, Vdot_0 = 75) annotation (
- Placement(transformation(extent = {{-100, 80}, {-80, 100}})));
- Modelica.Blocks.Sources.Ramp gateOpening(
- height=5,
- duration=1000,
- offset=0.1,
- startTime=500) annotation (Placement(transformation(extent={{-40,30},{-20,50}})));
- Waterway.Reservoir upstream(
- h_0=5,
- constantLevel=true,
- L=10,
- W=10) annotation (Placement(transformation(extent={{-40,-20},{-20,0}})));
- Waterway.Reservoir downstream(
- h_0=4,
- constantLevel=false,
- useLevel=true,
- L=10,
- W=10) annotation (Placement(transformation(
- extent={{-10,10},{10,-10}},
- rotation=180,
- origin={30,-10})));
- Waterway.TainterGate tainterGate(W=16.5, T=5.6) annotation (Placement(transformation(extent={{-10,-20},{10,0}})));
- Modelica.Blocks.Sources.Ramp level(
- height=4.89,
- duration=1000,
- offset=0.1,
- startTime=500) annotation (Placement(transformation(extent={{80,-20},{60,0}})));
-equation
- connect(upstream.o, tainterGate.i) annotation (Line(points={{-20,-10},{-10,-10}}, color={0,128,255}));
- connect(tainterGate.o, downstream.o) annotation (Line(points={{10,-10},{20,-10}}, color={0,128,255}));
- connect(gateOpening.y, tainterGate.B) annotation (Line(points={{-19,40},{0,40},{0,2}}, color={0,0,127}));
- connect(level.y, downstream.level) annotation (Line(points={{59,-10},{50,-10},{50,-4},{42,-4}}, color={0,0,127}));
- annotation (
- experiment(StopTime=2000, Interval=0.4));
-end TainterGate;
diff --git a/OpenHPL/Examples/TainterGate3.mo b/OpenHPL/Examples/TainterGate3.mo
new file mode 100644
index 0000000..21ab0c7
--- /dev/null
+++ b/OpenHPL/Examples/TainterGate3.mo
@@ -0,0 +1,42 @@
+within OpenHPL.Examples;
+model TainterGate3 "Usage of the tainter gate"
+ extends Modelica.Icons.Example;
+ inner Data data(SteadyState = true, Vdot_0 = 75) annotation (
+ Placement(transformation(extent = {{-100, 80}, {-80, 100}})));
+ Modelica.Blocks.Sources.Ramp gateOpening(
+ height=0,
+ duration=1000,
+ offset=0.4,
+ startTime=500) annotation (Placement(transformation(extent={{-40,30},{-20,50}})));
+ Waterway.Reservoir upstream(
+ h_0=5.6,
+ constantLevel=true,
+ L=10,
+ W=10) annotation (Placement(transformation(extent={{-40,-20},{-20,0}})));
+ Waterway.Reservoir downstream(
+ h_0=2.8,
+ constantLevel=false,
+ useLevel=true,
+ L=10,
+ W=10) annotation (Placement(transformation(
+ extent={{-10,10},{10,-10}},
+ rotation=180,
+ origin={30,-10})));
+ Waterway.Gate tainterGate3_1(
+ sluice=true,
+ r=8.5,
+ h_h=5.55,
+ b=5.9) annotation (Placement(transformation(extent={{-10,-20},{10,0}})));
+ Modelica.Blocks.Sources.Ramp downstream_level(
+ height=4,
+ duration=1000,
+ offset=0,
+ startTime=500) annotation (Placement(transformation(extent={{80,-20},{60,0}})));
+equation
+ connect(upstream.o, tainterGate3_1.i) annotation (Line(points={{-20,-10},{-10,-10}}, color={0,128,255}));
+ connect(tainterGate3_1.o, downstream.o) annotation (Line(points={{10,-10},{20,-10}}, color={0,128,255}));
+ connect(tainterGate3_1.a, gateOpening.y) annotation (Line(points={{0,2},{-2,2},{-2,42},{-19,42},{-19,40}}, color={0,0,127}));
+ connect(downstream.level, downstream_level.y) annotation (Line(points={{42,-4},{54,-4},{54,-10},{59,-10}}, color={0,0,127}));
+ annotation (
+ experiment(StopTime=2000, Interval=0.4));
+end TainterGate3;
diff --git a/OpenHPL/Examples/package.order b/OpenHPL/Examples/package.order
index 79ab819..7bb5e3b 100644
--- a/OpenHPL/Examples/package.order
+++ b/OpenHPL/Examples/package.order
@@ -7,5 +7,6 @@ DetailedGen
DetailedGenFrancis
PowerSystemSimple
VolumeFlowSource
-TainterGate
+Gate
WithOpenIPSL
+TainterGate3
diff --git a/OpenHPL/Icons/TainterGate.mo b/OpenHPL/Icons/Gate.mo
similarity index 71%
rename from OpenHPL/Icons/TainterGate.mo
rename to OpenHPL/Icons/Gate.mo
index 1693094..aef475c 100644
--- a/OpenHPL/Icons/TainterGate.mo
+++ b/OpenHPL/Icons/Gate.mo
@@ -1,12 +1,30 @@
within OpenHPL.Icons;
-partial class TainterGate "Icon of a tainter gate"
+partial class Gate "Icons for the gate"
annotation (Icon(graphics={
Rectangle(
- extent={{-100,-2},{-46,-72}},
+ extent={{-46,-60},{100,-72}},
+ lineColor={28,108,200},
+ fillColor={28,108,200},
+ fillPattern=FillPattern.Solid),
+ Rectangle(
+ visible = sluice,
+ extent={{-46,0},{-4,-60}},
+ lineColor={28,108,200},
+ fillColor={28,108,200},
+ fillPattern=FillPattern.Solid),
+ Rectangle(
+ visible = sluice,
+ extent={{-4,20},{4,-60}},
+ lineColor={0,0,0},
+ fillColor={175,175,175},
+ fillPattern=FillPattern.Solid),
+ Rectangle(
+ extent={{-100,0},{-46,-72}},
lineColor={28,108,200},
fillColor={28,108,200},
fillPattern=FillPattern.Solid),
Ellipse(
+ visible = not sluice,
extent={{-60,140},{220,-140}},
lineColor={135,135,135},
startAngle=155,
@@ -18,11 +36,6 @@ partial class TainterGate "Icon of a tainter gate"
lineColor={0,0,0},
fillColor={215,215,215},
fillPattern=FillPattern.Forward),
- Rectangle(
- extent={{-46,-60},{100,-72}},
- lineColor={28,108,200},
- fillColor={28,108,200},
- fillPattern=FillPattern.Solid),
Rectangle(extent={{-100,100},{100,-100}}, lineColor={0,0,0}),
Text(
lineColor={28,108,200},
@@ -38,4 +51,4 @@ partial class TainterGate "Icon of a tainter gate"
points={{0,-6},{0,100}},
color={0,0,0},
pattern=LinePattern.Dash)}));
-end TainterGate;
+end Gate;
diff --git a/OpenHPL/Icons/package.order b/OpenHPL/Icons/package.order
index 61cedf1..7c45fcf 100644
--- a/OpenHPL/Icons/package.order
+++ b/OpenHPL/Icons/package.order
@@ -7,6 +7,7 @@ Surge
Fitting
DraftTube
OpenChannel
+Gate
ElectroMech
Turbine
Generator
@@ -14,4 +15,3 @@ Pylon
RunOff
Method
Governor
-TainterGate
diff --git a/OpenHPL/Waterway/TainterGate3.mo b/OpenHPL/Waterway/Gate.mo
similarity index 71%
rename from OpenHPL/Waterway/TainterGate3.mo
rename to OpenHPL/Waterway/Gate.mo
index 408b856..1ac6ce8 100644
--- a/OpenHPL/Waterway/TainterGate3.mo
+++ b/OpenHPL/Waterway/Gate.mo
@@ -1,39 +1,54 @@
within OpenHPL.Waterway;
-model TainterGate3 "Model of a tainter gate based on [Bollrich2019]"
+model Gate "Model of a sluice or tainter gate based on [Bollrich2019]"
outer Data data "Using standard class with system parameters";
- extends Icons.TainterGate;
+ extends Icons.Gate;
extends OpenHPL.Interfaces.ContactPort;
-
-// parameter SI.Height b_max "Maxium opening of the gate";
-// parameter SI.Height b_min = 0 "Minimum opening of the gate";
- parameter SI.Length r "Radius of the gate arm";
- parameter SI.Height a "Height of the hinge above gate bottom";
- parameter SI.Height b "Width of the gate";
- parameter Real Cc_[3] = {1,2,3} "Polinomial factors of contraction coefficient Cc {linear,quadratic,cube}";
- SI.Height h_i "Inlet water level";
- SI.Height h_o "Outlet water level";
- Real alpha = h_o/(Cc*u);
- Real beta = h_i/h_o;
- Real gamma = (h_o/(Cc*u))^2 - (h_o/h_i)^2 "Loss factor";
- Real psi = (1/beta)^2 - 1 + (gamma^2*(beta-1))/(psi_x1 + psi_x2) "Head-loss parameter";
- Real psi_ = (1/beta)^2 - 1 + (gamma^2*(beta-1))/(psi_x1 - psi_x2) "Neg Head-loss parameter";
- Real psi_x1 = gamma*beta-2*(alpha-1);
- Real psi_x2 = sqrt((2*(alpha-1)-gamma*beta)^2 - gamma^2*(beta^2-1));
-
- SI.Angle theta = C.pi/2 - asin((a-u)/r) "Flow angle of the gate";
- Real Cc = Cc_[3]*theta^3 + Cc_[2]*theta^2 + Cc_[1]*theta + 1.002282138151680 "Contraction coefficient";
- SI.VolumeFlowRate Vdot,Vdot_gamma "Volume flow rate through the gate";
-
- Modelica.Blocks.Interfaces.RealInput u "Opening of the gate [m]" annotation (Placement(transformation(
+ import Modelica.Units.Conversions.to_deg;
+ parameter Boolean sluice=false "if true, gate is of type sluice gate, otherwise it is a radial/tainter gate type" annotation (Dialog(group="Type"), choices(checkBox=true));
+ parameter SI.Height b "Width of the gate" annotation (Dialog(group="Common"));
+ parameter SI.Length r "Radius of the gate arm" annotation (Dialog(enable=not sluice, group="Radial/Tainter"));
+ parameter SI.Height h_h "Height of the hinge above gate bottom" annotation (Dialog(group="Radial/Tainter", enable=not sluice));
+ SI.Height h_0 "Inlet water level";
+ SI.Height h_2 "Outlet water level";
+ SI.Height h_2_limit "Limit of free flow";
+ SI.Area A = a*b "Area of the physical gate opening";
+ SI.VolumeFlowRate Vdot "Volume flow rate through the gate";
+ Real mu_A "Discharge coefficient";
+ Real psi "Contraction coefficient";
+ //Real psi90 "Contraction coefficient for vertical gate";
+ Real chi "Back-up coefficient";
+ SI.Angle alpha = C.pi/2 - asin((h_h-a)/r) "Edge angle of the gate";
+ Real x,y,z;
+ Real h0_a = h_0/a;
+ Real h2_a = h_2/a;
+ Modelica.Blocks.Interfaces.RealInput a "Opening of the gate [m]" annotation (Placement(transformation(
extent={{-20,-20},{20,20}},
rotation=270,
origin={0,120})));
equation
- Vdot = b*h_o * sqrt((2*data.g*max(0,(h_i - h_o)))/(psi + 1 - (h_o/h_i)^2)) "Calculated flow";
- Vdot_gamma = b*h_o * sqrt((2*data.g*max(0,(h_i - h_o)))/(gamma + 1 - (h_o/h_i)^2)) "Calculated flow";
+ mu_A = psi/sqrt(1+psi*a/h_0);
+ if sluice then
+ psi = 1 / (1+ 0.64 * sqrt(1-(a/h_0)^2));
+ else
+ psi = 1.3 - 0.8 * sqrt(1 - ((to_deg(alpha)-205)/220)^2) "Normally only valid for a/h_0 --> 0";
+ end if;
+ x = (1-2*psi*a/h_0*(1-psi*a/max(C.small,h_2)))^2;
+ y = x+z-1;
+ z = (h_2/h_0)^2;
+
+ h_2_limit = a*psi/2*(sqrt(1+16/(psi*(1+psi*a/h_0)) * (h_0/a))-1);
+
+ if h_2 >= h_2_limit then
+ chi = sqrt((1+psi*a/h_0) * ((1-2*psi*a/h_0 * (1-psi*a/h_2))-
+ sqrt((1-2*psi*a/h_0*(1-psi*a/max(C.small,h_2)))^2 + (h_2/h_0)^2 - 1))) "Backed-up flow";
+ else
+ chi = 1 "Free flow";
+ end if;
+
+ Vdot = chi * mu_A * A * sqrt(2*data.g*h_0) "Volume flow rate through the gate";
mdot = Vdot * data.rho "Mass flow rate through the gate";
- i.p = h_i * data.g * data.rho + data.p_a "Inlet water pressure";
- o.p = h_o * data.g * data.rho + data.p_a "Outlet water pressure";
+ i.p = h_0 * data.g * data.rho + data.p_a "Inlet water pressure";
+ o.p = h_2 * data.g * data.rho + data.p_a "Outlet water pressure";
annotation (Documentation(info="
Implementation
@@ -85,9 +100,9 @@ $$Q_A = \\chi \\cdot \\mu_A \\cdot A \\cdot \\sqrt{2g\\cdot h_0} \\tag{8.29} $$
With
-- Back-up factor
+- Back-up coefficient
- $$ \\chi = \\sqrt{
- \\left(
+ \\left(
1 + \\frac{\\psi\\cdot a}{h_0}
\\right) \\cdot
\\left\\{
@@ -105,8 +120,8 @@ With
\\right)
\\right]^2
+
- \\left(
- \\frac{h_2}{h_0}
+ \\left(
+ \\frac{h_2}{h_0}
\\right)^2
- 1
}
@@ -123,4 +138,4 @@ $$ \\frac{h_2^*}{a} = \\frac{\\psi}{2} \\cdot \\left( \\sqrt{ 1 + \\frac{16}{\\p
So when \\(\\frac{h_2}{a} \\geq \\frac{h_2^*}{a}\\) then we have back-up flow.
"));
-end TainterGate3;
+end Gate;
diff --git a/OpenHPL/Waterway/TainterGate.mo b/OpenHPL/Waterway/Gate_HR.mo
similarity index 97%
rename from OpenHPL/Waterway/TainterGate.mo
rename to OpenHPL/Waterway/Gate_HR.mo
index 79515d8..ac208b7 100644
--- a/OpenHPL/Waterway/TainterGate.mo
+++ b/OpenHPL/Waterway/Gate_HR.mo
@@ -1,7 +1,7 @@
within OpenHPL.Waterway;
-model TainterGate "Model of a tainter gate (HEC-RAS)"
+model Gate_HR "Model of a tainter gate (HEC-RAS)"
outer Data data "Using standard class with system parameters";
- extends Icons.TainterGate;
+ extends Icons.Gate;
extends OpenHPL.Interfaces.ContactPort;
parameter SI.Height W "Width of the gated spillway"
@@ -84,4 +84,4 @@ $$Q = C_{dx} A \\sqrt{2gH} \\tag{3}$$
The use of Cdx
is different to the implementaion as done in HEC-RAS. This was done in order to have a smoother transition from the partially to fully submerged region.