Exemple #1
0
 def load(cls, data, model):
     mrf = load_parameter(model, data.pop("mrf", 0.0))
     mrf_cost = load_parameter(model, data.pop("mrf_cost", 0.0))
     unconstrained_cost = load_parameter(model, data.pop("unconstrained_cost", 0.0))
     del data["type"]
     node = cls(model, mrf=mrf, mrf_cost=mrf_cost, unconstrained_cost=unconstrained_cost, **data)
     return node
Exemple #2
0
 def load(cls, data, model):
     mrf = load_parameter(model, data.pop("mrf"))
     mrf_cost = load_parameter(model, data.pop("mrf_cost"))
     cost = load_parameter(model, data.pop("cost", 0.0))
     del (data["type"])
     node = cls(model, mrf=mrf, mrf_cost=mrf_cost, cost=cost, **data)
     return node
Exemple #3
0
    def load(cls, data, model):
        # max_flow and cost should be lists of parameter definitions
        max_flow = [load_parameter(model, p) for p in data.pop('max_flow')]
        cost = [load_parameter(model, p) for p in data.pop('cost')]

        del (data["type"])
        return cls(model, max_flow=max_flow, cost=cost, **data)
Exemple #4
0
    def load(cls, data, model):
        name = data.pop('name')

        cost = data.pop('cost', 0.0)
        min_flow = data.pop('min_flow', None)
        max_flow = data.pop('max_flow', None)

        data.pop('type')
        node = cls(model=model, name=name,
                   **data)

        cost = load_parameter(model, cost)
        min_flow = load_parameter(model, min_flow)
        max_flow = load_parameter(model, max_flow)
        if cost is None:
            cost = 0.0
        if min_flow is None:
            min_flow = 0.0
        if max_flow is None:
            max_flow = np.inf
        node.cost = cost
        node.min_flow = min_flow
        node.max_flow = max_flow

        return node
Exemple #5
0
    def load(cls, data, model):
        name = data.pop('name')
        num_inputs = int(data.pop('inputs', 1))
        num_outputs = int(data.pop('outputs', 1))

        if 'initial_volume' not in data and 'initial_volume_pc' not in data:
            raise ValueError(
                'Initial volume must be specified in absolute or relative terms.'
            )

        initial_volume = data.pop('initial_volume', 0.0)
        initial_volume_pc = data.pop('initial_volume_pc', None)
        max_volume = data.pop('max_volume')
        min_volume = data.pop('min_volume', 0.0)
        level = data.pop('level', None)
        area = data.pop('area', None)
        cost = data.pop('cost', 0.0)

        data.pop('type', None)
        # Create the instance
        node = cls(model=model,
                   name=name,
                   num_inputs=num_inputs,
                   num_outputs=num_outputs,
                   **data)

        # Load the parameters after the instance has been created to prevent circular
        # loading errors

        # Try to coerce initial volume to float.
        try:
            initial_volume = float(initial_volume)
        except TypeError:
            initial_volume = load_parameter_values(model, initial_volume)
        node.initial_volume = initial_volume
        node.initial_volume_pc = initial_volume_pc

        max_volume = load_parameter(model, max_volume)
        if max_volume is not None:
            node.max_volume = max_volume

        min_volume = load_parameter(model, min_volume)
        if min_volume is not None:
            node.min_volume = min_volume

        cost = load_parameter(model, cost)
        if cost is None:
            cost = 0.0
        node.cost = cost

        if level is not None:
            level = load_parameter(model, level)
        node.level = level

        if area is not None:
            area = load_parameter(model, area)
        node.area = area

        return node
Exemple #6
0
 def load(cls, data, model):
     name = data.pop('name')
     costs = data.pop('cost')
     max_flows = data.pop('max_flow')
     data.pop('type')
     costs = [load_parameter(model, c) for c in costs]
     max_flows = [load_parameter(model, mf) for mf in max_flows]
     return cls(model, name, cost=costs, max_flow=max_flows, **data)
Exemple #7
0
 def load(cls, data, model):
     cost = load_parameter(model, data.pop('cost', 0.0))
     mrf_cost = load_parameter(model, data.pop('mrf_cost', 0.0))
     mrf = load_parameter(model, data.pop('mrf', 0.0))
     name = data.pop("name")
     data.pop("type", None)
     parameter = cls(model, name, mrf=mrf, cost=cost, mrf_cost=mrf_cost, **data)
     return parameter
Exemple #8
0
 def load(cls, data, model):
     base_flow = load_parameter(model, data.pop("base_flow", 0.0))
     base_cost = load_parameter(model, data.pop("base_cost", 0.0))
     excess_cost = load_parameter(model, data.pop("excess_cost", 0.0))
     # turbine_capacity = load_parameter(model, data.pop("turbine_capacity", 0.0))
     # unconstrained_cost = load_parameter(model, data.pop("unconstrained_cost", 0.0))
     del (data["type"])
     node = cls(model, base_flow=base_flow, base_cost=base_cost, excess_cost=excess_cost, **data)
     return node
Exemple #9
0
    def __init__(self, *args, **kwargs):
        """Initialise a new RiverSplit instance

        """
        cost = load_parameter(self.model, kwargs.pop('cost', 0.0))
        mrf_cost = load_parameter(self.model, kwargs.pop('mrf_cost', 0.0))
        kwargs['cost'] = [mrf_cost, cost]
        mrf = load_parameter(self.model, kwargs.pop('mrf', 0.0))
        kwargs['max_flow'] = [mrf, None]
        super(RiverSplitWithGauge, self).__init__(*args, **kwargs)
Exemple #10
0
 def load(cls, model, data):
     from pywr.parameters import load_parameter
     threshold = data.pop("threshold")
     try:
         threshold = load_parameter(model, threshold)
     except KeyError:
         threshold = load_recorder(model, threshold)
     tracked_param = data.pop("tracked_parameter", None)
     if tracked_param:
         tracked_param = load_parameter(model, tracked_param)
     return cls(model, threshold, tracked_parameter=tracked_param, **data)
Exemple #11
0
    def finalise_load(self):
        """Finish loading a node by converting parameter name references to instance references."""
        for key, parameter_data in self.__parameters_to_load.items():
            if isinstance(parameter_data, list):
                # List of parameter references
                parameter = [load_parameter(self.model, d) for d in parameter_data]
            else:
                parameter = load_parameter(self.model, parameter_data)

            setattr(self, key, parameter)
        del self.__parameters_to_load
Exemple #12
0
    def load(cls, data, model):
        # max_flow and cost should be lists of parameter definitions
        max_flow = [load_parameter(model, p) for p in data.pop('max_flow')]
        cost = [load_parameter(model, p) for p in data.pop('cost')]
        factors = AggregatedNode.load_factors(model, data)

        del (data["type"])
        return cls(model,
                   max_flow=max_flow,
                   cost=cost,
                   factors=factors,
                   **data)
Exemple #13
0
    def load(cls, model, data):
        node = model._get_node_from_ref(model, data.pop("node"))
        water_elevation_reservoir = None
        water_elevation_parameter = None
        if node.water_elevation_reservoir:
            water_elevation_reservoir = model._get_node_from_ref(
                model, node.water_elevation_reservoir)
        elif node.water_elevation_parameter:
            water_elevation_parameter = load_parameter(
                model, node.water_elevation_parameter)
        else:
            water_elevation_parameter = node.head

        data['efficiency'] = node.efficiency
        data['tailwater_elevation'] = node.tailwater_elevation

        # For now, we add this flow unit conversion here
        # conversion is from mcm (model) to cms (energy calculation)
        data['flow_unit_conversion'] = 1 / 0.0864

        # For now, we add the energy unit conversion here
        # conversion is from W (J/s) to MWh
        data['energy_unit_conversion'] = 24 / 1e6

        return cls(model,
                   node,
                   water_elevation_parameter=water_elevation_parameter,
                   water_elevation_reservoir=water_elevation_reservoir,
                   **data)
Exemple #14
0
def test_daily_profile_control_curve(simple_linear_model):
    """ Test `DailyProfileControlCurveParameter` """
    model = simple_linear_model
    s = Storage(model, 'Storage', max_volume=100.0)
    l = Link(model, 'Link2')

    data = {
        'type': 'dailyprofilecontrolcurve',
        'control_curves': [0.8, 0.6],
        'values': [[1.0] * 366, [0.7] * np.arange(366), [0.3] * 366],
        'storage_node': 'Storage'
    }

    l.max_flow = p = load_parameter(model, data)
    model.setup()

    @assert_rec(model, p)
    def expected_func(timestep, scenario_index):
        v = s.initial_volume
        doy = timestep.dayofyear
        if v >= 80.0:
            expected = 1.0
        elif v >= 60:
            expected = 0.7 * (doy - 1)
        else:
            expected = 0.3

        return expected

    for initial_volume in (90, 70, 30):
        s.initial_volume = initial_volume
        model.run()
Exemple #15
0
    def test_load_wth_scaling(self, simple_storage_model):
        model = simple_storage_model
        stg = model.nodes['Storage']

        x = 2.0
        y = stg.initial_volume / stg.max_volume
        data = {
            "type": "polynomial2dstorage",
            "coefficients": [[0.5, np.pi], [2.5, 0.3]],
            "use_proportional_volume": True,
            "parameter": {
                "type": "constant",
                "value": x
            },
            "storage_node": "Storage",
            "storage_scale": 1.3,
            "storage_offset": 0.75,
            "parameter_scale": 1.25,
            "parameter_offset": -0.5
        }

        p1 = load_parameter(model, data)

        # Scaled parameters
        x = x * 1.25 - 0.5
        y = y * 1.3 + 0.75

        @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()
Exemple #16
0
def test_parameter_registry_overwrite(model):
    # define a parameter
    class NewParameter(Parameter):
        DATA = 42

        def __init__(self, model, values, *args, **kwargs):
            super(NewParameter, self).__init__(model, *args, **kwargs)
            self.values = values

    NewParameter.register()

    # re-define a parameter
    class NewParameter(IndexParameter):
        DATA = 43

        def __init__(self, model, values, *args, **kwargs):
            super(NewParameter, self).__init__(model, *args, **kwargs)
            self.values = values

    NewParameter.register()

    data = {"type": "new", "values": 0}
    parameter = load_parameter(model, data)

    # parameter is instance of new class, not old class
    assert (isinstance(parameter, NewParameter))
    assert (parameter.DATA == 43)
Exemple #17
0
    def test_parameter_threshold_parameter(self, simple_linear_model,
                                           threshold):
        """ Test ParameterThresholdParameter """
        m = simple_linear_model
        m.nodes['Input'].max_flow = 10.0
        m.nodes['Output'].cost = -10.0

        data = {
            "type": "parameterthreshold",
            "parameter": {
                "type": "constant",
                "value": 3.0
            },
            "threshold": threshold,
            "predicate": "<"
        }

        p1 = load_parameter(m, data)

        si = ScenarioIndex(0, np.array([0], dtype=np.int32))

        m.setup()
        m.step()
        # value < 5
        assert p1.index(m.timestepper.current, si) == 1

        p1.param.update(np.array([
            8.0,
        ]))
        m.setup()
        m.step()
        # flow < 5
        assert p1.index(m.timestepper.current, si) == 0
    def test_binary_step(self, simple_linear_model, internal_value, max_output,
                         upper_bounds):
        """Test the binary step profile parameter."""

        m = simple_linear_model
        m.timestepper.start = '2015-01-01'
        m.timestepper.end = '2015-12-31'

        if internal_value <= 0.0:
            expected_values = np.zeros(365)
        else:
            expected_values = np.ones(
                365) * max_output * internal_value / upper_bounds

        data = {
            'type': 'rectifier',
            'value': internal_value,
            'max_output': max_output,
            'upper_bounds': upper_bounds
        }

        p = load_parameter(m, data)

        @assert_rec(m, p)
        def expected_func(timestep, _scenario_index):
            return expected_values[timestep.index]

        m.run()
Exemple #19
0
 def load(cls, data, model):
     # accept plurals of max_flow and cost
     try:
         max_flow = data.pop("max_flows")
     except KeyError:
         pass
     else:
         data["max_flow"] = [load_parameter(p) for p in max_flow]
     try:
         cost = data.pop("costs")
     except KeyError:
         pass
     else:
         data["cost"] = [load_parameter(p) for p in cost]
     del(data["type"])
     return cls(model, **data)
Exemple #20
0
    def test_parameters_load(self, model):
        """ Test load of parameter lists for 'control_curves' and 'parameters' keys. """

        m = model
        s = m.nodes['Storage']

        data = {
            "type":
            "controlcurve",
            "storage_node":
            "Storage",
            "control_curves": [{
                "type": "constant",
                "value": 0.8
            }, {
                "type": "monthlyprofile",
                "values": [0.6] * 12
            }],
            "parameters": [{
                "type": "constant",
                "value": 1.0,
            }, {
                "type": "constant",
                "value": 0.7
            }, {
                "type": "constant",
                "value": 0.4
            }]
        }

        s.cost = p = load_parameter(model, data)
        assert isinstance(p, ControlCurveParameter)
        self._assert_results(m, s)
Exemple #21
0
    def test_binary_step(self, simple_linear_model, internal_value, max_output,
                         upper_bounds, min_output):
        """Test the binary step profile parameter."""

        m = simple_linear_model
        m.timestepper.start = "2015-01-01"
        m.timestepper.end = "2015-12-31"

        if internal_value <= 0.0:
            expected_values = np.zeros(365)
        else:
            range = max_output - min_output
            expected_values = np.ones(365) * (
                min_output + range * internal_value / upper_bounds)

        data = {
            "type": "rectifier",
            "value": internal_value,
            "max_output": max_output,
            "min_output": min_output,
            "upper_bounds": upper_bounds,
        }

        p = load_parameter(m, data)

        @assert_rec(m, p)
        def expected_func(timestep, _scenario_index):
            return expected_values[timestep.index]

        m.run()
Exemple #22
0
    def test_binary_step(self, simple_linear_model, internal_value, output):
        """Test the binary step profile parameter."""

        m = simple_linear_model
        m.timestepper.start = "2015-01-01"
        m.timestepper.end = "2015-12-31"

        if internal_value <= 0.0:
            expected_values = np.zeros(365)
        else:
            expected_values = np.ones(365) * output

        data = {
            "type": "binarystep",
            "value": internal_value,
            "output": output,
        }

        p = load_parameter(m, data)

        @assert_rec(m, p)
        def expected_func(timestep, _scenario_index):
            return expected_values[timestep.index]

        m.run()
Exemple #23
0
    def test_single_cc_load(self, model):
        """ Test load from dict with 'control_curve' key

        This is different to the above test by using singular 'control_curve' key in the dict
        """
        m = model
        m.scenarios.setup()
        s = Storage(m, 'Storage', max_volume=100.0)

        data = {
            "type": "controlcurve",
            "storage_node": "Storage",
            "control_curve": 0.8,
        }

        s.cost = p = load_parameter(model, data)
        assert isinstance(p, ControlCurveParameter)

        s.setup(m)  # Init memory view on storage (bypasses usual `Model.setup`)

        si = ScenarioIndex(0, np.array([0], dtype=np.int32))
        s.initial_volume = 90.0
        m.reset()
        assert_allclose(s.get_cost(m.timestepper.current, si), 0)

        s.initial_volume = 70.0
        m.reset()
        assert_allclose(s.get_cost(m.timestepper.current, si), 1)
Exemple #24
0
    def test_parameter(cls, simple_linear_model, ptype,profile):
        model = simple_linear_model
        model.timestepper.start = "2017-01-01"
        model.timestepper.end = "2017-01-15"

        data = {
            "type": ptype,
            "parameter": {
                "name": "raw",
                "type": "dailyprofile",
                "values": profile,
            }
        }


        if ptype in ("max", "min"):
            data["threshold"] = 3

        func = {"min": min, "max": max, "negative": lambda t,x: -x, "negativemax": lambda t,x: max(t, -x)}[ptype]

        model.nodes["Input"].max_flow = parameter = load_parameter(model, data)
        model.nodes["Output"].max_flow = 9999
        model.nodes["Output"].cost = -100

        daily_profile = model.parameters["raw"]

        @assert_rec(model, parameter)
        def expected(timestep, scenario_index):
            value = daily_profile.get_value(scenario_index)
            return func(3, value)
        model.run()
Exemple #25
0
 def load(cls, data, model):
     flow = data.pop('flow', None)
     if flow is not None:
         flow = load_parameter(model, flow)
     node = super(Catchment, cls).load(data, model)
     node.flow = flow
     return node
Exemple #26
0
    def test_single_cc_load(self, model):
        """ Test load from dict with 'control_curve' key

        This is different to the above test by using singular 'control_curve' key in the dict
        """
        m = model
        s = m.nodes['Storage']

        data = {
            "type": "controlcurve",
            "storage_node": "Storage",
            "control_curve": 0.8,
        }

        s.cost = p = load_parameter(model, data)
        assert isinstance(p, ControlCurveParameter)

        @assert_rec(m, p)
        def expected_func(timestep, scenario_index):
            v = s.initial_volume
            if v >= 80.0:
                expected = 0
            else:
                expected = 1
            return expected

        for initial_volume in (90, 70):
            s.initial_volume = initial_volume
            m.run()
Exemple #27
0
    def test_with_nonstorage_load(self, model):
        """Test load from dict with 'storage_node' key."""
        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)

        data = {
            "type": "controlcurve",
            "control_curve": 0.8,
            "values": [10.0, 0.0],
            "storage_node": "Storage",
        }

        l.cost = p = load_parameter(model, data)
        assert isinstance(p, ControlCurveParameter)

        @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()
Exemple #28
0
    def test_with_nonstorage_load(self, model):
        """ Test load from dict with 'storage_node' key. """
        m = model
        s = m.nodes['Storage']
        l = Link(m, 'Link')

        data = {
            "type": "controlcurve",
            "control_curve": 0.8,
            "values": [10.0, 0.0],
            "storage_node": "Storage"
        }

        l.cost = p = load_parameter(model, data)
        assert isinstance(p, ControlCurveParameter)

        @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()
Exemple #29
0
    def test_with_nonstorage_load(self, model):
        """ Test load from dict with 'storage_node' key. """
        m = model
        m.scenarios.setup()
        s = Storage(m, 'Storage', max_volume=100.0)
        l = Link(m, 'Link')

        data = {
            "type": "controlcurve",
            "control_curve": 0.8,
            "values": [10.0, 0.0],
            "storage_node": "Storage"
        }

        l.cost = p = load_parameter(model, data)
        assert isinstance(p, ControlCurveParameter)

        s.setup(m)  # Init memory view on storage (bypasses usual `Model.setup`)
        si = ScenarioIndex(0, np.array([0], dtype=np.int32))
        print(s.volume)
        assert_allclose(l.get_cost(m.timestepper.current, si), 0.0)
        # When storage volume changes, the cost of the link changes.
        s.initial_volume = 90.0
        m.reset()
        assert_allclose(l.get_cost(m.timestepper.current, si), 10.0)
Exemple #30
0
    def test_divsion(self, simple_linear_model):
        model = simple_linear_model
        model.timestepper.start = "2017-01-01"
        model.timestepper.end = "2017-01-15"

        profile = list(range(1, 367))

        data = {
            "type": "division",
            "numerator": {
                "name": "raw",
                "type": "dailyprofile",
                "values": profile,
            },
            "denominator": {
                "type": "constant",
                "value": 123.456
            }
        }

        model.nodes["Input"].max_flow = parameter = load_parameter(model, data)
        model.nodes["Output"].max_flow = 9999
        model.nodes["Output"].cost = -100

        daily_profile = model.parameters["raw"]

        @assert_rec(model, parameter)
        def expected(timestep, scenario_index):
            value = daily_profile.get_value(scenario_index)
            return value / 123.456

        model.run()