Overflow modelling#
This example will demonstrate overflow modelling based on the basic example. The recommended method of modelling overflow is using the river object. The river upstream_elevation should be equal to the reservoir hrl. The river may also use a flow description, such as up_head_flow_curve or width_depth_curve to describe the head dependent flow. Additionally, flow_cost can be used to penalize overflow.
The model setup is available in the following formats:
pyshop
The example below illustrates overflow modelling in SHOP:
from pyshop import ShopSession
from basic import build_model
import pandas as pd
import plotly.graph_objs as go
shop = ShopSession()
build_model(shop)
starttime = shop.get_time_resolution()['starttime']
# Add spill river and set elevation to hrl
spill_river = shop.model.river.add_object('SpillRiver')
spill_river.upstream_elevation.set(100)
spill_river.downstream_elevation.set(90)
# Connect objects in watercourse
shop.model.reservoir.Reservoir1.connect_to(spill_river)
spill_river.connect_to(shop.model.reservoir.Reservoir2)
# Add river to describe flow out of reservoir below. (Crest at 43 meters.)
discharge_river = shop.model.river.add_object('DischargeRiver')
discharge_river.upstream_elevation.set(43)
discharge_river.downstream_elevation.set(0)
discharge_river.width_depth_curve.set(pd.Series(index=[10, 10], data=[0, 7]))
shop.model.reservoir.Reservoir2.connect_to(discharge_river)
# Set start level to almost full, high inflow and scheduled production to ensure overflow
shop.model.reservoir.Reservoir1.start_head.set(98)
shop.model.reservoir.Reservoir1.inflow.set(200)
shop.model.generator.P1G1.production_schedule.set(50)
shop.start_sim([], [3])
spill_flow = spill_river.flow.get()
fig = go.Figure()
fig.add_trace(go.Scatter(x=spill_flow.index, y=spill_flow.values, name="Spill gate flow"))
fig.update_layout(xaxis_title="Time", yaxis_title="Flow")
fig.show()
In the illustrated case, all water above the maximum volume is routed to the spill gate immediately. Alternatively, a flow function can be used as shown below where the overflow is given by a width_depth_curve:
shop = ShopSession()
build_model(shop)
starttime = shop.get_time_resolution()['starttime']
# Add spill river and set elevation to hrl
spill_river = shop.model.river.add_object('SpillRiver')
spill_river.upstream_elevation.set(100)
spill_river.downstream_elevation.set(90)
# Use widht depth curve for overflow description
spill_river.width_depth_curve.set(pd.Series(index=[30, 30], data=[0, 1]))
# Connect objects in watercourse
shop.model.reservoir.Reservoir1.connect_to(spill_river)
spill_river.connect_to(shop.model.reservoir.Reservoir2)
# Add river to describe flow out of reservoir below. (Crest at 43 meters.)
discharge_river = shop.model.river.add_object('DischargeRiver')
discharge_river.upstream_elevation.set(43)
discharge_river.downstream_elevation.set(0)
discharge_river.width_depth_curve.set(pd.Series(index=[10, 10], data=[0, 7]))
shop.model.reservoir.Reservoir2.connect_to(discharge_river)
# Set start level to almost full, high inflow and scheduled production to ensure overflow
shop.model.reservoir.Reservoir1.start_head.set(98)
shop.model.reservoir.Reservoir1.inflow.set(200)
shop.model.generator.P1G1.production_schedule.set(50)
shop.start_sim([], [3])
spill_flow = spill_river.flow.get()
fig = go.Figure()
fig.add_trace(go.Scatter(x=spill_flow.index, y=spill_flow.values, name="Spill gate flow"))
fig.update_layout(xaxis_title="Time", yaxis_title="Flow")
fig.show()
Overflow with gate#
Before river was introduced in SHOP, overflow was modelled using gate. This is still supported and requires that the relation between level and overflow is given by flow_descr. Moreover, the upstream reservoir and the spill gate must be connected using the spill connection type. The example below show how the overflow can be modelled using a spill gate.
shop = ShopSession()
build_model(shop)
starttime = shop.get_time_resolution()['starttime']
# Add spill gate and set flow_descr
spill_gate = shop.model.gate.add_object('SpillGate')
shop.model.reservoir.Reservoir1.flow_descr.set(pd.Series([0, 1000], index=[100, 101]))
# Connect objects in watercourse
shop.model.reservoir.Reservoir1.connect_to(spill_gate, 'spill')
spill_river.connect_to(shop.model.reservoir.Reservoir2)
# Add river to describe flow out of reservoir below. (Crest at 43 meters.)
discharge_river = shop.model.river.add_object('DischargeRiver')
discharge_river.upstream_elevation.set(43)
discharge_river.downstream_elevation.set(0)
discharge_river.width_depth_curve.set(pd.Series(index=[10, 10], data=[0, 7]))
shop.model.reservoir.Reservoir2.connect_to(discharge_river)
# Set start level to almost full, high inflow and scheduled production to ensure overflow
shop.model.reservoir.Reservoir1.start_head.set(98)
shop.model.reservoir.Reservoir1.inflow.set(200)
shop.model.generator.P1G1.production_schedule.set(50)
shop.start_sim([], [3])
spill_flow = spill_gate.discharge.get()
fig = go.Figure()
fig.add_trace(go.Scatter(x=spill_flow.index, y=spill_flow.values, name="Spill gate flow"))
fig.update_layout(xaxis_title="Time", yaxis_title="Flow")
fig.show()