コード例 #1
0
def test_storage_max_volume_param():
    """Test a that an max_volume with a Parameter results in the correct current_pc

    """

    model = Model(start=pandas.to_datetime('2016-01-01'),
                  end=pandas.to_datetime('2016-01-01'))

    storage = Storage(model, 'storage', inputs=1, outputs=0)
    otpt = Output(model, 'output', max_flow=99999, cost=-99999)
    storage.connect(otpt)

    p = ConstantParameter(model, 20.0)
    storage.max_volume = p
    storage.initial_volume = 10.0
    storage.initial_volume_pc = 0.5

    model.setup()
    np.testing.assert_allclose(storage.current_pc, 0.5)

    model.run()

    p.set_double_variables(np.asarray([
        40.0,
    ]))
    model.reset()

    # This is a demonstration of the issue describe in #470
    #   https://github.com/pywr/pywr/issues/470
    # The initial storage is defined in both absolute and relative terms
    # but these are now not consistent with one another and the updated max_volume

    np.testing.assert_allclose(storage.volume, 10.0)
    np.testing.assert_allclose(storage.current_pc, 0.5)
コード例 #2
0
def optimisation_model(simple_storage_model):
    model = simple_storage_model

    # Modify the model to have two variables.
    inpt = model.nodes["Input"]
    inpt.max_flow = ConstantParameter(
        model,
        inpt.max_flow,
        lower_bounds=0.0,
        upper_bounds=10.0,
        name="Input flow",
        is_variable=True,
    )

    otpt = model.nodes["Output"]
    otpt.max_flow = ConstantParameter(
        model,
        otpt.max_flow,
        lower_bounds=0.0,
        upper_bounds=10.0,
        name="Output flow",
        is_variable=True,
    )

    # And two objectives.
    TotalFlowNodeRecorder(model,
                          inpt,
                          name="Total inflow",
                          is_objective="maximise")
    TotalFlowNodeRecorder(model,
                          otpt,
                          name="Total outflow",
                          is_objective="maximise")

    return model
コード例 #3
0
def test_storage_max_volume_param_raises(solver):
    """Test a that an max_volume with a Parameter that has children.
    
    Only some aggregated style parameters should work here.
    """

    model = Model(solver=solver,
                  start=pandas.to_datetime('2016-01-01'),
                  end=pandas.to_datetime('2016-01-01'))

    storage = Storage(model, 'storage', num_inputs=1, num_outputs=0)
    otpt = Output(model, 'output', max_flow=99999, cost=-99999)
    storage.connect(otpt)

    p = AggregatedParameter(
        model,
        [ConstantParameter(model, 20.0),
         ConstantParameter(model, 20.0)],
        agg_func='sum')

    storage.max_volume = p
    storage.initial_volume = 10.0

    model.setup()
    np.testing.assert_allclose(storage.current_pc, 0.25)
コード例 #4
0
def test_storage_max_volume_param_raises(solver):
    """Test a that an max_volume with a Parameter that has children is an error

    """

    model = Model(solver=solver,
                  start=pandas.to_datetime('2016-01-01'),
                  end=pandas.to_datetime('2016-01-01'))

    storage = Storage(model, 'storage', num_inputs=1, num_outputs=0)
    otpt = Output(model, 'output', max_flow=99999, cost=-99999)
    storage.connect(otpt)

    p = AggregatedParameter(
        model,
        [ConstantParameter(model, 20.0),
         ConstantParameter(model, 20.0)],
        agg_func='sum')
    p1 = AggregatedParameter(model, [p, ConstantParameter(model, 1.5)],
                             agg_func="product")

    storage.max_volume = p1
    storage.initial_volume = 10.0

    with pytest.raises(RuntimeError):
        model.run()
コード例 #5
0
def test_storage_max_volume_param(solver):
    """Test a that an max_volume with a Parameter results in the correct current_pc

    """

    model = Model(solver=solver,
                  start=pandas.to_datetime('2016-01-01'),
                  end=pandas.to_datetime('2016-01-01'))

    storage = Storage(model, 'storage', num_inputs=1, num_outputs=0)
    otpt = Output(model, 'output', max_flow=99999, cost=-99999)
    storage.connect(otpt)

    p = ConstantParameter(model, 20.0)
    storage.max_volume = p
    storage.initial_volume = 10.0

    model.setup()
    np.testing.assert_allclose(storage.current_pc, 0.5)

    model.run()

    p.update(np.asarray([
        40.0,
    ]))
    model.reset()
    np.testing.assert_allclose(storage.current_pc, 0.25)
コード例 #6
0
def test_storage_initial_volume_pc(solver):
    """Test that setting initial volume as a percentage works as expected.
    """
    model = Model(solver=solver,
                  start=pandas.to_datetime('2016-01-01'),
                  end=pandas.to_datetime('2016-01-01'))

    storage = Storage(model, 'storage', num_inputs=1, num_outputs=0)
    otpt = Output(model, 'output', max_flow=99999, cost=-99999)
    storage.connect(otpt)

    p = ConstantParameter(model, 20.0)
    storage.max_volume = p
    storage.initial_volume_pc = 0.5

    model.setup()
    np.testing.assert_allclose(storage.current_pc, 0.5)
    np.testing.assert_allclose(storage.volume, 10.0)

    model.run()

    p.update(np.asarray([
        40.0,
    ]))
    model.reset()
    np.testing.assert_allclose(storage.current_pc, 0.5)
    np.testing.assert_allclose(storage.volume, 20.0)
コード例 #7
0
    def __init__(self, model, name, *args, **kwargs):
        demand = kwargs.pop('demand', ConstantParameter(model, 0))
        supply = kwargs.pop('supply', ConstantParameter(model, 0))
        headroom = kwargs.pop('headroom', ConstantParameter(model, 0))
        super().__init__(model, name, *args, **kwargs)

        self.supply_node = Input(model, name=f'{name}-supply', parent=self)
        self.demand_node = Output(model, name=f'{name}-demand', parent=self)

        self.supply_node.max_flow = MaxParameter(model, supply)

        demand_headroom = AggregatedParameter(model,
                                              parameters=[demand, headroom],
                                              agg_func='sum')

        self.demand_node.max_flow = MaxParameter(model, demand_headroom)
        self.demand_node.cost = -100

        self.supply_node.connect(self)
        self.connect(self.demand_node)

        # Track deficits
        deficit_param = DeficitParameter(model,
                                         self.demand_node,
                                         name=f'{name}-deficit_param')
        NumpyArrayParameterRecorder(model,
                                    deficit_param,
                                    name=f'__{name}-demand__:deficit',
                                    temporal_agg_func='sum')
コード例 #8
0
def test_control_curve_interpolated(model):
    m = model
    m.timestepper.delta = 200

    s = m.nodes['Storage']
    o = m.nodes['Output']
    s.connect(o)

    cc = ConstantParameter(model, 0.8)
    values = [20.0, 5.0, 0.0]
    s.cost = p = ControlCurveInterpolatedParameter(model, s, cc, values)

    @assert_rec(model, p)
    def expected_func(timestep, scenario_index):
        v = s.initial_volume
        c = cc.value(timestep, scenario_index)
        if c == 1.0 and v == 100.0:
            expected = values[1]
        elif c == 0.0 and v == 0.0:
            expected = values[1]
        else:
            expected = np.interp(v / 100.0, [0.0, c, 1.0], values[::-1])
        return expected

    for control_curve in (0.0, 0.8, 1.0):
        cc.update(np.array([
            control_curve,
        ]))
        for initial_volume in (0.0, 10.0, 50.0, 80.0, 90.0, 100.0):
            s.initial_volume = initial_volume
            model.run()
コード例 #9
0
    def __init__(self, *args, **kwargs):
        """

        Keywords:
            control_curve - A Parameter object that can return the control curve position,
                as a percentage of fill, for the given timestep.
        """
        control_curve = pop_kwarg_parameter(kwargs, 'control_curve', None)
        above_curve_cost = kwargs.pop('above_curve_cost', None)
        cost = kwargs.pop('cost', 0.0)
        if above_curve_cost is not None:
            if control_curve is None:
                # Make a default control curve at 100% capacity
                control_curve = ConstantParameter(1.0)
            elif not isinstance(control_curve, Parameter):
                # Assume parameter is some kind of constant and coerce to ConstantParameter
                control_curve = ConstantParameter(control_curve)

            if not isinstance(cost, Parameter):
                # In the case where an above_curve_cost is given and cost is not a Parameter
                # a default cost Parameter is created.
                kwargs['cost'] = ControlCurveParameter(
                    self, control_curve, [above_curve_cost, cost])
            else:
                raise ValueError(
                    'If an above_curve_cost is given cost must not be a Parameter.'
                )
        else:
            # reinstate the given cost parameter to pass to the parent constructors
            kwargs['cost'] = cost
        super(Reservoir, self).__init__(*args, **kwargs)
コード例 #10
0
    def __init__(self, model, name, **kwargs):
        # Create the keyword arguments for the HP recorder
        hp_recorder_kwarg_names = ('efficiency', 'density',
                                   'flow_unit_conversion',
                                   'energy_unit_conversion')
        hp_kwargs = {}
        for kwd in hp_recorder_kwarg_names:
            try:
                hp_kwargs[kwd] = kwargs.pop(kwd)
            except KeyError:
                pass

        self.storage_node = storage_node = kwargs.pop('storage_node', None)
        # See if there is a level parameter on the storage node
        if storage_node is not None:
            level_parameter = storage_node.level
            if not isinstance(level_parameter, Parameter):
                level_parameter = ConstantParameter(model,
                                                    value=level_parameter)
        else:
            level_parameter = None

        turbine_elevation = kwargs.pop('turbine_elevation', 0)
        generation_capacity = kwargs.pop('generation_capacity', 0)
        min_operating_elevation = kwargs.pop('min_operating_elevation', 0)
        min_head = min_operating_elevation - turbine_elevation

        super().__init__(model, name, **kwargs)

        if isinstance(generation_capacity, (float, int)):
            generation_capacity = ConstantParameter(model, generation_capacity)

        hp_target_flow = HydropowerTargetParameter(
            model,
            generation_capacity,
            water_elevation_parameter=level_parameter,
            min_head=min_head,
            min_flow=ConstantParameter(model, 0),
            turbine_elevation=turbine_elevation,
            **{k: v
               for k, v in hp_kwargs.items()})

        self.max_flow = hp_target_flow

        hp_recorder = HydropowerRecorder(
            model,
            self,
            water_elevation_parameter=level_parameter,
            turbine_elevation=turbine_elevation,
            **hp_kwargs)
        self.hydropower_recorder = hp_recorder
コード例 #11
0
    def test_with_parameters(self, model):
        """ Test with `parameters` keyword argument. """
        m = model
        s = m.nodes['Storage']

        # Two different control curves
        cc = [ConstantParameter(model, 0.8), ConstantParameter(model, 0.6)]
        # Three different parameters to return
        params = [
            ConstantParameter(model, 1.0), ConstantParameter(model, 0.7), ConstantParameter(model, 0.4)
        ]
        s.cost = ControlCurveParameter(model, s, cc, parameters=params)

        self._assert_results(m, s)
コード例 #12
0
    def test_two_control_curves(self, simple_storage_model):
        """Test `ControlCurvePiecewiseInterpolatedParameter` with two control curves. """
        model = simple_storage_model
        storage_node = model.nodes["Storage"]
        input_node = model.nodes["Input"]
        output_node = model.nodes["Output"]

        control_curves = [
            ConstantParameter(model, 0.75),
            ConstantParameter(model, 0.25),
        ]

        parameter = ControlCurvePiecewiseInterpolatedParameter(model,
                                                               storage_node,
                                                               control_curves,
                                                               [(500, 200),
                                                                (100, 50),
                                                                (0, -100)],
                                                               name="CCPIP")
        assert parameter.minimum == 0.0
        assert parameter.maximum == 1.0

        input_node.max_flow = 1.0
        input_node.cost = 0
        output_node.max_flow = 0.0
        storage_node.initial_volume = 0.0
        storage_node.max_volume = 100.0
        storage_node.cost = -10

        model.timestepper.start = "1920-01-01"
        model.timestepper.delta = 1
        model.timestepper.end = model.timestepper.start + model.timestepper.offset * 100

        @assert_rec(model, parameter)
        def expected_func(timestep, scenario_index):
            volume = timestep.index

            current_position = volume / storage_node.max_volume
            if current_position >= 0.75:
                factor = (volume - 75) / 25
                value = 200 + factor * (500 - 200)
            elif current_position >= 0.25:
                factor = (volume - 25) / 50
                value = 50 + factor * (100 - 50)
            else:
                factor = volume / 25
                value = -100 + factor * 100
            return value

        model.run()
コード例 #13
0
    def test_parameters(self, simple_linear_model, tmpdir):
        """
        Test the TablesRecorder

        """
        from pywr.parameters import ConstantParameter

        model = simple_linear_model
        otpt = model.nodes['Output']
        inpt = model.nodes['Input']

        p = ConstantParameter(model, 10.0, name='max_flow')
        inpt.max_flow = p

        # ensure TablesRecorder can handle parameters with a / in the name
        p_slash = ConstantParameter(model, 0.0, name='name with a / in it')
        inpt.min_flow = p_slash

        agg_node = AggregatedNode(model, 'Sum', [otpt, inpt])

        inpt.max_flow = 10.0
        otpt.cost = -2.0

        h5file = tmpdir.join('output.h5')
        import tables
        with tables.open_file(str(h5file), 'w') as h5f:
            with pytest.warns(ParameterNameWarning):
                rec = TablesRecorder(model, h5f, parameters=[p, p_slash])

            # check parameters have been added to the component tree
            # this is particularly important for parameters which update their
            # values in `after`, e.g. DeficitParameter (see #465)
            assert(not model.find_orphaned_parameters())
            assert(p in rec.children)
            assert(p_slash in rec.children)

            with pytest.warns(tables.NaturalNameWarning):
                model.run()

            for node_name in model.nodes.keys():
                ca = h5f.get_node('/', node_name)
                assert ca.shape == (365, 1)
                if node_name == 'Sum':
                    np.testing.assert_allclose(ca, 20.0)
                elif "name with a" in node_name:
                    assert(node_name == "name with a _ in it")
                    np.testing.assert_allclose(ca, 0.0)
                else:
                    np.testing.assert_allclose(ca, 10.0)
コード例 #14
0
 def test_init(self, simple_storage_model):
     """ Test initialisation raises error with too many keywords """
     stg = simple_storage_model.nodes['Storage']
     param = ConstantParameter(simple_storage_model, 2.0)
     with pytest.raises(ValueError):
         # Passing both "parameter" and "storage_node" is invalid
         Polynomial1DParameter(simple_storage_model, [0.5, np.pi], parameter=param, storage_node=stg)
コード例 #15
0
    def test_with_nonstorage(self, model):
        """Test usage on non-`Storage` node."""
        # Now test if the parameter is used on a non storage node
        m = model
        s = m.nodes["Storage"]

        l = Link(m, "Link")
        # Connect the link node to the network to create a valid model
        o = m.nodes["Output"]
        s.connect(l)
        l.connect(o)

        cc = ConstantParameter(model, 0.8)
        l.cost = ControlCurveParameter(model, s, cc, [10.0, 0.0])

        @assert_rec(m, l.cost)
        def expected_func(timestep, scenario_index):
            v = s.initial_volume
            if v >= 80.0:
                expected = 10.0
            else:
                expected = 0.0
            return expected

        for initial_volume in (90, 70):
            s.initial_volume = initial_volume
            m.run()
コード例 #16
0
    def test_parameters(self, simple_linear_model, tmpdir):
        """
        Test the TablesRecorder

        """
        from pywr.parameters import ConstantParameter

        model = simple_linear_model
        otpt = model.nodes['Output']
        inpt = model.nodes['Input']

        p = ConstantParameter(10.0, name='max_flow')
        inpt.max_flow = p

        agg_node = AggregatedNode(model, 'Sum', [otpt, inpt])

        inpt.max_flow = 10.0
        otpt.cost = -2.0

        h5file = tmpdir.join('output.h5')
        import tables
        with tables.open_file(str(h5file), 'w') as h5f:
            rec = TablesRecorder(model, h5f, parameters=[p, ])

            model.run()

            for node_name in model.nodes.keys():
                ca = h5f.get_node('/', node_name)
                assert ca.shape == (365, 1)
                if node_name == 'Sum':
                    np.testing.assert_allclose(ca, 20.0)
                else:
                    np.testing.assert_allclose(ca, 10.0)
コード例 #17
0
 def test_run(self, simple_storage_model):
     model = simple_storage_model
     storage_node = model.nodes["Storage"]
     input_node = model.nodes["Input"]
     output_node = model.nodes["Output"]
     control_curve = ConstantParameter(model, 0.5)
     parameter = PiecewiseLinearControlCurve(model, storage_node, control_curve, values=[(50, 100), (200, 500)], name="PLCC")
     assert parameter.minimum == 0.0
     assert parameter.maximum == 1.0
 
     input_node.max_flow = 1.0
     input_node.cost = 0
     output_node.max_flow = 0.0
     storage_node.initial_volume = 0.0
     storage_node.max_volume = 100.0
     storage_node.cost = -10
     
     model.timestepper.start = "1920-01-01"
     model.timestepper.delta = 1
     model.timestepper.end = model.timestepper.start + model.timestepper.delta*100
     
     @assert_rec(model, parameter)
     def expected_func(timestep, scenario_index):
         volume = timestep.index
         control_curve = 0.5
         current_position = volume / storage_node.max_volume
         if current_position > control_curve:
             factor = (volume - 50) / 50
             value = 200 + factor * (500 - 200)
         else:
             factor = volume / 50
             value = 50 + factor * (100 - 50)
         return value
     
     model.run()
コード例 #18
0
    def test_nodes_with_str(self, simple_linear_model, tmpdir):
        """
        Test the TablesRecorder

        """
        from pywr.parameters import ConstantParameter

        model = simple_linear_model
        otpt = model.nodes['Output']
        inpt = model.nodes['Input']
        agg_node = AggregatedNode(model, 'Sum', [otpt, inpt])
        p = ConstantParameter(model, 10.0, name='max_flow')
        inpt.max_flow = p

        otpt.cost = -2.0

        h5file = tmpdir.join('output.h5')
        import tables
        with tables.open_file(str(h5file), 'w') as h5f:
            nodes = ['Output', 'Input', 'Sum']
            where = "/agroup"
            rec = TablesRecorder(model, h5f, nodes=nodes,
                                 parameters=[p, ], where=where)

            model.run()

            for node_name in ['Output', 'Input', 'Sum', 'max_flow']:
                ca = h5f.get_node("/agroup/" + node_name)
                assert ca.shape == (365, 1)
                if node_name == 'Sum':
                    np.testing.assert_allclose(ca, 20.0)
                else:
                    np.testing.assert_allclose(ca, 10.0)
コード例 #19
0
def test_annual_count_index_parameter_recorder(simple_storage_model):
    """ Test AnnualCountIndexParameterRecord

    The test sets uses a simple reservoir model with different inputs that
    trigger a control curve failure after different numbers of years.
    """
    from pywr.parameters import ConstantScenarioParameter, ConstantParameter
    from pywr.parameters.control_curves import ControlCurveIndexParameter
    model = simple_storage_model
    scenario = Scenario(model, 'A', size=2)
    # Simulate 5 years
    model.timestepper.start = '2015-01-01'
    model.timestepper.end = '2019-12-31'
    # Control curve parameter
    param = ControlCurveIndexParameter(model, model.nodes['Storage'], ConstantParameter(model, 0.25))

    # Storage model has a capacity of 20, but starts at 10 Ml
    # Demand is roughly 2 Ml/d per year
    #  First ensemble balances the demand
    #  Second ensemble should fail during 3rd year
    demand = 2.0 / 365
    model.nodes['Input'].max_flow = ConstantScenarioParameter(model, scenario, [demand, 0])
    model.nodes['Output'].max_flow = demand

    # Create the recorder with a threshold of 1
    rec = AnnualCountIndexParameterRecorder(model, param, 1)

    model.run()
    # We expect no failures in the first ensemble, but 3 out of 5 in the second
    assert_allclose(rec.values(), [0, 3])
コード例 #20
0
ファイル: test_river.py プロジェクト: jetuk/pywr
def test_control_curve(solver):
    """
    Use a simple model of a Reservoir to test that a control curve
    behaves as expected.

    The control curve should alter the cost of the Reservoir when it
    is above or below a particular threshold.

    (flow = 8.0)          (max_flow = 10.0)
    Catchment -> River -> DemandCentre
                     |        ^
    (max_flow = 2.0) v        | (max_flow = 2.0)
                    Reservoir

    """
    in_flow = 8

    model = pywr.core.Model(solver=solver)
    catchment = river.Catchment(model, name="Catchment", flow=in_flow)
    lnk = river.River(model, name="River")
    catchment.connect(lnk)
    demand = pywr.core.Output(model, name="Demand", cost=-10.0, max_flow=10)
    lnk.connect(demand)
    from pywr.parameters import ConstantParameter
    control_curve = ConstantParameter(0.8)
    reservoir = river.Reservoir(model,
                                name="Reservoir",
                                max_volume=10,
                                cost=-20,
                                above_curve_cost=0.0,
                                control_curve=control_curve,
                                initial_volume=10)
    reservoir.inputs[0].max_flow = 2.0
    reservoir.outputs[0].max_flow = 2.0
    lnk.connect(reservoir)
    reservoir.connect(demand)

    model.step()
    # Reservoir is currently above control curve. 2 should be taken from the
    # reservoir
    assert (reservoir.volume == 8)
    assert (demand.flow == 10)
    # Reservoir is still at (therefore above) control curve. So 2 is still taken
    model.step()
    assert (reservoir.volume == 6)
    assert (demand.flow == 10)
    # Reservoir now below curve. Better to retain volume and divert some of the
    # inflow
    model.step()
    assert (reservoir.volume == 8)
    assert (demand.flow == 6)
    # Set the above_curve_cost function to keep filling
    from pywr.parameters.control_curves import ControlCurveParameter
    # We know what we're doing with the control_curve Parameter so unset its parent before overriding
    # the cost parameter.
    reservoir.cost = ControlCurveParameter(reservoir, control_curve,
                                           [-20.0, -20.0])
    model.step()
    assert (reservoir.volume == 10)
    assert (demand.flow == 6)
コード例 #21
0
    def test_basic_use(self, simple_linear_model):
        """ Test the basic use of `ConstantParameter` using the Python API """
        model = simple_linear_model
        # Add two scenarios
        scA = Scenario(model, 'Scenario A', size=2)
        scB = Scenario(model, 'Scenario B', size=5)

        p = ConstantParameter(model, np.pi, name='pi', comment='Mmmmm Pi!')

        assert not p.is_variable
        assert p.double_size == 1
        assert p.integer_size == 0

        model.setup()
        ts = model.timestepper.current
        # Now ensure the appropriate value is returned for all scenarios
        for i, (a, b) in enumerate(itertools.product(range(scA.size), range(scB.size))):
            si = ScenarioIndex(i, np.array([a, b], dtype=np.int32))
            np.testing.assert_allclose(p.value(ts, si), np.pi)
コード例 #22
0
 def test_json(self, simple_storage_model):
     """Test loading from JSON data."""
     model = simple_storage_model
     control_curve1 = ConstantParameter(model, 0.5, name="cc1")
     control_curve2 = ConstantParameter(model, 0.25, name="cc2")
     parameter_data = {
         "type": "controlcurvepiecewiseinterpolated",
         "storage_node": "Storage",
         "control_curves": ["cc1", "cc2"],
         "minimum": 0.2,
         "maximum": 0.7,
         "values": [[200, 100], [10, 5], [0, -10]]
     }
     parameter = load_parameter(model, parameter_data)
     assert parameter.minimum == 0.2
     assert parameter.maximum == 0.7
     np.testing.assert_allclose(parameter.values, [[200, 100], [10, 5], [0, -10]])
     assert parameter.control_curves == [control_curve1, control_curve2]
     assert parameter.storage_node is model.nodes["Storage"]
コード例 #23
0
def test_storage_max_volume_nested_param():
    """Test that a max_volume can be used with a Parameter with children.
    """

    model = Model(
        start=pandas.to_datetime('2016-01-01'),
        end=pandas.to_datetime('2016-01-01')
    )

    storage = Storage(model, 'storage', num_inputs=1, num_outputs=0)
    otpt = Output(model, 'output', max_flow=99999, cost=-99999)
    storage.connect(otpt)

    p = AggregatedParameter(model, [ConstantParameter(model, 20.0), ConstantParameter(model, 20.0)], agg_func='sum')

    storage.max_volume = p
    storage.initial_volume = 10.0

    model.setup()
    np.testing.assert_allclose(storage.current_pc, 0.25)
コード例 #24
0
    def test_1st_order_with_parameter(self, simple_linear_model):
        """ Test 1st order with a `Parameter` """
        model = simple_linear_model

        x = 2.0
        p1 = Polynomial1DParameter(model, [0.5, np.pi], parameter=ConstantParameter(model, x))

        @assert_rec(model, p1)
        def expected_func(timestep, scenario_index):
            return 0.5 + np.pi * x
        model.run()
コード例 #25
0
def test_control_curve_interpolated(model, use_parameters):
    m = model
    m.timestepper.delta = 200

    s = m.nodes['Storage']
    o = m.nodes['Output']
    s.connect(o)

    cc = ConstantParameter(model, 0.8)
    values = [20.0, 5.0, 0.0]

    if use_parameters:
        # Create the parameter using parameters for the values
        parameters = [ConstantParameter(model, v) for v in values]
        s.cost = p = ControlCurveInterpolatedParameter(model,
                                                       s,
                                                       cc,
                                                       parameters=parameters)
    else:
        # Create the parameter using a list of values
        s.cost = p = ControlCurveInterpolatedParameter(model, s, cc, values)

    @assert_rec(model, p)
    def expected_func(timestep, scenario_index):
        v = s.initial_volume
        c = cc.value(timestep, scenario_index)
        if c == 1.0 and v == 100.0:
            expected = values[1]
        elif c == 0.0 and v == 0.0:
            expected = values[1]
        else:
            expected = np.interp(v / 100.0, [0.0, c, 1.0], values[::-1])
        return expected

    for control_curve in (0.0, 0.8, 1.0):
        cc.set_double_variables(np.array([
            control_curve,
        ]))
        for initial_volume in (0.0, 10.0, 50.0, 80.0, 90.0, 100.0):
            s.initial_volume = initial_volume
            model.run()
コード例 #26
0
    def test_2nd_order_with_parameter(self, simple_linear_model):
        """ Test 2nd order with a `Parameter` """
        model = simple_linear_model

        x = 2.0
        px = ConstantParameter(model, x)
        p1 = Polynomial1DParameter(model, [0.5, np.pi, 3.0], parameter=px)

        @assert_rec(model, p1)
        def expected_func(timestep, scenario_index):
            return 0.5 + np.pi*x + 3.0*x**2
        model.run()
コード例 #27
0
ファイル: test_control_curves.py プロジェクト: jetuk/pywr
def test_control_curve_interpolated(model):
    m = model
    m.scenarios.setup()
    si = ScenarioIndex(0, np.array([0], dtype=np.int32))

    s = Storage(m, 'Storage', max_volume=100.0)

    cc = ConstantParameter(0.8)
    values = [20.0, 5.0, 0.0]
    s.cost = ControlCurveInterpolatedParameter(s, cc, values)
    s.setup(m)

    for v in (0.0, 10.0, 50.0, 80.0, 90.0, 100.0):
        s.initial_volume = v
        s.reset()
        assert_allclose(s.get_cost(m.timestepper.current, si), np.interp(v/100.0, [0.0, 0.8, 1.0], values[::-1]))

    # special case when control curve is 100%
    cc.update(np.array([1.0,]))
    s.initial_volume == 100.0
    s.reset()
    assert_allclose(s.get_cost(m.timestepper.current, si), values[1])

    # special case when control curve is 0%
    cc.update(np.array([0.0,]))
    s.initial_volume == 0.0
    s.reset()
    assert_allclose(s.get_cost(m.timestepper.current, si), values[0])
コード例 #28
0
    def _make_weather_nodes(self, model, weather, cost):

        if not isinstance(self.area, Parameter):
            raise ValueError(
                'Weather nodes can only be created if an area Parameter is given.'
            )

        rainfall = weather['rainfall'].astype(np.float64)
        rainfall_param = MonthlyProfileParameter(model, rainfall)

        evaporation = weather['evaporation'].astype(np.float64)
        evaporation_param = MonthlyProfileParameter(model, evaporation)

        # Assume rainfall/evap is mm/day
        # Need to convert:
        #   Mm2 -> m2
        #   mm/day -> m/day
        #   m3/day -> Mm3/day
        # TODO allow this to be configured
        const = ConstantParameter(model, 1e6 * 1e-3 * 1e-6)

        # Create the flow parameters multiplying area by rate of rainfall/evap
        rainfall_flow_param = AggregatedParameter(
            model, [rainfall_param, const, self.area], agg_func='product')
        evaporation_flow_param = AggregatedParameter(
            model, [evaporation_param, const, self.area], agg_func='product')

        # Create the nodes to provide the flows
        rainfall_node = Input(model,
                              '{}.rainfall'.format(self.name),
                              parent=self)
        rainfall_node.max_flow = rainfall_flow_param
        rainfall_node.cost = cost

        evporation_node = Output(model,
                                 '{}.evaporation'.format(self.name),
                                 parent=self)
        evporation_node.max_flow = evaporation_flow_param
        evporation_node.cost = cost

        rainfall_node.connect(self)
        self.connect(evporation_node)
        self.rainfall_node = rainfall_node
        self.evaporation_node = evporation_node

        # Finally record these flows
        self.rainfall_recorder = NumpyArrayNodeRecorder(
            model, rainfall_node, name=f'__{rainfall_node.name}__:rainfall')
        self.evaporation_recorder = NumpyArrayNodeRecorder(
            model,
            evporation_node,
            name=f'__{evporation_node.name}__:evaporation')
コード例 #29
0
ファイル: test_parameters.py プロジェクト: Batch21/pywr
def test_orphaned_components(simple_linear_model):
    model = simple_linear_model
    model.nodes["Input"].max_flow = ConstantParameter(model, 10.0)

    result = model.find_orphaned_parameters()
    assert (not result)
    # assert that warning not raised by check
    with pytest.warns(None) as record:
        model.check()
    for w in record:
        if isinstance(w, OrphanedParameterWarning):
            pytest.fail("OrphanedParameterWarning raised unexpectedly!")

    # add some orphans
    orphan1 = ConstantParameter(model, 5.0)
    orphan2 = ConstantParameter(model, 10.0)
    orphans = {orphan1, orphan2}
    result = model.find_orphaned_parameters()
    assert (orphans == result)

    with pytest.warns(OrphanedParameterWarning):
        model.check()
コード例 #30
0
    def test_1st(self, simple_storage_model):
        """ Test 1st order """
        model = simple_storage_model
        stg = model.nodes['Storage']

        x = 2.0
        y = stg.initial_volume
        coefs = [[0.5, np.pi], [2.5, 0.3]]

        p1 = Polynomial2DStorageParameter(model, coefs, stg, ConstantParameter(model, x))

        @assert_rec(model, p1)
        def expected_func(timestep, scenario_index):
            return 0.5 + np.pi*x + 2.5*y+ 0.3*x*y
        model.setup()
        model.step()