Separate ammonia from other "Basic chemicals"
This allows us to control the substitution of natural gas for hydrogen in NH3 production. Remaining basic chemicals are olefins, BTX and chlorine. For 2015 NH3 production, we use the USGS data source.
This commit is contained in:
parent
b761281b3d
commit
f45b9a37ae
2
.gitignore
vendored
2
.gitignore
vendored
@ -43,3 +43,5 @@ gurobi.log
|
||||
config.yaml
|
||||
|
||||
doc/_build
|
||||
|
||||
*.xls
|
13
Snakefile
13
Snakefile
@ -146,8 +146,19 @@ rule build_biomass_potentials:
|
||||
resources: mem_mb=1000
|
||||
script: 'scripts/build_biomass_potentials.py'
|
||||
|
||||
rule build_ammonia_production:
|
||||
input:
|
||||
usgs="data/myb1-2017-nitro.xls"
|
||||
output:
|
||||
ammonia_production="resources/ammonia_production.csv"
|
||||
threads: 1
|
||||
resources: mem_mb=1000
|
||||
script: 'scripts/build_ammonia_production.py'
|
||||
|
||||
|
||||
rule build_industry_sector_ratios:
|
||||
input:
|
||||
ammonia_production="resources/ammonia_production.csv"
|
||||
output:
|
||||
industry_sector_ratios="resources/industry_sector_ratios.csv"
|
||||
threads: 1
|
||||
@ -156,6 +167,8 @@ rule build_industry_sector_ratios:
|
||||
|
||||
|
||||
rule build_industrial_production_per_country:
|
||||
input:
|
||||
ammonia_production="resources/ammonia_production.csv"
|
||||
output:
|
||||
industrial_production_per_country="resources/industrial_production_per_country.csv"
|
||||
threads: 1
|
||||
|
@ -161,7 +161,10 @@ industry:
|
||||
'St_primary_fraction' : 0.3 # fraction of steel produced via primary route (DRI + EAF) versus secondary route (EAF); today fraction is 0.6
|
||||
'H2_DRI' : 1.7 #H2 consumption in Direct Reduced Iron (DRI), MWh_H2,LHV/ton_Steel from Vogl et al (2018) doi:10.1016/j.jclepro.2018.08.279
|
||||
'Al_primary_fraction' : 0.2 # fraction of aluminium produced via the primary route versus scrap; today fraction is 0.4
|
||||
'H2_for_NH3' : 85000 # H2 in GWh/a for 17 MtNH3/a transformed from SMR to electrolyzed-H2, following Lechtenböhmer(2016)
|
||||
'MWh_CH4_per_tNH3_SMR' : 10.8 # 2012's demand from https://ec.europa.eu/docsroom/documents/4165/attachments/1/translations/en/renditions/pdf
|
||||
'MWh_elec_per_tNH3_SMR' : 0.7 # same source, assuming 94-6% split methane-elec of total energy demand 11.5 MWh/tNH3
|
||||
'MWh_H2_per_tNH3_electrolysis' : 6.5 # from https://doi.org/10.1016/j.joule.2018.04.017, around 0.197 tH2/tHN3 (>3/17 since some H2 lost and used for energy)
|
||||
'MWh_elec_per_tNH3_electrolysis' : 1.17 # from https://doi.org/10.1016/j.joule.2018.04.017 Table 13 (air separation and HB)
|
||||
'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
|
||||
|
||||
|
@ -161,7 +161,10 @@ industry:
|
||||
'St_primary_fraction' : 0.3 # fraction of steel produced via primary route (DRI + EAF) versus secondary route (EAF); today fraction is 0.6
|
||||
'H2_DRI' : 1.7 #H2 consumption in Direct Reduced Iron (DRI), MWh_H2,LHV/ton_Steel from Vogl et al (2018) doi:10.1016/j.jclepro.2018.08.279
|
||||
'Al_primary_fraction' : 0.2 # fraction of aluminium produced via the primary route versus scrap; today fraction is 0.4
|
||||
'H2_for_NH3' : 85000 # H2 in GWh/a for 17 MtNH3/a transformed from SMR to electrolyzed-H2, following Lechtenböhmer(2016)
|
||||
'MWh_CH4_per_tNH3_SMR' : 10.8 # 2012's demand from https://ec.europa.eu/docsroom/documents/4165/attachments/1/translations/en/renditions/pdf
|
||||
'MWh_elec_per_tNH3_SMR' : 0.7 # same source, assuming 94-6% split methane-elec of total energy demand 11.5 MWh/tNH3
|
||||
'MWh_H2_per_tNH3_electrolysis' : 6.5 # from https://doi.org/10.1016/j.joule.2018.04.017, around 0.197 tH2/tHN3 (>3/17 since some H2 lost and used for energy)
|
||||
'MWh_elec_per_tNH3_electrolysis' : 1.17 # from https://doi.org/10.1016/j.joule.2018.04.017 Table 13 (air separation and HB)
|
||||
'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
|
||||
|
||||
|
45
scripts/build_ammonia_production.py
Normal file
45
scripts/build_ammonia_production.py
Normal file
@ -0,0 +1,45 @@
|
||||
|
||||
|
||||
import pandas as pd
|
||||
|
||||
ammonia = pd.read_excel(snakemake.input.usgs,
|
||||
sheet_name="T12",
|
||||
skiprows=5,
|
||||
header=0,
|
||||
index_col=0,
|
||||
skipfooter=19)
|
||||
|
||||
rename = {"Austriae" : "AT",
|
||||
"Bulgaria" : "BG",
|
||||
"Belgiume" : "BE",
|
||||
"Croatia" : "HR",
|
||||
"Czechia" : "CZ",
|
||||
"Estonia" : "EE",
|
||||
"Finland" : "FI",
|
||||
"France" : "FR",
|
||||
"Germany" : "DE",
|
||||
"Greece" : "GR",
|
||||
"Hungarye" : "HU",
|
||||
"Italye" : "IT",
|
||||
"Lithuania" : "LT",
|
||||
"Netherlands" : "NL",
|
||||
"Norwaye" : "NO",
|
||||
"Poland" : "PL",
|
||||
"Romania" : "RO",
|
||||
"Serbia" : "RS",
|
||||
"Slovakia" : "SK",
|
||||
"Spain" : "ES",
|
||||
"Switzerland" : "CH",
|
||||
"United Kingdom" : "GB",
|
||||
}
|
||||
|
||||
ammonia = ammonia.rename(rename)
|
||||
|
||||
ammonia = ammonia.loc[rename.values(),[str(i) for i in range(2013,2018)]].astype(float)
|
||||
|
||||
#convert from ktonN to ktonNH3
|
||||
ammonia = ammonia*17/14
|
||||
|
||||
ammonia.index.name = "ktonNH3/a"
|
||||
|
||||
ammonia.to_csv(snakemake.output.ammonia_production)
|
@ -9,6 +9,10 @@ ktoe_to_twh = 0.01163
|
||||
jrc_base_dir = "data/jrc-idees-2015"
|
||||
eb_base_dir = "data/eurostat-energy_balances-may_2018_edition"
|
||||
|
||||
# year for which data is retrieved
|
||||
raw_year = 2015
|
||||
year = raw_year-2016
|
||||
|
||||
sub_sheet_name_dict = { 'Iron and steel':'ISI',
|
||||
'Chemicals Industry':'CHI',
|
||||
'Non-metallic mineral products': 'NMM',
|
||||
@ -162,7 +166,7 @@ for country in countries:
|
||||
#energy consumption in the sector and EU28
|
||||
excel_sum_out = pd.read_excel('{}/JRC-IDEES-2015_Industry_EU28.xlsx'.format(jrc_base_dir),
|
||||
sheet_name='Ind_Summary', index_col=0,header=0,squeeze=True) # the summary sheet
|
||||
s_sum_out = excel_sum_out.iloc[49:76,-1]
|
||||
s_sum_out = excel_sum_out.iloc[49:76,year]
|
||||
e_EU28 = s_sum_out[dic_sec_summary[sector]]
|
||||
|
||||
ratio_country_EU28=e_country/e_EU28
|
||||
@ -170,7 +174,7 @@ for country in countries:
|
||||
excel_out = pd.read_excel('{}/JRC-IDEES-2015_Industry_EU28.xlsx'.format(jrc_base_dir),
|
||||
sheet_name=sub_sheet_name_dict[sector],index_col=0,header=0,squeeze=True) # the summary sheet
|
||||
|
||||
s_out = excel_out.iloc[loc_dic[sector][0]:loc_dic[sector][1],-1]
|
||||
s_out = excel_out.iloc[loc_dic[sector][0]:loc_dic[sector][1],year]
|
||||
|
||||
for subsector in sect2sub[sector]:
|
||||
countries_demand.loc[country,subsector] = ratio_country_EU28*s_out[out_dic[subsector]]
|
||||
@ -180,11 +184,34 @@ for country in countries:
|
||||
# read the input sheets
|
||||
excel_out = pd.read_excel('{}/JRC-IDEES-2015_Industry_{}.xlsx'.format(jrc_base_dir,jrc_names.get(country,country)), sheet_name=sub_sheet_name_dict[sector],index_col=0,header=0,squeeze=True) # the summary sheet
|
||||
|
||||
s_out = excel_out.iloc[loc_dic[sector][0]:loc_dic[sector][1],-1]
|
||||
s_out = excel_out.iloc[loc_dic[sector][0]:loc_dic[sector][1],year]
|
||||
|
||||
for subsector in sect2sub[sector]:
|
||||
countries_demand.loc[country,subsector] = s_out[out_dic[subsector]]
|
||||
|
||||
|
||||
#include ammonia demand separately and remove ammonia from basic chemicals
|
||||
|
||||
ammonia = pd.read_csv(snakemake.input.ammonia_production,
|
||||
index_col=0)
|
||||
|
||||
there = ammonia.index.intersection(countries_demand.index)
|
||||
missing = countries_demand.index^there
|
||||
|
||||
print("Following countries have no ammonia demand:", missing)
|
||||
|
||||
countries_demand.insert(2,"Ammonia",0.)
|
||||
|
||||
countries_demand.loc[there,"Ammonia"] = ammonia.loc[there, str(raw_year)]
|
||||
|
||||
countries_demand["Basic chemicals"] -= countries_demand["Ammonia"]
|
||||
|
||||
#EE, HR and LT got negative demand through subtraction - poor data
|
||||
countries_demand.loc[countries_demand["Basic chemicals"] < 0.,"Basic chemicals"] = 0.
|
||||
|
||||
countries_demand.rename(columns={"Basic chemicals" : "Basic chemicals (without ammonia)"},
|
||||
inplace=True)
|
||||
|
||||
countries_demand.index.name = "kton/a"
|
||||
|
||||
countries_demand.to_csv(snakemake.output.industrial_production_per_country,
|
||||
|
@ -5,11 +5,11 @@ import numpy as np
|
||||
|
||||
base_dir = "data/jrc-idees-2015"
|
||||
|
||||
# year for wich data is retrieved
|
||||
year = 2015
|
||||
year = year-2016
|
||||
# year for which data is retrieved
|
||||
raw_year = 2015
|
||||
year = raw_year-2016
|
||||
|
||||
conv_factor=11.630 #ktoe/kton -> MWh/ton
|
||||
conv_factor=11.630 #GWh/ktoe OR MWh/toe
|
||||
|
||||
country = 'EU28'
|
||||
|
||||
@ -185,6 +185,8 @@ excel_emi = pd.read_excel('{}/JRC-IDEES-2015_Industry_{}.xlsx'.format(base_dir,c
|
||||
|
||||
### Basic chemicals
|
||||
|
||||
## Ammonia is separate afterwards
|
||||
|
||||
sector = 'Basic chemicals'
|
||||
|
||||
df[sector] = 0
|
||||
@ -203,9 +205,8 @@ df.loc['heat',sector] += s_fec['Low enthalpy heat']
|
||||
#### Chemicals: Feedstock (energy used as raw material)
|
||||
#> There are Solids, Refinery gas, LPG, Diesel oil, Residual fuel oil, Other liquids, Naphtha, Natural gas for feedstock.
|
||||
#
|
||||
#> Naphta represents 47%, methane 17%. LPG (18%) solids, refinery gas, diesel oil, residual fuel oils and other liquids are asimilated to Napthta
|
||||
#
|
||||
#> Following Lechtenbohmer 2016, the 85 TWh/year of methane for the ammonia industry are substited by hydrogen.
|
||||
#> Naphta represents 47%, methane 17%. LPG (18%) solids, refinery gas, diesel oil, residual fuel oils and other liquids are asimilated to Naphtha
|
||||
|
||||
|
||||
subsector = 'Chemicals: Feedstock (energy used as raw material)'
|
||||
|
||||
@ -218,10 +219,7 @@ assert s_fec.index[0] == subsector
|
||||
df.loc['naphtha',sector] += s_fec['Naphtha']
|
||||
|
||||
# natural gas
|
||||
# 85 TWh/year of methane for the ammonia industry are substituted by hydrogen
|
||||
df.loc['methane',sector] += s_fec['Natural gas'] - snakemake.config["industry"]["H2_for_NH3"]/conv_factor
|
||||
df.loc['hydrogen',sector] += snakemake.config["industry"]["H2_for_NH3"]/conv_factor
|
||||
# 1 ktoe = 11630 MWh
|
||||
df.loc['methane',sector] += s_fec['Natural gas']
|
||||
|
||||
# LPG and other feedstock materials are assimilated to naphtha since they will be produced trough Fischer-Tropsh process
|
||||
df.loc['naphtha',sector] += (s_fec['Solids'] + s_fec['Refinery gas'] + s_fec['LPG'] + s_fec['Diesel oil']
|
||||
@ -244,8 +242,10 @@ assert s_fec.index[0] == subsector
|
||||
# efficiency of biomass
|
||||
eff_bio = s_ued['Biomass']/s_fec['Biomass']
|
||||
|
||||
# replace all fec by biomass
|
||||
df.loc['biomass',sector] += s_ued[subsector]/eff_bio
|
||||
# replace all non-methane fec by biomass
|
||||
df.loc['biomass',sector] += (s_ued[subsector]-s_ued['Natural gas (incl. biogas)'])/eff_bio
|
||||
|
||||
df.loc['methane',sector] += s_fec['Natural gas (incl. biogas)']
|
||||
|
||||
#### Chemicals: Furnaces
|
||||
#> assume fully electrified
|
||||
@ -297,10 +297,25 @@ s_emi = excel_emi.iloc[3:57,year]
|
||||
|
||||
assert s_emi.index[0] == sector
|
||||
|
||||
|
||||
## Correct everything by subtracting 2015's ammonia demand and putting in ammonia demand for H2 and electricity separately
|
||||
|
||||
s_out = excel_out.iloc[8:9,year]
|
||||
|
||||
assert sector in str(s_out.index)
|
||||
|
||||
ammonia = pd.read_csv(snakemake.input.ammonia_production,
|
||||
index_col=0)
|
||||
|
||||
eu28 = ['FR', 'DE', 'GB', 'IT', 'ES', 'PL', 'SE', 'NL', 'BE', 'FI',
|
||||
'DK', 'PT', 'RO', 'AT', 'BG', 'EE', 'GR', 'LV', 'CZ',
|
||||
'HU', 'IE', 'SK', 'LT', 'HR', 'LU', 'SI', 'CY', 'MT']
|
||||
|
||||
#ktNH3/a
|
||||
total_ammonia = ammonia.loc[ammonia.index.intersection(eu28),str(raw_year)].sum()
|
||||
|
||||
s_out -= total_ammonia
|
||||
|
||||
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
|
||||
@ -310,8 +325,24 @@ df.loc['process emission from feedstock',sector] += (snakemake.config["industry"
|
||||
# final energy consumption per t
|
||||
sources=['elec','biomass', 'methane', 'hydrogen', 'heat','naphtha']
|
||||
|
||||
df.loc[sources,sector] = df.loc[sources,sector]*conv_factor/s_out.values# unit MWh/t material
|
||||
# 1 ktoe = 11630 MWh
|
||||
#convert from ktoe/a to GWh/a
|
||||
df.loc[sources,sector] *= conv_factor
|
||||
|
||||
df.loc['methane',sector] -= total_ammonia*snakemake.config['industry']['MWh_CH4_per_tNH3_SMR']
|
||||
df.loc['elec',sector] -= total_ammonia*snakemake.config['industry']['MWh_elec_per_tNH3_SMR']
|
||||
|
||||
df.loc[sources,sector] = df.loc[sources,sector]/s_out.values # unit MWh/t material
|
||||
|
||||
df.rename(columns={sector : sector + " (without ammonia)"},
|
||||
inplace=True)
|
||||
|
||||
sector = 'Ammonia'
|
||||
|
||||
df[sector] = 0.
|
||||
|
||||
df.loc['hydrogen',sector] = snakemake.config['industry']['MWh_H2_per_tNH3_electrolysis']
|
||||
df.loc['elec',sector] = snakemake.config['industry']['MWh_elec_per_tNH3_electrolysis']
|
||||
|
||||
|
||||
### Other chemicals
|
||||
|
||||
@ -404,7 +435,7 @@ df.loc['process emission',sector] += s_emi['Process emissions']/s_out.values # u
|
||||
# final energy consumption per t
|
||||
sources=['elec','biomass', 'methane', 'hydrogen', 'heat','naphtha']
|
||||
|
||||
df.loc[sources,sector] = df.loc[sources,sector]*11.630/s_out.values # unit MWh/t material
|
||||
df.loc[sources,sector] = df.loc[sources,sector]*conv_factor/s_out.values # unit MWh/t material
|
||||
# 1 ktoe = 11630 MWh
|
||||
|
||||
### Pharmaceutical products etc.
|
||||
@ -494,7 +525,7 @@ df.loc['process emission',sector] += 0 # unit tCO2/t material
|
||||
# final energy consumption per t
|
||||
sources=['elec','biomass', 'methane', 'hydrogen', 'heat', 'naphtha']
|
||||
|
||||
df.loc[sources,sector] = df.loc[sources,sector]*11.630/s_out.values # unit MWh/t material
|
||||
df.loc[sources,sector] = df.loc[sources,sector]*conv_factor/s_out.values # unit MWh/t material
|
||||
# 1 ktoe = 11630 MWh
|
||||
|
||||
## Non-metallic mineral products
|
||||
@ -634,7 +665,7 @@ df.loc['process emission',sector] += s_emi['Process emissions']/s_out.values # u
|
||||
# final energy consumption per t
|
||||
sources=['elec','biomass', 'methane', 'hydrogen', 'heat','naphtha']
|
||||
|
||||
df.loc[sources,sector] = df.loc[sources,sector]*11.630/s_out.values # unit MWh/t material
|
||||
df.loc[sources,sector] = df.loc[sources,sector]*conv_factor/s_out.values # unit MWh/t material
|
||||
# 1 ktoe = 11630 MWh
|
||||
|
||||
### Glass production
|
||||
|
Loading…
Reference in New Issue
Block a user