add H2 boiler and constraint to avoid existing gas boiler back up
This commit is contained in:
parent
369eaf3457
commit
abb584de45
@ -20,7 +20,7 @@ remote:
|
||||
|
||||
# docs in https://pypsa-eur.readthedocs.io/en/latest/configuration.html#run
|
||||
run:
|
||||
name: "test_co2limit"
|
||||
name: "test_h2_retrofit"
|
||||
disable_progressbar: false
|
||||
shared_resources: true
|
||||
shared_cutouts: true
|
||||
@ -35,7 +35,7 @@ scenario:
|
||||
- ''
|
||||
ll:
|
||||
- v1.0
|
||||
- v1.5
|
||||
# - v1.5
|
||||
clusters:
|
||||
- 37
|
||||
# - 128
|
||||
@ -45,7 +45,9 @@ scenario:
|
||||
opts:
|
||||
- ''
|
||||
sector_opts:
|
||||
- 4380H-T-H-B-I-A-solar+p3-dist1
|
||||
- 1p7-4380H-T-H-B-I-A-solar+p3-dist1
|
||||
- 1p5-4380H-T-H-B-I-A-solar+p3-dist1
|
||||
- 2p0-4380H-T-H-B-I-A-solar+p3-dist1
|
||||
planning_horizons:
|
||||
- 2020
|
||||
- 2030
|
||||
@ -69,7 +71,7 @@ enable:
|
||||
retrieve_sector_databundle: true
|
||||
retrieve_cost_data: true
|
||||
build_cutout: false
|
||||
retrieve_cutout: false
|
||||
retrieve_cutout: true
|
||||
build_natura_raster: false
|
||||
retrieve_natura_raster: true
|
||||
custom_busmap: false
|
||||
@ -133,7 +135,7 @@ electricity:
|
||||
# docs in https://pypsa-eur.readthedocs.io/en/latest/configuration.html#atlite
|
||||
atlite:
|
||||
default_cutout: europe-2013-era5
|
||||
nprocesses: 4
|
||||
nprocesses: 1
|
||||
show_progress: false
|
||||
cutouts:
|
||||
# use 'base' to determine geographical bounds and time span from config
|
||||
@ -916,6 +918,7 @@ plotting:
|
||||
H2 for shipping: "#ebaee0"
|
||||
H2: '#bf13a0'
|
||||
hydrogen: '#bf13a0'
|
||||
retrofitted H2 boiler: '#e5a0d9'
|
||||
SMR: '#870c71'
|
||||
SMR CC: '#4f1745'
|
||||
H2 liquefaction: '#d647bd'
|
||||
|
@ -306,6 +306,29 @@ def adjust_CO2_glc(n):
|
||||
n.df(c).loc[mask, "type"] = "co2_limit"
|
||||
|
||||
return n
|
||||
|
||||
|
||||
def add_H2_boilers(n):
|
||||
c = "Link"
|
||||
logger.info("Add H2 boilers.")
|
||||
# existing gas boilers
|
||||
mask = n.links.carrier.str.contains("gas boiler") & ~n.links.p_nom_extendable
|
||||
gas_i = n.links[mask].index
|
||||
df = n.links.loc[gas_i]
|
||||
# adjust bus 0
|
||||
df["bus0"] = df.bus1.map(n.buses.location) + " H2"
|
||||
# rename carrier and index
|
||||
df["carrier"] = df.carrier.apply(lambda x: x.replace("gas boiler", "retrofitted H2 boiler"))
|
||||
df.rename(index = lambda x: x.replace("gas boiler", "retrofitted H2 boiler"), inplace=True)
|
||||
# todo, costs for retrofitting
|
||||
df["capital_costs"] = 100
|
||||
# set existing capacity to zero
|
||||
df["p_nom"] = 0
|
||||
df["p_nom_extendable"] = True
|
||||
# add H2 boilers to network
|
||||
import_components_from_dataframe(n, df, c)
|
||||
|
||||
|
||||
# %%
|
||||
if __name__ == "__main__":
|
||||
if "snakemake" not in globals():
|
||||
@ -339,14 +362,17 @@ if __name__ == "__main__":
|
||||
n = concat_networks(years)
|
||||
|
||||
# adjust global constraints lv limit if the same for all years
|
||||
n = adjust_lvlimit(n)
|
||||
|
||||
n = adjust_lvlimit(n)
|
||||
# adjust global constraints CO2 limit
|
||||
n = adjust_CO2_glc(n)
|
||||
# set phase outs
|
||||
set_all_phase_outs(n)
|
||||
# adjust stores to multi period investment
|
||||
n = adjust_stores(n)
|
||||
|
||||
# set phase outs
|
||||
set_all_phase_outs(n)
|
||||
|
||||
# add H2 boiler
|
||||
add_H2_boilers(n)
|
||||
|
||||
# set carbon constraints
|
||||
opts = snakemake.wildcards.sector_opts.split("-")
|
||||
|
@ -32,7 +32,7 @@ import re
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
import pypsa
|
||||
from pypsa.descriptors import nominal_attrs
|
||||
from pypsa.descriptors import nominal_attrs, get_activity_mask
|
||||
import xarray as xr
|
||||
from _helpers import configure_logging, update_config_with_sector_opts
|
||||
|
||||
@ -41,6 +41,7 @@ from vresutils.benchmark import memory_logger
|
||||
logger = logging.getLogger(__name__)
|
||||
pypsa.pf.logger.setLevel(logging.WARNING)
|
||||
from pypsa.descriptors import get_switchable_as_dense as get_as_dense
|
||||
from pypsa.io import import_components_from_dataframe
|
||||
from linopy.expressions import merge
|
||||
from numpy import isnan
|
||||
|
||||
@ -276,7 +277,51 @@ def add_max_growth(n, config):
|
||||
n.carriers.loc[carrier, "max_relative_growth"] = max_r_per_period
|
||||
|
||||
return n
|
||||
|
||||
|
||||
|
||||
def add_retrofit_gas_boiler_constraint(n, snapshots):
|
||||
"""Allow retrofitting of existing gas boilers to H2 boilers.
|
||||
"""
|
||||
c = "Link"
|
||||
logger.info("Add constraint for retrofitting gas boilers to H2 boilers.")
|
||||
# existing gas boilers
|
||||
mask = n.links.carrier.str.contains("gas boiler") & ~n.links.p_nom_extendable
|
||||
gas_i = n.links[mask].index
|
||||
mask = n.links.carrier.str.contains("retrofitted H2 boiler")
|
||||
h2_i = n.links[mask].index
|
||||
|
||||
|
||||
n.links.loc[gas_i, "p_nom_extendable"] = True
|
||||
p_nom = n.links.loc[gas_i, "p_nom"]
|
||||
n.links.loc[gas_i, "p_nom"] = 0
|
||||
|
||||
# heat profile
|
||||
cols = n.loads_t.p_set.columns[n.loads_t.p_set.columns.str.contains("heat")
|
||||
& ~n.loads_t.p_set.columns.str.contains("industry")
|
||||
& ~n.loads_t.p_set.columns.str.contains("agriculture")]
|
||||
profile = n.loads_t.p_set[cols].div(n.loads_t.p_set[cols].groupby(level=0).max(), level=0)
|
||||
# to deal if max value is zero
|
||||
profile.fillna(0, inplace=True)
|
||||
profile.rename(columns=n.loads.bus.to_dict(), inplace=True)
|
||||
profile = profile.reindex(columns=n.links.loc[gas_i, "bus1"])
|
||||
profile.columns = gas_i
|
||||
|
||||
|
||||
rhs = profile.mul(p_nom)
|
||||
|
||||
dispatch = n.model["Link-p"]
|
||||
active = get_activity_mask(n, c, snapshots, gas_i)
|
||||
rhs = rhs[active]
|
||||
p_gas = dispatch.sel(Link=gas_i)
|
||||
p_h2 = dispatch.sel(Link=h2_i)
|
||||
|
||||
lhs = p_gas + p_h2
|
||||
|
||||
n.model.add_constraints(lhs == rhs, name="gas_retrofit")
|
||||
|
||||
|
||||
|
||||
|
||||
def prepare_network(
|
||||
n,
|
||||
solve_opts=None,
|
||||
@ -740,6 +785,7 @@ def extra_functionality(n, snapshots):
|
||||
if n._multi_invest:
|
||||
add_carbon_constraint(n, snapshots)
|
||||
add_carbon_budget_constraint(n, snapshots)
|
||||
add_retrofit_gas_boiler_constraint(n, snapshots)
|
||||
|
||||
|
||||
def solve_network(n, config, solving, opts="", **kwargs):
|
||||
|
Loading…
Reference in New Issue
Block a user