diff --git a/Snakefile b/Snakefile index b0668fce..9330dc9c 100644 --- a/Snakefile +++ b/Snakefile @@ -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" diff --git a/config.yaml b/config.yaml index b0f56b10..86916b81 100644 --- a/config.yaml +++ b/config.yaml @@ -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. diff --git a/data/costs.csv b/data/costs.csv index b414c0ec..9daca579 100644 --- a/data/costs.csv +++ b/data/costs.csv @@ -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 diff --git a/scripts/prepare_sector_network.py b/scripts/prepare_sector_network.py index b361227f..11a1d965 100644 --- a/scripts/prepare_sector_network.py +++ b/scripts/prepare_sector_network.py @@ -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)