示例#1
0
        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;
        }
示例#2
0
            public Action(string[] tok, IEnumerable <SimulationLink> links, string label)
            {
                _label = label;

                int ntokens = tok.Length;

                Values k;

                if (ntokens != 6)
                {
                    throw new ENException(ErrorCode.Err201);
                }

                SimulationLink link = links.FirstOrDefault(simLink => simLink.Link.Name.Equals(tok[2], StringComparison.OrdinalIgnoreCase));

                if (link == null)
                {
                    throw new ENException(ErrorCode.Err204);
                }

                if (link.Type == LinkType.CV)
                {
                    throw new ENException(ErrorCode.Err207);
                }

                var    s = (Values)(-1);
                double x = double.NaN;

                if (EnumsTxt.TryParse(tok[5], out k) && k > Values.IS_NUMBER)
                {
                    s = k;
                }
                else
                {
                    if (!tok[5].ToDouble(out x) || x < 0.0)
                    {
                        throw new ENException(ErrorCode.Err202);
                    }
                }

                if (!double.IsNaN(x) && link.Type == LinkType.GPV)
                {
                    throw new ENException(ErrorCode.Err202);
                }

                if (!double.IsNaN(x) && link.Type == LinkType.PIPE)
                {
                    s = x == 0.0 ? Values.IS_CLOSED : Values.IS_OPEN;
                    x = double.NaN;
                }

                _link    = link;
                _status  = s;
                _setting = x;
            }
示例#3
0
        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);
        }
示例#4
0
        ///<summary>Get the shortest time step to activate the control.</summary>
        private long GetRequiredTimeStep(EpanetNetwork net, long htime, long tstep)
        {
            long t = 0;

            // Node control
            if (Node != null)
            {
                if (!(Node is SimulationTank)) // Check if node is a tank
                {
                    return(tstep);
                }

                double h = _node.SimHead;   // Current tank grade
                double q = _node.SimDemand; // Flow into tank

                if (Math.Abs(q) <= Constants.QZERO)
                {
                    return(tstep);
                }

                if ((h < Grade && Type == ControlType.HILEVEL && q > 0.0) || // Tank below hi level & filling
                    (h > Grade && Type == ControlType.LOWLEVEL && q < 0.0))
                // Tank above low level & emptying
                {
                    SimulationTank tank = (SimulationTank)Node;
                    double         v    = tank.FindVolume(net.FieldsMap, Grade) - tank.SimVolume;
                    t = (long)Math.Round(v / q); // Time to reach level
                }
            }

            // Time control
            if (Type == ControlType.TIMER)
            {
                if (Time > htime)
                {
                    t = Time - htime;
                }
            }

            // Time-of-day control
            if (Type == ControlType.TIMEOFDAY)
            {
                long t1 = (htime + net.Tstart) % Constants.SECperDAY;
                long t2 = Time;
                if (t2 >= t1)
                {
                    t = t2 - t1;
                }
                else
                {
                    t = Constants.SECperDAY - t1 + t2;
                }
            }

            // Revise time step
            if (t > 0 && t < tstep)
            {
                SimulationLink link = Link;

                // Check if rule actually changes link status or setting
                if (link != null &&
                    (link.Type > LinkType.PIPE && link.SimSetting != Setting) ||
                    (link.SimStatus != Status))
                {
                    tstep = t;
                }
            }

            return(tstep);
        }
示例#5
0
        private static void LogStatChange(TraceSource log, FieldsMap fMap, SimulationLink link, StatType oldstatus)
        {
            StatType s1 = oldstatus;
            StatType s2 = link.SimStatus;

            try {
                if (s2 == s1)
                {
                    double setting = link.SimSetting;
                    switch (link.Type)
                    {
                    case LinkType.PRV:
                    case LinkType.PSV:
                    case LinkType.PBV:
                        setting *= fMap.GetUnits(FieldType.PRESSURE);
                        break;

                    case LinkType.FCV:
                        setting *= fMap.GetUnits(FieldType.FLOW);
                        break;
                    }

                    log.Warning(
                        string.Format(
                            Text.FMT56,
                            link.Type.ParseStr(),
                            link.Link.Name,
                            setting));
                    return;
                }

                StatType j1, j2;

                if (s1 == StatType.ACTIVE)
                {
                    j1 = StatType.ACTIVE;
                }
                else if (s1 <= StatType.CLOSED)
                {
                    j1 = StatType.CLOSED;
                }
                else
                {
                    j1 = StatType.OPEN;
                }
                if (s2 == StatType.ACTIVE)
                {
                    j2 = StatType.ACTIVE;
                }
                else if (s2 <= StatType.CLOSED)
                {
                    j2 = StatType.CLOSED;
                }
                else
                {
                    j2 = StatType.OPEN;
                }

                if (j1 != j2)
                {
                    log.Warning(
                        Text.FMT57,
                        link.Type.ParseStr(),
                        link.Link.Name,
                        j1.ReportStr(),
                        j2.ReportStr());
                }
            }
            catch (ENException) {}
        }
示例#6
0
        /// <summary>Adjusts settings of links controlled by junction pressures after a hydraulic solution is found.</summary>
        public static bool PSwitch(
            TraceSource log,
            EpanetNetwork net,
            IEnumerable <SimulationControl> controls)
        {
            bool anychange = false;

            foreach (SimulationControl control  in  controls)
            {
                bool reset = false;
                if (control.Link == null)
                {
                    continue;
                }

                // Determine if control based on a junction, not a tank
                if (control.Node != null && !(control.Node is SimulationTank))
                {
                    // Determine if control conditions are satisfied
                    if (control.Type == ControlType.LOWLEVEL &&
                        control.Node.SimHead <= control.Grade + net.HTol)
                    {
                        reset = true;
                    }

                    if (control.Type == ControlType.HILEVEL &&
                        control.Node.SimHead >= control.Grade - net.HTol)
                    {
                        reset = true;
                    }
                }

                SimulationLink link = control.Link;

                //  Determine if control forces a status or setting change
                if (reset)
                {
                    bool change = false;

                    StatType s = link.SimStatus;

                    if (link.Type == LinkType.PIPE)
                    {
                        if (s != control.Status)
                        {
                            change = true;
                        }
                    }

                    if (link.Type == LinkType.PUMP)
                    {
                        if (link.SimSetting != control.Setting)
                        {
                            change = true;
                        }
                    }

                    if (link.Type >= LinkType.PRV)
                    {
                        if (link.SimSetting != control.Setting)
                        {
                            change = true;
                        }
                        else if (double.IsNaN(link.SimSetting) &&
                                 s != control.Status)
                        {
                            change = true;
                        }
                    }

                    // If a change occurs, update status & setting
                    if (change)
                    {
                        link.SimStatus = control.Status;
                        if (link.Type > LinkType.PIPE)
                        {
                            link.SimSetting = control.Setting;
                        }
                        if (net.StatFlag == StatFlag.FULL)
                        {
                            LogStatChange(log, net.FieldsMap, link, s);
                        }

                        anychange = true;
                    }
                }
            }
            return(anychange);
        }
示例#7
0
        /// <summary>Implements simple controls based on time or tank levels.</summary>
        public static int StepActions(
            TraceSource log,
            EpanetNetwork net,
            IEnumerable <SimulationControl> controls,
            long htime)
        {
            int setsum = 0;

            // Examine each control statement
            foreach (SimulationControl control  in  controls)
            {
                bool reset = false;

                // Make sure that link is defined
                if (control.Link == null)
                {
                    continue;
                }

                // Link is controlled by tank level
                var node = control.Node as SimulationTank;
                if (node != null)
                {
                    double h     = node.SimHead;
                    double vplus = Math.Abs(node.SimDemand);

                    SimulationTank tank = node;

                    double v1 = tank.FindVolume(net.FieldsMap, h);
                    double v2 = tank.FindVolume(net.FieldsMap, control.Grade);

                    if (control.Type == ControlType.LOWLEVEL && v1 <= v2 + vplus)
                    {
                        reset = true;
                    }
                    if (control.Type == ControlType.HILEVEL && v1 >= v2 - vplus)
                    {
                        reset = true;
                    }
                }

                // Link is time-controlled
                if (control.Type == ControlType.TIMER)
                {
                    if (control.Time == htime)
                    {
                        reset = true;
                    }
                }

                //  Link is time-of-day controlled
                if (control.Type == ControlType.TIMEOFDAY)
                {
                    if ((htime + net.Tstart) % Constants.SECperDAY == control.Time)
                    {
                        reset = true;
                    }
                }

                // Update link status & pump speed or valve setting
                if (reset)
                {
                    StatType       s1, s2;
                    SimulationLink link = control.Link;

                    if (link.SimStatus <= StatType.CLOSED)
                    {
                        s1 = StatType.CLOSED;
                    }
                    else
                    {
                        s1 = StatType.OPEN;
                    }

                    s2 = control.Status;

                    double k1 = link.SimSetting;
                    double k2 = k1;

                    if (control.Link.Type > LinkType.PIPE)
                    {
                        k2 = control.Setting;
                    }

                    if (s1 != s2 || k1 != k2)
                    {
                        link.SimStatus  = s2;
                        link.SimSetting = k2;
                        if (net.StatFlag != StatFlag.NO)
                        {
                            LogControlAction(log, control, htime);
                        }
                        setsum++;
                    }
                }
            }

            return(setsum);
        }
示例#8
0
        protected static void LogStatChange(
            FieldsMap fMap,
            TraceSource logger,
            SimulationLink link,
            StatType s1,
            StatType s2)
        {
            if (s1 == s2)
            {
                switch (link.Type)
                {
                case LinkType.PRV:
                case LinkType.PSV:
                case LinkType.PBV:
                    link.setting *= fMap.GetUnits(FieldType.PRESSURE);
                    break;

                case LinkType.FCV:
                    link.setting *= fMap.GetUnits(FieldType.FLOW);
                    break;
                }
                logger.Verbose(
                    Text.FMT56,
                    link.Type.ParseStr(),
                    link.Link.Name,
                    link.setting);
                return;
            }

            StatType j1, j2;

            if (s1 == StatType.ACTIVE)
            {
                j1 = StatType.ACTIVE;
            }
            else if (s1 <= StatType.CLOSED)
            {
                j1 = StatType.CLOSED;
            }
            else
            {
                j1 = StatType.OPEN;
            }
            if (s2 == StatType.ACTIVE)
            {
                j2 = StatType.ACTIVE;
            }
            else if (s2 <= StatType.CLOSED)
            {
                j2 = StatType.CLOSED;
            }
            else
            {
                j2 = StatType.OPEN;
            }

            if (j1 != j2)
            {
                logger.Verbose(
                    Text.FMT57,
                    link.Type.ParseStr(),
                    link.Link.Name,
                    j1.ReportStr(),
                    j2.ReportStr());
            }
        }
示例#9
0
            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;
            }
示例#10
0
            /// <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);
            }
示例#11
0
 private static void LogBadValve(TraceSource log, SimulationLink link, long htime)
 {
     log.Warning(Properties.Text.FMT61, htime.GetClockTime(), link.Link.Name);
 }