How to use the wntr.network.controls.ControlCondition function in wntr

To help you get started, we’ve selected a few wntr examples, based on popular ways it is used in public projects.

Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.

github USEPA / WNTR / wntr / network / controls.py View on Github external
if abs(dh) > self.Htol:
            if dh < -self.Htol:
                return False
            elif self._cv.flow < -self.Qtol:
                return False
            else:
                return True
        else:
            return False

    def __str__(self):
        s = '{0} head - {1} head > {2} and {3} flow >= {4}'.format(self._start_node.name, self._end_node.name, self.Htol, self._cv.name, -self.Qtol)
        return s


class _ClosePowerPumpCondition(ControlCondition):
    """
    Prevents reverse flow in pumps.
    """
    Htol = 0.0001524
    Qtol = 2.83168e-6
    Hmax = 1e10

    def __init__(self, wn, pump):
        """
        Parameters
        ----------
        wn: wntr.network.WaterNetworkModel
        pump: wntr.network.Pump
        """
        self._pump = pump
        self._start_node = wn.get_node(pump.start_node)
github USEPA / WNTR / wntr / network / controls.py View on Github external
tatt = self._threshold_attr
        fmt = "{}('{}').{} {} {}('{}').{}"
        return fmt.format(typ, obj, att,
                          rel,
                          ttyp, tobj, tatt)

    def evaluate(self):
        cur_value = getattr(self._source_obj, self._source_attr)
        thresh_value = getattr(self._threshold_obj, self._threshold_attr)
        relation = self._relation.func
        state = relation(cur_value, thresh_value)
        return bool(state)


@DocInheritor({'requires', 'evaluate', 'backtrack'})
class OrCondition(ControlCondition):
    """Combine two WNTR Conditions with an OR.
    
    Parameters
    ----------
    cond1 : ControlCondition
        The first condition
    cond2 : ControlCondition
        The second condition

    """
    def __init__(self, cond1, cond2):
        self._condition_1 = cond1
        self._condition_2 = cond2

        if isinstance(cond1, TankLevelCondition):
            if cond1._relation is Comparison.eq:
github USEPA / WNTR / wntr / network / controls.py View on Github external
elif self._relation is Comparison.lt and cur_time < self._threshold:
            self._backtrack = 0
            return True
        elif self._relation is Comparison.le and cur_time <= self._threshold:
            self._backtrack = 0
            return True
        elif self._relation is Comparison.le and prev_time < self._threshold:
            self._backtrack = int(cur_time - self._threshold)
            return True
        else:
            self._backtrack = 0
            return False


@DocInheritor({'requires', 'evaluate', 'name'})
class ValueCondition(ControlCondition):
    """Compare a network element attribute to a set value.

    Parameters
    ----------
    source_obj : object
        The object (such as a Junction, Tank, Pipe, etc.) to use in the comparison
    source_attr : str
        The attribute of the object (such as level, pressure, setting, etc.) to
        compare against the threshold
    operation : function or str
        A two-parameter comparison function (e.g., numpy.greater, numpy.less_equal), or a
        string describing the comparison (e.g., '=', 'below', 'is', '>=', etc.)
        Words, such as 'below', are only accepted from the EPANET rules conditions list (see ...)
    threshold : float
        A value to compare the source object attribute against
    """
github USEPA / WNTR / wntr / network / controls.py View on Github external
self._end_node = wn.get_node(self._fcv.end_node)
        self._backtrack = 0

    def requires(self):
        return OrderedSet([self._fcv, self._start_node, self._end_node])

    def evaluate(self):
        if self._start_node.head - self._end_node.head < -self._Htol:
            return True
        elif self._fcv.flow < -self._Qtol:
            return True
        else:
            return False


class _ActiveFCVCondition(ControlCondition):
    _Qtol = 2.83168e-6
    _Htol = 0.0001524

    def __init__(self, wn, fcv):
        """
        Parameters
        ----------
        wn: wntr.network.WaterNetworkModel
        fcv: wntr.network.Valve
        """
        self._fcv = fcv
        self._start_node = wn.get_node(self._fcv.start_node)
        self._end_node = wn.get_node(self._fcv.end_node)
        self._backtrack = 0

    def requires(self):
github USEPA / WNTR / wntr / network / controls.py View on Github external
def evaluate(self):
        return bool(self._condition_1) or bool(self._condition_2)

    @property
    def backtrack(self):
        return np.max([self._condition_1.backtrack, self._condition_2.backtrack])

    def requires(self):
        req = self._condition_1.requires()
        req.update(self._condition_2.requires())
        return req


@DocInheritor({'requires', 'evaluate', 'backtrack'})
class AndCondition(ControlCondition):
    """Combine two WNTR Conditions with an AND
    
    Parameters
    ----------
    cond1 : ControlCondition
        The first condition
    cond2 : ControlCondition
        The second condition
    """
    def __init__(self, cond1, cond2):
        self._condition_1 = cond1
        self._condition_2 = cond2

        if isinstance(cond1, TankLevelCondition):
            if cond1._relation is Comparison.eq:
                logger.warning('Using Comparison.eq with {0} will probably not work!'.format(type(cond1)))
github USEPA / WNTR / wntr / network / controls.py View on Github external
elif self._prv._internal_status == LinkStatus.Closed:
            if self._start_node.head >= self._prv.setting + self._end_node.elevation + self._Htol and self._end_node.head < self._prv.setting + self._end_node.elevation - self._Htol:
                return False
            elif self._start_node.head < self._prv.setting + self._end_node.elevation - self._Htol and self._start_node.head > self._end_node.head + self._Htol:
                return True
            return False
        else:
            raise RuntimeError('Unexpected PRV _internal_status for valve {0}: {1}.'.format(self._prv,
                                                                                            self._prv._internal_status))

    def __str__(self):
        s = 'prv {0} needs to be open'.format(self._prv.name)
        return s


class _ActivePRVCondition(ControlCondition):
    _Qtol = 2.83168e-6
    _Htol = 0.0001524

    def __init__(self, wn, prv):
        """
        Parameters
        ----------
        wn: wntr.network.WaterNetworkModel
        prv: wntr.network.Valve
        """
        self._prv = prv
        self._start_node = wn.get_node(self._prv.start_node)
        self._end_node = wn.get_node(self._prv.end_node)
        self._backtrack = 0
        self._r = 8.0 * self._prv.minor_loss / (9.81 * math.pi**2 * self._prv.diameter**4)
github USEPA / WNTR / wntr / network / controls.py View on Github external
return False
        elif self._psv._internal_status == LinkStatus.Closed:
            if ((self._end_node.head > setting + self._Htol) and
                    (self._start_node.head > self._end_node.head + self._Htol)):
                return True
            return False
        else:
            raise RuntimeError('Unexpected PSV _internal_status for valve {0}: {1}.'.format(self._psv,
                                                                                            self._psv._internal_status))

    def __str__(self):
        s = 'psv {0} needs to be open'.format(self._psv.name)
        return s


class _ActivePSVCondition(ControlCondition):
    _Qtol = 2.83168e-6
    _Htol = 0.0001524

    def __init__(self, wn, psv):
        """
        Parameters
        ----------
        wn: wntr.network.WaterNetworkModel
        psv: wntr.network.Valve
        """
        self._psv = psv
        self._start_node = wn.get_node(self._psv.start_node)
        self._end_node = wn.get_node(self._psv.end_node)
        self._backtrack = 0
        self._r = 8.0 * self._psv.minor_loss / (9.81 * math.pi**2 * self._psv.diameter**4)
github USEPA / WNTR / wntr / network / controls.py View on Github external
if state and not relation(self._last_value, thresh_value):
            # if the condition is satisfied and the last value did not satisfy the condition, then backtracking
            # is needed.
            # The math.floor is not actually needed, but I leave it here for clarity. We want the backtrack value to be
            # slightly lower than what the floating point computation would give. This ensures the next time step will
            # be slightly later than when the tank level hits the threshold. This ensures the tank level will go
            # slightly beyond the threshold. This ensures that relation(self._last_value, thresh_value) will be True
            # next time. This prevents us from computing very small backtrack values over and over.
            if self._source_obj.demand != 0:
                self._backtrack = int(math.floor((cur_value - thresh_value)*math.pi/4.0*self._source_obj.diameter**2/self._source_obj.demand))
        self._last_value = cur_value  # update the last value
        return bool(state)


@DocInheritor({'requires', 'evaluate', 'name'})
class RelativeCondition(ControlCondition):
    """Compare attributes of two different objects (e.g., levels from tanks 1 and 2)
    This type of condition does not work with the EpanetSimulator, only the WNTRSimulator.
    
    Parameters
    ----------
    source_obj : object
        The object (such as a Junction, Tank, Pipe, etc.) to use in the comparison
    source_attr : str
        The attribute of the object (such as level, pressure, setting, etc.) to
        compare against the threshold
    relation : function
        A numpy or other comparison method that takes two values and returns a bool
        (e.g., numpy.greater, numpy.less_equal)
    threshold_obj : object
        The object (such as a Junction, Tank, Pipe, etc.) to use in the comparison of attributes
    threshold_attr : str
github USEPA / WNTR / wntr / network / controls.py View on Github external
elif self._prv._internal_status == LinkStatus.Open:
            if self._prv.flow < -self._Qtol:
                return True
            return False
        elif self._prv._internal_status == LinkStatus.Closed:
            return False
        else:
            raise RuntimeError('Unexpected PRV _internal_status for valve {0}: {1}.'.format(self._prv,
                                                                                            self._prv._internal_status))

    def __str__(self):
        s = 'prv {0} needs to be closed'.format(self._prv.name)
        return s


class _OpenPRVCondition(ControlCondition):
    _Qtol = 2.83168e-6
    _Htol = 0.0001524

    def __init__(self, wn, prv):
        """
        Parameters
        ----------
        wn: wntr.network.WaterNetworkModel
        prv: wntr.network.Valve
        """
        super(_OpenPRVCondition, self).__init__()
        self._prv = prv
        self._start_node = wn.get_node(self._prv.start_node)
        self._end_node = wn.get_node(self._prv.end_node)
        self._backtrack = 0
        self._r = 8.0 * self._prv.minor_loss / (9.81 * math.pi**2 * self._prv.diameter**4)
github USEPA / WNTR / wntr / network / controls.py View on Github external
def evaluate(self):
        """
        If True is returned, the pump needs to be closed
        """
        dh = self._end_node.head - self._start_node.head
        if dh > self.Hmax + self.Htol:
            return True
        return False

    def __str__(self):
        s = '{0} head - {1} head > {2:.4f}'.format(self._end_node.name, self._start_node.name, self.Hmax + self.Htol)
        return s


class _OpenPowerPumpCondition(ControlCondition):
    Htol = 0.0001524
    Qtol = 2.83168e-6
    Hmax = 1e10

    def __init__(self, wn, pump):
        """
        Parameters
        ----------
        wn: wntr.network.WaterNetworkModel
        pump: wntr.network.Pump
        """
        self._pump = pump
        self._start_node = wn.get_node(pump.start_node)
        self._end_node = wn.get_node(pump.end_node)
        self._backtrack = 0