Skip to content

Commit 3a8ae4a

Browse files
Add a valve model (#59)
* Splits the Turbine into a BaseValve and Turbine model Fixes #75 At the same time a simple valve component is introduced which is based on the `BaseValve` model just like the turbine model is now also based on this. An example model was also added. * Simplify the example parameters. * Rename the examples to reflect the turbine usage Since we now have a `SimpleValve` model a it seems better to emphasise when a turbine is part of the example. * Syntax clean up. * Refactor: Generalize BaseValve interface and parameter descriptions * Feat: Introduce mass flow rate for compressibility calculation * Chore: Remove redundant 'visible' annotation from Valve icon --------- Co-authored-by: Dietmar Winkler <dietmar.winkler@skagerakenergi.no>
1 parent 9fab5ee commit 3a8ae4a

14 files changed

Lines changed: 254 additions & 77 deletions

File tree

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
within OpenHPL.ElectroMech.BaseClasses;
2+
partial model BaseValve "Simple hydraulic valve (base class)"
3+
outer Data data "Using standard class with global parameters";
4+
extends OpenHPL.Interfaces.TwoContacts;
5+
6+
parameter Boolean ValveCapacity = true "If checked the valve capacity C_v should be specified,
7+
otherwise specify the nominal values (net head and flow rate)"
8+
annotation (Dialog(group = "Nominal values"), choices(checkBox = true));
9+
parameter Real C_v = 1 "Valve capacity"
10+
annotation (Dialog(group = "Nominal values", enable = ValveCapacity));
11+
parameter SI.Height H_n = 100 "Nominal net head"
12+
annotation (Dialog(group = "Nominal values", enable = not ValveCapacity));
13+
parameter SI.VolumeFlowRate Vdot_n = 3 "Nominal flow rate"
14+
annotation (Dialog(group = "Nominal values", enable = not ValveCapacity));
15+
parameter SI.PerUnit u_n = 0.95 "Nominal opening"
16+
annotation (Dialog(group = "Nominal values", enable = not ValveCapacity));
17+
parameter Boolean ConstEfficiency = true "If checked the constant efficiency eta_h is used,
18+
otherwise specify lookup table for efficiency"
19+
annotation (Dialog(group = "Efficiency data"), choices(checkBox = true));
20+
parameter SI.Efficiency eta_h = 0.9 "Hydraulic efficiency"
21+
annotation (Dialog(group = "Efficiency data", enable = ConstEfficiency));
22+
parameter Real lookup_table[:, :] = [0, 0.4; 0.2, 0.7; 0.5, 0.9; 0.95, 0.95; 1.0, 0.93]
23+
"Look-up table for the turbine/valve efficiency, described by a table matrix,
24+
where the first column is a pu value of the guide vane opening,
25+
and the second column is a pu value of the turbine efficiency."
26+
annotation (Dialog(group = "Efficiency data", enable = not ConstEfficiency));
27+
parameter Boolean WaterCompress = false "If checked, the water is compressible"
28+
annotation (Dialog(tab = "Advanced"), choices(checkBox = true));
29+
30+
SI.Pressure dp "Pressure drop";
31+
SI.EnergyFlowRate Kdot_i_tr "Kinetic energy flow";
32+
SI.MassFlowRate mdot "Mass flow rate";
33+
SI.VolumeFlowRate Vdot "Flow rate";
34+
Real C_v_ "Valve capacity";
35+
36+
output SI.EnergyFlowRate Wdot_s "Valve power";
37+
Modelica.Blocks.Tables.CombiTable1Dv look_up_table(table=lookup_table);
38+
protected
39+
Modelica.Blocks.Interfaces.RealInput u(min=0, max=1)
40+
"=1: completely open, =0: completely closed"
41+
annotation (Placement(transformation(
42+
origin={0,70},
43+
extent={{-10,-10},{10,10}},
44+
rotation=270), iconTransformation(
45+
extent={{-20,-20},{20,20}},
46+
rotation=270,
47+
origin={0,80})));
48+
equation
49+
i.mdot+o.mdot=0;
50+
mdot = i.mdot;
51+
Vdot = if WaterCompress then mdot / (data.rho * (1 + data.beta * (i.p - data.p_a))) else mdot / data.rho
52+
"Checking for water compressibility";
53+
look_up_table.u[1] = u "Link the valve opening";
54+
C_v_ = if ValveCapacity then C_v else Vdot_n/sqrt(H_n*data.g*data.rho/data.p_a)/u_n
55+
"Define 'valve capacity' base on the nominal values";
56+
dp = Vdot ^ 2 * data.p_a / (C_v_ * max(1e-6, u)) ^ 2 "Valve equation for pressure drop";
57+
dp = i.p - o.p "Link the pressure drop to the ports";
58+
Kdot_i_tr = dp * Vdot "Energy balance";
59+
if ConstEfficiency then
60+
Wdot_s = eta_h * Kdot_i_tr;
61+
else
62+
Wdot_s = look_up_table.y[1] * Kdot_i_tr;
63+
end if;
64+
65+
annotation (
66+
Documentation(info="<html><p>
67+
This is a simple model of hydraulic valve.
68+
The model can use a constant efficiency or varying
69+
efficiency from a lookup-table.
70+
</p>
71+
<p>
72+
This model is based on the energy balance of a valve.
73+
The valve capacity can either be specified
74+
directly by the user by specifying <code>C_v</code> or it will be calculated from
75+
the nominal head <code>H_n</code> and nominal flow rate <code>Vdot_n</code>.
76+
</p>
77+
<p>
78+
The valve efficiency is in per-unit values from 0 to 1, where 1 means that there are no losses in the valve.
79+
The valve power is defined as the product of the valve power and valve efficiency.
80+
</p>
81+
<p>
82+
Besides hydraulic input and output,
83+
there is an input <code>u</code> for controlling the valve opening.
84+
</p>
85+
</html>"));
86+
end BaseValve;
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
Power2Torque
2+
BaseValve

OpenHPL/ElectroMech/Turbines/Turbine.mo

Lines changed: 9 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,70 +1,21 @@
11
within OpenHPL.ElectroMech.Turbines;
22
model Turbine "Simple turbine model with mechanical connectors"
3-
outer Data data "Using standard class with global parameters";
4-
extends Icons.Turbine;
5-
6-
parameter Boolean ValveCapacity = true "If checked the guide vane capacity C_v should be specified,
7-
otherwise specify the nominal turbine parameters (net head and flow rate)"
8-
annotation (Dialog(group = "Nominal turbine parameters"), choices(checkBox = true));
9-
parameter Real C_v = 3.7 "Guide vane 'valve capacity'"
10-
annotation (Dialog(group = "Nominal turbine parameters", enable = ValveCapacity));
11-
parameter SI.Height H_n = 460 "Nominal net head"
12-
annotation (Dialog(group = "Nominal turbine parameters", enable = not ValveCapacity));
13-
parameter SI.VolumeFlowRate Vdot_n = 23.4 "Nominal flow rate"
14-
annotation (Dialog(group = "Nominal turbine parameters", enable = not ValveCapacity));
15-
parameter SI.PerUnit u_n = 0.95 "Nominal guide vane opening"
16-
annotation (Dialog(group = "Nominal turbine parameters", enable = not ValveCapacity));
17-
parameter Boolean ConstEfficiency = true "If checked the constant efficiency eta_h is used,
18-
otherwise specify lookup table for efficiency"
19-
annotation (Dialog(group = "Efficiency data"), choices(checkBox = true));
20-
parameter SI.Efficiency eta_h = 0.9 "Turbine hydraulic efficiency"
21-
annotation (Dialog(group = "Efficiency data", enable = ConstEfficiency));
22-
parameter Real lookup_table[:, :] = [0, 0.4; 0.2, 0.7; 0.5, 0.9; 0.95, 0.95; 1.0, 0.93]
23-
"Look-up table for the turbine efficiency, described by a table matrix,
24-
where the first column is a pu value of the guide vane opening,
25-
and the second column is a pu value of the turbine efficiency."
26-
annotation (Dialog(group = "Efficiency data", enable = not ConstEfficiency));
27-
parameter Boolean WaterCompress = false "If checked the water is compressible in the penstock"
28-
annotation (Dialog(tab = "Advanced"), choices(checkBox = true));
29-
3+
extends BaseClasses.BaseValve;
304
extends BaseClasses.Power2Torque(power(y=Wdot_s));
31-
extends OpenHPL.Interfaces.TurbineContacts;
32-
33-
SI.Pressure dp "Turbine pressure drop";
34-
SI.MassFlowRate mdot "Turbine pressure drop";
35-
SI.EnergyFlowRate Kdot_i_tr "Kinetic energy flow";
36-
SI.VolumeFlowRate Vdot "Flow rate";
37-
Real C_v_ "Guide vane 'valve capacity'";
5+
extends Interfaces.TurbineContacts;
6+
extends Icons.Turbine;
387

39-
output SI.EnergyFlowRate Wdot_s "Shaft power";
40-
Modelica.Blocks.Tables.CombiTable1Dv look_up_table(table=lookup_table);
41-
Modelica.Blocks.Math.Feedback lossCorrection annotation (Placement(transformation(extent={{-10,70},{10,90}})));
8+
Modelica.Blocks.Math.Feedback lossCorrection annotation (Placement(transformation(extent={{-50,70},{-30,90}})));
429
equation
43-
Vdot = if WaterCompress then mdot / (data.rho * (1 + data.beta * (i.p - data.p_a))) else mdot / data.rho
44-
"Checking for water compressibility";
45-
look_up_table.u[1] = u_t "Link the guide vane opening";
46-
C_v_ = if ValveCapacity then C_v else Vdot_n/sqrt(H_n*data.g*data.rho/data.p_a)/u_n
47-
"Define guide vane 'valve capacity' base on the Nominal turbine parameters";
48-
dp = Vdot ^ 2 * data.p_a / (C_v_ * max(1e-6, u_t)) ^ 2 "Turbine valve equation for pressure drop";
49-
dp = i.p - o.p "Link the pressure drop to the ports";
50-
i.mdot+o.mdot=0 "Mass balance";
51-
mdot = i.mdot "Flow direction";
52-
Kdot_i_tr = dp * Vdot "Turbine energy balance";
53-
if ConstEfficiency then
54-
Wdot_s = eta_h * Kdot_i_tr;
55-
else
56-
Wdot_s = look_up_table.y[1] * Kdot_i_tr;
57-
end if;
58-
59-
/* // for temperature variation, not finished...
60-
i.T = o.T; */
6110

6211
connect(P_out, lossCorrection.y) annotation (Line(
63-
points={{40,110},{40,80},{9,80}},
12+
points={{40,110},{40,80},{-31,80}},
6413
color={0,0,127},
6514
pattern=LinePattern.Dash));
66-
connect(lossCorrection.u1, power.y) annotation (Line(points={{-8,80},{-88,80},{-88,30},{-81,30}}, color={0,0,127}));
67-
connect(frictionLoss.power, lossCorrection.u2) annotation (Line(points={{-1,12},{0,12},{0,72}}, color={0,0,127}));
15+
connect(lossCorrection.u1, power.y) annotation (Line(points={{-48,80},{-88,80},{-88,30},{-81,30}},color={0,0,127}));
16+
connect(frictionLoss.power, lossCorrection.u2) annotation (Line(points={{-1,12},{-40,12},{-40,72}},
17+
color={0,0,127}));
18+
connect(u_t, u) annotation (Line(points={{-80,120},{-80,90},{0,90},{0,70}}, color={0,0,127}));
6819
annotation (
6920
Documentation(info="<html><p>
7021
This is a simple model of the turbine that give possibilities for simplified

OpenHPL/Examples/Detailed.mo

Lines changed: 0 additions & 5 deletions
This file was deleted.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
within OpenHPL.Examples;
2+
model DetailedTurbine "Hydropower system using KP scheme based penstock"
3+
extends SimpleTurbine(
4+
redeclare Waterway.PenstockKP penstock);
5+
annotation (experiment(StopTime=1000));
6+
end DetailedTurbine;

OpenHPL/Examples/SimpleGen.mo

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
within OpenHPL.Examples;
22
model SimpleGen "Model of a hydropower system with a simple turbine turbine and generator"
3-
extends Simple(turbine(
3+
extends SimpleTurbine(
4+
turbine(
45
enable_nomSpeed=false,
56
enable_P_out=true));
67
ElectroMech.Generators.SimpleGen simpleGen annotation (Placement(transformation(extent={{20,50},{40,70}})));
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
within OpenHPL.Examples;
2-
model Simple "Model of a hydropower system with a simple turbine turbine"
2+
model SimpleTurbine "Model of a hydropower system with a simple turbine turbine"
33
extends Modelica.Icons.Example;
4-
OpenHPL.Waterway.Reservoir reservoir(h_0=48) annotation (Placement(transformation(
4+
OpenHPL.Waterway.Reservoir reservoir(h_0=10) annotation (Placement(transformation(
55
origin={-90,30},
66
extent={{-10,-10},{10,10}})));
77
Modelica.Blocks.Sources.Ramp control(
8-
duration=30, height = -0.04615, offset = 0.7493,
8+
duration=30,
9+
height=-0.9,
10+
offset=1,
911
startTime=500) annotation (
1012
Placement(transformation(origin={-10,70}, extent = {{-10, -10}, {10, 10}})));
11-
OpenHPL.Waterway.Pipe intake(H=23, Vdot(fixed = true)) annotation (Placement(transformation(extent={{-70,20},{-50,40}})));
13+
OpenHPL.Waterway.Pipe intake(H=10, Vdot(fixed = true)) annotation (Placement(transformation(extent={{-70,20},{-50,40}})));
1214
OpenHPL.Waterway.Pipe discharge(H=0.5, L=600) annotation (Placement(transformation(extent={{50,-10},{70,10}})));
1315
OpenHPL.Waterway.Reservoir tail(h_0=5) annotation (Placement(transformation(
1416
origin={90,0},
@@ -17,18 +19,20 @@ model Simple "Model of a hydropower system with a simple turbine turbine"
1719
replaceable OpenHPL.Waterway.Pipe penstock(
1820
D_i=3,
1921
D_o=3,
20-
H=428.5,
21-
L=600,
22+
H=80,
23+
L=200,
2224
vertical=true) constrainedby Interfaces.TwoContact annotation (Placement(transformation(origin={0,30}, extent={{-10,-10},{10,10}})));
23-
OpenHPL.Waterway.SurgeTank surgeTank(h_0=69.9) annotation (Placement(transformation(
25+
OpenHPL.Waterway.SurgeTank surgeTank(h_0=20) annotation (Placement(transformation(
2426
origin={-30,30},
2527
extent={{-10,-10},{10,10}})));
26-
ElectroMech.Turbines.Turbine turbine(C_v=3.7, ConstEfficiency=false, enable_nomSpeed=true,
28+
ElectroMech.Turbines.Turbine turbine(
29+
ValveCapacity=false, ConstEfficiency=false, enable_nomSpeed=true,
2730
enable_f=false)
2831
annotation (Placement(transformation(
2932
origin={30,10},
3033
extent={{-10,-10},{10,10}})));
31-
inner OpenHPL.Data data annotation (Placement(transformation(
34+
inner OpenHPL.Data data(Vdot_0=3)
35+
annotation (Placement(transformation(
3236
origin={-90,90},
3337
extent={{-10,-10},{10,10}})));
3438
equation
@@ -43,4 +47,4 @@ equation
4347
connect(surgeTank.o, penstock.i) annotation (Line(points={{-20,30},{-10,30}}, color={28,108,200}));
4448
connect(discharge.o, tail.o) annotation (Line(points={{70,0},{80,0}}, color={28,108,200}));
4549
annotation (experiment(StopTime=1000));
46-
end Simple;
50+
end SimpleTurbine;

OpenHPL/Examples/SimpleValve.mo

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
within OpenHPL.Examples;
2+
model SimpleValve "Model of a hydropower system with a simple turbine turbine"
3+
extends Modelica.Icons.Example;
4+
OpenHPL.Waterway.Reservoir reservoir(h_0=10) annotation (Placement(transformation(
5+
origin={-90,30},
6+
extent={{-10,-10},{10,10}})));
7+
Modelica.Blocks.Sources.Ramp control(
8+
duration=30,
9+
height=-0.9,
10+
offset=1,
11+
startTime=500) annotation (
12+
Placement(transformation(origin={-10,70}, extent = {{-10, -10}, {10, 10}})));
13+
OpenHPL.Waterway.Pipe intake(H=10, Vdot(fixed = true)) annotation (Placement(transformation(extent={{-70,20},{-50,40}})));
14+
OpenHPL.Waterway.Pipe discharge(H=0.5, L=600) annotation (Placement(transformation(extent={{50,20},{70,40}})));
15+
OpenHPL.Waterway.Reservoir tail(h_0=5) annotation (Placement(transformation(
16+
origin={90,30},
17+
extent={{-10,10},{10,-10}},
18+
rotation=180)));
19+
replaceable OpenHPL.Waterway.Pipe penstock(
20+
D_i=3,
21+
D_o=3,
22+
H=80,
23+
L=200,
24+
vertical=true) constrainedby Interfaces.TwoContact annotation (Placement(transformation(origin={0,30}, extent={{-10,-10},{10,10}})));
25+
OpenHPL.Waterway.SurgeTank surgeTank(
26+
H=30,
27+
L=30,
28+
h_0=20) annotation (Placement(transformation(
29+
origin={-30,30},
30+
extent={{-10,-10},{10,10}})));
31+
inner OpenHPL.Data data(Vdot_0=3)
32+
annotation (Placement(transformation(
33+
origin={-90,90},
34+
extent={{-10,-10},{10,10}})));
35+
Waterway.Valve valve(
36+
ValveCapacity=false,
37+
C_v=1,
38+
ConstEfficiency=false,
39+
WaterCompress=false) annotation (Placement(transformation(extent={{20,20},{40,40}})));
40+
equation
41+
connect(reservoir.o, intake.i) annotation (
42+
Line(points={{-80,30},{-70,30}}, color = {28, 108, 200}));
43+
connect(intake.o, surgeTank.i) annotation (
44+
Line(points={{-50,30},{-40,30}}, color = {28, 108, 200}));
45+
connect(surgeTank.o, penstock.i) annotation (Line(points={{-20,30},{-10,30}}, color={28,108,200}));
46+
connect(discharge.o, tail.o) annotation (Line(points={{70,30},{80,30}},
47+
color={28,108,200}));
48+
connect(penstock.o, valve.i) annotation (Line(points={{10,30},{20,30}}, color={0,128,255}));
49+
connect(valve.o, discharge.i) annotation (Line(points={{40,30},{50,30}}, color={0,128,255}));
50+
connect(control.y, valve.opening) annotation (Line(points={{1,70},{30,70},{30,38}}, color={0,0,127}));
51+
annotation (experiment(StopTime=1000), Documentation(info="<html>
52+
<p>
53+
Simple model of a water way with only a valve component.
54+
This can be used to investigate the effect of different opening and closing times in the waterway.
55+
</p>
56+
</html>"));
57+
end SimpleValve;

OpenHPL/Examples/package.order

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
BranchingPipes
2-
Simple
2+
SimpleValve
3+
SimpleTurbine
34
SimpleGen
45
SimpleGenFrancis
5-
Detailed
6+
DetailedTurbine
67
DetailedGen
78
DetailedGenFrancis
89
PowerSystemSimple

OpenHPL/Icons/Valve.mo

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
within OpenHPL.Icons;
2+
partial class Valve "Valve icon"
3+
annotation (
4+
Icon(graphics={
5+
Text(
6+
lineColor={28,108,200},
7+
extent={{-100,-60},{100,-100}},
8+
textString="%name",
9+
textStyle={TextStyle.Bold}),
10+
Polygon(
11+
points={{-90,40},{0,10},{90,40},{90,30},{0,0},{-90,30},{-90,40}},
12+
lineColor={0,0,0},
13+
fillColor={175,175,175},
14+
fillPattern=FillPattern.Solid),
15+
Polygon(
16+
points={{-90,-30},{0,0},{90,-30},{90,-40},{0,-10},{-90,-40},{-90,-30}},
17+
lineColor={0,0,0},
18+
fillColor={175,175,175},
19+
fillPattern=FillPattern.Solid),
20+
Polygon(
21+
points={{-90,-30},{-90,30},{0,0},{-90,-30}},
22+
lineColor={0,128,255},
23+
fillColor={0,128,255},
24+
fillPattern=FillPattern.Solid),
25+
Polygon(
26+
points={{90,-30},{90,30},{0,0},{90,-30}},
27+
lineColor={0,128,255},
28+
fillColor={0,128,255},
29+
fillPattern=FillPattern.Solid),
30+
Rectangle(
31+
extent={{-20,60},{20,50}},
32+
fillPattern=FillPattern.Solid),
33+
Line(points={{0,50},{0,0}})}));
34+
end Valve;

0 commit comments

Comments
 (0)