diff --git a/OpenHPL/Data.mo b/OpenHPL/Data.mo index 84a3f62..e04ede0 100644 --- a/OpenHPL/Data.mo +++ b/OpenHPL/Data.mo @@ -3,7 +3,7 @@ record Data "Provides a data set of most common used settings" extends Modelica.Icons.Record; parameter Boolean showElevation=true "Display elevation of connectors" annotation(Dialog(group = "Icon"), - choices(checkBox = true)); + choices(checkBox = true)); parameter SI.Acceleration g = Modelica.Constants.g_n "Gravity constant" annotation (Dialog(enable=false, group = "Constants")); parameter Real gamma_air = 1.4 "Ratio of heat capacities at constant pressure (C_p) to constant volume (C_v) for air at STP" @@ -16,8 +16,24 @@ record Data "Provides a data set of most common used settings" annotation (Dialog(group = "Waterway properties")); parameter SI.DynamicViscosity mu = 1.3076e-3 "Dynamic viscosity of water at T_0" annotation (Dialog(group = "Waterway properties")); - parameter SI.Height p_eps = 0 "Pipe roughness height (default is smooth pipe)" - annotation (Dialog(group = "Waterway properties")); + parameter Types.FrictionMethod FrictionMethod = Types.FrictionMethod.PipeRoughness "Default friction specification method" + annotation (Dialog(group = "Friction")); + parameter SI.Height p_eps_input = 0 "Pipe roughness height (for PipeRoughness method)" + annotation (Dialog(group = "Friction", enable = FrictionMethod == Types.FrictionMethod.PipeRoughness)); + parameter Real f_moody(min=0) = 0.02 "Moody friction factor (used when FrictionMethod = MoodyFriction)" + annotation (Dialog(group = "Friction", enable = FrictionMethod == Types.FrictionMethod.MoodyFriction)); + parameter Real m_manning(unit="m(1/3)/s", min=0) = 40 "Manning M (Strickler) coefficient (used when FrictionMethod = ManningFriction)" + annotation (Dialog(group = "Friction", enable = FrictionMethod == Types.FrictionMethod.ManningFriction and not use_n)); + parameter Boolean use_n = false "If true, use Manning's n instead of M" + annotation (Dialog(group = "Friction", enable = FrictionMethod == Types.FrictionMethod.ManningFriction), choices(checkBox=true)); + parameter Real n_manning(unit="s/m(1/3)", min=0) = 0.025 "Manning's n coefficient (used when FrictionMethod = ManningFriction and use_n)" + annotation (Dialog(group = "Friction", enable = FrictionMethod == Types.FrictionMethod.ManningFriction and use_n)); + parameter SI.Diameter D_h = 1.0 "Reference hydraulic diameter for friction conversion (used for Moody/Manning)" + annotation (Dialog(group = "Friction", enable = FrictionMethod <> Types.FrictionMethod.PipeRoughness)); + final parameter Real n_eff_ = if use_n then n_manning else 1/m_manning "Effective Manning's n coefficient"; + final parameter SI.Height p_eps = if FrictionMethod == Types.FrictionMethod.PipeRoughness then p_eps_input + elseif FrictionMethod == Types.FrictionMethod.MoodyFriction then 3.7 * D_h * 10^(-1/(2*sqrt(f_moody))) + else D_h * 3.0971 * exp(-0.118/n_eff_) "Computed equivalent pipe roughness height"; parameter SI.Compressibility beta = 4.5e-10 "Water compressibility" annotation (Dialog(group = "Waterway properties")); parameter SI.Compressibility beta_total = 1 / (rho*1000^2) "Total compressibility" diff --git a/OpenHPL/Types/FrictionSpec.mo b/OpenHPL/Types/FrictionSpec.mo new file mode 100644 index 0000000..c816a05 --- /dev/null +++ b/OpenHPL/Types/FrictionSpec.mo @@ -0,0 +1,51 @@ +within OpenHPL.Types; +partial model FrictionSpec "Reusable friction specification with multiple input methods" + outer Data data "Using standard data set"; + + parameter Types.FrictionMethod FrictionMethod = data.FrictionMethod "Method for specifying pipe friction" annotation ( + Dialog(group = "Friction")); + parameter SI.Height p_eps_input = data.p_eps "Pipe roughness height (absolute)" annotation ( + Dialog(group = "Friction", enable = FrictionMethod == Types.FrictionMethod.PipeRoughness)); + parameter Real f_moody(min=0) = data.f_moody "Moody friction factor (dimensionless, typically 0.01-0.05)" annotation ( + Dialog(group = "Friction", enable = FrictionMethod == Types.FrictionMethod.MoodyFriction)); + parameter Real m_manning(unit="m(1/3)/s", min=0) = data.m_manning "Manning M (Strickler) coefficient M=1/n (typically 60-110 for steel, 30-60 for rock tunnels)" annotation ( + Dialog(group = "Friction", enable = FrictionMethod == Types.FrictionMethod.ManningFriction and not use_n)); + parameter Boolean use_n = data.use_n "If true, use Mannings coefficient n (=1/M) instead of Manning's M (Strickler)" annotation ( + Dialog(group = "Friction", enable = FrictionMethod == Types.FrictionMethod.ManningFriction), choices(checkBox=true)); + parameter Real n_manning(unit="s/m(1/3)", min=0) = data.n_manning "Manning's n coefficient (typically 0.009-0.017 for steel/concrete, 0.017-0.030 for rock tunnels)" annotation ( + Dialog(group = "Friction", enable = FrictionMethod == Types.FrictionMethod.ManningFriction and use_n)); + + parameter SI.Diameter D_h "Hydraulic diameter used for friction conversion" annotation ( + Dialog(group = "Friction")); + +protected + parameter Real n_eff = if use_n then n_manning else 1/m_manning "Effective Manning's n coefficient"; + parameter SI.Height p_eps = if FrictionMethod == Types.FrictionMethod.PipeRoughness then p_eps_input + elseif FrictionMethod == Types.FrictionMethod.MoodyFriction then 3.7 * D_h * 10^(-1/(2*sqrt(f_moody))) + else D_h * 3.0971 * exp(-0.118/n_eff) "Equivalent pipe roughness height"; + + annotation (preferredView="info", + Documentation(info=" +

Friction Specification

+

Partial model providing a reusable friction parameter set. Extending models must supply +the hydraulic diameter D_h used for converting Moody and Manning coefficients +to equivalent pipe roughness height p_eps.

+ +

Three friction specification methods are supported via the FrictionMethod parameter:

+ +")); +end FrictionSpec; diff --git a/OpenHPL/Types/package.order b/OpenHPL/Types/package.order index d23f790..5071474 100644 --- a/OpenHPL/Types/package.order +++ b/OpenHPL/Types/package.order @@ -2,5 +2,6 @@ DraftTube Efficiency Fitting FrictionMethod +FrictionSpec Lambda SurgeTank diff --git a/OpenHPL/Waterway/DraftTube.mo b/OpenHPL/Waterway/DraftTube.mo index 71ecde7..0847abe 100644 --- a/OpenHPL/Waterway/DraftTube.mo +++ b/OpenHPL/Waterway/DraftTube.mo @@ -2,6 +2,7 @@ within OpenHPL.Waterway; model DraftTube "Model of a draft tube for reaction turbines" outer Data data "Using standard data set"; extends OpenHPL.Icons.DraftTube; + extends Types.FrictionSpec( final D_h = 0.5 * (D_i + D_o)); import Modelica.Constants.pi; parameter Types.DraftTube DraftTubeType = OpenHPL.Types.DraftTube.ConicalDiffuser "Types of draft tube" annotation ( Dialog(group = "Draft tube types")); @@ -29,8 +30,6 @@ model DraftTube "Model of a draft tube for reaction turbines" choice = 45 "45°", choice = 60 "60°", choice = 90 "90°")); - parameter SI.Height p_eps = data.p_eps "Pipe roughness height" annotation ( - Dialog(group = "Geometry")); parameter Boolean SteadyState=data.SteadyState "If true, starts in steady state" annotation (Dialog(group="Initialization")); parameter SI.VolumeFlowRate Vdot_0=data.Vdot_0 "Initial volume flow rate" annotation (Dialog(group="Initialization")); diff --git a/OpenHPL/Waterway/PenstockKP.mo b/OpenHPL/Waterway/PenstockKP.mo index 31a592e..e1c68ae 100644 --- a/OpenHPL/Waterway/PenstockKP.mo +++ b/OpenHPL/Waterway/PenstockKP.mo @@ -2,6 +2,7 @@ within OpenHPL.Waterway; model PenstockKP "Detailed model of the pipe. Could have elastic walls and compressible water. KP scheme" outer OpenHPL.Data data "Using standard data set"; extends OpenHPL.Icons.Pipe( vertical=true); + extends Types.FrictionSpec( final D_h = (D_i + D_o) / 2); import Modelica.Constants.pi; // geometrical parameters of the pipe parameter SI.Height H = 420 "Height difference from the inlet to the outlet of the pipe" annotation ( @@ -12,8 +13,6 @@ model PenstockKP "Detailed model of the pipe. Could have elastic walls and compr Dialog(group = "Geometry")); parameter SI.Diameter D_o = D_i "Diametr from the outlet side of the pipe" annotation ( Dialog(group = "Geometry")); - parameter SI.Height p_eps = data.p_eps "Pipe roughness height" annotation ( - Dialog(group = "Geometry")); // condition of steady state parameter Boolean SteadyState=data.SteadyState "If true, starts in steady state" annotation (Dialog(group="Initialization")); // staedy state values for flow rate in all segments of the pipe diff --git a/OpenHPL/Waterway/Pipe.mo b/OpenHPL/Waterway/Pipe.mo index 3b88d2b..62f6b95 100644 --- a/OpenHPL/Waterway/Pipe.mo +++ b/OpenHPL/Waterway/Pipe.mo @@ -3,6 +3,7 @@ model Pipe "Model of a pipe" outer Data data "Using standard data set"; extends OpenHPL.Icons.Pipe; extends OpenHPL.Interfaces.TwoContacts; + extends Types.FrictionSpec( final D_h = (D_i + D_o) / 2); // Geometrical parameters of the pipe: parameter SI.Length H = 0 "Height difference from the inlet to the outlet" annotation ( @@ -14,21 +15,6 @@ model Pipe "Model of a pipe" parameter SI.Diameter D_o = D_i "Diameter of the outlet side" annotation ( Dialog(group = "Geometry")); - // Friction specification: - parameter Types.FrictionMethod friction_method = Types.FrictionMethod.PipeRoughness "Method for specifying pipe friction" annotation ( - Dialog(group = "Friction")); - parameter SI.Height p_eps_input = data.p_eps "Pipe roughness height (absolute)" annotation ( - Dialog(group = "Friction", enable = friction_method == Types.FrictionMethod.PipeRoughness)); - parameter Real f_moody(min=0) = 0.02 "Moody friction factor (dimensionless, typically 0.01-0.05)" annotation ( - Dialog(group = "Friction", enable = friction_method == Types.FrictionMethod.MoodyFriction)); - parameter Real m_manning(unit="m(1/3)/s", min=0) = 40 "Manning M (Strickler) coefficient M=1/n (typically 60-110 for steel, 30-60 for rock tunnels)" annotation ( - Dialog(group = "Friction", enable = friction_method == Types.FrictionMethod.ManningFriction and not use_n)); - parameter Boolean use_n = false "If true, use Mannings coefficient n (=1/M) instead of Manning's M (Strickler)" annotation ( - Dialog(group = "Friction", enable = friction_method == Types.FrictionMethod.ManningFriction), choices(checkBox=true)); - parameter Real n_manning(unit="s/m(1/3)", min=0) = 0.025 "Manning's n coefficient (typically 0.009-0.017 for steel/concrete, 0.017-0.030 for rock tunnels)" annotation ( - Dialog(group = "Friction", enable = friction_method == Types.FrictionMethod.ManningFriction and use_n)); - - // Steady state: parameter Boolean SteadyState=data.SteadyState "If true, starts in steady state" annotation (Dialog(group="Initialization")); parameter SI.VolumeFlowRate Vdot_0=data.Vdot_0 "Initial flow rate of the pipe" annotation (Dialog(group="Initialization")); @@ -44,10 +30,6 @@ model Pipe "Model of a pipe" SI.VolumeFlowRate Vdot "Volume flow rate"; protected - parameter Real n_eff = if use_n then n_manning else 1/m_manning "Effective Manning's n coefficient"; - parameter SI.Height p_eps = if friction_method == Types.FrictionMethod.PipeRoughness then p_eps_input - elseif friction_method == Types.FrictionMethod.MoodyFriction then 3.7 * D_ * 10^(-1/(2*sqrt(f_moody))) - else D_*3.0971 *exp(-0.118/n_eff) "Equivalent pipe roughness height"; parameter SI.Diameter D_ = ( D_i + D_o) / 2 "Average diameter"; parameter SI.Area A_i = D_i ^ 2 * C.pi / 4 "Inlet cross-sectional area"; parameter SI.Area A_o = D_o ^ 2 * C.pi / 4 "Outlet cross-sectional area"; @@ -119,24 +101,8 @@ slopes (positive or negative height difference).

taper geometry: 0.05–0.15 for gentle cones, up to 0.6 for sharp contractions.

Friction Specification
-

The pipe friction can be specified using one of three methods via the friction_method parameter:

- -

The conversions are simplified for hydropower applications assuming fully turbulent flow, -so they depend only on fixed pipe dimensions and the chosen friction coefficient.

+

Friction is specified via the inherited FrictionSpec +base class, which supports pipe roughness, Moody friction factor, and Manning coefficient methods.

Initialization

By default, the pipe provides an initial equation for the flow rate: either der(mdot) = 0 diff --git a/OpenHPL/Waterway/Reservoir.mo b/OpenHPL/Waterway/Reservoir.mo index 951f082..afa4f22 100644 --- a/OpenHPL/Waterway/Reservoir.mo +++ b/OpenHPL/Waterway/Reservoir.mo @@ -1,4 +1,4 @@ -within OpenHPL.Waterway; +within OpenHPL.Waterway; model Reservoir "Model of the reservoir" outer Data data "using standard class with constants"; extends OpenHPL.Icons.Reservoir; diff --git a/OpenHPL/Waterway/SurgeTank.mo b/OpenHPL/Waterway/SurgeTank.mo index 687b775..e674200 100644 --- a/OpenHPL/Waterway/SurgeTank.mo +++ b/OpenHPL/Waterway/SurgeTank.mo @@ -3,6 +3,7 @@ model SurgeTank "Model of the surge tank/shaft" outer Data data "Using standard data set"; extends OpenHPL.Icons.Surge(lds=l, Lds=L); extends OpenHPL.Interfaces.TwoContacts; + extends Types.FrictionSpec( final D_h = D); parameter Types.SurgeTank SurgeTankType = OpenHPL.Types.SurgeTank.STSimple "Types of surge tank" annotation (Dialog(group = "Surge tank types")); @@ -16,8 +17,6 @@ model SurgeTank "Model of the surge tank/shaft" annotation (Dialog(group = "Geometry")); - parameter SI.Height p_eps = data.p_eps "Pipe roughness height" annotation ( - Dialog(group = "Geometry")); parameter SI.Diameter D_so = D "If Sharp orifice type: Diameter of sharp orifice" annotation ( Dialog(group = "Geometry",enable=SurgeTankType == OpenHPL.Types.SurgeTank.STSharpOrifice)); parameter SI.Diameter D_t = D "If Throttle value type: Diameter of throat" annotation ( @@ -113,9 +112,9 @@ equation F_f = Functions.DarcyFriction.Friction(v, D, l, data.rho, data.mu, p_eps) + A * phiSO * 0.5 * data.rho * abs(v) * v; F_p = (p_b - p_t) * A; if v >= 0 then - phiSO = Functions.Fitting.FittingPhi(v, D, D_so, L, 90, data.rho, data.mu, data.p_eps, OpenHPL.Types.Fitting.SharpOrifice); + phiSO = Functions.Fitting.FittingPhi(v, D, D_so, L, 90, data.rho, data.mu, p_eps, OpenHPL.Types.Fitting.SharpOrifice); else - phiSO = Functions.Fitting.FittingPhi(v, D_so, D, L, 90, data.rho, data.mu, data.p_eps, OpenHPL.Types.Fitting.SharpOrifice); + phiSO = Functions.Fitting.FittingPhi(v, D_so, D, L, 90, data.rho, data.mu, p_eps, OpenHPL.Types.Fitting.SharpOrifice); end if; elseif SurgeTankType == OpenHPL.Types.SurgeTank.STThrottleValve then if l <= L_t then @@ -131,10 +130,10 @@ equation M = m * v; if v > 0 then F_f = Functions.DarcyFriction.Friction(Vdot/A_t, D_t, L_t, data.rho, data.mu, p_eps) + Functions.DarcyFriction.Friction(Vdot/A, D, l - L_t, data.rho, data.mu, p_eps) + A_t * phiSO * 0.5 * data.rho * abs(Vdot/A_t) * Vdot/A_t; - phiSO = Functions.Fitting.FittingPhi(Vdot/A_t, D_t, D, L, 90, data.rho, data.mu, data.p_eps, OpenHPL.Types.Fitting.Square); + phiSO = Functions.Fitting.FittingPhi(Vdot/A_t, D_t, D, L, 90, data.rho, data.mu, p_eps, OpenHPL.Types.Fitting.Square); elseif v < 0 then F_f = Functions.DarcyFriction.Friction(Vdot/A_t, D_t, L_t, data.rho, data.mu, p_eps) + Functions.DarcyFriction.Friction(Vdot/A, D, l - L_t, data.rho, data.mu, p_eps) + A * phiSO * 0.5 * data.rho * abs(Vdot/A) * Vdot/A; - phiSO = Functions.Fitting.FittingPhi(Vdot/A, D, D_t, L, 90, data.rho, data.mu, data.p_eps, OpenHPL.Types.Fitting.Square); + phiSO = Functions.Fitting.FittingPhi(Vdot/A, D, D_t, L, 90, data.rho, data.mu, p_eps, OpenHPL.Types.Fitting.Square); else F_f = 0; phiSO = 0;