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