Beispiel #1
0
        /// <summary>Computes intercept and slope of head v. flow curve at current flow.</summary>
        /// <param name="fMap"></param>
        /// <param name="q">Flow value.</param>
        /// <param name="h0">Head at zero flow (y-intercept).</param>
        /// <param name="r">dHead/dFlow (slope).</param>
        public void GetCoeff(FieldsMap fMap, double q, out double h0, out double r)
        {
            q *= fMap.GetUnits(FieldType.FLOW);

            int npts = points.Count;

            var k2 = 0;

            while (k2 < npts && points[k2].X < q)
            {
                k2++;
            }

            if (k2 == 0)
            {
                k2++;
            }
            else if (k2 == npts)
            {
                k2--;
            }

            int k1 = k2 - 1;

            r  = (points[k2].Y - points[k1].Y) / (points[k2].X - points[k1].X);
            h0 = points[k1].Y - r * points[k1].X;

            h0 /= fMap.GetUnits(FieldType.HEAD);
            r  *= fMap.GetUnits(FieldType.FLOW) / fMap.GetUnits(FieldType.HEAD);
        }
        /// <summary>Finds water level in tank corresponding to current volume.</summary>
        private double FindGrade(FieldsMap fMap)
        {
            Curve curve = Vcurve;

            if (curve == null)
            {
                return(Hmin + (_volume - Vmin) / Area);
            }
            else
            {
                return(Elevation
                       + curve.Interpolate(_volume * fMap.GetUnits(FieldType.VOLUME))
                       / fMap.GetUnits(FieldType.HEAD));
            }
        }
        /// Simulation methods

        ///<summary>Finds water volume in tank corresponding to elevation 'h'</summary>
        public double FindVolume(FieldsMap fMap, double h)
        {
            Curve curve = Vcurve;

            if (curve == null)
            {
                return(Vmin + (h - Hmin) * Area);
            }
            else
            {
                return
                    (curve.Interpolate((h - Elevation) * fMap.GetUnits(FieldType.HEAD)
                                       / fMap.GetUnits(FieldType.VOLUME)));
            }
        }
Beispiel #4
0
        private void ComposeDemands(Network net)
        {
            FieldsMap fMap = net.FieldsMap;

            if (!net.Junctions.Any())
            {
                return;
            }

            buffer.WriteLine(SectType.DEMANDS.ParseStr());
            buffer.WriteLine(DEMANDS_SUBTITLE);

            double ucf = fMap.GetUnits(FieldType.DEMAND);

            foreach (Node node in net.Junctions)
            {
                foreach (Demand demand in node.Demands)
                {
                    buffer.Write("{0}\t{1}", node.Name, ucf * demand.Base);

                    if (demand.pattern != null)
                    {
                        buffer.Write("\t" + demand.pattern.Name);
                    }

                    buffer.WriteLine();
                }
            }

            buffer.WriteLine();
        }
Beispiel #5
0
        ///<summary>Convert hydraulic structures values from user units to simulation system units.</summary>
        /// <param name="net">Hydraulic network reference.</param>
        private static void ConvertUnits(Network net)
        {
            FieldsMap fMap = net.FieldsMap;

            foreach (Node node  in  net.Nodes)
            {
                node.Elevation /= fMap.GetUnits(FieldType.ELEV);
                node.C0        /= fMap.GetUnits(FieldType.QUALITY);
            }


            foreach (Node node  in  net.Junctions)
            {
                foreach (Demand d  in  node.Demands)
                {
                    d.Base /= fMap.GetUnits(FieldType.DEMAND);
                }
            }


            double ucf = Math.Pow(fMap.GetUnits(FieldType.FLOW), net.QExp)
                         / fMap.GetUnits(FieldType.PRESSURE);

            foreach (Node node  in  net.Junctions)
            {
                if (node.Ke > 0.0)
                {
                    node.Ke = ucf / Math.Pow(node.Ke, net.QExp);
                }
            }


            // FIXME:Tanks and reservoirs here?
            // foreach (var res in net.Reservoirs) res.H0 = res.Elevation + res.H0 / fMap.GetUnits(FieldType.ELEV);

            foreach (Tank tk  in  net.Nodes.OfType <Tank>())
            {
                tk.H0    = tk.Elevation + tk.H0 / fMap.GetUnits(FieldType.ELEV);
                tk.Hmin  = tk.Elevation + tk.Hmin / fMap.GetUnits(FieldType.ELEV);
                tk.Hmax  = tk.Elevation + tk.Hmax / fMap.GetUnits(FieldType.ELEV);
                tk.Area  = Math.PI * Math.Pow(tk.Area / fMap.GetUnits(FieldType.ELEV), 2) / 4.0;
                tk.V0   /= fMap.GetUnits(FieldType.VOLUME);
                tk.Vmin /= fMap.GetUnits(FieldType.VOLUME);
                tk.Vmax /= fMap.GetUnits(FieldType.VOLUME);
                tk.Kb   /= Constants.SECperDAY;
                // tk.Volume = tk.V0;
                tk.C      = tk.C0;
                tk.V1Max *= tk.Vmax;
            }

            net.CLimit /= fMap.GetUnits(FieldType.QUALITY);
            net.Ctol   /= fMap.GetUnits(FieldType.QUALITY);

            net.KBulk /= Constants.SECperDAY;
            net.KWall /= Constants.SECperDAY;

            foreach (Link link  in  net.Links)
            {
                switch (link.Type)
                {
                case LinkType.CV:
                case LinkType.PIPE:
                    if (net.FormFlag == FormType.DW)
                    {
                        link.Kc /= 1000.0 * fMap.GetUnits(FieldType.ELEV);
                    }

                    link.Diameter /= fMap.GetUnits(FieldType.DIAM);
                    link.Lenght   /= fMap.GetUnits(FieldType.LENGTH);

                    link.Km = 0.02517 * link.Km / Math.Pow(link.Diameter, 2) / Math.Pow(link.Diameter, 2);

                    link.Kb /= Constants.SECperDAY;
                    link.Kw /= Constants.SECperDAY;
                    break;

                case LinkType.PUMP:
                    Pump pump = (Pump)link;

                    if (pump.Ptype == PumpType.CONST_HP)
                    {
                        if (net.UnitsFlag == UnitsType.SI)
                        {
                            pump.FlowCoefficient /= fMap.GetUnits(FieldType.POWER);
                        }
                    }
                    else
                    {
                        if (pump.Ptype == PumpType.POWER_FUNC)
                        {
                            pump.H0 /= fMap.GetUnits(FieldType.HEAD);

                            pump.FlowCoefficient *=
                                Math.Pow(fMap.GetUnits(FieldType.FLOW), pump.N) /
                                fMap.GetUnits(FieldType.HEAD);
                        }

                        pump.Q0   /= fMap.GetUnits(FieldType.FLOW);
                        pump.Qmax /= fMap.GetUnits(FieldType.FLOW);
                        pump.Hmax /= fMap.GetUnits(FieldType.HEAD);
                    }
                    break;

                default:
                    link.Diameter /= fMap.GetUnits(FieldType.DIAM);
                    link.Km        = 0.02517 * link.Km / Math.Pow(link.Diameter, 2) / Math.Pow(link.Diameter, 2);

                    if (!double.IsNaN(link.Kc))
                    {
                        switch (link.Type)
                        {
                        case LinkType.FCV:
                            link.Kc /= fMap.GetUnits(FieldType.FLOW);
                            break;

                        case LinkType.PRV:
                        case LinkType.PSV:
                        case LinkType.PBV:
                            link.Kc /= fMap.GetUnits(FieldType.PRESSURE);
                            break;
                        }
                    }

                    break;
                }

                link.InitResistance(net.FormFlag, net.HExp);
            }

            foreach (Control ctl  in  net.Controls)
            {
                if (ctl.Link == null)
                {
                    continue;
                }
                if (ctl.Node != null)
                {
                    ctl.Grade = ctl.Node.Type == NodeType.JUNC
                        ? ctl.Node.Elevation + ctl.Grade / fMap.GetUnits(FieldType.PRESSURE)
                        : ctl.Node.Elevation + ctl.Grade / fMap.GetUnits(FieldType.ELEV);
                }

                if (!double.IsNaN(ctl.Setting))
                {
                    switch (ctl.Link.Type)
                    {
                    case LinkType.PRV:
                    case LinkType.PSV:
                    case LinkType.PBV:
                        ctl.Setting /= fMap.GetUnits(FieldType.PRESSURE);
                        break;

                    case LinkType.FCV:
                        ctl.Setting /= fMap.GetUnits(FieldType.FLOW);
                        break;
                    }
                }
            }
        }
Beispiel #6
0
        private static void LogStatChange(TraceSource log, FieldsMap fMap, SimulationLink link, StatType oldstatus)
        {
            StatType s1 = oldstatus;
            StatType s2 = link.SimStatus;

            try {
                if (s2 == s1)
                {
                    double setting = link.SimSetting;
                    switch (link.Type)
                    {
                    case LinkType.PRV:
                    case LinkType.PSV:
                    case LinkType.PBV:
                        setting *= fMap.GetUnits(FieldType.PRESSURE);
                        break;

                    case LinkType.FCV:
                        setting *= fMap.GetUnits(FieldType.FLOW);
                        break;
                    }

                    log.Warning(
                        string.Format(
                            Text.FMT56,
                            link.Type.ParseStr(),
                            link.Link.Name,
                            setting));
                    return;
                }

                StatType j1, j2;

                if (s1 == StatType.ACTIVE)
                {
                    j1 = StatType.ACTIVE;
                }
                else if (s1 <= StatType.CLOSED)
                {
                    j1 = StatType.CLOSED;
                }
                else
                {
                    j1 = StatType.OPEN;
                }
                if (s2 == StatType.ACTIVE)
                {
                    j2 = StatType.ACTIVE;
                }
                else if (s2 <= StatType.CLOSED)
                {
                    j2 = StatType.CLOSED;
                }
                else
                {
                    j2 = StatType.OPEN;
                }

                if (j1 != j2)
                {
                    log.Warning(
                        Text.FMT57,
                        link.Type.ParseStr(),
                        link.Link.Name,
                        j1.ReportStr(),
                        j2.ReportStr());
                }
            }
            catch (ENException) {}
        }
        protected static void LogStatChange(
            FieldsMap fMap,
            TraceSource logger,
            SimulationLink link,
            StatType s1,
            StatType s2)
        {
            if (s1 == s2)
            {
                switch (link.Type)
                {
                case LinkType.PRV:
                case LinkType.PSV:
                case LinkType.PBV:
                    link.setting *= fMap.GetUnits(FieldType.PRESSURE);
                    break;

                case LinkType.FCV:
                    link.setting *= fMap.GetUnits(FieldType.FLOW);
                    break;
                }
                logger.Verbose(
                    Text.FMT56,
                    link.Type.ParseStr(),
                    link.Link.Name,
                    link.setting);
                return;
            }

            StatType j1, j2;

            if (s1 == StatType.ACTIVE)
            {
                j1 = StatType.ACTIVE;
            }
            else if (s1 <= StatType.CLOSED)
            {
                j1 = StatType.CLOSED;
            }
            else
            {
                j1 = StatType.OPEN;
            }
            if (s2 == StatType.ACTIVE)
            {
                j2 = StatType.ACTIVE;
            }
            else if (s2 <= StatType.CLOSED)
            {
                j2 = StatType.CLOSED;
            }
            else
            {
                j2 = StatType.OPEN;
            }

            if (j1 != j2)
            {
                logger.Verbose(
                    Text.FMT57,
                    link.Type.ParseStr(),
                    link.Link.Name,
                    j1.ReportStr(),
                    j2.ReportStr());
            }
        }
            /// <summary>Checks if numerical condition on a variable is true.</summary>
            private bool CheckValue(FieldsMap fMap, double dsystem)
            {
                const double TOL = 0.001D;
                double       x;

                SimulationLink link = _object as SimulationLink;
                SimulationNode node = _object as SimulationNode;


                switch (_variable)
                {
                case Varwords.DEMAND:
                    if ((Objects)_object == Objects.SYSTEM)
                    {
                        x = dsystem * fMap.GetUnits(FieldType.DEMAND);
                    }
                    else
                    {
                        x = node.SimDemand * fMap.GetUnits(FieldType.DEMAND);
                    }

                    break;

                case Varwords.HEAD:
                case Varwords.GRADE:
                    x = node.SimHead * fMap.GetUnits(FieldType.HEAD);
                    break;

                case Varwords.PRESSURE:
                    x = (node.SimHead - node.Elevation) * fMap.GetUnits(FieldType.PRESSURE);
                    break;

                case Varwords.LEVEL:
                    x = (node.SimHead - node.Elevation) * fMap.GetUnits(FieldType.HEAD);
                    break;

                case Varwords.FLOW:
                    x = Math.Abs(link.SimFlow) * fMap.GetUnits(FieldType.FLOW);
                    break;

                case Varwords.SETTING:

                    if (double.IsNaN(link.SimSetting))
                    {
                        return(false);
                    }

                    x = link.SimSetting;
                    switch (link.Type)
                    {
                    case LinkType.PRV:
                    case LinkType.PSV:
                    case LinkType.PBV:
                        x *= fMap.GetUnits(FieldType.PRESSURE);
                        break;

                    case LinkType.FCV:
                        x *= fMap.GetUnits(FieldType.FLOW);
                        break;
                    }
                    break;

                case Varwords.FILLTIME: {
                    if (!(_object is SimulationTank))
                    {
                        return(false);
                    }

                    SimulationTank tank = (SimulationTank)_object;

                    if (tank.IsReservoir)
                    {
                        return(false);
                    }

                    if (tank.SimDemand <= Constants.TINY)
                    {
                        return(false);
                    }

                    x = (tank.Vmax - tank.SimVolume) / tank.SimDemand;

                    break;
                }

                case Varwords.DRAINTIME: {
                    if (!(_object is SimulationTank))
                    {
                        return(false);
                    }

                    SimulationTank tank = (SimulationTank)_object;

                    if (tank.IsReservoir)
                    {
                        return(false);
                    }

                    if (tank.SimDemand >= -Constants.TINY)
                    {
                        return(false);
                    }

                    x = (tank.Vmin - tank.SimVolume) / tank.SimDemand;
                    break;
                }

                default:
                    return(false);
                }

                switch (_relop)
                {
                case Operators.EQ:
                    if (Math.Abs(x - _value) > TOL)
                    {
                        return(false);
                    }
                    break;

                case Operators.NE:
                    if (Math.Abs(x - _value) < TOL)
                    {
                        return(false);
                    }
                    break;

                case Operators.LT:
                    if (x > _value + TOL)
                    {
                        return(false);
                    }
                    break;

                case Operators.LE:
                    if (x > _value - TOL)
                    {
                        return(false);
                    }
                    break;

                case Operators.GT:
                    if (x < _value - TOL)
                    {
                        return(false);
                    }
                    break;

                case Operators.GE:
                    if (x < _value + TOL)
                    {
                        return(false);
                    }
                    break;
                }
                return(true);
            }