public SimulationLink(List <SimulationNode> indexedNodes, Link @ref, int idx) { link = @ref; foreach (SimulationNode indexedNode in indexedNodes) { if (indexedNode.Id == link.FirstNode.Name) { first = indexedNode; } else if (indexedNode.Id == link.SecondNode.Name) { second = indexedNode; } if (first != null && second != null) { break; } } index = idx; // Init setting = link.Kc; status = link.Status; }
public SimulationControl(IEnumerable <SimulationNode> nodes, IEnumerable <SimulationLink> links, Control @ref) { if (@ref.Node != null) { string nid = @ref.Node.Name; foreach (SimulationNode simulationNode in nodes) { if (simulationNode.Id.Equals(nid, StringComparison.OrdinalIgnoreCase)) { _node = simulationNode; break; } } } if (@ref.Link != null) { string linkId = @ref.Link.Name; foreach (SimulationLink simulationLink in links) { if (simulationLink.Link.Name.Equals(linkId, StringComparison.OrdinalIgnoreCase)) { _link = simulationLink; break; } } } _control = @ref; }
public SimulationLink(Dictionary <string, SimulationNode> byId, Link @ref, int idx) { link = @ref; first = byId[link.FirstNode.Name]; second = byId[link.SecondNode.Name]; index = idx; // Init setting = link.Kc; status = link.Status; }
private static void LogControlAction(TraceSource log, SimulationControl control, long htime) { SimulationNode n = control.Node; SimulationLink l = control.Link; string msg; switch (control.Type) { case ControlType.LOWLEVEL: case ControlType.HILEVEL: { string type = Keywords.w_JUNC; // NodeType type= NodeType.JUNC; var tank = n as SimulationTank; if (tank != null) { type = tank.IsReservoir ? Keywords.w_RESERV : Keywords.w_TANK; } msg = string.Format( Text.FMT54, htime.GetClockTime(), l.Type.ParseStr(), l.Link.Name, type, n.Id); break; } case ControlType.TIMER: case ControlType.TIMEOFDAY: msg = string.Format( Text.FMT55, htime.GetClockTime(), l.Type.ParseStr(), l.Link.Name); break; default: return; } log.Warning(msg); }
/// <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); }
/// <summary>Closes link flowing into full or out of empty tank.</summary> private void TankStatus(EpanetNetwork net) { double q = flow; SimulationNode n1 = First; SimulationNode n2 = Second; // Make node n1 be the tank if (!(n1 is SimulationTank)) { if (!(n2 is SimulationTank)) { return; // neither n1 or n2 is a tank } // N2 is a tank, swap ! SimulationNode n = n1; n1 = n2; n2 = n; q = -q; } double h = n1.SimHead - n2.SimHead; SimulationTank tank = (SimulationTank)n1; // Skip reservoirs & closed links if (tank.Area == 0.0 || status <= StatType.CLOSED) { return; } // If tank full, then prevent flow into it if (tank.SimHead >= tank.Hmax - net.HTol) { //Case 1: Link is a pump discharging into tank if (Type == LinkType.PUMP) { if (Second == n1) { status = StatType.TEMPCLOSED; } } else if (CvStatus(net, StatType.OPEN, h, q) == StatType.CLOSED) { // Case 2: Downstream head > tank head status = StatType.TEMPCLOSED; } } // If tank empty, then prevent flow out of it if (tank.SimHead <= tank.Hmin + net.HTol) { // Case 1: Link is a pump discharging from tank if (Type == LinkType.PUMP) { if (First == n1) { status = StatType.TEMPCLOSED; } } // Case 2: Tank head > downstream head else if (CvStatus(net, StatType.CLOSED, h, q) == StatType.OPEN) { status = StatType.TEMPCLOSED; } } }
public double GetNodalInFlow(SimulationNode id) { return(_nodalInflows[id.Index]); }
public void AddNodalInFlow(SimulationNode id, double value) { _nodalInflows[id.Index] += value; }
public Premise(string[] tok, Rulewords lOp, IEnumerable <SimulationNode> nodes, IEnumerable <SimulationLink> links) { Objects loType; Varwords lVar; object lObj; Operators lROp; if (tok.Length != 5 && tok.Length != 6) { throw new ENException(ErrorCode.Err201); } EnumsTxt.TryParse(tok[1], out loType); if (loType == Objects.SYSTEM) { EnumsTxt.TryParse(tok[2], out lVar); switch (lVar) { case Varwords.DEMAND: case Varwords.TIME: case Varwords.CLOCKTIME: lObj = Objects.SYSTEM; break; default: throw new ENException(ErrorCode.Err201); } } else { if (!EnumsTxt.TryParse(tok[3], out lVar)) { throw new ENException(ErrorCode.Err201); } switch (loType) { case Objects.NODE: case Objects.JUNC: case Objects.RESERV: case Objects.TANK: loType = Objects.NODE; break; case Objects.LINK: case Objects.PIPE: case Objects.PUMP: case Objects.VALVE: loType = Objects.LINK; break; default: throw new ENException(ErrorCode.Err201); } if (loType == Objects.NODE) { SimulationNode node = nodes.FirstOrDefault(simNode => simNode.Node.Name.Equals(tok[2], StringComparison.OrdinalIgnoreCase)); if (node == null) { throw new ENException(ErrorCode.Err203); } switch (lVar) { case Varwords.DEMAND: case Varwords.HEAD: case Varwords.GRADE: case Varwords.LEVEL: case Varwords.PRESSURE: break; case Varwords.FILLTIME: case Varwords.DRAINTIME: if (node is SimulationTank) { throw new ENException(ErrorCode.Err201); } break; default: throw new ENException(ErrorCode.Err201); } lObj = node; } else { SimulationLink link = links .FirstOrDefault(simLink => simLink.Link.Name.Equals(tok[2], StringComparison.OrdinalIgnoreCase)); if (link == null) { throw new ENException(ErrorCode.Err204); } switch (lVar) { case Varwords.FLOW: case Varwords.STATUS: case Varwords.SETTING: break; default: throw new ENException(ErrorCode.Err201); } lObj = link; } } Operators op; if (!EnumsTxt.TryParse(loType == Objects.SYSTEM ? tok[3] : tok[4], out op)) { throw new ENException(ErrorCode.Err201); } switch (op) { case Operators.IS: lROp = Operators.EQ; break; case Operators.NOT: lROp = Operators.NE; break; case Operators.BELOW: lROp = Operators.LT; break; case Operators.ABOVE: lROp = Operators.GT; break; default: lROp = op; break; } // BUG: Baseform bug lStat == Rule.Values.IS_NUMBER Values lStat = Values.IS_NUMBER; double lVal = double.NaN; if (lVar == Varwords.TIME || lVar == Varwords.CLOCKTIME) { lVal = tok.Length == 6 ? Utilities.GetHour(tok[4], tok[5]) : Utilities.GetHour(tok[4]); lVal *= 3600; if (lVal < 0.0) { throw new ENException(ErrorCode.Err202); } } else { Values k; if (!EnumsTxt.TryParse(tok[tok.Length - 1], out k) || lStat <= Values.IS_NUMBER) { if (lStat == (Values)(-1) || lStat <= Values.IS_NUMBER) { if (!tok[tok.Length - 1].ToDouble(out lVal)) { throw new ENException(ErrorCode.Err202); } if (lVar == Varwords.FILLTIME || lVar == Varwords.DRAINTIME) { lVal *= 3600.0; } } } else { lStat = k; } } _status = lStat; _value = lVal; logop = lOp; _relop = lROp; _variable = lVar; _object = lObj; }
/// <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); }