def simple_gauge_model(request, solver): """ Make a simple model with a single Input and Output and RiverGauge Input -> PiecewiseLink -> Output """ in_flow, out_flow, benefit = request.param min_flow_req = 5.0 model = pywr.core.Model(solver=solver) inpt = river.Catchment(model, name="Catchment", flow=in_flow) lnk = river.RiverGauge(model, name="Gauge", mrf=min_flow_req, mrf_cost=-1.0) inpt.connect(lnk) otpt = pywr.core.Output(model, name="Demand", max_flow=out_flow, cost=-benefit) lnk.connect(otpt) default = inpt.domain expected_sent = in_flow if benefit > 1.0 else out_flow expected_node_results = { "Catchment": expected_sent, "Gauge": expected_sent, "Gauge Sublink 0": min(min_flow_req, expected_sent), "Gauge Sublink 1": expected_sent - min(min_flow_req, expected_sent), "Demand": expected_sent, } return model, expected_node_results
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)
def simple_gauge_model(request): """ Make a simple model with a single Input and Output and RiverGauge Input -> PiecewiseLink -> Output """ in_flow, out_flow, benefit = request.param min_flow_req = 5.0 model = pywr.core.Model() inpt = river.Catchment(model, name="Catchment", flow=in_flow) lnk = river.RiverGauge(model, name="Gauge", mrf=min_flow_req, benefit=1.0) inpt.connect(lnk) otpt = river.DemandCentre(model, name="Demand", min_flow=out_flow, benefit=benefit) lnk.connect(otpt) default = inpt.domain expected_requested = {default: out_flow} expected_sent = {default: in_flow if benefit > 1.0 else out_flow} expected_node_results = { "Catchment": expected_sent[default], "Gauge": 0.0, "Gauge Sublink 0": min(min_flow_req, expected_sent[default]), "Gauge Sublink 1": expected_sent[default] - min(min_flow_req, expected_sent[default]), "Demand": expected_sent[default], } return model, expected_requested, expected_sent, expected_node_results
def simple_river_split_gauge_model(): """ Make a simple model with a single Input and Output and RiverGauge :: Input -> RiverSplit -> Output 1 \\ --->--> Output 2 """ in_flow = 100.0 min_flow_req = 40.0 out_flow = 50.0 model = pywr.core.Model() inpt = river.Catchment(model, name="Catchment", flow=in_flow) lnk = river.RiverSplitWithGauge( model, name="Gauge", mrf=min_flow_req, mrf_cost=-100, slot_names=("river", "abstraction"), factors=[3, 1], ) inpt.connect(lnk) estuary = pywr.core.Output(model, name="Estuary") lnk.connect(estuary, from_slot="river") otpt = pywr.core.Output(model, name="Demand", max_flow=out_flow, cost=-10) lnk.connect(otpt, from_slot="abstraction") net_flow_after_mrf = in_flow - min_flow_req expected_node_results = { "Catchment": in_flow, "Gauge": in_flow, "Gauge Sublink 0": min_flow_req, "Gauge Sublink 1": net_flow_after_mrf * 0.75, "Gauge Sublink 2": net_flow_after_mrf * 0.25, "Demand": min(out_flow, net_flow_after_mrf * 0.25), } return model, expected_node_results