PipeExt

model PipeExt
    parameter Modelica.SIunits.Length diameter = 0.032 "Pipe diameter";
    parameter Modelica.SIunits.Length length = 5 "Pipe length";
    parameter Modelica.SIunits.Length h_g = 0 "Geodetic height (height difference from flowPort_a to flowPort_b)";
    parameter Real relRoughness = 1e-6 "Relative roughness";
    parameter Real sumZeta = 0 "Sum of loss factors (bends, elbows)";
    parameter Real frictionLoss(min = 0, max = 1) = 0 "Part of friction losses fed to medium";
    parameter Real nueT[:,:] = [273,4e-4; 313,3.2e-5] "Table kin. viscosity(T)";
    parameter Boolean useHeatPort = false "enable HeatPort"
        annotation (
            Evaluate = true,
            HideResult = true,
            choices(checkBox = true));
    parameter Modelica.SIunits.Acceleration g(final min = 0) = Modelica.Constants.g_n "Gravitation";
    Modelica.SIunits.Pressure pressureDrop;
    Modelica.SIunits.Power Q_friction;

    extends Modelica.Thermal.FluidHeatFlow.Interfaces.Partials.TwoPort;

    Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a heatPort(T = T_q, Q_flow = Q_flowHeatPort) if useHeatPort "Heat port"
        annotation (Placement(transformation(extent = {
            {-10, -110}, 
            {10, -90}})));
    Modelica.Blocks.Tables.CombiTable1Ds nueTable(table = nueT, smoothness = Modelica.Blocks.Types.Smoothness.MonotoneContinuousDerivative1);
protected
    Modelica.SIunits.HeatFlowRate Q_flowHeatPort "Heat flow at conditional heatPort";
    Real reynoldsNo;
equation
    if not useHeatPort then 
        Q_flowHeatPort = 0;
    end if;
    Q_flow = Q_flowHeatPort + Q_friction;
    dp = pressureDrop + medium.rho * g * h_g;
    Q_friction = frictionLoss * V_flow * pressureDrop;
    pressureDrop = medium.rho * abs(V_flow) * V_flow / (2 * (0.25 * Modelica.Constants.pi * diameter ^ 2) ^ 2) * (Tools.calcLambdaRough(reynoldsNo, relRoughness) * length / diameter + sumZeta);
    reynoldsNo = abs(4 * V_flow / (nueTable.y[1] * Modelica.Constants.pi * diameter));
    nueTable.u = T_q;

    annotation (
        Icon(
            coordinateSystem(
                preserveAspectRatio = true,
                extent = {
                    {-100, -100}, 
                    {100, 100}}),
            graphics = {
                Rectangle(
                    extent = {
                        {-90, 20}, 
                        {90, -20}},
                    lineColor = {255, 0, 0},
                    fillColor = {0, 0, 255},
                    fillPattern = FillPattern.Solid), 
                Polygon(
                    visible = useHeatPort,
                    points = {
                        {-10, -90}, 
                        {-10, -40}, 
                        {0, -20}, 
                        {10, -40}, 
                        {10, -90}, 
                        {-10, -90}},
                    lineColor = {255, 0, 0}), 
                Text(
                    extent = {
                        {-150, 60}, 
                        {150, 20}},
                    textString = "%name",
                    lineColor = {0, 0, 255})}),
        Documentation(info = "<html>\n                <p>\n                    Pipe with geometric parameters, temperature-dependent viscosity, and optional heat exchange.\n                </p>\n                <p>\n                    Thermodynamic equations are defined by Partials.TwoPort.\n                    Q_flow is defined by heatPort.Q_flow (useHeatPort=true) or zero (useHeatPort=false).</p>\n                <p>\n                    <strong>Note:</strong> Setting parameter m (mass of medium within pipe) to zero\n                    leads to neglect of temperature transient cv * m * der(T).\n                </p>\n                <p>\n                    <strong>Note:</strong> Injecting heat into a pipe with zero mass flow causes\n                    temperature rise defined by storing heat in medium's mass.\n                </p>\n                </html>"));
end PipeExt;