예제 #1
0
        ///<summary>Get link average quality.</summary>
        public double GetAverageQuality(EpanetNetwork net)
        {
            double vsum = 0.0,
                   msum = 0.0;

            try {
                if (net != null && net.QualFlag == QualType.NONE)
                {
                    return(0.0);
                }
            }
            catch (ENException) {
                return(0.0);
            }

            foreach (QualitySegment seg  in  Segments)
            {
                vsum += seg.V;
                msum += seg.C * seg.V;
            }

            return(vsum > 0.0
                ? msum / vsum
                : (FirstNode.Quality + SecondNode.Quality) / 2.0);
        }
예제 #2
0
        /// <summary>Computes matrix coeffs. for emitters.</summary>
        /// <remarks>
        /// Emitters consist of a fictitious pipe connected to
        /// a fictitious reservoir whose elevation equals that
        /// of the junction. The headloss through this pipe is
        /// Ke*(Flow)^Qexp, where Ke = emitter headloss coeff.
        /// </remarks>
        public static void ComputeEmitterCoeffs(
            EpanetNetwork net,
            List <SimulationNode> junctions,
            SparseMatrix smat,
            LsVariables ls)
        {
            foreach (SimulationNode node  in  junctions)
            {
                if (node.Node.Ke == 0.0)
                {
                    continue;
                }

                double ke = Math.Max(Constants.CSMALL, node.Node.Ke);
                double q  = node._emitter;
                double z  = ke * Math.Pow(Math.Abs(q), net.QExp);
                double p  = net.QExp * z / Math.Abs(q);

                p = p < net.RQtol ? 1.0 / net.RQtol : 1.0 / p;

                double y = Utilities.GetSignal(q) * z * p;
                ls.AddAii(smat.GetRow(node.Index), +p);
                ls.AddRhsCoeff(smat.GetRow(node.Index), +(y + p * node.Node.Elevation));
                ls.AddNodalInFlow(node, -q);
            }
        }
예제 #3
0
        /// <summary>
        /// Computes solution matrix coeffs. for PRVs, PSVs & FCVs
        /// whose status is not fixed to OPEN/CLOSED.
        /// </summary>
        public static void ComputeMatrixCoeffs(
            EpanetNetwork net,
            LsVariables ls,
            SparseMatrix smat,
            List <SimulationValve> valves)
        {
            foreach (SimulationValve valve  in  valves)
            {
                if (double.IsNaN(valve.SimSetting))
                {
                    continue;
                }

                switch (valve.Type)
                {
                case LinkType.PRV:
                    valve.PrvCoeff(net, ls, smat);
                    break;

                case LinkType.PSV:
                    valve.PsvCoeff(net, ls, smat);
                    break;

                case LinkType.FCV:
                    valve.FcvCoeff(net, ls, smat);
                    break;
                }
            }
        }
예제 #4
0
        /// <summary>
        /// Computes solution matrix coeffs. for a completely open,
        /// closed, or throttled control valve.
        /// </summary>
        private void ValveCoeff(EpanetNetwork net, double km)
        {
            // Valve is closed. Use a very small matrix coeff.
            if (status <= StatType.CLOSED)
            {
                invHeadLoss    = 1.0 / Constants.CBIG;
                flowCorrection = flow;
                return;
            }

            // Account for any minor headloss through the valve
            if (km > 0.0)
            {
                double p = 2.0 * km * Math.Abs(flow);
                if (p < net.RQtol)
                {
                    p = net.RQtol;
                }

                invHeadLoss    = 1.0 / p;
                flowCorrection = flow / 2.0;
            }
            else
            {
                invHeadLoss    = 1.0 / net.RQtol;
                flowCorrection = flow;
            }
        }
예제 #5
0
        /// <summary>Compute P & Y coefficients for PBV,TCV,GPV valves.</summary>
        public bool ComputeValveCoeff(EpanetNetwork net, IList <Curve> curves)
        {
            switch (Type)
            {
            case LinkType.PBV:
                PbvCoeff(net);
                break;

            case LinkType.TCV:
                TcvCoeff(net);
                break;

            case LinkType.GPV:
                GpvCoeff(net, curves);
                break;

            case LinkType.FCV:
            case LinkType.PRV:
            case LinkType.PSV:

                if (double.IsNaN(SimSetting))
                {
                    ValveCoeff(net);
                }
                else
                {
                    return(false);
                }

                break;
            }

            return(true);
        }
예제 #6
0
        /// <summary>Computes solution matrix coeffs. for flow control valve.</summary>
        private void FcvCoeff(EpanetNetwork net, LsVariables ls, SparseMatrix smat)
        {
            int    k  = Index;
            double q  = setting;
            int    n1 = smat.GetRow(first.Index);
            int    n2 = smat.GetRow(second.Index);

            // If valve active, break network at valve and treat
            // flow setting as external demand at upstream node
            // and external supply at downstream node.
            if (status == StatType.ACTIVE)
            {
                ls.AddNodalInFlow(first.Index, -q);
                ls.AddRhsCoeff(n1, -q);
                ls.AddNodalInFlow(second.Index, +q);
                ls.AddRhsCoeff(n2, +q);
                invHeadLoss = 1.0 / Constants.CBIG;
                ls.AddAij(smat.GetNdx(k), -invHeadLoss);
                ls.AddAii(n1, +invHeadLoss);
                ls.AddAii(n2, +invHeadLoss);
                flowCorrection = flow - q;
            }
            else
            {
                //  Otherwise treat valve as an open pipe
                ValveCoeff(net);
                ls.AddAij(smat.GetNdx(k), -invHeadLoss);
                ls.AddAii(n1, +invHeadLoss);
                ls.AddAii(n2, +invHeadLoss);
                ls.AddRhsCoeff(n1, +(flowCorrection - flow));
                ls.AddRhsCoeff(n2, -(flowCorrection - flow));
            }
        }
예제 #7
0
        /// <summary>Computes solution matrix coeffs. for pressure sustaining valve.</summary>
        private void PsvCoeff(EpanetNetwork net, LsVariables ls, SparseMatrix smat)
        {
            int    k    = Index;
            int    n1   = smat.GetRow(first.Index);
            int    n2   = smat.GetRow(second.Index);
            double hset = first.Elevation + setting;

            if (status == StatType.ACTIVE)
            {
                invHeadLoss    = 0.0;
                flowCorrection = flow - ls.GetNodalInFlow(first);
                ls.AddRhsCoeff(n1, +(hset * Constants.CBIG));
                ls.AddAii(n1, +Constants.CBIG);
                if (ls.GetNodalInFlow(first) > 0.0)
                {
                    ls.AddRhsCoeff(n2, +ls.GetNodalInFlow(first));
                }
                return;
            }

            ValveCoeff(net);
            ls.AddAij(smat.GetNdx(k), -invHeadLoss);
            ls.AddAii(n1, +invHeadLoss);
            ls.AddAii(n2, +invHeadLoss);
            ls.AddRhsCoeff(n1, +(flowCorrection - flow));
            ls.AddRhsCoeff(n2, -(flowCorrection - flow));
        }
예제 #8
0
        /// <summary>Computes flow energy associated with this link pump.</summary>
        /// <param name="net"></param>
        /// <param name="power">Pump used power (KW)</param>
        /// <param name="efficiency">Pump effiency</param>
        private void GetFlowEnergy(EpanetNetwork net, out double power, out double efficiency)
        {
            power = efficiency = 0.0;

            if (status <= StatType.CLOSED)
            {
                return;
            }

            double q  = Math.Abs(flow);
            double dh = Math.Abs(first.SimHead - second.SimHead);

            double e = net.EPump;

            if (Ecurve != null)
            {
                Curve curve = Ecurve;
                e = curve.Interpolate(q * net.FieldsMap.GetUnits(FieldType.FLOW));
            }

            e  = Math.Min(e, 100.0);
            e  = Math.Max(e, 1.0);
            e /= 100.0;

            power      = dh * q * net.SpGrav / 8.814 / e * Constants.KWperHP;
            efficiency = e;
        }
예제 #9
0
        /// <summary>Computes P and Y coeffs. for pump in the link.</summary>
        public void ComputePumpCoeff(EpanetNetwork net)
        {
            if (status <= StatType.CLOSED || setting == 0.0)
            {
                invHeadLoss    = 1.0 / Constants.CBIG;
                flowCorrection = flow;
                return;
            }


            double q = Math.Max(Math.Abs(flow), Constants.TINY);

            if (Ptype == PumpType.CUSTOM)
            {
                double hh0, rr;
                Hcurve.GetCoeff(net.FieldsMap, q / setting, out hh0, out rr);

                H0 = -hh0;
                FlowCoefficient = -rr;
                N = 1.0;
            }

            double h0 = setting * setting * H0;
            double n  = N;
            double r  = FlowCoefficient * Math.Pow(setting, 2.0 - n);

            if (n != 1.0)
            {
                r = n * r * Math.Pow(q, n - 1.0);
            }

            invHeadLoss    = 1.0 / Math.Max(r, net.RQtol);
            flowCorrection = flow / n + invHeadLoss * h0;
        }
예제 #10
0
        /// <summary>Computes flow change at an emitter node.</summary>
        public double EmitFlowChange(EpanetNetwork net)
        {
            double ke = Math.Max(Constants.CSMALL, Ke);
            double p  = net.QExp * ke * Math.Pow(Math.Abs(_emitter), (net.QExp - 1.0));

            p = p < net.RQtol ? 1.0d / net.RQtol : 1.0d / p;
            return(_emitter / net.QExp - p * (head - Elevation));
        }
 ///<summary>Chezy-Manning model calculator, which is implemented through the Hazen-Williams model.</summary>
 public static void CmModelCalculator(
     EpanetNetwork net,
     SimulationLink sl,
     out double invheadloss,
     out double flowcorrection)
 {
     HwModelCalculator(net, sl, out invheadloss, out flowcorrection);
 }
예제 #12
0
        /// <summary>Get new pump status.</summary>
        /// <param name="net"></param>
        /// <param name="dh">head gain</param>
        /// <returns></returns>
        public StatType PumpStatus(EpanetNetwork net, double dh)
        {
            double hmax = Ptype == PumpType.CONST_HP
                ? Constants.BIG
                : setting * setting * Hmax;

            return(dh > hmax + net.HTol
                ? StatType.XHEAD
                : StatType.OPEN);
        }
예제 #13
0
        /// <summary>Computes P & Y coeffs. for throttle control valve.</summary>
        private void TcvCoeff(EpanetNetwork net)
        {
            double km = Km;

            if (!double.IsNaN(setting))
            {
                km = 0.02517 * setting / Math.Pow(Diameter, 4);
            }

            ValveCoeff(net, km);
        }
예제 #14
0
 /// <summary>Computes P & Y coeffs. for general purpose valve.</summary>
 private void GpvCoeff(EpanetNetwork net, IList <Curve> curves)
 {
     if (status == StatType.CLOSED)
     {
         ValveCoeff(net);
     }
     else
     {
         double q = Math.Max(Math.Abs(flow), Constants.TINY);
         double h0, r;
         curves[(int)Math.Round(setting)].GetCoeff(net.FieldsMap, q, out h0, out r);
         invHeadLoss    = 1.0 / Math.Max(r, net.RQtol);
         flowCorrection = invHeadLoss * (h0 + r * q) * Utilities.GetSignal(flow);
     }
 }
예제 #15
0
 /// <summary>Computes P & Y coeffs. for pressure breaker valve.</summary>
 private void PbvCoeff(EpanetNetwork net)
 {
     if (double.IsNaN(setting) || setting == 0.0)
     {
         ValveCoeff(net);
     }
     else if (Km * (flow * flow) > setting)
     {
         ValveCoeff(net);
     }
     else
     {
         invHeadLoss    = Constants.CBIG;
         flowCorrection = setting * Constants.CBIG;
     }
 }
예제 #16
0
        /// <summary>Update pumps energy.</summary>
        public static double StepEnergy(
            EpanetNetwork net,
            Pattern epat,
            List <SimulationPump> pumps,
            long htime,
            long hstep)
        {
            double dt, psum = 0.0;


            if (net.Duration == 0)
            {
                dt = 1.0;
            }
            else if (htime < net.Duration)
            {
                dt = hstep / 3600.0;
            }
            else
            {
                dt = 0.0;
            }

            if (dt == 0.0)
            {
                return(0.0);
            }

            long n = (htime + net.PStart) / net.PStep;


            double c0 = net.ECost;
            double f0 = 1.0;

            if (epat != null)
            {
                long m = n % epat.Count;
                f0 = epat[(int)m];
            }

            foreach (SimulationPump pump  in  pumps)
            {
                psum += pump.UpdateEnergy(net, n, c0, f0, dt);
            }

            return(psum);
        }
예제 #17
0
        /// <summary>Updates status for PRVs & PSVs whose status is not fixed to OPEN/CLOSED.</summary>
        public static bool ValveStatus(
            EpanetNetwork net,
            TraceSource log,
            IEnumerable <SimulationValve> valves)
        {
            bool change = false;

            foreach (SimulationValve v  in  valves)
            {
                if (double.IsNaN(v.setting))
                {
                    continue;
                }

                StatType s = v.status;

                switch (v.Type)
                {
                case LinkType.PRV: {
                    double hset = v.second.Elevation + v.setting;
                    v.status = v.PrvStatus(net, hset);
                    break;
                }

                case LinkType.PSV: {
                    double hset = v.first.Elevation + v.setting;
                    v.status = v.PsvStatus(net, hset);
                    break;
                }

                default:
                    continue;
                }

                if (s != v.status)
                {
                    if (net.StatFlag == StatFlag.FULL)
                    {
                        LogStatChange(net.FieldsMap, log, v, s, v.status);
                    }
                    change = true;
                }
            }

            return(change);
        }
예제 #18
0
        /// <summary>Updates status of a flow control valve.</summary>
        public StatType FcvStatus(EpanetNetwork net, StatType s)
        {
            StatType stat = s;

            if (First.SimHead - Second.SimHead < -net.HTol)
            {
                stat = StatType.XFCV;
            }
            else if (flow < -net.QTol)
            {
                stat = StatType.XFCV;
            }
            else if (s == StatType.XFCV && flow >= setting)
            {
                stat = StatType.ACTIVE;
            }
            return(stat);
        }
예제 #19
0
        /// <summary>Accumulates pump energy usage.</summary>
        private double UpdateEnergy(
            EpanetNetwork net,
            long n,
            double c0,
            double f0,
            double dt)
        {
            //Skip closed pumps
            if (status <= StatType.CLOSED)
            {
                return(0.0);
            }
            double q = Math.Max(Constants.QZERO, Math.Abs(flow));

            // Find pump-specific energy cost
            double c = Ecost > 0.0 ? Ecost : c0;

            if (Epat != null)
            {
                int m = (int)(n % Epat.Count);
                c *= Epat[m];
            }
            else
            {
                c *= f0;
            }

            // Find pump energy & efficiency
            double power, efficiency;

            GetFlowEnergy(net, out power, out efficiency);

            // Update pump's cumulative statistics
            _energy[0] = _energy[0] + dt;              // Time on-line
            _energy[1] = _energy[1] + efficiency * dt; // Effic.-hrs
            _energy[2] = _energy[2] + power / q * dt;  // kw/cfs-hrs
            _energy[3] = _energy[3] + power * dt;      // kw-hrs
            _energy[4] = Math.Max(_energy[4], power);
            _energy[5] = _energy[5] + c * power * dt;  // cost-hrs.

            return(power);
        }
        ///<summary>Hazen-Williams model calculator.</summary>
        public static void HwModelCalculator(
            EpanetNetwork net,
            SimulationLink sL,
            out double invHeadLoss,
            out double flowCorrection)
        {
            // Evaluate headloss coefficients
            double q  = Math.Abs(sL.SimFlow);   // Absolute flow
            double ml = sL.Link.Km;             // Minor loss coeff.
            double r  = sL.Link.FlowResistance; // Resistance coeff.

            double r1 = 1.0 * r + ml;

            // Use large P coefficient for small flow resistance product
            if (r1 * q < net.RQtol)
            {
                invHeadLoss    = 1d / net.RQtol;
                flowCorrection = sL.SimFlow / net.HExp;
                return;
            }

            double hpipe = r * Math.Pow(q, net.HExp); // Friction head loss
            double p     = net.HExp * hpipe;          // Q*dh(friction)/dQ
            double hml;

            if (ml > 0d)
            {
                hml = ml * q * q; // Minor head loss
                p  += 2d * hml;   // Q*dh(Total)/dQ
            }
            else
            {
                hml = 0d;
            }

            p = sL.SimFlow / p; // 1 / (dh/dQ)

            invHeadLoss    = Math.Abs(p);
            flowCorrection = p * (hpipe + hml);
        }
예제 #21
0
        /// <summary>
        /// Determines if a node belongs to an active control valve
        /// whose setting causes an inconsistent set of eqns. If so,
        /// the valve status is fixed open and a warning condition
        /// is generated.
        /// </summary>
        public static bool CheckBadValve(
            EpanetNetwork net,
            TraceSource log,
            List <SimulationValve> valves,
            long htime,
            int n)
        {
            foreach (SimulationValve link  in  valves)
            {
                SimulationNode n1 = link.First;
                SimulationNode n2 = link.Second;
                if (n == n1.Index || n == n2.Index)
                {
                    if (link.Type == LinkType.PRV || link.Type == LinkType.PSV ||
                        link.Type == LinkType.FCV)
                    {
                        if (link.status == StatType.ACTIVE)
                        {
                            if (net.StatFlag == StatFlag.FULL)
                            {
                                LogBadValve(log, link, htime);
                            }

                            link.status = link.Type == LinkType.FCV
                                ? StatType.XFCV
                                : StatType.XPRESSURE;

                            return(true);
                        }
                    }
                    return(false);
                }
            }

            return(false);
        }
예제 #22
0
        public static void main(string[] args)
        {
            int i;

            var net = new EpanetNetwork();

            //Tank
            Tank tank = new Tank("0")
            {
                Elevation = 210
            };

            net.Nodes.Add(tank);

            //Nodes
            Node[] node = new Node[7];

            for (i = 1; i < 7; i++)
            {
                node[i] = new Node(i.ToString());
            }


            node[1].Elevation = 150;
            node[1].Demands.Add(new Demand(100, null));
            node[2].Elevation = 160;
            node[2].Demands.Add(new Demand(100, null));
            node[3].Elevation = 155;
            node[3].Demands.Add(new Demand(120, null));
            node[4].Elevation = 150;
            node[4].Demands.Add(new Demand(270, null));
            node[5].Elevation = 165;
            node[5].Demands.Add(new Demand(330, null));
            node[6].Elevation = 160;
            node[6].Demands.Add(new Demand(200, null));

            //Links
            Link[] pipe = new Link[8];
            for (i = 0; i < 8; i++)
            {
                pipe[i] = new Link(i.ToString())
                {
                    Lenght = 1000
                };
            }
            pipe[0].FirstNode  = tank;
            pipe[0].SecondNode = node[1];
            pipe[1].FirstNode  = node[1];
            pipe[1].SecondNode = node[2];
            pipe[2].FirstNode  = node[1];
            pipe[2].SecondNode = node[3];
            pipe[3].FirstNode  = node[3];
            pipe[3].SecondNode = node[4];
            pipe[4].FirstNode  = node[3];
            pipe[4].SecondNode = node[5];
            pipe[5].FirstNode  = node[5];
            pipe[5].SecondNode = node[6];
            pipe[6].FirstNode  = node[2];
            pipe[6].SecondNode = node[4];
            pipe[7].FirstNode  = node[4];
            pipe[7].SecondNode = node[6];

            for (i = 1; i < 7; i++)
            {
                net.Nodes.Add(node[i]);
            }
            for (i = 0; i < 8; i++)
            {
                net.Links.Add(pipe[i]);
            }

            //Prepare Network
            TraceSource log = new TraceSource(typeof(SampleOOPNetwork2).FullName, SourceLevels.All);
            NullParser  nP  = (NullParser)InputParser.Create(FileType.NULL_FILE);

            Debug.Assert(nP != null);
            nP.Parse(new EpanetNetwork(), null);

            //// Simulate hydraulics
            string       hydFile = Path.GetTempFileName(); // ("hydSim", "bin");
            HydraulicSim hydSim  = new HydraulicSim(net, log);

            hydSim.Simulate(hydFile);

            // Read hydraulic results

            HydraulicReader hydReader = new HydraulicReader(hydFile);

            for (long time = net.RStart; time <= net.Duration; time += net.RStep)
            {
                AwareStep step = hydReader.GetStep((int)time);
                Console.WriteLine("Time : " + step.Time.GetClockTime() + ", nodes heads : ");

                i = 0;
                foreach (Node inode in net.Nodes)
                {
                    Console.Write("{0:F2}\t", step.GetNodeHead(i++, inode, null));
                }

                Console.WriteLine();
            }

            hydReader.Close();
        }
예제 #23
0
 public DynamicSimulation(EpanetNetwork net, TraceSource log) : base(net, log)
 {
 }
예제 #24
0
        public static void main(string[] args)
        {
            var net = new EpanetNetwork();

            //Tank
            Tank tank = new Tank("0")
            {
                Elevation = 210
            };

            net.Nodes.Add(tank);

            //Nodes
            Node[] node = new Node[7];
            for (int i = 1; i < 7; i++)
            {
                node[i] = new Node(i.ToString());
            }

            node[1].Elevation = 150;
            node[1].Demands.Add(new Demand(100, null));
            node[2].Elevation = 160;
            node[2].Demands.Add(new Demand(100, null));
            node[3].Elevation = 155;
            node[3].Demands.Add(new Demand(120, null));
            node[4].Elevation = 150;
            node[4].Demands.Add(new Demand(270, null));
            node[5].Elevation = 165;
            node[5].Demands.Add(new Demand(330, null));
            node[6].Elevation = 160;
            node[6].Demands.Add(new Demand(200, null));

            //Links
            Link[] pipe = new Link[8];
            for (int i = 0; i < 8; i++)
            {
                pipe[i] = new Link(i.ToString())
                {
                    Lenght = 1000
                };
            }

            pipe[0].FirstNode  = tank;
            pipe[0].SecondNode = node[1];
            pipe[1].FirstNode  = node[1];
            pipe[1].SecondNode = node[2];
            pipe[2].FirstNode  = node[1];
            pipe[2].SecondNode = node[3];
            pipe[3].FirstNode  = node[3];
            pipe[3].SecondNode = node[4];
            pipe[4].FirstNode  = node[3];
            pipe[4].SecondNode = node[5];
            pipe[5].FirstNode  = node[5];
            pipe[5].SecondNode = node[6];
            pipe[6].FirstNode  = node[2];
            pipe[6].SecondNode = node[4];
            pipe[7].FirstNode  = node[4];
            pipe[7].SecondNode = node[6];

            for (int i = 1; i < 7; i++)
            {
                net.Nodes.Add(node[i]);
            }

            for (int i = 0; i < 8; i++)
            {
                net.Links.Add(pipe[i]);
            }


            //Prepare Network
            TraceSource log = new TraceSource(typeof(SampleOOPNetwork2).FullName, SourceLevels.All);
            NullParser  nP  = (NullParser)InputParser.Create(FileType.NULL_FILE);

            Debug.Assert(nP != null);
            nP.Parse(new EpanetNetwork(), null);

            //// Simulate hydraulics and get streaming/dynamic results
            new DynamicSimulation(net, log).Simulate();
        }
        private const double AC = -5.14214965799e-03; // AA*AB

        ///<summary>Darcy-Weishbach model calculator.</summary>
        public static void DwModelCalculator(
            EpanetNetwork net,
            SimulationLink sL,
            out double invHeadLoss,
            out double flowCorrection)
        {
            Link   link           = sL.Link;
            double simFlow        = sL.SimFlow;
            double q              = Math.Abs(simFlow);   // Absolute flow
            double km             = link.Km;             // Minor loss coeff.
            double flowResistance = link.FlowResistance; // Resistance coeff.
            double roughness      = link.Kc;
            double diameter       = link.Diameter;
            bool   isOne          = sL.Type > LinkType.PIPE;

            double resistance;

            if (isOne)
            {
                resistance = 1d;
            }
            else
            {
                double s = net.Viscos * diameter;
                double w = q / s;

                if (w >= A1)
                {
                    double y1 = A8 / Math.Pow(w, 0.9d);
                    double y2 = roughness / (3.7 * diameter) + y1;
                    double y3 = A9 * Math.Log(y2);
                    resistance = 1.0 / (y3 * y3);
                }
                else if (w > A2)
                {
                    double y2 = roughness / (3.7 * diameter) + AB;
                    double y3 = A9 * Math.Log(y2);
                    double fa = 1.0 / (y3 * y3);
                    double fb = (2.0 + AC / (y2 * y3)) * fa;
                    double r2 = w / A2;
                    double x1 = 7.0 * fa - fb;
                    double x2 = 0.128 - 17.0 * fa + 2.5 * fb;
                    double x3 = -0.128 + 13.0 * fa - (fb + fb);
                    double x4 = r2 * (0.032 - 3.0 * fa + 0.5 * fb);
                    resistance = x1 + r2 * (x2 + r2 * (x3 + x4));
                }
                else if (w > A4)
                {
                    resistance = A3 * s / q;
                }
                else
                {
                    resistance = 8d;
                }
            }

            double r1 = resistance * flowResistance + km;

            // Use large P coefficient for small flow resistance product
            if (r1 * q < net.RQtol)
            {
                invHeadLoss    = 1d / net.RQtol;
                flowCorrection = simFlow / net.HExp;
            }
            else
            {
                // Compute P and Y coefficients
                double hpipe = r1 * (q * q); // Total head loss
                double p     = 2d * r1 * q;  // |dh/dQ|
                invHeadLoss    = 1d / p;
                flowCorrection = simFlow < 0 ? -hpipe * invHeadLoss : hpipe * invHeadLoss;
            }
        }
예제 #26
0
        ///<summary>Init hydraulic simulation, preparing the linear solver and the hydraulic structures wrappers.</summary>
        /// <param name="net">Hydraulic network reference.</param>
        /// <param name="log">Logger reference.</param>
        public HydraulicSim(EpanetNetwork net, TraceSource log)
        {
            _running = false;
            _logger  = log;
            // this.CreateSimulationNetwork(net);


            _nodes     = new SimulationNode[net.Nodes.Count];
            _links     = new SimulationLink[net.Links.Count];
            _pumps     = new List <SimulationPump>();
            _tanks     = new List <SimulationTank>();
            _junctions = new List <SimulationNode>();
            _valves    = new List <SimulationValve>();

            var nodesById = new Dictionary <string, SimulationNode>(net.Nodes.Count);

            for (int i = 0; i < net.Nodes.Count; i++)
            {
                SimulationNode node;

                var networkNode = net.Nodes[i];

                if (networkNode.Type == NodeType.JUNC)
                {
                    node = new SimulationNode(networkNode, i);
                    _junctions.Add(node);
                }
                else
                {
                    node = new SimulationTank(networkNode, i);
                    _tanks.Add((SimulationTank)node);
                }

                _nodes[i]          = node;
                nodesById[node.Id] = node;
            }

            for (int i = 0; i < net.Links.Count; i++)
            {
                SimulationLink link;

                var networkLink = net.Links[i];

                if (networkLink is Valve)
                {
                    var valve = new SimulationValve(nodesById, networkLink, i);
                    _valves.Add(valve);
                    link = valve;
                }
                else if (networkLink is Pump)
                {
                    var pump = new SimulationPump(nodesById, networkLink, i);
                    _pumps.Add(pump);
                    link = pump;
                }
                else
                {
                    link = new SimulationLink(nodesById, networkLink, i);
                }

                _links[i] = link;
            }

            _rules = net.Rules.Select(r => new SimulationRule(r, _links, _nodes)).ToArray();

            _curves = net.Curves.ToArray();

            _controls = net.Controls.Select(x => new SimulationControl(_nodes, _links, x)).ToArray();


            this.net = net;
            _epat    = net.GetPattern(this.net.EPatId);
            _smat    = new SparseMatrix(_nodes, _links, _junctions.Count);
            _lsv     = new LsVariables(_nodes.Length, _smat.CoeffsCount);

            Htime = 0;

            switch (this.net.FormFlag)
            {
            case FormType.HW:
                _pHlModel = PipeHeadModelCalculators.HwModelCalculator;
                break;

            case FormType.DW:
                _pHlModel = PipeHeadModelCalculators.DwModelCalculator;
                break;

            case FormType.CM:
                _pHlModel = PipeHeadModelCalculators.CmModelCalculator;
                break;
            }

            foreach (SimulationLink link in _links)
            {
                link.InitLinkFlow();
            }

            foreach (SimulationNode node in _junctions)
            {
                if (node.Ke > 0.0)
                {
                    node.SimEmitter = 1.0;
                }
            }

            foreach (SimulationLink link in _links)
            {
                if ((link.Type == LinkType.PRV ||
                     link.Type == LinkType.PSV ||
                     link.Type == LinkType.FCV) &&
                    !double.IsNaN(link.Roughness))
                {
                    link.SimStatus = StatType.ACTIVE;
                }


                if (link.SimStatus <= StatType.CLOSED)
                {
                    link.SimFlow = Constants.QZERO;
                }
                else if (Math.Abs(link.SimFlow) <= Constants.QZERO)
                {
                    link.InitLinkFlow(link.SimStatus, link.SimSetting);
                }

                link.SimOldStatus = link.SimStatus;
            }


            Htime = 0;
            Rtime = this.net.RStep;
        }
예제 #27
0
        ///<summary>Initializes WQ solver system</summary>

        public QualitySim(EpanetNetwork net, TraceSource ignored)
        {
//        this.log = log;
            _net = net;

            _nodes = net.Nodes.Select(QualityNode.Create).ToArray();
            _tanks = _nodes.OfType <QualityTank>().ToArray();
            _juncs = _nodes.Where(x => !(x is QualityTank)).ToArray();
            _links = net.Links.Select(n => new QualityLink(net.Nodes, _nodes, n)).ToArray();


            /*
             * this.nodes = new List<QualityNode>(net.Nodes.Count);
             * this.links = new List<QualityLink>(net.Links.Count);
             * this.tanks = new List<QualityTank>(net.Tanks.Count());
             * this.juncs = new List<QualityNode>(net.Junctions.Count());
             *
             * foreach (Node n in net.Nodes) {
             *  QualityNode qN = QualityNode.Create(n);
             *
             *  this.nodes.Add(qN);
             *
             *  var tank = qN as QualityTank;
             *
             *  if (tank != null)
             *      this.tanks.Add(tank);
             *  else
             *      this.juncs.Add(qN);
             * }
             *
             * foreach (Link n  in  net.Links)
             *  this.links.Add(new QualityLink(net.Nodes, this.nodes, n));
             *
             */

            _bucf      = 1.0;
            _tucf      = 1.0;
            _reactflag = false;

            _qualflag = _net.QualFlag;

            if (_qualflag != QualType.NONE)
            {
                if (_qualflag == QualType.TRACE)
                {
                    foreach (QualityNode qN  in  _nodes)
                    {
                        if (qN.Node.Name.Equals(_net.TraceNode, StringComparison.OrdinalIgnoreCase))
                        {
                            _traceNode         = qN;
                            _traceNode.Quality = 100.0;
                            break;
                        }
                    }
                }

                if (_net.Diffus > 0.0)
                {
                    _sc = _net.Viscos / _net.Diffus;
                }
                else
                {
                    _sc = 0.0;
                }

                _bucf = GetUcf(_net.BulkOrder);
                _tucf = GetUcf(_net.TankOrder);

                _reactflag = GetReactflag();
            }


            _wbulk   = 0.0;
            _wwall   = 0.0;
            _wtank   = 0.0;
            _wsource = 0.0;

            _htime     = 0;
            _rtime     = _net.RStart;
            _qtime     = 0;
            _nperiods  = 0;
            _elevUnits = _net.FieldsMap.GetUnits(FieldType.ELEV);
        }
예제 #28
0
 private void menuClose_Click(object sender, EventArgs e)
 {
     Net = null;
 }
예제 #29
0
        private void DoOpen(string netFile)
        {
            string fileExtension = (Path.GetExtension(netFile) ?? string.Empty).ToLowerInvariant();

            if (fileExtension != ".net" &&
                fileExtension != ".inp" &&
                fileExtension != ".xml" &&
                fileExtension != ".gz")
            {
                return;
            }

            _inpFile = netFile;

            InputParser inpParser;

            switch (fileExtension.ToLowerInvariant())
            {
            case ".inp":
                inpParser = new InpParser();
                break;

            case ".net":
                inpParser = new NetParser();
                break;

            case ".xml":
                inpParser = new XmlParser(false);
                break;

            case ".gz":
                inpParser = new XmlParser(true);
                break;

            default:
                MessageBox.Show(
                    "Not supported file type: *" + fileExtension,
                    "Error",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);
                return;
            }

            EpanetNetwork net;

            try {
                net = inpParser.Parse(new EpanetNetwork(), _inpFile);
            }
            catch (ENException ex) {
                MessageBox.Show(
                    this,
                    ex + "\nCheck epanet.log for detailed error description",
                    "Error",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);
                ClearInterface();
                _inpFile = null;
                return;
            }
            catch (Exception ex) {
                MessageBox.Show(
                    this,
                    "Unable to parse network configuration file",
                    "Error",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);

                Log.Error("Unable to parse network configuration file: {0}", ex);

                ClearInterface();
                _inpFile = null;

                return;
            }

            Net = net;
        }
예제 #30
0
        /// <summary>Report options dialog constructor.</summary>
        public ReportOptions(string inpFile, string msxFile) : this()
        {
            if (inpFile == null)
            {
                return;
            }

            _fileInp = inpFile;
            _net     = new EpanetNetwork();

            try {
                InputParser inpParser;

                string extension = Path.GetExtension(inpFile);

                switch (extension.ToLowerInvariant())
                {
                case ".inp":
                    inpParser = new InpParser();
                    break;

                case ".net":
                    inpParser = new NetParser();
                    break;

                case ".xml":
                    inpParser = new XmlParser(false);

                    break;

                case ".gz":
                    inpParser = new XmlParser(true);
                    break;

                default:
                    inpParser = new InpParser();
                    break;
                }

                _net = inpParser.Parse(new EpanetNetwork(), inpFile);
            }
            catch (ENException ex) {
                MessageBox.Show(
                    ex.Message + "\nCheck epanet.log for detailed error description",
                    "Error",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);

                return;
            }

            if (msxFile == null)
            {
                return;
            }

            _fileMsx  = msxFile;
            _epanetTk = new EnToolkit2(_net);
            _netMsx   = new EpanetMSX(_epanetTk);

            try {
                ErrorCodeType ret = _netMsx.Load(_fileMsx);
                if (ret != 0)
                {
                    MessageBox.Show("MSX parsing error " + ret, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    _fileMsx  = null;
                    _netMsx   = null;
                    _epanetTk = null;
                }
            }
            catch (IOException) {
                MessageBox.Show(
                    "IO error while reading the MSX file",
                    "Error",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);
                _fileMsx  = null;
                _netMsx   = null;
                _epanetTk = null;
            }
        }