/// <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); } }
///<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)); } }