--- jupytext: text_representation: extension: .md format_name: myst format_version: 0.13 jupytext_version: 1.13.8 kernelspec: display_name: Python 3 (ipykernel) language: python name: python3 --- (reservoir-overflow)= # 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](river:upstream_elevation) should be equal to the [](reservoir) [hrl](reservoir:hrl). The river may also use a flow description, such as [up_head_flow_curve](river:up_head_flow_curve) or [width_depth_curve](river:width_depth_curve) to describe the head dependent flow. Additionally, [flow_cost](river:flow_cost) can be used to penalize overflow. The example below illustrates overflow modelling in SHOP: ```{code-cell} ipython3 :Collapsed: 'false' 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](river:width_depth_curve): ```{code-cell} ipython3 :Collapsed: 'false' 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 head and overflow is given by [flow_descr](reservoir: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. ```{code-cell} ipython3 :Collapsed: 'false' 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() ``` ### basic.py ```{code-cell} ipython3 :Collapsed: 'false' :tags: ['remove-input'] with open('basic.py', 'r') as f: print(f.read()) ```