ValveCompressible

model ValveCompressible "Valve for compressible fluids, accounts for choked flow conditions"
    import Modelica.Fluid.Types.CvTypes;
    import Modelica.Constants.pi;

    extends BaseClasses.PartialValve;

    parameter Medium.AbsolutePressure p_nominal "Nominal inlet pressure"
        annotation (Dialog(group = "Nominal operating point"));
    parameter Real Fxt_full = 0.5 "Fk*xt critical ratio at full opening";

    replaceable function xtCharacteristic = Modelica.Fluid.Valves.BaseClasses.ValveCharacteristics.one constrainedby Modelica.Fluid.Valves.BaseClasses.ValveCharacteristics.baseFun "Critical ratio characteristic";

    Real Fxt;
    Real x "Pressure drop ratio";
    Real xs "Saturated pressure drop ratio";
    Real Y "Compressibility factor";
    Medium.AbsolutePressure p "Inlet pressure";
    constant SI.ReynoldsNumber Re_turbulent = 4000 "cf. straight pipe for fully open valve -- dp_turbulent increases for closing valve";
    parameter Boolean use_Re = system.use_eps_Re "= true, if turbulent region is defined by Re, otherwise by m_flow_small"
        annotation (
            Dialog(tab = "Advanced"),
            Evaluate = true);
    SI.AbsolutePressure dp_turbulent = if not use_Re then dp_small else max(dp_small, 0.125 * ((Medium.dynamicViscosity(state_a) + Medium.dynamicViscosity(state_b)) ^ 2 * pi) * Re_turbulent ^ 2 / (max(valveCharacteristic(opening_actual), 0.001) * Av * Y * (Medium.density(state_a) + Medium.density(state_b))));
protected
    parameter Real Fxt_nominal(fixed = false) "Nominal Fxt";
    parameter Real x_nominal(fixed = false) "Nominal pressure drop ratio";
    parameter Real xs_nominal(fixed = false) "Nominal saturated pressure drop ratio";
    parameter Real Y_nominal(fixed = false) "Nominal compressibility factor";
initial equation
    if CvData == CvTypes.OpPoint then 
        Fxt_nominal = Fxt_full * xtCharacteristic(opening_nominal);
        x_nominal = dp_nominal / p_nominal;
        xs_nominal = smooth(0, if Fxt_nominal < x_nominal then Fxt_nominal else x_nominal);
        Y_nominal = 1 - abs(xs_nominal) / (3 * Fxt_nominal);
        m_flow_nominal = valveCharacteristic(opening_nominal) * Av * Y_nominal * sqrt(rho_nominal) * Utilities.regRoot(p_nominal * xs_nominal, dp_small);
    else 
        Fxt_nominal = 0;
        x_nominal = 0;
        xs_nominal = 0;
        Y_nominal = 0;
    end if;
equation
    if checkValve then 
        m_flow = homotopy(valveCharacteristic(opening_actual) * Av * Y * sqrt(Medium.density(state_a)) * (if 0 <= xs then Utilities.regRoot(p * xs, dp_turbulent) else 0), valveCharacteristic(opening_actual) * m_flow_nominal * dp / dp_nominal);
    elseif not allowFlowReversal then 
        m_flow = homotopy(valveCharacteristic(opening_actual) * Av * Y * sqrt(Medium.density(state_a)) * Utilities.regRoot(p * xs, dp_turbulent), valveCharacteristic(opening_actual) * m_flow_nominal * dp / dp_nominal);
    else 
        m_flow = homotopy(valveCharacteristic(opening_actual) * Av * Y * Utilities.regRoot2(p * xs, dp_turbulent, Medium.density(state_a), Medium.density(state_b)), valveCharacteristic(opening_actual) * m_flow_nominal * dp / dp_nominal);
    end if;
    Y = 1 - abs(xs) / (3 * Fxt);
    p = max(port_a.p, port_b.p);
    x = dp / p;
    Fxt = Fxt_full * xtCharacteristic(opening_actual);
    xs = max(-Fxt, min(x, Fxt));

    annotation (Documentation(
        info = "<html>\n<p>Valve model according to the IEC 534/ISA S.75 standards for valve sizing, compressible fluid, no phase change, also covering choked-flow conditions.</p>\n\n<p>\nThe parameters of this model are explained in detail in\n<a href=\"modelica://Modelica.Fluid.Valves.BaseClasses.PartialValve\">PartialValve</a>\n(the base model for valves).\n</p>\n\n<p>This model can be used with gases and vapours, with arbitrary pressure ratio between inlet and outlet.</p>\n\n<p>The product Fk*xt is given by the parameter <code>Fxt_full</code>, and is assumed constant by default. The relative change (per unit) of the xt coefficient with the valve opening can be specified by replacing the <code>xtCharacteristic</code> function.</p>\n<p>If <code>checkValve</code> is false, the valve supports reverse flow, with a symmetric flow characteristic curve. Otherwise, reverse flow is stopped (check valve behaviour).</p>\n\n<p>\nThe treatment of parameters <strong>Kv</strong> and <strong>Cv</strong> is\nexplained in detail in the\n<a href=\"modelica://Modelica.Fluid.UsersGuide.ComponentDefinition.ValveCharacteristics\">User's Guide</a>.\n</p>\n\n</html>",
        revisions = "<html>\n<ul>\n<li><em>2 Nov 2005</em>\n    by <a href=\"mailto:francesco.casella@polimi.it\">Francesco Casella</a>:<br>\n       Adapted from the ThermoPower library.</li>\n</ul>\n</html>"));
end ValveCompressible;