Backpressure CHP¶
This example demonstrates how to model a Combined Heat and Power (CHP) plant with a fixed heat-power ratio, assuming that the plant is operated in backpressure mode.
For an example of a CHP plant with a more complicated heat-power feasible operational area, see the extraction-condensing CHP example. In this example, the CHP is modelled as a Link component with two output buses: one for electricity and one for heat. The CHP unit must be heat-following since there is no other supply of heat to the "Frankfurt heat" bus.
In [2]:
Copied!
import pypsa
n = pypsa.Network()
n.add("Bus", "Frankfurt", carrier="AC")
n.add("Load", "Frankfurt", bus="Frankfurt", p_set=5)
n.add("Bus", "Frankfurt heat", carrier="heat")
n.add("Load", "Frankfurt heat", bus="Frankfurt heat", p_set=3)
n.add("Bus", "Frankfurt gas", carrier="gas")
n.add("Generator", "Frankfurt gas", bus="Frankfurt gas", marginal_cost=100, p_nom=100)
n.add(
"Link",
"OCGT",
bus0="Frankfurt gas",
bus1="Frankfurt",
p_nom_extendable=True,
capital_cost=600,
efficiency=0.4, # electricity per unit of gas
)
n.add(
"Link",
"CHP",
bus0="Frankfurt gas",
bus1="Frankfurt",
bus2="Frankfurt heat",
p_nom_extendable=True,
capital_cost=1400,
efficiency=0.3, # electricity per unit of gas
efficiency2=0.3, # heat per unit of gas
)
n.optimize();
import pypsa
n = pypsa.Network()
n.add("Bus", "Frankfurt", carrier="AC")
n.add("Load", "Frankfurt", bus="Frankfurt", p_set=5)
n.add("Bus", "Frankfurt heat", carrier="heat")
n.add("Load", "Frankfurt heat", bus="Frankfurt heat", p_set=3)
n.add("Bus", "Frankfurt gas", carrier="gas")
n.add("Generator", "Frankfurt gas", bus="Frankfurt gas", marginal_cost=100, p_nom=100)
n.add(
"Link",
"OCGT",
bus0="Frankfurt gas",
bus1="Frankfurt",
p_nom_extendable=True,
capital_cost=600,
efficiency=0.4, # electricity per unit of gas
)
n.add(
"Link",
"CHP",
bus0="Frankfurt gas",
bus1="Frankfurt",
bus2="Frankfurt heat",
p_nom_extendable=True,
capital_cost=1400,
efficiency=0.3, # electricity per unit of gas
efficiency2=0.3, # heat per unit of gas
)
n.optimize();
/tmp/ipykernel_3595/1890019209.py:36: 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. n.optimize(); WARNING:pypsa.consistency:The following buses have carriers which are not defined. Run n.sanitize() to add them. Components with undefined carriers: Index(['Frankfurt', 'Frankfurt heat', 'Frankfurt gas'], dtype='object', name='name')
WARNING:pypsa.consistency:The following links have carriers which are not defined. Run n.sanitize() to add them. Components with undefined carriers: Index(['OCGT', 'CHP'], 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: 5 primals, 11 duals Objective: 1.85e+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 were not assigned to the network.
In [3]:
Copied!
n.loads_t.p
n.loads_t.p
Out[3]:
| name | Frankfurt | Frankfurt heat |
|---|---|---|
| snapshot | ||
| now | 5.0 | 3.0 |
In [4]:
Copied!
n.links_t.p0
n.links_t.p0
Out[4]:
| name | OCGT | CHP |
|---|---|---|
| snapshot | ||
| now | 5.0 | 10.0 |
In [5]:
Copied!
n.links_t.p1
n.links_t.p1
Out[5]:
| name | OCGT | CHP |
|---|---|---|
| snapshot | ||
| now | -2.0 | -3.0 |
In [6]:
Copied!
n.links_t.p2
n.links_t.p2
Out[6]:
| name | OCGT | CHP |
|---|---|---|
| snapshot | ||
| now | 0.0 | -3.0 |