DivergingTee

model DivergingTee
    import SI = Modelica.SIunits;

    parameter SI.Length Dc = 0.005 "Diameter of main passage";
    parameter SI.Length Ds = 0.005 "Diameter of branch";
    parameter Modelica.Thermal.FluidHeatFlow.Media.Medium medium = Modelica.Thermal.FluidHeatFlow.Media.Medium() "Medium in the component"
        annotation (choicesAllMatching = true);
    parameter SI.Temperature T0(start = 293.15, displayUnit = "degC") "Initial temperature of medium";
    parameter Boolean T0fixed = false "Initial temperature guess value or fixed"
        annotation (
            choices(checkBox = true),
            Dialog(enable = Modelica.Constants.small < m));
    output SI.Temperature T(start = 293.15, fixed = T0fixed) "Outlet temperature of medium";
    parameter Real frictionLoss(min = 0, max = 1, start = 0) "Part of friction losses fed to medium";
protected
    parameter Real m = 0;
    SI.SpecificEnthalpy h(start = medium.cp * T0) "Medium's specific enthalpy";
    Modelica.SIunits.HeatFlowRate Q_flowHeatPort "Heat flow at conditional heatPort";
    Real Fc = 0.25 * (Dc * Dc * Modelica.Constants.pi);
    Real Fs = 0.25 * (Ds * Ds * Modelica.Constants.pi);
    Real dpcst "Pressure drop c->st";
    Real dpcs "Pressure drop c->s";
    Real zetacst "zeta main passage";
    Real zetacs "zeta side branch";
    Modelica.SIunits.VolumeFlowRate Vflowst(start = 0) "Volume flow c->s";
    Modelica.SIunits.VolumeFlowRate Vflows(start = 0) "Volume flow c->b";
    Modelica.SIunits.VolumeFlowRate Vflowc(start = 0) "Volume flow c";
    Real tau;
    Real As;
    Real Qflowst;
    Real Qflows;
public
    Modelica.Thermal.FluidHeatFlow.Interfaces.FlowPort_a flowPort_c(final medium = medium) "Inlet port c"
        annotation (Placement(transformation(extent = {
            {-110, -10}, 
            {-90, 10}})));
    Modelica.Thermal.FluidHeatFlow.Interfaces.FlowPort_b flowPort_st(final medium = medium) "Outlet port straight passage"
        annotation (Placement(transformation(extent = {
            {90, -10}, 
            {110, 10}})));
    Modelica.Thermal.FluidHeatFlow.Interfaces.FlowPort_b flowPort_s(final medium = medium) "Outlet port side branch"
        annotation (Placement(transformation(extent = {
            {-10, -90}, 
            {10, -110}})));
    parameter Boolean enableZetaOutput = false "Enable zeta output"
        annotation (choices(checkBox = true));
    Modelica.Blocks.Interfaces.RealOutput zeta_st if enableZetaOutput "zetacst"
        annotation (Placement(transformation(
            origin = {100, 100},
            extent = {
                {-10, -10}, 
                {10, 10}},
            rotation = 0)));
    Modelica.Blocks.Interfaces.RealOutput zeta_s if enableZetaOutput "zetacs"
        annotation (Placement(transformation(
            origin = {100, -100},
            extent = {
                {-10, -10}, 
                {10, 10}},
            rotation = -90)));
    Modelica.Blocks.Interfaces.RealOutput QsQc if enableZetaOutput "Qs/Qc"
        annotation (Placement(transformation(
            origin = {-100, -100},
            extent = {
                {-10, -10}, 
                {10, 10}},
            rotation = -90)));
    parameter Boolean useHeatPort = false "Enable HeatPort"
        annotation (
            Evaluate = true,
            HideResult = true,
            choices(checkBox = true));
    Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a heatPort(T = T, Q_flow = Q_flowHeatPort) if useHeatPort annotation (Placement(transformation(extent = {
        {-10, 110}, 
        {10, 90}})));
equation
    if enableZetaOutput then 
        zeta_st = zetacst;
        zeta_s = zetacs;
        QsQc = Vflows / max(Vflowc, Modelica.Constants.small);
    end if;
    if not useHeatPort then 
        Q_flowHeatPort = 0;
    end if;
    if noEvent(Modelica.Constants.small < Vflowc) then 
        if noEvent(Fs / Fc <= 0.4) then 
            tau = 0.4;
        else 
            tau = if noEvent(0.5 < Vflows / Vflowc) then 0.3 * (2 * Vflows / Vflowc - 1) else 2 * (2 * Vflows / Vflowc - 1);
        end if;
        zetacst = tau * (Vflows / Vflowc) ^ 2;
        if noEvent(Ds / Dc <= 0.666666666666667) then 
            zetacs = 1 + (Vflows * Fc / Vflowc / Fs) ^ 2;
            As = 1;
        else 
            if noEvent(Fs / Fc <= 0.35) then 
                if noEvent(Vflows / Vflowc <= 0.4) then 
                    As = 1.1 - 0.7 * Vflows / Vflowc;
                else 
                    As = 0.85;
                end if;
            else 
                if noEvent(Vflows / Vflowc <= 0.6) then 
                    As = 1 - 0.6 * Vflows / Vflowc;
                else 
                    As = 0.6;
                end if;
            end if;
            zetacs = As * (1 + 0.3 * (Vflows * Fc / Vflowc / Fs) ^ 2);
        end if;
    else 
        tau = 1;
        As = 1;
        zetacst = 1 + time * (0.001);
        zetacs = 1 - time * (0.001);
    end if;
    flowPort_c.H_flow + flowPort_st.H_flow + flowPort_s.H_flow + Qflowst + Qflows = 0;
    flowPort_c.m_flow + flowPort_st.m_flow + flowPort_s.m_flow = 0;
    h = medium.cp * T;
    Qflows = frictionLoss * Vflows * dpcs + Vflows / max(Vflowc, Modelica.Constants.small) * Q_flowHeatPort;
    Qflowst = frictionLoss * Vflowst * dpcst + Vflowst / max(Vflowc, Modelica.Constants.small) * Q_flowHeatPort;
    Vflowc = flowPort_c.m_flow / medium.rho;
    Vflows = -flowPort_s.m_flow / medium.rho;
    Vflowst = -flowPort_st.m_flow / medium.rho;
    dpcs = 0.5 * (Vflowc ^ 2 / Fc ^ 2 * medium.rho * zetacs);
    dpcs = flowPort_c.p - flowPort_s.p;
    dpcst = 0.5 * (Vflowc ^ 2 / Fc ^ 2 * medium.rho * zetacst);
    dpcst = flowPort_c.p - flowPort_st.p;
    flowPort_c.H_flow = semiLinear(flowPort_c.m_flow, flowPort_c.h, h);
    flowPort_s.H_flow = semiLinear(flowPort_s.m_flow, flowPort_s.h, h);
    flowPort_st.H_flow = semiLinear(flowPort_st.m_flow, flowPort_st.h, h);

    annotation (
        Icon(
            coordinateSystem(initialScale = 0.1),
            graphics = {
                Polygon(
                    origin = {0, -30},
                    lineColor = {255, 0, 0},
                    fillColor = {0, 0, 255},
                    fillPattern = FillPattern.Solid,
                    points = {
                        {-90, 50}, 
                        {90, 50}, 
                        {90, 10}, 
                        {20, 10}, 
                        {20, -60}, 
                        {-20, -60}, 
                        {-20, 10}, 
                        {-90, 10}, 
                        {-90, 50}}), 
                Line(
                    points = {
                        {-52, 0}, 
                        {52, 0}},
                    thickness = 0.5,
                    arrow = {Arrow.None, Arrow.Open},
                    arrowSize = 10), 
                Line(
                    points = {
                        {0, 0}, 
                        {0, -52}},
                    thickness = 0.5,
                    arrow = {Arrow.None, Arrow.Open},
                    arrowSize = 10), 
                Text(
                    origin = {-70, 0},
                    extent = {
                        {-30, 20}, 
                        {30, -20}},
                    textString = "C"), 
                Text(
                    origin = {70, 0},
                    extent = {
                        {-30, 20}, 
                        {30, -20}},
                    textString = "St"), 
                Text(
                    origin = {0, -70},
                    extent = {
                        {-30, 20}, 
                        {30, -20}},
                    textString = "S")}),
        Documentation(info = "<html>                           \n                <p>\n                    The component DivergingTee is a specialized element that works only in a narrow boundary condition.\n                    It represents a 90° T-branch with equal diameter for main passage (sides c and st) and any diameter for branch s.\n                </p>\n                <p>\n                    The flow direction is mandantory and has to be from port c to port st and port c to port s.\n                    Other flow directions are not supported.\n                </p>\n                <p>\n                    Calculation of zeta is taken from Idelchik 'Handbook of Hydraulic Resistance', 4th Edition 2007, Diagram 7.18 and 7.20\n                </p>\n                </html>"));
end DivergingTee;