191108: Include a correctly-costed H2 network

Offers same topology to optimisation for H2 grid as that of HVAC and
HVDC grid.
This commit is contained in:
Tom Brown 2019-11-26 18:00:45 +01:00
parent 8d68146e7c
commit 3fac944e5b
4 changed files with 38 additions and 22 deletions

View File

@ -202,7 +202,7 @@ rule prepare_sector_network:
solar_thermal_rural="resources/solar_thermal_rural_{network}_s{simpl}_{clusters}.nc"
output: config['results_dir'] + config['run'] + '/prenetworks/{network}_s{simpl}_{clusters}_lv{lv}_{opts}_{sector_opts}.nc'
threads: 1
resources: mem=1000
resources: mem=2000
benchmark: "benchmarks/prepare_network/{network}_s{simpl}_{clusters}_lv{lv}_{opts}_{sector_opts}"
script: "scripts/prepare_sector_network.py"
@ -219,7 +219,7 @@ rule solve_network:
memory="logs/" + config['run'] + "/{network}_s{simpl}_{clusters}_lv{lv}_{opts}_{sector_opts}_memory.log"
benchmark: "benchmarks/solve_network/{network}_s{simpl}_{clusters}_lv{lv}_{opts}_{sector_opts}"
threads: 4
resources: mem=50000 #memory in MB; 40 GB enough for 45+B+I; 100 GB based on RESI usage for 128
resources: mem=120000 #memory in MB; 40 GB enough for 45+B+I; 100 GB based on RESI usage for 128
# group: "solve" # with group, threads is ignored https://bitbucket.org/snakemake/snakemake/issues/971/group-job-description-does-not-contain
script: "scripts/solve_network.py"

View File

@ -2,7 +2,7 @@ logging_level: INFO
results_dir: 'results/'
summary_dir: results
run: '190807-resserv_bdew'
run: '191108-h2_pipeline_network'
scenario:
sectors: [E] # ,E+EV,E+BEV,E+BEV+V2G] # [ E+EV, E+BEV, E+BEV+V2G ]
@ -10,7 +10,7 @@ scenario:
lv: [1.0]#, 1.125, 1.25, 1.5, 2.0]# or opt
clusters: [50] #[90, 128, 181] #[45, 64, 90, 128, 181, 256] #, 362] # (2**np.r_[5.5:9:.5]).astype(int) minimum is 37
opts: [''] #for pypsa-eur
sector_opts: [Co2L0-3H-T-H-B-I]#,Co2L0p1-3H-T-H-B-I,Co2L0p25-3H-T-H-B-I,Co2L0p5-3H-T-H-B-I]#[Co2L0-3H-T-H-B-I-onwind0-solar3,Co2L0-3H-T-H-B-I-onwind0p125-solar3,Co2L0-3H-T-H-B-I-onwind0p25-solar3,Co2L0-3H-T-H-B-I-onwind0p50-solar3,Co2L0-3H-T-H-B-I-solar3]#,Co2L0-3H-T-H-B-I-onwind0p25-solar3]#,Co2L0p05-3H-T-H-B-I,Co2L0p10-3H-T-H-B-I,Co2L0p20-3H-T-H-B-I,Co2L0p30-3H-T-H-B-I,Co2L0p50-3H-T-H-B-I]#[Co2L-3H-T-H,Co2L0p10-3H-T-H,Co2L0-3H-T-H,Co2L0p20-3H-T-H] #Co2L-3H-T-H,Co2L0p10-3H-T-H,Co2L0p20-3H-T-HCo2L-3H-T-H,Co2L0p10-3H-T-H,Co2L0p30-3H-T-H,Co2L0p50-3H-T-H] #Co2L-3H,Co2L-3H-T,, LC-FL, LC-T, Ep-T, Co2L-T]
sector_opts: [Co2L0-3H-T-H-B-I,Co2L0-5H-T-H-B-I]#,Co2L0p1-3H-T-H-B-I,Co2L0p25-3H-T-H-B-I,Co2L0p5-3H-T-H-B-I]#[Co2L0-3H-T-H-B-I-onwind0-solar3,Co2L0-3H-T-H-B-I-onwind0p125-solar3,Co2L0-3H-T-H-B-I-onwind0p25-solar3,Co2L0-3H-T-H-B-I-onwind0p50-solar3,Co2L0-3H-T-H-B-I-solar3]#,Co2L0-3H-T-H-B-I-onwind0p25-solar3]#,Co2L0p05-3H-T-H-B-I,Co2L0p10-3H-T-H-B-I,Co2L0p20-3H-T-H-B-I,Co2L0p30-3H-T-H-B-I,Co2L0p50-3H-T-H-B-I]#[Co2L-3H-T-H,Co2L0p10-3H-T-H,Co2L0-3H-T-H,Co2L0p20-3H-T-H] #Co2L-3H-T-H,Co2L0p10-3H-T-H,Co2L0p20-3H-T-HCo2L-3H-T-H,Co2L0p10-3H-T-H,Co2L0p30-3H-T-H,Co2L0p50-3H-T-H] #Co2L-3H,Co2L-3H-T,, LC-FL, LC-T, Ep-T, Co2L-T]
# Co2L will give default (5%); Co2L0p25 will give 25% CO2 emissions; Co2Lm0p05 will give 5% negative emissions
@ -67,7 +67,7 @@ sector:
'space_heating_fraction' : 1.0 #fraction of space heating active
'retrofitting' : False
'retroI-fraction' : 0.25
'retroI-fraction' : 0.55
'retroII-fraction' : 0.55
'retrofitting-cost_factor' : 1.0
'tes' : True
'tes_tau' : 3.

View File

@ -94,6 +94,9 @@ hydrogen storage,2030,investment,11.2,USD/kWh,budischak2013
hydrogen storage,2030,lifetime,20,years,budischak2013
hydrogen underground storage,2030,investment,0.5,EUR/kWh,maximum from https://www.nrel.gov/docs/fy10osti/46719.pdf
hydrogen underground storage,2030,lifetime,40,years,http://www.acatech.de/fileadmin/user_upload/Baumstruktur_nach_Website/Acatech/root/de/Publikationen/Materialien/ESYS_Technologiesteckbrief_Energiespeicher.pdf
H2 pipeline,2030,investment,267,EUR/MW/km,Welder et al https://doi.org/10.1016/j.ijhydene.2018.12.156
H2 pipeline,2030,lifetime,40,years,TODO
H2 pipeline,2030,FOM,3,%/year,TODO
methanation,2030,investment,1000,EUR/kWH2,Schaber thesis
methanation,2030,lifetime,25,years,Schaber thesis
methanation,2030,FOM,3,%/year,Schaber thesis

1 technology year parameter value unit source
94 hydrogen storage 2030 lifetime 20 years budischak2013
95 hydrogen underground storage 2030 investment 0.5 EUR/kWh maximum from https://www.nrel.gov/docs/fy10osti/46719.pdf
96 hydrogen underground storage 2030 lifetime 40 years http://www.acatech.de/fileadmin/user_upload/Baumstruktur_nach_Website/Acatech/root/de/Publikationen/Materialien/ESYS_Technologiesteckbrief_Energiespeicher.pdf
97 H2 pipeline 2030 investment 267 EUR/MW/km Welder et al https://doi.org/10.1016/j.ijhydene.2018.12.156
98 H2 pipeline 2030 lifetime 40 years TODO
99 H2 pipeline 2030 FOM 3 %/year TODO
100 methanation 2030 investment 1000 EUR/kWH2 Schaber thesis
101 methanation 2030 lifetime 25 years Schaber thesis
102 methanation 2030 FOM 3 %/year Schaber thesis

View File

@ -522,34 +522,46 @@ def add_storage(network):
efficiency=costs.at["fuel cell","efficiency"],
capital_cost=costs.at["fuel cell","fixed"]*costs.at["fuel cell","efficiency"]) #NB: fixed cost is per MWel
network.add("Bus",
"EU H2",
carrier="H2")
#TODO Add capital costs, efficiency losses
network.madd("Link",
nodes + " H2 pipeline",
bus0=nodes + " H2",
bus1="EU H2",
p_min_pu=-1,
p_nom_extendable=True,
carrier="H2 pipeline")
if options['hydrogen_underground_storage']:
h2_capital_cost = costs.at["hydrogen underground storage","fixed"]
else:
h2_capital_cost = costs.at["hydrogen storage","fixed"]
network.madd("Store",
["EU H2 Store"],
bus="EU H2",
#nodes + " H2 Store",
#bus=nodes + " H2",
nodes + " H2 Store",
bus=nodes + " H2",
e_nom_extendable=True,
e_cyclic=True,
carrier="H2 Store",
capital_cost=h2_capital_cost)
h2_links = pd.DataFrame(columns=["bus0","bus1","length"])
prefix = "H2 pipeline "
connector = " -> "
attrs = ["bus0","bus1","length"]
candidates = pd.concat([n.lines[attrs],n.links.loc[n.links.carrier == "DC",attrs]])
for candidate in candidates.index:
buses = [candidates.at[candidate,"bus0"],candidates.at[candidate,"bus1"]]
buses.sort()
name = prefix + buses[0] + connector + buses[1]
if name not in h2_links.index:
h2_links.at[name,"bus0"] = buses[0]
h2_links.at[name,"bus1"] = buses[1]
h2_links.at[name,"length"] = candidates.at[candidate,"length"]
#TODO Add efficiency losses
network.madd("Link",
h2_links.index,
bus0=h2_links.bus0.values + " H2",
bus1=h2_links.bus1.values + " H2",
p_min_pu=-1,
p_nom_extendable=True,
length=h2_links.length.values,
capital_cost=costs.at['H2 pipeline','fixed']*h2_links.length.values,
carrier="H2 pipeline")
network.add("Carrier","battery")
@ -1247,6 +1259,7 @@ if __name__ == "__main__":
input=dict(network='../pypsa-eur/networks/{network}_s{simpl}_{clusters}.nc', timezone_mappings='data/timezone_mappings.csv'),
output=['networks/{network}_s{simpl}_{clusters}_lv{lv}_{opts}.nc']
)
import yaml
with open('config.yaml') as f:
snakemake.config = yaml.load(f)