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 https://www.pypsa.org/examples/power-to-gas-boiler-chp.html.

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".

In [1]:
import pypsa, numpy as np
In [2]:
#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,....

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.,"2nd bus efficiency","Input (optional)"]
override_component_attrs["Link"].loc["p2"] = ["series","MW",0.,"2nd bus output","Output"]
In [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)
In [4]:
network.lopf()
WARNING:pypsa.pf:No generators in sub-network 0, better hope power is already balanced
INFO:pypsa.pf:Slack bus for sub-network 0 is Frankfurt
WARNING:pypsa.pf:No generators in sub-network 1, better hope power is already balanced
INFO:pypsa.pf:Slack bus for sub-network 1 is Frankfurt heat
WARNING:pypsa.pf:No generators in sub-network 2, better hope power is already balanced
INFO:pypsa.pf:Slack bus for sub-network 2 is Frankfurt gas
INFO:pypsa.opf:Performed preliminary steps
INFO:pypsa.opf:Building pyomo model using `angles` 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: 12
  Number of variables: 10
  Number of nonzeros: 18
  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.027088403701782227
# ----------------------------------------------------------
#   Solution Information
# ----------------------------------------------------------
Solution: 
- number of solutions: 0
  number of solutions displayed: 0
Out[4]:
('ok', 'optimal')
In [5]:
network.loads_t.p
Out[5]:
Frankfurt Frankfurt heat
now 5.0 3.0
In [6]:
network.links_t.p0
Out[6]:
OCGT CHP
now 5.0 10.0
In [7]:
network.links_t.p1
Out[7]:
OCGT CHP
now -2.0 -3.0
In [8]:
network.links_t.p2
Out[8]:
OCGT CHP
now 0.0 -3.0