From 17a348d1e608b41a07dcb6f78c3eb91ce314729d Mon Sep 17 00:00:00 2001 From: martavp Date: Fri, 17 Jul 2020 15:20:20 +0200 Subject: [PATCH] Add lifetime attribute to generators, links and stores in prepare_sector_network and use that attribute to check if a generator optimized in a previous time step should be added in add_brownfield (or if its lifetime has expired) --- scripts/add_brownfield.py | 57 +++++++++---- scripts/prepare_sector_network.py | 135 ++++++++++++++++++++---------- 2 files changed, 128 insertions(+), 64 deletions(-) diff --git a/scripts/add_brownfield.py b/scripts/add_brownfield.py index f79c0fa3..f7ca624c 100755 --- a/scripts/add_brownfield.py +++ b/scripts/add_brownfield.py @@ -44,6 +44,26 @@ override_component_attrs["Link"].loc["p3"] = ["series","MW",0.,"3rd bus output", def add_brownfield(n, n_p, year): print("adding brownfield") + #first, remove generators, links and stores that track CO2 or global EU values + n_p.mremove("Generator", [index for index in n_p.generators.index.to_list() if 'ror' in index]) + n_p.mremove("Generator", ['EU fossil gas', 'fossil oil'] ) + n_p.mremove("Store", ['co2 atmosphere', 'co2 stored', 'EU gas Store'] ) + n_p.mremove("Link", ['co2 vent'] ) + + if "H" in opts: + n_p.mremove("Link", [index for index in n_p.links.index.to_list() if 'water tanks charger' in index]) + n_p.mremove("Link", [index for index in n_p.links.index.to_list() if 'water tanks discharger' in index]) + if "B" in opts: + n_p.mremove("Store", ['EU biogas', 'EU solid biomass']) + n_p.mremove("Link", ['biogas to gas']) + if "I" in opts: + n_p.mremove("Store", ['Fischer-Tropsch Store']) + n_p.mremove("Link", ['process emissions' , 'gas for industry', 'solid biomass for industry']) + if "T" in opts: + n_p.mremove("Store", [index for index in n_p.stores.index.to_list() if 'battery storage' in index]) + n_p.mremove("Link", [index for index in n_p.links.index.to_list() if 'BEV charger' in index]) + n_p.mremove("Link", [index for index in n_p.links.index.to_list() if 'V2G' in index]) + previous_timestep=snakemake.config['scenario']['planning_horizons'][snakemake.config['scenario']['planning_horizons'].index(year)-1] previous_timesteps=snakemake.config['scenario']['planning_horizons'][0:snakemake.config['scenario']['planning_horizons'].index(year)] @@ -51,11 +71,8 @@ def add_brownfield(n, n_p, year): # they are added again by add_power_capacities_installed_before_baseyear() # with updated capacities (some of them have been decomissioned) n_p.mremove("Generator", [index for index in n_p.generators.index.to_list() if '<'+snakemake.config['scenario']['planning_horizons'][0] in index]) - - n_p.mremove("Generator", [index for index in n_p.generators.index.to_list() if 'ror' in index]) - # generators whose installationYear + lifetime < year are removed - #n_p.mremove("Generator", [index for index in n_p.generators.index.to_list() if (index[-4:] in previous_timesteps) and (int(index[-4:])+snakemake.config['costs']['lifetime'] < int(year))]) + # generators whose build_year + lifetime < year are removed n_p.mremove("Generator", [index for index in n_p.generators.index.to_list() if (n_p.generators.loc[index, 'build_year'] in previous_timesteps) and (n_p.generators.loc[index, 'build_year']+n_p.generators.loc[index, 'lifetime'] < int(year))]) @@ -64,6 +81,9 @@ def add_brownfield(n, n_p, year): n_p.generators.index=np.where(n_p.generators.index.str[-4:].isin(previous_timesteps)==False, n_p.generators.index + '-' + previous_timestep, n_p.generators.index) + n_p.generators.loc[[index for index in n_p.generators.index.to_list() + if previous_timestep in index], 'build_year']=int(previous_timestep) + #add generators from previous step n.madd("Generator", n_p.generators.index, @@ -74,22 +94,22 @@ def add_brownfield(n, n_p, year): capital_cost=n_p.generators.capital_cost, efficiency=n_p.generators.efficiency, p_max_pu=n_p.generators_t.p_max_pu, - build_year=int(previous_timestep), - lifetime=snakemake.config['costs']['lifetime']) + build_year=n_p.generators.build_year, + lifetime=n_p.generators.lifetime) #add stores from previous steps - n_p.mremove("Store", ['co2 atmosphere', 'co2 stored', 'EU gas Store'] ) # stores whose installationYear + lifetime < year are removed - #n_p.mremove("Store", [index for index in n_p.stores.index.to_list() if (index[-4:] in previous_timesteps) and (int(index[-4:])+snakemake.config['costs']['lifetime'] < int(year))]) n_p.mremove("Store", [index for index in n_p.stores.index.to_list() - if (n_p.stores.loc[index, 'build_year'] in previous_timesteps) - and (n_p.stores.loc[index, 'build_year']+n_p.stores.loc[index, 'lifetime'] < int(year))]) + if (n_p.stores.loc[index, 'build_year'] in previous_timesteps) + and (n_p.stores.loc[index, 'build_year']+n_p.stores.loc[index, 'lifetime'] < int(year))]) # stores whose capacity was optimized in the previous year are renamed n_p.stores.index=np.where(n_p.stores.index.str[-4:].isin(previous_timesteps)==False, n_p.stores.index + '-' + previous_timestep, n_p.stores.index) + n_p.stores.loc[[index for index in n_p.stores.index.to_list() + if previous_timestep in index], 'build_year']=int(previous_timestep) n.madd("Store", n_p.stores.index, bus=n_p.stores.bus, @@ -97,8 +117,8 @@ def add_brownfield(n, n_p, year): e_nom=n_p.stores.e_nom_opt, e_cyclic=True, capital_cost=n_p.stores.capital_cost, - build_year=int(previous_timestep), - lifetime=snakemake.config['costs']['lifetime']) + build_year=n_p.stores.build_year, + lifetime=n_p.stores.lifetime) ## add links from previous steps # TODO: add_chp_constraint() in solve_network needs to be adjusted @@ -106,7 +126,6 @@ def add_brownfield(n, n_p, year): n_p.mremove("Link", [index for index in n_p.links.index.to_list() if 'CHP' in index]) # stores whose installationYear + lifetime < year are removed - #n_p.mremove("Link", [index for index in n_p.links.index.to_list() if (index[-4:] in previous_timesteps) and (int(index[-4:])+snakemake.config['costs']['lifetime'] < int(year))]) n_p.mremove("Link", [index for index in n_p.links.index.to_list() if (n_p.links.loc[index, 'build_year'] in previous_timesteps) and (n_p.links.loc[index, 'build_year']+n_p.links.loc[index, 'lifetime'] < int(year))]) @@ -115,6 +134,8 @@ def add_brownfield(n, n_p, year): n_p.links.index=np.where(n_p.links.index.str[-4:].isin(previous_timesteps)==False, n_p.links.index + '-' + previous_timestep, n_p.links.index) + n_p.links.loc[[index for index in n_p.links.index.to_list() + if previous_timestep in index], 'build_year']=int(previous_timestep) n.madd("Link", n_p.links.index, bus0=n_p.links.bus0, @@ -126,8 +147,8 @@ def add_brownfield(n, n_p, year): capital_cost=n_p.links.capital_cost, efficiency=n_p.links.efficiency, efficiency2=n_p.links.efficiency2, - build_year=int(previous_timestep), - lifetime=snakemake.config['costs']['lifetime']) + build_year=n_p.links.build_year, + lifetime=n_p.links.lifetime) if __name__ == "__main__": @@ -138,13 +159,13 @@ if __name__ == "__main__": wildcards=dict(network='elec', simpl='', clusters='37', lv='1.0', sector_opts='Co2L0-168H-T-H-B-I-solar3-dist1', co2_budget_name='go', - planning_horizons='2030'), + planning_horizons='2050'), input=dict(network='pypsa-eur-sec/results/test/prenetworks/{network}_s{simpl}_{clusters}_lv{lv}__{sector_opts}_{co2_budget_name}_{planning_horizons}.nc', - network_p='pypsa-eur-sec/results/test/postnetworks/{network}_s{simpl}_{clusters}_lv{lv}__{sector_opts}_{co2_budget_name}_2020.nc', + network_p='pypsa-eur-sec/results/test/postnetworks/{network}_s{simpl}_{clusters}_lv{lv}__{sector_opts}_{co2_budget_name}_2040.nc', costs='pypsa-eur-sec/data/costs/costs_{planning_horizons}.csv', cop_air_total="pypsa-eur-sec/resources/cop_air_total_{network}_s{simpl}_{clusters}.nc", cop_soil_total="pypsa-eur-sec/resources/cop_soil_total_{network}_s{simpl}_{clusters}.nc"), - output=['pypsa-eur-sec/results/test/prenetworks_bf/{network}_s{simpl}_{clusters}_lv{lv}__{sector_opts}_{planning_horizons}.nc'] + output=['pypsa-eur-sec/results/test/prenetworks_brownfied/{network}_s{simpl}_{clusters}_lv{lv}__{sector_opts}_{planning_horizons}.nc'] ) import yaml with open('config.yaml') as f: diff --git a/scripts/prepare_sector_network.py b/scripts/prepare_sector_network.py index a13d9876..615457e6 100755 --- a/scripts/prepare_sector_network.py +++ b/scripts/prepare_sector_network.py @@ -102,7 +102,8 @@ def add_co2_tracking(n): carrier="DAC", marginal_cost=75., efficiency=1., - p_nom_extendable=True) + p_nom_extendable=True, + lifetime=costs.at['DAC','lifetime']) def add_co2limit(n, Nyears=1.,limit=0.): @@ -492,7 +493,8 @@ def add_generation(network): p_nom_extendable=True, carrier=generator, efficiency=costs.at[generator,'efficiency'], - efficiency2=costs.at[carrier,'CO2 intensity']) + efficiency2=costs.at[carrier,'CO2 intensity'], + lifetime=costs.at[generator,'lifetime']) def add_wave(network, wave_cost_factor): wave_fn = "data/WindWaveWEC_GLTB.xlsx" @@ -547,6 +549,7 @@ def insert_electricity_distribution_grid(network): carrier="electricity distribution grid", efficiency=1, marginal_cost=0, + lifetime=costs.at['electricity distribution grid','lifetime'], capital_cost=costs.at['electricity distribution grid','fixed']*snakemake.config["sector"]['electricity_distribution_grid_cost_factor']) loads = network.loads.index[network.loads.carrier=="electricity"] @@ -574,7 +577,8 @@ def insert_electricity_distribution_grid(network): marginal_cost=network.generators.loc[solar, 'marginal_cost'], capital_cost=costs.at['solar-rooftop','fixed'], efficiency=network.generators.loc[solar, 'efficiency'], - p_max_pu=network.generators_t.p_max_pu[solar]) + p_max_pu=network.generators_t.p_max_pu[solar], + lifetime=costs.at['solar-rooftop','lifetime']) @@ -590,7 +594,8 @@ def insert_electricity_distribution_grid(network): e_cyclic=True, e_nom_extendable=True, carrier="home battery", - capital_cost=costs.at['battery storage','fixed']) + capital_cost=costs.at['battery storage','fixed'], + lifetime=costs.at['battery storage','lifetime']) network.madd("Link", nodes + " home battery charger", @@ -599,7 +604,8 @@ def insert_electricity_distribution_grid(network): carrier="home battery charger", efficiency=costs.at['battery inverter','efficiency']**0.5, capital_cost=costs.at['battery inverter','fixed'], - p_nom_extendable=True) + p_nom_extendable=True, + lifetime=costs.at['battery inverter','lifetime']) network.madd("Link", nodes + " home battery discharger", @@ -608,7 +614,8 @@ def insert_electricity_distribution_grid(network): carrier="home battery discharger", efficiency=costs.at['battery inverter','efficiency']**0.5, marginal_cost=options['marginal_cost_storage'], - p_nom_extendable=True) + p_nom_extendable=True, + lifetime=costs.at['battery inverter','lifetime']) def add_electricity_grid_connection(network): @@ -636,7 +643,8 @@ def add_storage(network): p_nom_extendable=True, carrier="H2 Electrolysis", efficiency=costs.at["electrolysis","efficiency"], - capital_cost=costs.at["electrolysis","fixed"]) + capital_cost=costs.at["electrolysis","fixed"], + lifetime=costs.at['electrolysis','lifetime']) network.madd("Link", nodes + " H2 Fuel Cell", @@ -645,10 +653,12 @@ def add_storage(network): p_nom_extendable=True, carrier ="H2 Fuel Cell", efficiency=costs.at["fuel cell","efficiency"], - capital_cost=costs.at["fuel cell","fixed"]*costs.at["fuel cell","efficiency"]) #NB: fixed cost is per MWel + capital_cost=costs.at["fuel cell","fixed"]*costs.at["fuel cell","efficiency"], #NB: fixed cost is per MWel + lifetime=costs.at['fuel cell','lifetime']) if options['hydrogen_underground_storage']: h2_capital_cost = costs.at["gas storage","fixed"] + #TODO: change gas storage to hydrogen underground storage when cost database is updated #h2_capital_cost = costs.at["hydrogen underground storage","fixed"] else: h2_capital_cost = costs.at["hydrogen storage","fixed"] @@ -659,7 +669,8 @@ def add_storage(network): e_nom_extendable=True, e_cyclic=True, carrier="H2 Store", - capital_cost=h2_capital_cost) + capital_cost=h2_capital_cost, + lifetime=costs.at['gas storage','lifetime']) h2_links = pd.DataFrame(columns=["bus0","bus1","length"]) prefix = "H2 pipeline " @@ -687,7 +698,8 @@ def add_storage(network): p_nom_extendable=True, length=h2_links.length.values, capital_cost=costs.at['H2 pipeline','fixed']*h2_links.length.values, - carrier="H2 pipeline") + carrier="H2 pipeline", + lifetime=costs.at['H2 pipeline','lifetime']) network.add("Carrier","battery") @@ -702,7 +714,8 @@ def add_storage(network): e_cyclic=True, e_nom_extendable=True, carrier="battery", - capital_cost=costs.at['battery storage','fixed']) + capital_cost=costs.at['battery storage','fixed'], + lifetime=costs.at['battery storage','lifetime']) network.madd("Link", nodes + " battery charger", @@ -711,7 +724,8 @@ def add_storage(network): carrier="battery charger", efficiency=costs.at['battery inverter','efficiency']**0.5, capital_cost=costs.at['battery inverter','fixed'], - p_nom_extendable=True) + p_nom_extendable=True, + lifetime=costs.at['battery inverter','lifetime']) network.madd("Link", nodes + " battery discharger", @@ -720,7 +734,8 @@ def add_storage(network): carrier="battery discharger", efficiency=costs.at['battery inverter','efficiency']**0.5, marginal_cost=options['marginal_cost_storage'], - p_nom_extendable=True) + p_nom_extendable=True, + lifetime=costs.at['battery inverter','lifetime']) if options['methanation']: @@ -733,7 +748,8 @@ def add_storage(network): carrier="Sabatier", efficiency=costs.at["methanation","efficiency"], efficiency2=-costs.at["methanation","efficiency"]*costs.at['gas','CO2 intensity'], - capital_cost=costs.at["methanation","fixed"]) + capital_cost=costs.at["methanation","fixed"], + lifetime=costs.at['methanation','lifetime']) if options['helmeth']: network.madd("Link", @@ -745,7 +761,8 @@ def add_storage(network): p_nom_extendable=True, efficiency=costs.at["helmeth","efficiency"], efficiency2=-costs.at["helmeth","efficiency"]*costs.at['gas','CO2 intensity'], - capital_cost=costs.at["helmeth","fixed"]) + capital_cost=costs.at["helmeth","fixed"], + lifetime=costs.at['helmeth','lifetime']) if options['SMR']: @@ -760,7 +777,8 @@ def add_storage(network): efficiency=costs.at["SMR CCS","efficiency"], efficiency2=costs.at['gas','CO2 intensity']*(1-options["ccs_fraction"]), efficiency3=costs.at['gas','CO2 intensity']*options["ccs_fraction"], - capital_cost=costs.at["SMR CCS","fixed"]) + capital_cost=costs.at["SMR CCS","fixed"], + lifetime=costs.at['SMR CCS','lifetime']) network.madd("Link", nodes + " SMR", @@ -771,7 +789,8 @@ def add_storage(network): carrier="SMR", efficiency=costs.at["SMR","efficiency"], efficiency2=costs.at['gas','CO2 intensity'], - capital_cost=costs.at["SMR","fixed"]) + capital_cost=costs.at["SMR","fixed"], + lifetime=costs.at['SMR','lifetime']) def add_transport(network): @@ -909,7 +928,8 @@ def add_heat(network): carrier="{} {} heat pump".format(name,heat_pump_type), efficiency=efficiency, capital_cost=costs.at[costs_name,'efficiency']*costs.at[costs_name,'fixed'], - p_nom_extendable=True) + p_nom_extendable=True, + lifetime=costs.at[costs_name,'lifetime']) if options["tes"]: @@ -946,8 +966,8 @@ def add_heat(network): e_nom_extendable=True, carrier=name + " water tanks", standing_loss=1-np.exp(-1/(24.*tes_time_constant_days)), - capital_cost=costs.at[name_type + ' water tank storage','fixed']/(1.17e-3*40)) #conversion from EUR/m^3 to EUR/MWh for 40 K diff and 1.17 kWh/m^3/K - + capital_cost=costs.at[name_type + ' water tank storage','fixed']/(1.17e-3*40), #conversion from EUR/m^3 to EUR/MWh for 40 K diff and 1.17 kWh/m^3/K + lifetime=costs.at[name_type + ' water tank storage','lifetime']) if options["boilers"]: @@ -958,7 +978,8 @@ def add_heat(network): carrier=name + " resistive heater", efficiency=costs.at[name_type + ' resistive heater','efficiency'], capital_cost=costs.at[name_type + ' resistive heater','efficiency']*costs.at[name_type + ' resistive heater','fixed'], - p_nom_extendable=True) + p_nom_extendable=True, + lifetime=costs.at[name_type + ' resistive heater','lifetime']) network.madd("Link", nodes[name] + " " + name + " gas boiler", @@ -969,7 +990,8 @@ def add_heat(network): carrier=name + " gas boiler", efficiency=costs.at[name_type + ' gas boiler','efficiency'], efficiency2=costs.at['gas','CO2 intensity'], - capital_cost=costs.at[name_type + ' gas boiler','efficiency']*costs.at[name_type + ' gas boiler','fixed']) + capital_cost=costs.at[name_type + ' gas boiler','efficiency']*costs.at[name_type + ' gas boiler','fixed'], + lifetime=costs.at[name_type + ' gas boiler','lifetime']) @@ -984,7 +1006,8 @@ def add_heat(network): carrier=name + " solar thermal", p_nom_extendable=True, capital_cost=costs.at[name_type + ' solar thermal','fixed'], - p_max_pu=solar_thermal[nodes[name]]) + p_max_pu=solar_thermal[nodes[name]], + lifetime=costs.at[name_type + ' solar thermal','lifetime']) if options["chp"]: @@ -1004,7 +1027,8 @@ def add_heat(network): efficiency2=costs.at['gas','CO2 intensity'], c_b=costs.at['central gas CHP','c_b'], c_v=costs.at['central gas CHP','c_v'], - p_nom_ratio=costs.at['central gas CHP','p_nom_ratio']) + p_nom_ratio=costs.at['central gas CHP','p_nom_ratio'], + lifetime=costs.at['central gas CHP','lifetime']) network.madd("Link", nodes[name] + " urban central gas CHP heat", @@ -1015,7 +1039,8 @@ def add_heat(network): p_nom_extendable=True, marginal_cost=costs.at['central gas CHP','VOM'], efficiency=costs.at['central gas CHP','efficiency']/costs.at['central gas CHP','c_v'], - efficiency2=costs.at['gas','CO2 intensity']) + efficiency2=costs.at['gas','CO2 intensity'], + lifetime=costs.at['central gas CHP','lifetime']) network.madd("Link", nodes[name] + " urban central gas CHP CCS electric", @@ -1032,7 +1057,8 @@ def add_heat(network): efficiency3=costs.at['gas','CO2 intensity']*options["ccs_fraction"], c_b=costs.at['central gas CHP CCS','c_b'], c_v=costs.at['central gas CHP CCS','c_v'], - p_nom_ratio=costs.at['central gas CHP CCS','p_nom_ratio']) + p_nom_ratio=costs.at['central gas CHP CCS','p_nom_ratio'], + lifetime=costs.at['central gas CHP CCS','lifetime']) network.madd("Link", nodes[name] + " urban central gas CHP CCS heat", @@ -1045,7 +1071,8 @@ def add_heat(network): marginal_cost=costs.at['central gas CHP CCS','VOM'], efficiency=costs.at['central gas CHP CCS','efficiency']/costs.at['central gas CHP CCS','c_v'], efficiency2=costs.at['gas','CO2 intensity']*(1-options["ccs_fraction"]), - efficiency3=costs.at['gas','CO2 intensity']*options["ccs_fraction"]) + efficiency3=costs.at['gas','CO2 intensity']*options["ccs_fraction"], + lifetime=costs.at['central gas CHP CCS','lifetime']) else: network.madd("Link", @@ -1059,7 +1086,8 @@ def add_heat(network): efficiency=costs.at['micro CHP','efficiency'], efficiency2=costs.at['micro CHP','efficiency-heat'], efficiency3=costs.at['gas','CO2 intensity'], - capital_cost=costs.at['micro CHP','fixed']) + capital_cost=costs.at['micro CHP','fixed'], + lifetime=costs.at['micro CHP','lifetime']) #NB: this currently doesn't work for pypsa-eur model @@ -1207,7 +1235,8 @@ def add_biomass(network): efficiency=costs.at['central solid biomass CHP','efficiency'], c_b=costs.at['central solid biomass CHP','c_b'], c_v=costs.at['central solid biomass CHP','c_v'], - p_nom_ratio=costs.at['central solid biomass CHP','p_nom_ratio']) + p_nom_ratio=costs.at['central solid biomass CHP','p_nom_ratio'], + lifetime=costs.at['central solid biomass CHP','lifetime']) network.madd("Link", @@ -1217,7 +1246,8 @@ def add_biomass(network): carrier="urban central solid biomass CHP heat", p_nom_extendable=True, marginal_cost=costs.at['central solid biomass CHP','VOM'], - efficiency=costs.at['central solid biomass CHP','efficiency']/costs.at['central solid biomass CHP','c_v']) + efficiency=costs.at['central solid biomass CHP','efficiency']/costs.at['central solid biomass CHP','c_v'], + lifetime=costs.at['central solid biomass CHP','lifetime']) network.madd("Link", urban_central + " urban central solid biomass CHP CCS electric", @@ -1234,7 +1264,8 @@ def add_biomass(network): efficiency3=costs.at['solid biomass','CO2 intensity']*options["ccs_fraction"], c_b=costs.at['central solid biomass CHP','c_b'], c_v=costs.at['central solid biomass CHP','c_v'], - p_nom_ratio=costs.at['central solid biomass CHP','p_nom_ratio']) + p_nom_ratio=costs.at['central solid biomass CHP','p_nom_ratio'], + lifetime=costs.at['central solid biomass CHP CCS','lifetime']) network.madd("Link", urban_central + " urban central solid biomass CHP CCS heat", @@ -1247,7 +1278,8 @@ def add_biomass(network): marginal_cost=costs.at['central solid biomass CHP CCS','VOM'], efficiency=costs.at['central solid biomass CHP CCS','efficiency']/costs.at['central solid biomass CHP CCS','c_v'], efficiency2=-costs.at['solid biomass','CO2 intensity']*options["ccs_fraction"], - efficiency3=costs.at['solid biomass','CO2 intensity']*options["ccs_fraction"]) + efficiency3=costs.at['solid biomass','CO2 intensity']*options["ccs_fraction"], + lifetime=costs.at['central solid biomass CHP CCS','lifetime']) def add_industry(network): @@ -1292,7 +1324,8 @@ def add_industry(network): capital_cost=costs.at["industry CCS","fixed"]*costs.at['solid biomass','CO2 intensity']*8760, #8760 converts EUR/(tCO2/a) to EUR/(tCO2/h) efficiency=0.9, efficiency2=-costs.at['solid biomass','CO2 intensity']*options["ccs_fraction"], - efficiency3=costs.at['solid biomass','CO2 intensity']*options["ccs_fraction"]) + efficiency3=costs.at['solid biomass','CO2 intensity']*options["ccs_fraction"], + lifetime=costs.at['industry CCS','lifetime']) network.madd("Bus", @@ -1326,7 +1359,8 @@ def add_industry(network): capital_cost=costs.at["industry CCS","fixed"]*costs.at['gas','CO2 intensity']*8760, #8760 converts EUR/(tCO2/a) to EUR/(tCO2/h) efficiency=0.9, efficiency2=costs.at['gas','CO2 intensity']*(1-options["ccs_fraction"]), - efficiency3=costs.at['gas','CO2 intensity']*options["ccs_fraction"]) + efficiency3=costs.at['gas','CO2 intensity']*options["ccs_fraction"], + lifetime=costs.at['industry CCS','lifetime']) network.madd("Load", @@ -1380,7 +1414,8 @@ def add_industry(network): efficiency=costs.at['decentral oil boiler', 'efficiency'], efficiency2=costs.at['oil', 'CO2 intensity'], capital_cost=costs.at['decentral oil boiler', 'efficiency'] * costs.at[ - 'decentral oil boiler', 'fixed']) + 'decentral oil boiler', 'fixed'], + lifetime=costs.at['decentral oil boiler','lifetime']) network.madd("Link", nodes + " Fischer-Tropsch", @@ -1391,7 +1426,8 @@ def add_industry(network): efficiency=costs.at["Fischer-Tropsch",'efficiency'], capital_cost=costs.at["Fischer-Tropsch",'fixed'], efficiency2=-costs.at["oil",'CO2 intensity']*costs.at["Fischer-Tropsch",'efficiency'], - p_nom_extendable=True) + p_nom_extendable=True, + lifetime=costs.at['Fischer-Tropsch','lifetime']) network.madd("Load", ["naphtha for industry"], @@ -1460,7 +1496,8 @@ def add_industry(network): p_nom_extendable=True, capital_cost=costs.at["industry CCS","fixed"]*8760, #8760 converts EUR/(tCO2/a) to EUR/(tCO2/h) efficiency=(1-options["ccs_fraction"]), - efficiency2=options["ccs_fraction"]) + efficiency2=options["ccs_fraction"], + lifetime=costs.at['industry CCS','lifetime']) @@ -1578,6 +1615,20 @@ if __name__ == "__main__": n.loads["carrier"] = "electricity" + # Add lifetime and build_year attributes to generators, links and stores + n.generators["lifetime"]=np.nan + n.generators["build_year"]=np.nan + n.links["lifetime"]=np.nan + n.links["build_year"]=np.nan + n.stores["lifetime"]=np.nan + + # Add lifetime for solar and wind generators + for carrier in ['solar', 'onwind', 'offwind-dc', 'offwind-ac']: + carrier_name='offwind' if carrier in ['offwind-dc', 'offwind-ac'] else carrier + n.generators.loc[[index for index in n.generators.index.to_list() + if carrier in index], 'lifetime']=costs.at[carrier_name,'lifetime'] + + add_co2_tracking(n) add_generation(n) @@ -1663,14 +1714,6 @@ if __name__ == "__main__": insert_electricity_distribution_grid(n) if snakemake.config["sector"]['electricity_grid_connection']: add_electricity_grid_connection(n) - - - # Add lifetime and build_year attributes to generators, links and stores - n.generators["lifetime"]=np.nan - n.generators["build_year"]=np.nan - n.links["lifetime"]=np.nan - n.links["build_year"]=np.nan - n.stores["lifetime"]=np.nan + n.stores["build_year"]=np.nan - n.export_to_netcdf(snakemake.output[0])