From c3dcff8a35ce24e7256142fe8f33f041e4f24264 Mon Sep 17 00:00:00 2001 From: Thomas Gilon Date: Tue, 14 May 2024 16:40:31 +0200 Subject: [PATCH] Define methanol energy demand for industry --- config/config.default.yaml | 2 + doc/configtables/industry.csv | 1 + doc/configtables/sector.csv | 2 +- doc/release_notes.rst | 2 + doc/supply_demand.rst | 7 +- scripts/build_industry_sector_ratios.py | 4 +- scripts/prepare_sector_network.py | 120 ++++++++++++++++-------- 7 files changed, 93 insertions(+), 45 deletions(-) diff --git a/config/config.default.yaml b/config/config.default.yaml index 0ac068479..87ff3780c 100644 --- a/config/config.default.yaml +++ b/config/config.default.yaml @@ -706,6 +706,7 @@ industry: methanol_production_today: 1.5 MWh_elec_per_tMeOH: 0.167 MWh_CH4_per_tMeOH: 10.25 + MWh_MeOH_per_tMeOH: 5.528 hotmaps_locate_missing: false reference_year: 2015 @@ -1146,6 +1147,7 @@ plotting: methanolisation: '#83d6d5' methanol: '#468c8b' shipping methanol: '#468c8b' + industry methanol: '#468c8b' # co2 CC: '#f29dae' CCS: '#f29dae' diff --git a/doc/configtables/industry.csv b/doc/configtables/industry.csv index cee06c974..4187e1183 100644 --- a/doc/configtables/industry.csv +++ b/doc/configtables/industry.csv @@ -32,5 +32,6 @@ MWh_H2_per_tCl,MWhH2/tCl,float,"The energy amount of hydrogen needed to produce methanol_production _today,MtMeOH/a,float,"The amount of methanol produced. From `DECHEMA (2017) `_, page 62" MWh_elec_per_tMeOH,MWh/tMeOH,float,"The energy amount of electricity needed to produce a ton of methanol. From `DECHEMA (2017) `_, Table 14, page 65" MWh_CH4_per_tMeOH,MWhCH4/tMeOH,float,"The energy amount of methane needed to produce a ton of methanol. From `DECHEMA (2017) `_, Table 14, page 65" +MWh_MeOH_per_tMeOH,LHV,float,"The energy amount per ton of methanol. From `DECHEMA (2017) `_, page 74." hotmaps_locate_missing,--,"{true,false}",Locate industrial sites without valid locations based on city and countries. reference_year,year,YYYY,The year used as the baseline for industrial energy demand and production. Data extracted from `JRC-IDEES 2015 `_ diff --git a/doc/configtables/sector.csv b/doc/configtables/sector.csv index 703652b50..901688882 100644 --- a/doc/configtables/sector.csv +++ b/doc/configtables/sector.csv @@ -39,7 +39,7 @@ agriculture_machinery _oil_share,--,float,The share for agricultural machinery t agriculture_machinery _fuel_efficiency,--,float,The efficiency of electric-powered machinery in the conversion of electricity to meet agricultural needs. agriculture_machinery _electric_efficiency,--,float,The efficiency of oil-powered machinery in the conversion of oil to meet agricultural needs. Mwh_MeOH_per_MWh_H2,LHV,float,"The energy amount of the produced methanol per energy amount of hydrogen. From `DECHEMA (2017) `_, page 64." -MWh_MeOH_per_tCO2,LHV,float,"The energy amount of the produced methanol per ton of CO2. From `DECHEMA (2017) `_, page 64." +MWh_MeOH_per_tCO2,LHV,float,"The energy amount of the produced methanol per ton of CO2. From `DECHEMA (2017) `_, page 66." MWh_MeOH_per_MWh_e,LHV,float,"The energy amount of the produced methanol per energy amount of electricity. From `DECHEMA (2017) `_, page 64." shipping_hydrogen _liquefaction,--,"{true, false}",Whether to include liquefaction costs for hydrogen demand in shipping. ,,, diff --git a/doc/release_notes.rst b/doc/release_notes.rst index b70a27f6a..72d34f306 100644 --- a/doc/release_notes.rst +++ b/doc/release_notes.rst @@ -280,6 +280,8 @@ Upcoming Release * Fix gas network retrofitting in `add_brownfield`. +* Change the methanol energy demand of industry to the low-carbon route defined by `DECHEMA report `__. + PyPSA-Eur 0.10.0 (19th February 2024) ===================================== diff --git a/doc/supply_demand.rst b/doc/supply_demand.rst index ab58368f7..e5646fcb0 100644 --- a/doc/supply_demand.rst +++ b/doc/supply_demand.rst @@ -459,8 +459,7 @@ Statistics for the production of ammonia, which is commonly used as a fertilizer The Haber-Bosch process is not explicitly represented in the model, such that demand for ammonia enters the model as a demand for hydrogen ( 6.5 MWh :math:`_{H_2}` / t :math:`_{NH_3}` ) and electricity ( 1.17 MWh :math:`_{el}` /t :math:`_{NH_3}` ) (see `Wang et. al `__). Today, natural gas dominates in Europe as the source for the hydrogen used in the Haber-Bosch process, but the model can choose among the various hydrogen supply options described in the hydrogen section (see :ref:`Hydrogen supply`) -The total production and specific energy consumption of chlorine and methanol is taken from a `DECHEMA report `__. According to this source, the production of chlorine amounts to 9.58 MtCl/a, which is assumed to require electricity at 3.6 MWh :math:`_{el}`/t of chlorine and yield hydrogen at 0.937 MWh :math:`_{H_2}`/t of chlorine in the chloralkali process. The production of methanol adds up to 1.5 MtMeOH/a, requiring electricity at 0.167 MWh :math:`_{el}`/t of methanol and methane at 10.25 MWh :math:`_{CH_4}`/t of methanol. - +The total production and specific energy consumption of chlorine and methanol is taken from a `DECHEMA report `__. According to this source, the production of chlorine amounts to 9.58 MtCl/a, which is assumed to require electricity at 3.6 MWh :math:`_{el}`/t of chlorine and yield hydrogen at 0.937 MWh :math:`_{H_2}`/t of chlorine in the chloralkali process. The production of methanol adds up to 1.5 MtMeOH/a. Low-carbon methanol production (or methanolisation) by hydrogenation of :math:`CO_2` requires hydrogen at 6.299 MWh :math:`_{H_2}`/t of methanol, carbon dioxide at 1.373 t :math:`_{CO_2}`/t of methanol and electricity at 1.5 MWh :math:`_{el}`/t of methanol. The energy content of methanol is 5.528 MWh :math:`_{MeOH}`/t of methanol. These values are set exogenously in the config file. The production of ammonia, methanol, and chlorine production is deducted from the JRC IDEES basic chemicals, leaving the production totals of high-value chemicals. For this, we assume that the liquid hydrocarbon feedstock comes from synthetic or fossil- origin naphtha (14 MWh :math:`_{naphtha}`/t of HVC, similar to `Lechtenböhmer et al `__), ignoring the methanol-to-olefin route. Furthermore, we assume the following transformations of the energy-consuming processes in the production of plastics: the final energy consumption in steam processing is converted to methane since requires temperature above 500 °C (4.1 MWh :math:`_{CH_4}` /t of HVC, see `Rehfeldt et al. `__); and the remaining processes are electrified using the current efficiency of microwave for high-enthalpy heat processing, electric furnaces, electric process cooling and electric generic processes (2.85 MWh :math:`_{el}`/t of HVC). @@ -573,7 +572,7 @@ The `demand for aviation `__. +Shipping energy demand is covered by a combination of oil, hydrogen and methanol. Other fuel options, like ammonia, are currently not included in PyPSA-Eur-Sec. The share of shipping that is assumed to be supplied by hydrogen or methanol can be selected in the `config file `__. To estimate the `hydrogen demand `__, the average fuel efficiency of the fleet is used in combination with the efficiency of the fuel cell defined in the technology-data repository. The average fuel efficiency is set in the `config file `__. @@ -581,6 +580,8 @@ The consumed hydrogen comes from the general hydrogen bus where it can be produc The energy demand for liquefaction of the hydrogen used for shipping can be `included `__. If this option is selected, liquifaction will happen at the `node where the shipping demand occurs `__. +The consumed methanol comes from the general methanol bus where it is produced through methanolisation (see :ref:`Chemicals Industry`). + .. _Carbon dioxide capture, usage and sequestration (CCU/S): Carbon dioxide capture, usage and sequestration (CCU/S) diff --git a/scripts/build_industry_sector_ratios.py b/scripts/build_industry_sector_ratios.py index 87c80c0de..06c8ecb7d 100644 --- a/scripts/build_industry_sector_ratios.py +++ b/scripts/build_industry_sector_ratios.py @@ -68,6 +68,7 @@ "heat", "naphtha", "ammonia", + "methanol", "process emission", "process emission from feedstock", ] @@ -456,8 +457,7 @@ def chemicals_industry(): sector = "Methanol" df[sector] = 0.0 - df.loc["methane", sector] = params["MWh_CH4_per_tMeOH"] - df.loc["elec", sector] = params["MWh_elec_per_tMeOH"] + df.loc["methanol", sector] = params["MWh_MeOH_per_tMeOH"] # Other chemicals diff --git a/scripts/prepare_sector_network.py b/scripts/prepare_sector_network.py index d99cceaab..f8d7dc22d 100755 --- a/scripts/prepare_sector_network.py +++ b/scripts/prepare_sector_network.py @@ -146,10 +146,12 @@ def define_spatial(nodes, options): if options["regional_methanol_demand"]: spatial.methanol.demand_locations = nodes + spatial.methanol.industry = nodes + " industry methanol" spatial.methanol.shipping = nodes + " shipping methanol" else: spatial.methanol.demand_locations = ["EU"] spatial.methanol.shipping = ["EU shipping methanol"] + spatial.methanol.industry = ["EU industry methanol"] # oil spatial.oil = SimpleNamespace() @@ -2760,57 +2762,97 @@ def add_industry(n, costs): p_set=p_set_hydrogen, ) - if shipping_methanol_share: - n.madd( - "Bus", - spatial.methanol.nodes, - carrier="methanol", - location=spatial.methanol.locations, - unit="MWh_LHV", - ) + n.madd( + "Bus", + spatial.methanol.nodes, + carrier="methanol", + location=spatial.methanol.locations, + unit="MWh_LHV", + ) - n.madd( - "Store", - spatial.methanol.nodes, - suffix=" Store", - bus=spatial.methanol.nodes, - e_nom_extendable=True, - e_cyclic=True, - carrier="methanol", - ) + n.madd( + "Store", + spatial.methanol.nodes, + suffix=" Store", + bus=spatial.methanol.nodes, + e_nom_extendable=True, + e_cyclic=True, + carrier="methanol", + ) - n.madd( - "Link", - spatial.h2.locations + " methanolisation", - bus0=spatial.h2.nodes, - bus1=spatial.methanol.nodes, - bus2=nodes, - bus3=spatial.co2.nodes, - carrier="methanolisation", - p_nom_extendable=True, - p_min_pu=options.get("min_part_load_methanolisation", 0), - capital_cost=costs.at["methanolisation", "fixed"] - * options["MWh_MeOH_per_MWh_H2"], # EUR/MW_H2/a - marginal_cost=options["MWh_MeOH_per_MWh_H2"] - * costs.at["methanolisation", "VOM"], - lifetime=costs.at["methanolisation", "lifetime"], - efficiency=options["MWh_MeOH_per_MWh_H2"], - efficiency2=-options["MWh_MeOH_per_MWh_H2"] / options["MWh_MeOH_per_MWh_e"], - efficiency3=-options["MWh_MeOH_per_MWh_H2"] / options["MWh_MeOH_per_tCO2"], - ) + n.madd( + "Bus", + spatial.methanol.industry, + carrier="industry methanol", + location=spatial.methanol.demand_locations, + unit="MWh_LHV", + ) + + p_set_methanol = ( + industrial_demand["methanol"] + .rename(lambda x: x + " industry methanol") + / nhours + ) + if not options["regional_methanol_demand"]: + p_set_methanol = p_set_methanol.sum() + + n.madd( + "Load", + spatial.methanol.industry, + bus=spatial.methanol.industry, + carrier="industry methanol", + p_set=p_set_methanol, + ) + + n.madd( + "Link", + spatial.methanol.industry, + bus0=spatial.methanol.nodes, + bus1=spatial.methanol.industry, + bus2="co2 atmosphere", + carrier="industry methanol", + p_nom_extendable=True, + efficiency2=1 + / options[ + "MWh_MeOH_per_tCO2" + ], + # CO2 intensity methanol based on stoichiometric calculation with 22.7 GJ/t methanol (32 g/mol), CO2 (44 g/mol), 277.78 MWh/TJ = 0.218 t/MWh + ) + + n.madd( + "Link", + spatial.h2.locations + " methanolisation", + bus0=spatial.h2.nodes, + bus1=spatial.methanol.nodes, + bus2=nodes, + bus3=spatial.co2.nodes, + carrier="methanolisation", + p_nom_extendable=True, + p_min_pu=options.get("min_part_load_methanolisation", 0), + capital_cost=costs.at["methanolisation", "fixed"] + * options["MWh_MeOH_per_MWh_H2"], # EUR/MW_H2/a + marginal_cost=options["MWh_MeOH_per_MWh_H2"] + * costs.at["methanolisation", "VOM"], + lifetime=costs.at["methanolisation", "lifetime"], + efficiency=options["MWh_MeOH_per_MWh_H2"], + efficiency2=-options["MWh_MeOH_per_MWh_H2"] / options["MWh_MeOH_per_MWh_e"], + efficiency3=-options["MWh_MeOH_per_MWh_H2"] / options["MWh_MeOH_per_tCO2"], + ) + + if shipping_methanol_share: efficiency = ( options["shipping_oil_efficiency"] / options["shipping_methanol_efficiency"] ) - p_set_methanol = ( + p_set_methanol_shipping = ( shipping_methanol_share * p_set.rename(lambda x: x + " shipping methanol") * efficiency ) if not options["regional_methanol_demand"]: - p_set_methanol = p_set_methanol.sum() + p_set_methanol_shipping = p_set_methanol_shipping.sum() n.madd( "Bus", @@ -2825,7 +2867,7 @@ def add_industry(n, costs): spatial.methanol.shipping, bus=spatial.methanol.shipping, carrier="shipping methanol", - p_set=p_set_methanol, + p_set=p_set_methanol_shipping, ) n.madd(