From 52581466b6e1cc084b93b54d1bb0b235990f5db1 Mon Sep 17 00:00:00 2001 From: Tom Brown Date: Wed, 18 Dec 2019 09:45:14 +0100 Subject: [PATCH] Account for chemical industry process emissions more carefully Remove emissions from hydrogen production for ammonia (since H2 now comes from electrolysis). Allow process emissions from petrochemical production to be captured (the carbon is not necessarily fossil, but could come from CCU). --- config.yaml | 4 +++- scripts/build_industry_sector_ratios.py | 9 ++++--- scripts/prepare_sector_network.py | 32 +++++++++++-------------- 3 files changed, 23 insertions(+), 22 deletions(-) diff --git a/config.yaml b/config.yaml index b3f0b6f8..0b09ffbd 100644 --- a/config.yaml +++ b/config.yaml @@ -146,7 +146,9 @@ industry: 'DRI_ratio' : 0.5 #ratio of today's blast-furnace steel (60% primary route, 40% secondary) to future assumption (30% primary, 70% secondary), transformed into DRI + electric arc 'H2_DRI' : 1.7 #H2 consumption in Direct Reduced Iron (DRI), MWh_H2/ton_Steel from Vogl et al (2018) doi:10.1016/j.jclepro.2018.08.279 'Al_to_scrap' : 0.5 # ratio of primary-route Aluminum transformed into scrap (today 40% to future 20% primary route) - 'H2_for_NH3' : 85000 # H2 for NH3 transformed from SMR to electrolyzed-H2, in GWh/year following Lechtenböhmer(2016) + 'H2_for_NH3' : 85000 # H2 in GWh/a for 17 MtNH3/a transformed from SMR to electrolyzed-H2, following Lechtenböhmer(2016) + 'NH3_process_emissions' : 24.5 # in MtCO2/a from SMR for H2 production for NH3 from UNFCCC for 2015 for EU28 + 'petrochemical_process_emissions' : 25.5 # in MtCO2/a for petrochemical and other from UNFCCC for 2015 for EU28 plotting: map: diff --git a/scripts/build_industry_sector_ratios.py b/scripts/build_industry_sector_ratios.py index baad720b..5d3acb9c 100644 --- a/scripts/build_industry_sector_ratios.py +++ b/scripts/build_industry_sector_ratios.py @@ -26,7 +26,7 @@ sub_sheet_name_dict = { 'Iron and steel':'ISI', 'Wood and wood products': 'WWP', 'Other Industrial Sectors': 'OIS'} -index = ['elec','biomass','methane','hydrogen','heat','naphtha','process emission'] +index = ['elec','biomass','methane','hydrogen','heat','naphtha','process emission','process emission from feedstock'] df = pd.DataFrame(index=index) @@ -302,7 +302,11 @@ s_out = excel_out.iloc[8:9,year] assert sector in str(s_out.index) -df.loc['process emission',sector] += s_emi['Process emissions']/s_out.values # unit tCO2/t material +df.loc['process emission',sector] += (s_emi['Process emissions'] - snakemake.config["industry"]['petrochemical_process_emissions']*1e3 - snakemake.config["industry"]['NH3_process_emissions']*1e3)/s_out.values # unit tCO2/t material + +#these are emissions originating from feedstock, i.e. could be non-fossil origin +df.loc['process emission from feedstock',sector] += (snakemake.config["industry"]['petrochemical_process_emissions']*1e3)/s_out.values # unit tCO2/t material + # final energy consumption per t sources=['elec','biomass', 'methane', 'hydrogen', 'heat','naphtha'] @@ -315,7 +319,6 @@ df.loc[sources,sector] = df.loc[sources,sector]*conv_factor/s_out.values# unit M sector = 'Other chemicals' df[sector] = 0 - # read the corresponding lines s_fec = excel_fec.iloc[58:64,year] diff --git a/scripts/prepare_sector_network.py b/scripts/prepare_sector_network.py index 3e89146d..508e51ee 100644 --- a/scripts/prepare_sector_network.py +++ b/scripts/prepare_sector_network.py @@ -1219,10 +1219,6 @@ def add_industry(network): "Fischer-Tropsch", carrier="Fischer-Tropsch") - network.add("Bus", - "Fischer-Tropsch-demand", - carrier="Fischer-Tropsch-demand") - #use madd to get carrier inserted network.madd("Store", ["Fischer-Tropsch Store"], @@ -1251,29 +1247,29 @@ def add_industry(network): efficiency2=-costs.at["oil",'CO2 intensity']*costs.at["Fischer-Tropsch",'efficiency'], p_nom_extendable=True) - #NB: CO2 gets released again to atmosphere when plastics decay or kerosene is burned - network.madd("Link", - ["Fischer-Tropsch-demand"], - bus0="Fischer-Tropsch", - bus1="Fischer-Tropsch-demand", - bus2="co2 atmosphere", - carrier="Fischer-Tropsch-demand", - efficiency=1., - efficiency2=costs.at["oil",'CO2 intensity'], - p_nom_extendable=True) - network.madd("Load", ["naphtha for industry"], - bus="Fischer-Tropsch-demand", + bus="Fischer-Tropsch", carrier="naphtha for industry", p_set = industrial_demand.loc[nodes,"naphtha"].sum()/8760.) network.madd("Load", ["kerosene for aviation"], - bus="Fischer-Tropsch-demand", + bus="Fischer-Tropsch", carrier="kerosene for aviation", p_set = nodal_energy_totals.loc[nodes,["total international aviation","total domestic aviation"]].sum(axis=1).sum()*1e6/8760.) + #NB: CO2 gets released again to atmosphere when plastics decay or kerosene is burned + #except for the process emissions when naphtha is used for petrochemicals, which can be captured with other industry process emissions + #tco2 per hour + co2 = network.loads.loc[["naphtha for industry","kerosene for aviation"],"p_set"].sum()*costs.at["oil",'CO2 intensity'] - industrial_demand.loc[nodes,"process emission from feedstock"].sum()/8760. + + network.madd("Load", + ["Fischer-Tropsch emissions"], + bus="co2 atmosphere", + carrier="Fischer-Tropsch emissions", + p_set=-co2) + network.madd("Load", nodes, suffix=" low-temperature heat for industry", @@ -1298,7 +1294,7 @@ def add_industry(network): ["process emissions"], bus="process emissions", carrier="process emissions", - p_set = -industrial_demand.loc[nodes,"process emission"].sum()/8760.) + p_set = -industrial_demand.loc[nodes,["process emission","process emission from feedstock"]].sum(axis=1).sum()/8760.) network.madd("Link", ["process emissions"],