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=" +
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:
use_n to enable.The pipe friction can be specified using one of three methods via the friction_method parameter:
use_n to enable this notation.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.
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;