Chained Hydro-Reservoirs¶
In this example, two disconnected electrical loads are fed from two reservoirs linked by a river; the first reservoir has inflow from rain onto a water basin.
Note that the two reservoirs are tightly coupled, meaning there is no time delay between the first one emptying and the second one filling, as there would be if there were a long stretch of river between the reservoirs. The reservoirs are hence assumed to be close to each other. A time delay is currently not supported in PyPSA.
import pandas as pd
import pypsa
n = pypsa.Network()
n.set_snapshots(range(4))
Add assets to the network.
n.add("Carrier", "reservoir")
n.add("Carrier", "rain")
n.add("Bus", "0 electricity")
n.add("Bus", "1 electricity")
n.add("Bus", "0 reservoir", carrier="reservoir")
n.add("Bus", "1 reservoir", carrier="reservoir")
n.add(
"Generator",
"rain",
bus="0 reservoir",
carrier="rain",
p_nom=1000,
p_max_pu=[0.0, 0.2, 0.7, 0.4],
)
n.add("Load", "0 load", bus="0 electricity", p_set=20)
n.add("Load", "1 load", bus="1 electricity", p_set=30);
The efficiency of a river is the relation between the gravitational potential energy of 1 cubic metre of water in reservoir 0 relative to its turbine versus the potential energy of 1 cubic metre of water in reservoir 1 relative to its turbine. Water can either be spilled without generating electricity or be sent through the turbine to generate power. In both cases, the water goes into the next reservoir.
n.add(
"Link",
"spillage",
bus0="0 reservoir",
bus1="1 reservoir",
efficiency=0.5,
p_nom_extendable=True,
)
n.add(
"Link",
"0 turbine",
bus0="0 reservoir",
bus1="0 electricity",
bus2="1 reservoir",
efficiency=0.9,
efficiency2=0.5,
capital_cost=1000,
p_nom_extendable=True,
)
n.add(
"Link",
"1 turbine",
bus0="1 reservoir",
bus1="1 electricity",
efficiency=0.9,
capital_cost=1000,
p_nom_extendable=True,
)
n.add(
"Store",
"0 reservoir",
bus="0 reservoir",
e_cyclic=True,
e_nom=10_000,
)
n.add(
"Store",
"1 reservoir",
bus="1 reservoir",
e_cyclic=True,
e_nom=10_000,
);
n.optimize(n.snapshots)
print("Objective:", n.objective)
/tmp/ipykernel_3446/2004667591.py:1: FutureWarning: The default value of `include_objective_constant` will change from True to False in version 2.0. Set `include_objective_constant` explicitly to suppress this warning. Using False improves LP numerical conditioning by not including the objective constant as a variable. WARNING:pypsa.consistency:The following buses have carriers which are not defined. Run n.sanitize() to add them. Components with undefined carriers: Index(['0 electricity', '1 electricity'], dtype='object', name='name')
WARNING:pypsa.consistency:Encountered nan's in static data for columns ['efficiency2'] of component 'Link'.
INFO:linopy.model: Solve problem using Highs solver
INFO:linopy.model:Solver options: - log_to_console: False
INFO:linopy.io: Writing time: 0.04s
INFO:linopy.constants: Optimization successful: Status: ok Termination condition: optimal Solution: 35 primals, 75 duals Objective: 5.56e+04 Solver model: available Solver message: Optimal
INFO:pypsa.optimization.optimize:The shadow-prices of the constraints Generator-fix-p-lower, Generator-fix-p-upper, Link-ext-p-lower, Link-ext-p-upper, Store-fix-e-lower, Store-fix-e-upper, Store-energy_balance were not assigned to the network.
Objective: 55555.55555555556
n.generators_t.p.plot.area()
<Axes: xlabel='snapshot'>
Now, let's have look at the different outputs of the links.
n.links_t.p0.plot()
<Axes: xlabel='snapshot'>
n.links_t.p1.plot()
<Axes: xlabel='snapshot'>
n.links_t.p2.plot()
<Axes: xlabel='snapshot'>
What are the energy outputs and energy levels at the reservoirs?
pd.DataFrame({attr: n.stores_t[attr]["0 reservoir"] for attr in ["p", "e"]})
| p | e | |
|---|---|---|
| snapshot | ||
| 0 | 22.222222 | -0.000000 |
| 1 | -0.000000 | -0.000000 |
| 2 | -0.000000 | -0.000000 |
| 3 | -22.222222 | 22.222222 |
pd.DataFrame({attr: n.stores_t[attr]["1 reservoir"] for attr in ["p", "e"]})
| p | e | |
|---|---|---|
| snapshot | ||
| 0 | 22.222222 | -0.000000 |
| 1 | -0.000000 | -0.000000 |
| 2 | -0.000000 | -0.000000 |
| 3 | -22.222222 | 22.222222 |