SimpleBend

model SimpleBend "Bend"
    import HydraulicsByFluidon.Media.Base.FluidInterface;
    import HydraulicsByFluidon.Tools.Pipes;

    outer HydraulicsByFluidon.Media.Environment environment;
    parameter Modelica.SIunits.Length Diameter = 0.032 "Diameter";
    parameter Modelica.SIunits.Angle BendAngle(min = 0.005555555555556 * (15 * Modelica.Constants.pi), max = 0.005555555555556 * (180 * Modelica.Constants.pi)) = 0.5 * Modelica.Constants.pi "Bend angle";
    parameter Modelica.SIunits.Length BendRadius(min = 1e-4) = 0.1 "Bend radius";
    parameter Modelica.SIunits.DimensionlessRatio relRoughness = 1e-6 "Relative roughness";
    parameter Boolean forwardFluidProperties = true "Forward fluid properties between ports"
        annotation (
            Dialog(tab = "Fluid Properties"),
            choices(checkBox = true));
    HydraulicsByFluidon.Interfaces.FluidPort fluidPortA(p(start = 101325, nominal = 100000)) "Hydraulic port A"
        annotation (Placement(transformation(extent = {
            {-110, -10}, 
            {-90, 10}})));
    HydraulicsByFluidon.Interfaces.FluidPort fluidPortB(p(start = 101325, nominal = 100000)) "Hydraulic port B"
        annotation (Placement(transformation(extent = {
            {-10, 110}, 
            {10, 90}})));
protected
    Real RbyD = HydraulicsByFluidon.Tools.max(1, BendRadius / Diameter);
    Real A = 0.25 * (Diameter * Diameter * Modelica.Constants.pi);
    Real LKr = BendAngle * BendRadius;
    Real AKr = 9.3 * exp(-0.06 * RbyD);
    Real BKr = 10.5;
    Real CKr = 15000 * exp(-2.7 * RbyD) + 1780 * exp(-0.0234 * (RbyD - 8) ^ 2);
    Real DKr = 0.0788 * tanh(0.8 * RbyD) + 0.00124 * RbyD;
    Real EKr = 4.95 + 4.042 * exp(-0.01 * (BendAngle * 180 / Modelica.Constants.pi - 7.5) ^ 3);
    Real fKr = AKr * tanh(DKr / AKr * (BendAngle * 180 / Modelica.Constants.pi + BKr)) + CKr * (0.01 * (BendAngle * 180 / Modelica.Constants.pi)) ^ 4 * exp((-EKr) * (0.01 * (BendAngle * 180 / Modelica.Constants.pi)));
    Real zetaKr = 2 * LKr / Diameter + fKr;
    Real lambda;
    Real rho;
    Real re;
    Real reunlim;
    Real dp;
    Real mFlow;
    Integer fluidId = fluidPortA.fluidId;
equation
    if forwardFluidProperties then 
        fluidPortA.fluidTemperature = fluidPortB.fluidTemperature;
        fluidPortA.fluidId = fluidPortB.fluidId;
        fluidPortA.proportionUndissolvedAir = fluidPortB.proportionUndissolvedAir;
        fluidPortA.polytropicExponent = fluidPortB.polytropicExponent;
    end if;
    if noEvent(fluidPortB.p < fluidPortA.p) then 
        rho = FluidInterface.calcRho(fluidPortA.fluidId, fluidPortA.p, fluidPortA.fluidTemperature);
        mFlow = fluidPortA.mFlow;
    else 
        rho = FluidInterface.calcRho(fluidPortB.fluidId, fluidPortB.p, fluidPortB.fluidTemperature);
        mFlow = fluidPortB.mFlow;
    end if;
    fluidPortA.mFlow + fluidPortB.mFlow = 0;
    dp = fluidPortB.p - fluidPortA.p;
    lambda = Pipes.calcLambda(relRoughness, re);
    re = max(10, reunlim);
    reunlim = abs(mFlow / rho * Diameter / (FluidInterface.calcNu(fluidPortB.fluidId, max(fluidPortA.p, fluidPortB.p), fluidPortB.fluidTemperature) * A));
    fluidPortB.mFlow = sqrt(2 / (zetaKr * lambda)) * A * sqrt(abs(dp) * rho) * noEvent(sign(dp));

    annotation (
        Icon(
            coordinateSystem(
                extent = {
                    {-100, -40}, 
                    {40, 100}},
                initialScale = 0.1),
            graphics = {
                Polygon(
                    origin = {-30, 30},
                    fillColor = {255, 255, 255},
                    fillPattern = FillPattern.Solid,
                    points = {
                        {-60, -1}, 
                        {-60, 0}, 
                        {-59, 0}, 
                        {-52, 0}, 
                        {-38, 4}, 
                        {-26, 10}, 
                        {-18, 16}, 
                        {-12, 24}, 
                        {-6, 34}, 
                        {-2, 44}, 
                        {0, 52}, 
                        {0, 59}, 
                        {0, 60}, 
                        {1, 60}, 
                        {59, 60}, 
                        {60, 60}, 
                        {60, 59}, 
                        {60, 52}, 
                        {58, 38}, 
                        {56, 28}, 
                        {52, 16}, 
                        {48, 8}, 
                        {42, -4}, 
                        {36, -12}, 
                        {30, -20}, 
                        {22, -28}, 
                        {12, -36}, 
                        {0, -44}, 
                        {-12, -50}, 
                        {-22, -54}, 
                        {-36, -58}, 
                        {-50, -60}, 
                        {-59, -60}, 
                        {-60, -60}, 
                        {-60, -59}, 
                        {-60, -1}},
                    smooth = Smooth.Bezier)}),
        Documentation(info = "<html>\n            <p>\n                The component Bend is a valid model for <var>Bend angle</var> between 15° and 180°.\n            </p>\n            <p>\n                <center><img align=\"middle\" src=\"modelica://HydraulicsByFluidon/Resources/Images/Components/Lines/BendSketch.png\"></center>\n            </p>\n            <p>\n                <b>Please consider:</b> The component was modeled in order to consider the pressure losses of well rounded bends. However, the use of \n                the component can lead to extremely long simulation times, since a small stepsize must be selected due to  \n                the low resistance of an elbow.\n            </p>\n            <p>\n                Formulas are taken from W. Wagner, Strömung und Druckverlust, 7. Auflage 2012.\n            </p></html>"));
end SimpleBend;