diff --git a/config.yaml b/config.yaml index 901827e6..7a57b453 100644 --- a/config.yaml +++ b/config.yaml @@ -2,17 +2,17 @@ logging_level: INFO results_dir: 'results/' summary_dir: results -run: '200126-181-lv-solar3' +run: '200325-distgrids-ev2' scenario: sectors: [E] # ,E+EV,E+BEV,E+BEV+V2G] # [ E+EV, E+BEV, E+BEV+V2G ] simpl: [''] - lv: [1.0, 1.125, 1.25, 1.5, 2.0]# or opt - clusters: [181] #[90, 128, 181] #[45, 64, 90, 128, 181, 256] #, 362] # (2**np.r_[5.5:9:.5]).astype(int) minimum is 37 + lv: [1.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-solar3]#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]#,Co2L0p2-3H-T-H-B-I,Co2L0p5-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-solar3-dist0,Co2L0-3H-T-H-B-I-solar3-dist0p25,Co2L0-3H-T-H-B-I-solar3-dist0p5,Co2L0-3H-T-H-B-I-solar3-dist1,Co2L0-3H-T-H-B-I-solar3-dist2]#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]#,Co2L0p2-3H-T-H-B-I,Co2L0p5-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] # Co2L will give default (5%); Co2L0p25 will give 25% CO2 emissions; Co2Lm0p05 will give 5% negative emissions - + #dist{n} includes distribution grids with investment cost of n times cost in data/costs.csv snapshots: # arguments to pd.date_range @@ -85,6 +85,8 @@ sector: 'hydrogen_underground_storage' : True 'use_fischer_tropsch_waste_heat' : True 'use_fuel_cell_waste_heat' : True + 'electricity_distribution_grid' : False + 'electricity_distribution_grid_cost_factor' : 1.0 #multiplies cost in data/costs.csv costs: year: 2030 @@ -287,6 +289,7 @@ plotting: "solid biomass" : "#DAA520" "today" : "#D2691E" "shipping" : "#6495ED" + "electricity distribution grid" : "#333333" nice_names: # OCGT: "Gas" # OCGT marginal: "Gas (marginal)" diff --git a/data/costs.csv b/data/costs.csv index 7779533b..c55a41d9 100644 --- a/data/costs.csv +++ b/data/costs.csv @@ -239,3 +239,6 @@ HVDC submarine,2030,FOM,2,%/year,Hagspiel HVDC inverter pair,2030,investment,150000,EUR/MW,Hagspiel HVDC inverter pair,2030,lifetime,40,years,Hagspiel HVDC inverter pair,2030,FOM,2,%/year,Hagspiel +electricity distribution grid,2030,investment,500,EUR/kW,TODO +electricity distribution grid,2030,lifetime,40,years,TODO +electricity distribution grid,2030,FOM,2,%/year,TODO diff --git a/scripts/prepare_sector_network.py b/scripts/prepare_sector_network.py index 4315b380..fb48206a 100644 --- a/scripts/prepare_sector_network.py +++ b/scripts/prepare_sector_network.py @@ -524,6 +524,39 @@ def add_wave(network, wave_cost_factor): capital_cost=(annuity(25,0.07)+0.03)*costs[wave_type], p_max_pu=wave["Hebrides",wave_type]) + + +def insert_electricity_distribution_grid(network): + print("Inserting electricity distribution grid with investment cost factor of", + snakemake.config["sector"]['electricity_distribution_grid_cost_factor']) + + nodes = pop_layout.index + + network.madd("Bus", + nodes+ " low voltage", + carrier="low voltage") + + network.madd("Link", + nodes + " electricity distribution grid", + bus0=nodes, + bus1=nodes + " low voltage", + p_nom_extendable=True, + p_min_pu=-1, + carrier="electricity distribution grid", + efficiency=1, + marginal_cost=0, + capital_cost=costs.at['electricity distribution grid','fixed']*snakemake.config["sector"]['electricity_distribution_grid_cost_factor']) + + loads = network.loads.index[network.loads.carrier=="electricity"] + network.loads.loc[loads,"bus"] += " low voltage" + + bevs = network.links.index[network.links.carrier == "BEV charger"] + network.links.loc[bevs,"bus0"] += " low voltage" + + v2gs = network.links.index[network.links.carrier == "V2G"] + network.links.loc[v2gs,"bus1"] += " low voltage" + + def add_storage(network): print("adding electricity storage") nodes = pop_layout.index @@ -571,7 +604,7 @@ def add_storage(network): connector = " -> " attrs = ["bus0","bus1","length"] - candidates = pd.concat([n.lines[attrs],n.links.loc[n.links.carrier == "DC",attrs]], + candidates = pd.concat([network.lines[attrs],network.links.loc[network.links.carrier == "DC",attrs]], keys=["lines","links"]) for candidate in candidates.index: @@ -1095,7 +1128,7 @@ def add_biomass(network): #AC buses with district heating - urban_central = n.buses.index[n.buses.carrier == "urban central heat"] + urban_central = network.buses.index[network.buses.carrier == "urban central heat"] if not urban_central.empty and options["chp"]: urban_central = urban_central.str[:-len(" urban central heat")] @@ -1355,17 +1388,17 @@ def add_waste_heat(network): print("adding possibility to use industrial waste heat in district heating") #AC buses with district heating - urban_central = n.buses.index[n.buses.carrier == "urban central heat"] + urban_central = network.buses.index[network.buses.carrier == "urban central heat"] if not urban_central.empty: urban_central = urban_central.str[:-len(" urban central heat")] if options['use_fischer_tropsch_waste_heat']: - n.links.loc[urban_central + " Fischer-Tropsch","bus3"] = urban_central + " urban central heat" - n.links.loc[urban_central + " Fischer-Tropsch","efficiency3"] = 0.95 - n.links.loc[urban_central + " Fischer-Tropsch","efficiency"] + network.links.loc[urban_central + " Fischer-Tropsch","bus3"] = urban_central + " urban central heat" + network.links.loc[urban_central + " Fischer-Tropsch","efficiency3"] = 0.95 - network.links.loc[urban_central + " Fischer-Tropsch","efficiency"] if options['use_fuel_cell_waste_heat']: - n.links.loc[urban_central + " H2 Fuel Cell","bus2"] = urban_central + " urban central heat" - n.links.loc[urban_central + " H2 Fuel Cell","efficiency2"] = 0.95 - n.links.loc[urban_central + " H2 Fuel Cell","efficiency"] + network.links.loc[urban_central + " H2 Fuel Cell","bus2"] = urban_central + " urban central heat" + network.links.loc[urban_central + " H2 Fuel Cell","efficiency2"] = 0.95 - network.links.loc[urban_central + " H2 Fuel Cell","efficiency"] def restrict_technology_potential(n,tech,limit): @@ -1457,6 +1490,9 @@ if __name__ == "__main__": wave_cost_factor = float(o[4:].replace("p",".").replace("m","-")) print("Including wave generators with cost factor of", wave_cost_factor) add_wave(n, wave_cost_factor) + if o[:4] == "dist": + snakemake.config["sector"]['electricity_distribution_grid'] = True + snakemake.config["sector"]['electricity_distribution_grid_cost_factor'] = float(o[4:].replace("p",".").replace("m","-")) nodal_energy_totals, heat_demand, ashp_cop, gshp_cop, solar_thermal, transport, avail_profile, dsm_profile, co2_totals, nodal_transport_data = prepare_data(n) @@ -1513,4 +1549,7 @@ if __name__ == "__main__": limit = float(limit.replace("p",".").replace("m","-")) restrict_technology_potential(n,tech,limit) + if snakemake.config["sector"]['electricity_distribution_grid']: + insert_electricity_distribution_grid(n) + n.export_to_netcdf(snakemake.output[0])