Exemple #1
0
 def setUpClass(cls):
     cls.wn = wn = wntr.network.WaterNetworkModel()
     wn.add_tank('t1', 0, 10, 0, 20, 15)
     wn.add_junction('j1', 0.01)
     wn.add_pipe('p1', 't1', 'j1', minor_loss=10.0)
     wn.add_curve('curve1', 'HEAD', [(0.0, 10.0), (0.05, 5.0), (0.1, 0.0)])
     wn.add_curve('curve2', 'HEAD', [(0.0, 10.0), (0.03, 5.0), (0.1, 0.0)])
     wn.add_curve('curve3', 'HEAD', [(0.0, 10.0), (0.07, 5.0), (0.1, 0.0)])
     wn.add_pump('pump1', 't1', 'j1', 'HEAD', 'curve1')
     wn.add_pump('pump2', 't1', 'j1', 'POWER', 50.0)
     cls.m = m = wntr.sim.aml.Model()
     cls.updater = updater = ModelUpdater()
     wntr.sim.models.constants.hazen_williams_constants(m)
     wntr.sim.models.param.hw_resistance_param.build(m, wn, updater)
     wntr.sim.models.param.minor_loss_param.build(m, wn, updater)
     wntr.sim.models.param.source_head_param(m, wn)
     wntr.sim.models.var.flow_var(m, wn)
     wntr.sim.models.var.head_var(m, wn)
     wntr.sim.models.constraint.piecewise_hazen_williams_headloss_constraint.build(
         m, wn, updater)
     wntr.sim.models.constants.head_pump_constants(m)
     wntr.sim.models.constraint.head_pump_headloss_constraint.build(
         m, wn, updater)
     wntr.sim.models.param.pump_power_param.build(m, wn, updater)
     wntr.sim.models.constraint.power_pump_headloss_constraint.build(
         m, wn, updater)
Exemple #2
0
    def setUpClass(cls):
        cls.wn = wn = wntr.network.WaterNetworkModel()
        wn.add_tank("t1", 0, 10, 0, 20, 15)
        wn.add_junction("j1", 0.01)
        wn.add_pipe("p1", "t1", "j1", minor_loss=10.0)
        wn.add_curve("curve1", "HEAD", [(0.0, 10.0), (0.05, 5.0), (0.1, 0.0)])
        wn.add_curve("curve2", "HEAD", [(0.0, 10.0), (0.03, 5.0), (0.1, 0.0)])
        wn.add_curve("curve3", "HEAD", [(0.0, 10.0), (0.07, 5.0), (0.1, 0.0)])

        # add a single point, 2-point, and a set of multi-point curves to test
        wn.add_curve("curve4", "HEAD", [(0.05, 5.0)])
        wn.add_curve("curve5", "HEAD", [(0.0, 10.0), (0.1, 0.0)])

        # multi_point_pump_curves = pump_curves_for_testing() # change to read in a csv file

        df = pd.read_csv(join(test_data_dir, "pump_practice_curves.csv"), skiprows=5)
        multi_point_pump_curves = []
        for i in range(11):
            multi_point_pump_curves.append(df[df["curve number"] == i].iloc[:, 1:3])

        for i, curve in enumerate(multi_point_pump_curves):
            curve_name = "curve{0:d}".format(i + 6)
            wn.add_curve(curve_name, "HEAD", curve.values)

        wn.add_pump("pump1", "t1", "j1", "HEAD", "curve1")
        wn.add_pump("pump2", "t1", "j1", "POWER", 50.0)
        cls.m = m = wntr.sim.aml.Model()
        cls.updater = updater = ModelUpdater()
        wntr.sim.models.constants.hazen_williams_constants(m)
        wntr.sim.models.param.hw_resistance_param.build(m, wn, updater)
        wntr.sim.models.param.minor_loss_param.build(m, wn, updater)
        wntr.sim.models.param.source_head_param(m, wn)
        wntr.sim.models.var.flow_var(m, wn)
        wntr.sim.models.var.head_var(m, wn)
        wntr.sim.models.constraint.piecewise_hazen_williams_headloss_constraint.build(
            m, wn, updater
        )
        wntr.sim.models.constants.head_pump_constants(m)
        wntr.sim.models.constraint.head_pump_headloss_constraint.build(m, wn, updater)
        wntr.sim.models.param.pump_power_param.build(m, wn, updater)
        wntr.sim.models.constraint.power_pump_headloss_constraint.build(m, wn, updater)
    def test_pdd(self):
        wn = self.wn
        # Changed to handle the specific heads_to_test range, which is bad
        node = wn.get_node('j1')
        node.required_pressure = 20.0
        node.minimum_pressure = 0.0

        m = wntr.sim.aml.Model()
        updater = ModelUpdater()
        wntr.sim.models.constants.pdd_constants(m)
        wntr.sim.models.param.expected_demand_param(m, wn)
        wntr.sim.models.param.elevation_param.build(m, wn, updater)
        wntr.sim.models.param.pdd_poly_coeffs_param.build(m, wn, updater)
        wntr.sim.models.param.pmin_param.build(m, wn, updater)
        wntr.sim.models.param.pnom_param.build(m, wn, updater)
        wntr.sim.models.var.head_var(m, wn)
        wntr.sim.models.var.demand_var(m, wn)
        wntr.sim.models.constraint.pdd_constraint.build(m, wn, updater)

        node = wn.get_node('j1')

        pmin = node.minimum_pressure
        pnom = node.required_pressure
        h0 = node.elevation + pmin
        h1 = node.elevation + pnom
        delta = m.pdd_smoothing_delta
        heads_to_test = [h0 - 1, h0, h0 + delta/2, h0 + delta, h0 + (pmin + pnom)/2, h1 - delta, h1 - delta/2, h1, h1 + 1]
        d_expected = node.demand_timeseries_list.at(wn.sim_time, multiplier=wn.options.hydraulic.demand_multiplier)

        d = 0.01

        m.demand['j1'].value = d
        a1 = m.pdd_poly1_coeffs_a['j1'].value
        b1 = m.pdd_poly1_coeffs_b['j1'].value
        c1 = m.pdd_poly1_coeffs_c['j1'].value
        d1 = m.pdd_poly1_coeffs_d['j1'].value
        a2 = m.pdd_poly2_coeffs_a['j1'].value
        b2 = m.pdd_poly2_coeffs_b['j1'].value
        c2 = m.pdd_poly2_coeffs_c['j1'].value
        d2 = m.pdd_poly2_coeffs_d['j1'].value
        delta = m.pdd_smoothing_delta
        slope = m.pdd_slope

        for h in heads_to_test:
            m.head['j1'].value = h
            r1 = m.pdd['j1'].evaluate()
            p = h - node.elevation
            if p <= pmin:
                r2 = d - d_expected * slope * (p - pmin)
            elif p <= pmin + delta:
                r2 = d - d_expected * (a1*p**3 + b1*p**2 + c1*p + d1)
            elif p <= pnom - delta:
                r2 = d - d_expected * ((p - pmin)/(pnom - pmin))**0.5
            elif p <= pnom:
                r2 = d - d_expected * (a2*p**3 + b2*p**2 + c2*p + d2)
            else:
                r2 = d - d_expected * (slope*(p - pnom) + 1.0)
            # print(p, r1, r2, abs(r1 - r2))
            self.assertAlmostEqual(r1, r2, 12)
            der1 = m.pdd['j1'].reverse_ad()[m.head['j1']]
            der2 = m.pdd['j1'].reverse_ad()[m.head['j1']]
            der3 = approximate_derivative(m.pdd['j1'], m.head['j1'], 1e-6)
            self.assertAlmostEqual(der1, der2, 7)
            self.assertAlmostEqual(der1, der3, 6)
Exemple #4
0
def create_hydraulic_model(wn, HW_approx='default'):
    """
    Parameters
    ----------
    wn: WaterNetworkModel
    mode: str
    HW_approx: str
        Specifies which Hazen-Williams headloss approximation to use. Options are 'default' and 'piecewise'. Please
        see the WNTR documentation on hydraulics for details.

    Returns
    -------
    m: wntr.aml.Model
    model_updater: wntr.models.utils.ModelUpdater
    """
    m = aml.Model()
    model_updater = ModelUpdater()

    # Global constants
    constants.hazen_williams_constants(m)
    constants.head_pump_constants(m)
    constants.leak_constants(m)
    constants.pdd_constants(m)

    param.source_head_param(m, wn)
    param.expected_demand_param(m, wn)
    mode = wn.options.hydraulic.demand_model
    if mode in ['DD', 'DDA']:
        pass
    elif mode in ['PDD', 'PDA']:
        param.pmin_param.build(m, wn, model_updater)
        param.pnom_param.build(m, wn, model_updater)
        param.pdd_poly_coeffs_param.build(m, wn, model_updater)
    param.leak_coeff_param.build(m, wn, model_updater)
    param.leak_area_param.build(m, wn, model_updater)
    param.leak_poly_coeffs_param.build(m, wn, model_updater)
    param.elevation_param.build(m, wn, model_updater)
    param.hw_resistance_param.build(m, wn, model_updater)
    param.minor_loss_param.build(m, wn, model_updater)
    param.tcv_resistance_param.build(m, wn, model_updater)
    param.pump_power_param.build(m, wn, model_updater)
    param.valve_setting_param.build(m, wn, model_updater)

    if mode in ['DD','DDA']:
        pass
    elif mode in ['PDD','PDA']:
        var.demand_var(m, wn)
    var.flow_var(m, wn)
    var.head_var(m, wn)
    var.leak_rate_var(m, wn)

    if mode in ['DD','DDA']:
        constraint.mass_balance_constraint.build(m, wn, model_updater)
    elif mode in ['PDD','PDA']:
        constraint.pdd_mass_balance_constraint.build(m, wn, model_updater)
        constraint.pdd_constraint.build(m, wn, model_updater)
    else:
        raise ValueError('mode not recognized: ' + str(mode))
    if HW_approx == 'default':
        constraint.approx_hazen_williams_headloss_constraint.build(m, wn, model_updater)
    elif HW_approx == 'piecewise':
        constraint.piecewise_hazen_williams_headloss_constraint.build(m, wn, model_updater)
    else:
        raise ValueError('Unexpected value for HW_approx: ' + str(HW_approx))
    constraint.head_pump_headloss_constraint.build(m, wn, model_updater)
    constraint.power_pump_headloss_constraint.build(m, wn, model_updater)
    constraint.prv_headloss_constraint.build(m, wn, model_updater)
    constraint.psv_headloss_constraint.build(m, wn, model_updater)
    constraint.tcv_headloss_constraint.build(m, wn, model_updater)
    constraint.fcv_headloss_constraint.build(m, wn, model_updater)
    if len(wn.pbv_name_list) > 0:
        raise NotImplementedError('PBV valves are not currently supported in the WNTRSimulator')
    if len(wn.gpv_name_list) > 0:
        raise NotImplementedError('GPV valves are not currently supported in the WNTRSimulator')
    constraint.leak_constraint.build(m, wn, model_updater)

    # TODO: Document that changing a curve with controls does not do anything; you have to change the pump_curve_name attribute on the pump

    return m, model_updater