def test_virtual_storage_duplicate_route(): """ Test the VirtualStorage node """ model = pywr.core.Model() inpt = Input(model, "Input", max_flow=20) lnk = Link(model, "Link") inpt.connect(lnk) otpt = Output(model, "Output", max_flow=10, cost=-10.0) lnk.connect(otpt) vs = pywr.core.VirtualStorage(model, "Licence", [lnk, otpt], factors=[0.5, 1.0], initial_volume=10.0, max_volume=10.0) model.setup() assert_allclose(vs.volume, [10], atol=1e-7) model.step() assert_allclose(otpt.flow, [10 / 1.5], atol=1e-7) assert_allclose(vs.volume, [0], atol=1e-7) model.step() assert_allclose(otpt.flow, [0], atol=1e-7) assert_allclose(vs.volume, [0], atol=1e-7)
def test_initial_volume(self): """Test RollingVirtualStorage node behaviour when initial volume is less than max volume""" model = pywr.core.Model(timestep="1D") inpt = Input(model, "Input", max_flow=0.0) lnk = Link(model, "Link") inpt.connect(lnk) otpt = Output(model, "Output", max_flow=10, cost=-10.0) lnk.connect(otpt) vs = pywr.core.RollingVirtualStorage(model, "Licence", [lnk], timesteps=3, initial_volume=70.0, max_volume=100.0) model.setup() assert_allclose(vs.volume, [70.0], atol=1e-7) model.step() assert_allclose(otpt.flow, [0.0], atol=1e-7) assert_allclose(vs.volume, [85.0], atol=1e-7) model.step() assert_allclose(otpt.flow, [0.0], atol=1e-7) assert_allclose(vs.volume, [100.0], atol=1e-7) model.step() assert_allclose(otpt.flow, [0.0], atol=1e-7) assert_allclose(vs.volume, [100.0], atol=1e-7)
def test_virtual_storage(solver): """ Test the VirtualStorage node """ model = pywr.core.Model(solver=solver) inpt = Input(model, "Input", max_flow=20) lnk = Link(model, "Link") inpt.connect(lnk) otpt = Output(model, "Output", max_flow=10, cost=-10.0) lnk.connect(otpt) vs = pywr.core.VirtualStorage(model, "Licence", [lnk], initial_volume=10.0, max_volume=10.0) model.setup() assert_allclose(vs.volume, [10], atol=1e-7) model.step() assert_allclose(otpt.flow, [10], atol=1e-7) assert_allclose(vs.volume, [0], atol=1e-7) model.step() assert_allclose(otpt.flow, [0], atol=1e-7) assert_allclose(vs.volume, [0], atol=1e-7)
def __init__(self, model, name, *args, **kwargs): reuse_proportion = kwargs.pop('reuse_proportion') super().__init__(model, name, *args, **kwargs) effluent_node = Link(model, f'{name}.effluent', parent=self) reuse_node = Link(model, f'{name}.reuse', parent=self) self.connect(effluent_node) self.connect(reuse_node) reuse_factors = [1 - reuse_proportion, reuse_proportion] self.reuse_aggregated_node = AggregatedNode(model, f'{name}.reuse_aggregated', factors=reuse_factors)
def create_model(): # create a model model = Model(start="2016-01-01", end="2019-12-31", timestep=7) # create three nodes (an input, a link, and an output) A = Input(model, name="A", max_flow=10.0) B = Link(model, name="B", cost=10.0) C = Output(model, name="C", max_flow=5.0, cost=-20.0) # connect the nodes together A.connect(B) B.connect(C) return model
def test_transfer2(pywr_solver, size): """Test a simple transfer model. """ model = Model() Scenario(model, name='test', size=size) demands = [9.47, 7.65, 9.04, 9.56, 9.44] supply = [4.74, 6.59, 12.04, 8.81, 11.75] for i, (s, d) in enumerate(zip(supply, demands)): s = Input(model, name=f'supply-{i}', max_flow=s) lnk = Link(model, name=f'wtw-{i}') d = Output(model, name=f'demand-{i}', max_flow=d, cost=-10.0) s.connect(lnk) lnk.connect(d) transfer04 = Link(model, name='transfer-04', max_flow=15.36, cost=1.0) model.nodes['wtw-0'].connect(transfer04) transfer04.connect(model.nodes['wtw-4']) model.setup() model.step() expected_supply = [4.74, 6.59, 9.04, 8.81, 9.44] for i, expected in enumerate(expected_supply): assert_allclose(model.nodes[f'supply-{i}'].flow, [expected] * size) assert_allclose(transfer04.flow, [0.0] * size, atol=1e-8)
def test_run(self, from_json): """Test RollingVirtualStorage node behaviour.""" if from_json: model = load_model('rolling_virtual_storage.json') vs = model.nodes['Licence'] otpt = model.nodes['Output'] else: model = pywr.core.Model() inpt = Input(model, "Input", max_flow=20) lnk = Link(model, "Link") inpt.connect(lnk) otpt = Output(model, "Output", max_flow=15, cost=-10.0) lnk.connect(otpt) vs = pywr.core.RollingVirtualStorage(model, "Licence", [lnk], days=3, initial_volume=30.0, max_volume=30.0) model.setup() assert_allclose(vs.volume, [30], atol=1e-7) model.step() assert_allclose(otpt.flow, [15], atol=1e-7) assert_allclose(vs.volume, [15], atol=1e-7) model.step() assert_allclose(otpt.flow, [15], atol=1e-7) assert_allclose(vs.volume, [0], atol=1e-7) model.step() assert_allclose(otpt.flow, [0], atol=1e-7) # End of third day the flow from the first day is return to the licence assert_allclose(vs.volume, [15], atol=1e-7) model.step() assert_allclose(otpt.flow, [15], atol=1e-7) assert_allclose(vs.volume, [15], atol=1e-7)
def test_run_weekly(self): """Test RollingVirtualStorage node behaviour with a weekly timestep.""" model = pywr.core.Model(timestep='7D') inpt = Input(model, "Input", max_flow=20) lnk = Link(model, "Link") inpt.connect(lnk) otpt = Output(model, "Output", max_flow=10, cost=-10.0) lnk.connect(otpt) vs = pywr.core.RollingVirtualStorage(model, "Licence", [lnk], timesteps=3, initial_volume=100.0, max_volume=100.0) model.setup() assert_allclose(vs.volume, [100.0], atol=1e-7) model.step() assert_allclose(otpt.flow, [10.0], atol=1e-7) assert_allclose(vs.volume, [30.0], atol=1e-7) model.step() assert_allclose(otpt.flow, [30.0 / 7], atol=1e-7) assert_allclose(vs.volume, [0], atol=1e-7) model.step() assert_allclose(otpt.flow, [0], atol=1e-7) # End of third day the flow from the first day is return to the licence assert_allclose(vs.volume, [70.0], atol=1e-7) model.step() assert_allclose(otpt.flow, [10.0], atol=1e-7) assert_allclose(vs.volume, [30.0], atol=1e-7)
def test_max_vol_param_zero_initial_vol(self): """Test RollingVirtualStorage node behaviour when initial volume is zero""" model = pywr.core.Model(timestep="1D") inpt = Input(model, "Input", max_flow=0.0) lnk = Link(model, "Link") inpt.connect(lnk) otpt = Output(model, "Output", max_flow=10, cost=-10.0) lnk.connect(otpt) mx_vol = ConstantParameter(model, 100) pywr.core.RollingVirtualStorage( model, "Licence", [lnk], timesteps=3, initial_volume=0.0, initial_volume_pc=0.0, max_volume=mx_vol, ) with pytest.raises(ValueError): model.setup()
def test_reservoir_circle(): """ Issue #140. A model with a circular route, from a reservoir Input back around to it's own Output. Demand ^ | Reservoir <- Pumping | ^ v | Compensation | | | v | Catchment -> River 1 -> River 2 ----> MRFA -> Waste | ^ |---> MRFB ----| """ model = Model() catchment = Input(model, "catchment", max_flow=500, min_flow=500) reservoir = Storage(model, "reservoir", max_volume=10000, initial_volume=5000) demand = Output(model, "demand", max_flow=50, cost=-100) pumping_station = Link(model, "pumping station", max_flow=100, cost=-10) river1 = Link(model, "river1") river2 = Link(model, "river2") compensation = Link(model, "compensation", cost=600) mrfA = Link(model, "mrfA", cost=-500, max_flow=50) mrfB = Link(model, "mrfB") waste = Output(model, "waste") catchment.connect(river1) river1.connect(river2) river2.connect(mrfA) river2.connect(mrfB) mrfA.connect(waste) mrfB.connect(waste) river2.connect(pumping_station) pumping_station.connect(reservoir) reservoir.connect(compensation) compensation.connect(river1) reservoir.connect(demand) model.check() model.setup() # not limited by mrf, pump capacity is constraint model.step() assert_allclose(catchment.flow, 500) assert_allclose(waste.flow, 400) assert_allclose(compensation.flow, 0) assert_allclose(pumping_station.flow, 100) assert_allclose(demand.flow, 50) # limited by mrf catchment.min_flow = catchment.max_flow = 100 model.step() assert_allclose(waste.flow, 50) assert_allclose(compensation.flow, 0) assert_allclose(pumping_station.flow, 50) assert_allclose(demand.flow, 50) # reservoir can support mrf, but doesn't need to compensation.cost = 200 model.step() assert_allclose(waste.flow, 50) assert_allclose(compensation.flow, 0) assert_allclose(pumping_station.flow, 50) assert_allclose(demand.flow, 50) # reservoir supporting mrf catchment.min_flow = catchment.max_flow = 0 model.step() assert_allclose(waste.flow, 50) assert_allclose(compensation.flow, 50) assert_allclose(pumping_station.flow, 0) assert_allclose(demand.flow, 50)
def test_transfer(pywr_solver, size): """Test a simple transfer model. """ model = Model() Scenario(model, name='test', size=size) supply1 = Input(model, name='supply-1', max_flow=5.0) wtw1 = Link(model, name='wtw-1') demand1 = Output(model, name='demand-1', max_flow=10.0, cost=-10.0) supply1.connect(wtw1) wtw1.connect(demand1) supply2 = Input(model, name='supply-2', max_flow=15.0) wtw2 = Link(model, name='wtw-2') demand2 = Output(model, name='demand-2', max_flow=10.0, cost=-10.0) supply2.connect(wtw2) wtw2.connect(demand2) transfer21 = Link(model, name='transfer-12', max_flow=2.0, cost=1.0) wtw2.connect(transfer21) transfer21.connect(wtw1) model.setup() model.step() assert_allclose(supply1.flow, [5.0] * size) assert_allclose(demand1.flow, [7.0] * size) assert_allclose(supply2.flow, [12.0] * size) assert_allclose(demand2.flow, [10.0] * size) assert_allclose(transfer21.flow, [2.0] * size)