From 1d874a4dd2ea8a05642e7e087b8a0fcad4f7c5ff 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.

")); -end TainterGate; +end Gate_HR; diff --git a/OpenHPL/Waterway/TainterGate_old.mo b/OpenHPL/Waterway/TainterGate_old.mo deleted file mode 100644 index e0bc63e..0000000 --- a/OpenHPL/Waterway/TainterGate_old.mo +++ /dev/null @@ -1,37 +0,0 @@ -within OpenHPL.Waterway; -model TainterGate_old "Model of a tainter gate (no friction considered)" - outer Data data "Using standard class with system parameters"; - extends Icons.TainterGate; - 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( - 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"; - 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"; -end TainterGate_old; diff --git a/OpenHPL/Waterway/package.order b/OpenHPL/Waterway/package.order index a006821..c1f5c6f 100644 --- a/OpenHPL/Waterway/package.order +++ b/OpenHPL/Waterway/package.order @@ -6,9 +6,8 @@ Pipe PenstockKP SurgeTank Reservoir -TainterGate -TainterGate_old -TainterGate3 +Gate +Gate_HR RunOff_zones RunOff_zones_input VolumeFlowSource