Note
You can download this example as a Jupyter notebook or start it in interactive mode.
Multi-Link usage: CHP with fixed heat-power ratio
This notebook if a demonstration of Link with multiple outputs: Combined-Heat-and-Power (CHP) with fixed heat-power ratio
For a CHP with a more complicated heat-power feasible operational area, see the power-to-gas example
This example demonstrates a Link component with more than one bus output (“bus2” in this case). In general links can have many output buses.
In this example a CHP must be heat-following because there is no other supply of heat to the bus “Frankfurt heat”.
[1]:
import pypsa, numpy as np
First tell PyPSA that links will have a 2nd bus by overriding the component_attrs. This can be done for as many buses as you need with format busi for i = 2,3,4,5,….
[2]:
override_component_attrs = pypsa.descriptors.Dict(
{k: v.copy() for k, v in pypsa.components.component_attrs.items()}
)
override_component_attrs["Link"].loc["bus2"] = [
"string",
np.nan,
np.nan,
"2nd bus",
"Input (optional)",
]
override_component_attrs["Link"].loc["efficiency2"] = [
"static or series",
"per unit",
1.0,
"2nd bus efficiency",
"Input (optional)",
]
override_component_attrs["Link"].loc["p2"] = [
"series",
"MW",
0.0,
"2nd bus output",
"Output",
]
[3]:
network = pypsa.Network(override_component_attrs=override_component_attrs)
network.add("Bus", "Frankfurt", carrier="AC")
network.add("Load", "Frankfurt", bus="Frankfurt", p_set=5)
network.add("Bus", "Frankfurt heat", carrier="heat")
network.add("Load", "Frankfurt heat", bus="Frankfurt heat", p_set=3)
network.add("Bus", "Frankfurt gas", carrier="gas")
network.add("Store", "Frankfurt gas", e_initial=1e6, e_nom=1e6, bus="Frankfurt gas")
network.add(
"Link",
"OCGT",
bus0="Frankfurt gas",
bus1="Frankfurt",
p_nom_extendable=True,
capital_cost=600,
efficiency=0.4,
)
network.add(
"Link",
"CHP",
bus0="Frankfurt gas",
bus1="Frankfurt",
bus2="Frankfurt heat",
p_nom_extendable=True,
capital_cost=1400,
efficiency=0.3,
efficiency2=0.3,
)
[4]:
network.lopf();
WARNING:pypsa.components:Solving optimisation problem with pyomo.In PyPSA version 0.21 the default will change to ``n.lopf(pyomo=False)``.Explicitly set ``n.lopf(pyomo=True)`` to retain current behaviour.
INFO:pypsa.opf:Performed preliminary steps
INFO:pypsa.opf:Building pyomo model using `kirchhoff` formulation
INFO:pypsa.opf:Solving model using glpk
INFO:pypsa.opf:Optimization successful
# ==========================================================
# = Solver Results =
# ==========================================================
# ----------------------------------------------------------
# Problem Information
# ----------------------------------------------------------
Problem:
- Name: unknown
Lower bound: 17000.0
Upper bound: 17000.0
Number of objectives: 1
Number of constraints: 9
Number of variables: 7
Number of nonzeros: 15
Sense: minimize
# ----------------------------------------------------------
# Solver Information
# ----------------------------------------------------------
Solver:
- Status: ok
Termination condition: optimal
Statistics:
Branch and bound:
Number of bounded subproblems: 0
Number of created subproblems: 0
Error rc: 0
Time: 0.002306699752807617
# ----------------------------------------------------------
# Solution Information
# ----------------------------------------------------------
Solution:
- number of solutions: 0
number of solutions displayed: 0
/home/docs/checkouts/readthedocs.org/user_builds/pypsa/conda/v0.20.1/lib/python3.10/site-packages/pypsa/opf.py:2097: FutureWarning: In a future version, `df.iloc[:, i] = newvals` will attempt to set the values inplace instead of always setting a new array. To retain the old behavior, use either `df[df.columns[i]] = newvals` or, if columns are non-unique, `df.isetitem(i, newvals)`
network.global_constraints.loc[:, "mu"] = -get_shadows(
[5]:
network.loads_t.p
[5]:
Load | Frankfurt | Frankfurt heat |
---|---|---|
snapshot | ||
now | 5.0 | 3.0 |
[6]:
network.links_t.p0
[6]:
Link | OCGT | CHP |
---|---|---|
snapshot | ||
now | 5.0 | 10.0 |
[7]:
network.links_t.p1
[7]:
Link | OCGT | CHP |
---|---|---|
snapshot | ||
now | -2.0 | -3.0 |
[8]:
network.links_t.p2
[8]:
Link | OCGT | CHP |
---|---|---|
snapshot | ||
now | 0.0 | -3.0 |