/// <summary>Computes P & Y coefficients for pipe k.</summary>
        private void ComputePipeCoeff(EpanetNetwork net, PipeHeadModelCalculators.Compute hlModel)
        {
            // For closed pipe use headloss formula: h = CBIG*q
            if (status <= StatType.CLOSED)
            {
                invHeadLoss    = 1.0 / Constants.CBIG;
                flowCorrection = flow;
                return;
            }

            hlModel(net, this, out invHeadLoss, out flowCorrection);
        }
 /// <summary>Computes solution matrix coefficients for links.</summary>
 public static void ComputeMatrixCoeffs(
     EpanetNetwork net,
     PipeHeadModelCalculators.Compute hlModel,
     IEnumerable <SimulationLink> links,
     IList <Curve> curves,
     SparseMatrix smat,
     LsVariables ls)
 {
     foreach (SimulationLink link  in  links)
     {
         link.ComputeMatrixCoeff(net, hlModel, curves, smat, ls);
     }
 }
Example #3
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;
        }
        /// <summary>Compute P, Y and matrix coeffs.</summary>
        private void ComputeMatrixCoeff(
            EpanetNetwork net,
            PipeHeadModelCalculators.Compute hlModel,
            IList <Curve> curves,
            SparseMatrix smat,
            LsVariables ls)
        {
            switch (Type)
            {
            // Pipes
            case LinkType.CV:
            case LinkType.PIPE:
                ComputePipeCoeff(net, hlModel);
                break;

            // Pumps
            case LinkType.PUMP:
                ((SimulationPump)this).ComputePumpCoeff(net);
                break;

            // Valves
            case LinkType.PBV:
            case LinkType.TCV:
            case LinkType.GPV:
            case LinkType.FCV:
            case LinkType.PRV:
            case LinkType.PSV:
                // If valve status fixed then treat as pipe
                // otherwise ignore the valve for now.
                if (!((SimulationValve)this).ComputeValveCoeff(net, curves))
                {
                    return;
                }
                break;

            default:
                return;
            }

            int n1 = first.Index;
            int n2 = second.Index;

            ls.AddNodalInFlow(n1, -flow);
            ls.AddNodalInFlow(n2, +flow);

            ls.AddAij(smat.GetNdx(Index), -invHeadLoss);

            if (!(first is SimulationTank))
            {
                ls.AddAii(smat.GetRow(n1), +invHeadLoss);
                ls.AddRhsCoeff(smat.GetRow(n1), +flowCorrection);
            }
            else
            {
                ls.AddRhsCoeff(smat.GetRow(n2), +(invHeadLoss * first.SimHead));
            }

            if (!(second is SimulationTank))
            {
                ls.AddAii(smat.GetRow(n2), +invHeadLoss);
                ls.AddRhsCoeff(smat.GetRow(n2), -flowCorrection);
            }
            else
            {
                ls.AddRhsCoeff(smat.GetRow(n1), +(invHeadLoss * second.SimHead));
            }
        }