From 3ff669b07b40745610a80cb1002e85e087431d23 Mon Sep 17 00:00:00 2001 From: Tom Brown Date: Wed, 9 Dec 2020 15:36:45 +0100 Subject: [PATCH 1/5] Move CO2 sequestration potential and costs to config.yaml --- config.default.yaml | 2 ++ scripts/prepare_sector_network.py | 8 +++----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/config.default.yaml b/config.default.yaml index 1885a8d0..3fd187c6 100644 --- a/config.default.yaml +++ b/config.default.yaml @@ -139,6 +139,8 @@ sector: 'dac' : True 'co2_vent' : True 'SMR' : True + 'co2_sequestration_potential' : 200 #MtCO2/a sequestration potential for Europe + 'co2_sequestration_cost' : 20 #EUR/tCO2 for transport and sequestration of CO2 'ccs_fraction' : 0.9 'hydrogen_underground_storage' : True 'use_fischer_tropsch_waste_heat' : True diff --git a/scripts/prepare_sector_network.py b/scripts/prepare_sector_network.py index 7105f806..20115c34 100644 --- a/scripts/prepare_sector_network.py +++ b/scripts/prepare_sector_network.py @@ -193,12 +193,10 @@ def add_co2_tracking(n): location="EU", carrier="co2 stored") - #TODO move cost to data/costs.csv - #TODO move maximum somewhere more transparent n.madd("Store",["co2 stored"], - e_nom_extendable = True, - e_nom_max=2e8, - capital_cost=20., + e_nom_extendable=True, + e_nom_max=options['co2_sequestration_potential']*1e6, + capital_cost=options['co2_sequestration_cost'], carrier="co2 stored", bus="co2 stored") From 608c9a5ac50389548ba46fb4a08a4231e4205fdb Mon Sep 17 00:00:00 2001 From: Tom Brown Date: Wed, 9 Dec 2020 16:38:49 +0100 Subject: [PATCH 2/5] Replace gas and solid biomass CHP CCS with CHP + DEA CC Use DEA assumptions for post-combustion carbon capture. Also rename CCS as CC whenever only carbon capture is involved, since sequestration (or CCU) is a separate step. --- config.default.yaml | 2 +- scripts/plot_summary.py | 2 +- scripts/prepare_sector_network.py | 90 +++++++++++++++---------------- 3 files changed, 47 insertions(+), 47 deletions(-) diff --git a/config.default.yaml b/config.default.yaml index 3fd187c6..52794c3d 100644 --- a/config.default.yaml +++ b/config.default.yaml @@ -141,7 +141,7 @@ sector: 'SMR' : True 'co2_sequestration_potential' : 200 #MtCO2/a sequestration potential for Europe 'co2_sequestration_cost' : 20 #EUR/tCO2 for transport and sequestration of CO2 - 'ccs_fraction' : 0.9 + 'cc_fraction' : 0.9 # default fraction of CO2 captured with post-combustion capture 'hydrogen_underground_storage' : True 'use_fischer_tropsch_waste_heat' : True 'use_fuel_cell_waste_heat' : True diff --git a/scripts/plot_summary.py b/scripts/plot_summary.py index 9ecea108..7f37159c 100644 --- a/scripts/plot_summary.py +++ b/scripts/plot_summary.py @@ -22,7 +22,7 @@ def rename_techs(label): "retrofitting" : "building retrofitting", "H2" : "hydrogen storage", "battery" : "battery storage", - "CCS" : "CCS"} + "CC" : "CC"} rename = {"solar" : "solar PV", "Sabatier" : "methanation", diff --git a/scripts/prepare_sector_network.py b/scripts/prepare_sector_network.py index 20115c34..bff5cdef 100644 --- a/scripts/prepare_sector_network.py +++ b/scripts/prepare_sector_network.py @@ -218,7 +218,7 @@ def add_co2_tracking(n): marginal_cost=75., efficiency=1., p_nom_extendable=True, - lifetime=costs.at['DAC','lifetime']) + lifetime=costs.at['direct air capture','lifetime']) def add_co2limit(n, Nyears=1.,limit=0.): @@ -936,18 +936,18 @@ def add_storage(network): if options['SMR']: network.madd("Link", - nodes + " SMR CCS", + nodes + " SMR CC", bus0=["EU gas"]*len(nodes), bus1=nodes+" H2", bus2="co2 atmosphere", bus3="co2 stored", p_nom_extendable=True, - carrier="SMR CCS", - 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"], - lifetime=costs.at['SMR CCS','lifetime']) + carrier="SMR CC", + efficiency=costs.at["SMR CC","efficiency"], + efficiency2=costs.at['gas','CO2 intensity']*(1-options["cc_fraction"]), + efficiency3=costs.at['gas','CO2 intensity']*options["cc_fraction"], + capital_cost=costs.at["SMR CC","fixed"], + lifetime=costs.at['SMR CC','lifetime']) network.madd("Link", nodes + " SMR", @@ -1241,21 +1241,21 @@ def add_heat(network): lifetime=costs.at['central gas CHP','lifetime']) network.madd("Link", - nodes[name] + " urban central gas CHP CCS", + nodes[name] + " urban central gas CHP CC", bus0="EU gas", bus1=nodes[name], bus2=nodes[name] + " urban central heat", bus3="co2 atmosphere", bus4="co2 stored", - carrier="urban central gas CHP CCS", + carrier="urban central gas CHP CC", p_nom_extendable=True, - capital_cost=costs.at['central gas CHP CCS','fixed']*costs.at['central gas CHP CCS','efficiency'], - marginal_cost=costs.at['central gas CHP CCS','VOM'], - efficiency=costs.at['central gas CHP CCS','efficiency'], - efficiency2=costs.at['central gas CHP CCS','efficiency']/costs.at['central gas CHP CCS','c_b'], - efficiency3=costs.at['gas','CO2 intensity']*(1-options["ccs_fraction"]), - efficiency4=costs.at['gas','CO2 intensity']*options["ccs_fraction"], - lifetime=costs.at['central gas CHP CCS','lifetime']) + capital_cost=costs.at['central gas CHP','fixed']*costs.at['central gas CHP','efficiency'] + costs.at['biomass CHP capture','fixed']*costs.at['gas','CO2 intensity'], + marginal_cost=costs.at['central gas CHP','VOM'], + efficiency=costs.at['central gas CHP','efficiency'] - costs.at['gas','CO2 intensity']*(costs.at['biomass CHP capture','electricity-input'] + costs.at['biomass CHP capture','compression-electricity-input']), + efficiency2=costs.at['central gas CHP','efficiency']/costs.at['central gas CHP','c_b'] + costs.at['gas','CO2 intensity']*(costs.at['biomass CHP capture','heat-output'] + costs.at['biomass CHP capture','compression-heat-output'] - costs.at['biomass CHP capture','heat-output']), + efficiency3=costs.at['gas','CO2 intensity']*(1-options["cc_fraction"]), + efficiency4=costs.at['gas','CO2 intensity']*options["cc_fraction"], + lifetime=costs.at['central gas CHP','lifetime']) else: if options["micro_chp"]: @@ -1460,21 +1460,21 @@ def add_biomass(network): lifetime=costs.at['central solid biomass CHP','lifetime']) network.madd("Link", - urban_central + " urban central solid biomass CHP CCS", + urban_central + " urban central solid biomass CHP CC", bus0="EU solid biomass", bus1=urban_central, bus2=urban_central + " urban central heat", bus3="co2 atmosphere", bus4="co2 stored", - carrier="urban central solid biomass CHP CCS", + carrier="urban central solid biomass CHP CC", p_nom_extendable=True, - capital_cost=costs.at['central solid biomass CHP CCS','fixed']*costs.at['central solid biomass CHP CCS','efficiency'], - marginal_cost=costs.at['central solid biomass CHP CCS','VOM'], - efficiency=costs.at['central solid biomass CHP CCS','efficiency'], - efficiency2=costs.at['central solid biomass CHP CCS','efficiency-heat'], - efficiency3=-costs.at['solid biomass','CO2 intensity']*options["ccs_fraction"], - efficiency4=costs.at['solid biomass','CO2 intensity']*options["ccs_fraction"], - lifetime=costs.at['central solid biomass CHP CCS','lifetime']) + capital_cost=costs.at['central solid biomass CHP','fixed']*costs.at['central solid biomass CHP','efficiency'] + costs.at['biomass CHP capture','fixed']*costs.at['solid biomass','CO2 intensity'], + marginal_cost=costs.at['central solid biomass CHP','VOM'], + efficiency=costs.at['central solid biomass CHP','efficiency'] - costs.at['solid biomass','CO2 intensity']*(costs.at['biomass CHP capture','electricity-input'] + costs.at['biomass CHP capture','compression-electricity-input']), + efficiency2=costs.at['central solid biomass CHP','efficiency-heat'] + costs.at['solid biomass','CO2 intensity']*(costs.at['biomass CHP capture','heat-output'] + costs.at['biomass CHP capture','compression-heat-output'] - costs.at['biomass CHP capture','heat-output']), + efficiency3=-costs.at['solid biomass','CO2 intensity']*options["cc_fraction"], + efficiency4=costs.at['solid biomass','CO2 intensity']*options["cc_fraction"], + lifetime=costs.at['central solid biomass CHP','lifetime']) @@ -1511,18 +1511,18 @@ def add_industry(network): efficiency=1.) network.madd("Link", - ["solid biomass for industry CCS"], + ["solid biomass for industry CC"], bus0="EU solid biomass", bus1="solid biomass for industry", bus2="co2 atmosphere", bus3="co2 stored", - carrier="solid biomass for industry CCS", + carrier="solid biomass for industry CC", p_nom_extendable=True, - capital_cost=costs.at["industry CCS","fixed"]*costs.at['solid biomass','CO2 intensity']*8760, #8760 converts EUR/(tCO2/a) to EUR/(tCO2/h) + capital_cost=costs.at["industry CC","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"], - lifetime=costs.at['industry CCS','lifetime']) + efficiency2=-costs.at['solid biomass','CO2 intensity']*options["cc_fraction"], + efficiency3=costs.at['solid biomass','CO2 intensity']*options["cc_fraction"], + lifetime=costs.at['industry CC','lifetime']) network.madd("Bus", @@ -1547,18 +1547,18 @@ def add_industry(network): efficiency2=costs.at['gas','CO2 intensity']) network.madd("Link", - ["gas for industry CCS"], + ["gas for industry CC"], bus0="EU gas", bus1="gas for industry", bus2="co2 atmosphere", bus3="co2 stored", - carrier="gas for industry CCS", + carrier="gas for industry CC", p_nom_extendable=True, - capital_cost=costs.at["industry CCS","fixed"]*costs.at['gas','CO2 intensity']*8760, #8760 converts EUR/(tCO2/a) to EUR/(tCO2/h) + capital_cost=costs.at["industry CC","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"], - lifetime=costs.at['industry CCS','lifetime']) + efficiency2=costs.at['gas','CO2 intensity']*(1-options["cc_fraction"]), + efficiency3=costs.at['gas','CO2 intensity']*options["cc_fraction"], + lifetime=costs.at['industry CC','lifetime']) network.madd("Load", @@ -1692,18 +1692,18 @@ def add_industry(network): p_nom_extendable=True, efficiency=1.) - #assume enough local waste heat for CCS + #assume enough local waste heat for CC network.madd("Link", - ["process emissions CCS"], + ["process emissions CC"], bus0="process emissions", bus1="co2 atmosphere", bus2="co2 stored", - carrier="process emissions CCS", + carrier="process emissions CC", 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"], - lifetime=costs.at['industry CCS','lifetime']) + capital_cost=costs.at["industry CC","fixed"]*8760, #8760 converts EUR/(tCO2/a) to EUR/(tCO2/h) + efficiency=(1-options["cc_fraction"]), + efficiency2=options["cc_fraction"], + lifetime=costs.at['industry CC','lifetime']) From 0d96ec1de4528b6c91f08a9c18bd8fa8f3964cc2 Mon Sep 17 00:00:00 2001 From: Tom Brown Date: Wed, 9 Dec 2020 17:26:29 +0100 Subject: [PATCH 3/5] Use DEA capture rates for CHP CC rather than default rate --- scripts/prepare_sector_network.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/prepare_sector_network.py b/scripts/prepare_sector_network.py index bff5cdef..03c45750 100644 --- a/scripts/prepare_sector_network.py +++ b/scripts/prepare_sector_network.py @@ -1253,8 +1253,8 @@ def add_heat(network): marginal_cost=costs.at['central gas CHP','VOM'], efficiency=costs.at['central gas CHP','efficiency'] - costs.at['gas','CO2 intensity']*(costs.at['biomass CHP capture','electricity-input'] + costs.at['biomass CHP capture','compression-electricity-input']), efficiency2=costs.at['central gas CHP','efficiency']/costs.at['central gas CHP','c_b'] + costs.at['gas','CO2 intensity']*(costs.at['biomass CHP capture','heat-output'] + costs.at['biomass CHP capture','compression-heat-output'] - costs.at['biomass CHP capture','heat-output']), - efficiency3=costs.at['gas','CO2 intensity']*(1-options["cc_fraction"]), - efficiency4=costs.at['gas','CO2 intensity']*options["cc_fraction"], + efficiency3=costs.at['gas','CO2 intensity']*(1-costs.at['biomass CHP capture','capture_rate']), + efficiency4=costs.at['gas','CO2 intensity']*costs.at['biomass CHP capture','capture_rate'], lifetime=costs.at['central gas CHP','lifetime']) else: @@ -1472,8 +1472,8 @@ def add_biomass(network): marginal_cost=costs.at['central solid biomass CHP','VOM'], efficiency=costs.at['central solid biomass CHP','efficiency'] - costs.at['solid biomass','CO2 intensity']*(costs.at['biomass CHP capture','electricity-input'] + costs.at['biomass CHP capture','compression-electricity-input']), efficiency2=costs.at['central solid biomass CHP','efficiency-heat'] + costs.at['solid biomass','CO2 intensity']*(costs.at['biomass CHP capture','heat-output'] + costs.at['biomass CHP capture','compression-heat-output'] - costs.at['biomass CHP capture','heat-output']), - efficiency3=-costs.at['solid biomass','CO2 intensity']*options["cc_fraction"], - efficiency4=costs.at['solid biomass','CO2 intensity']*options["cc_fraction"], + efficiency3=-costs.at['solid biomass','CO2 intensity']*costs.at['biomass CHP capture','capture_rate'], + efficiency4=costs.at['solid biomass','CO2 intensity']*costs.at['biomass CHP capture','capture_rate'], lifetime=costs.at['central solid biomass CHP','lifetime']) From 19a7a1a6841faa4c377884babecf079b9f3b30ad Mon Sep 17 00:00:00 2001 From: Tom Brown Date: Wed, 9 Dec 2020 18:19:57 +0100 Subject: [PATCH 4/5] Implement DAC properly with electricity and heat demand Before it just had a fixed marginal cost. Now it uses DEA assumptions for heat, electricity and capital costs. This necessitates locating it somewhere concrete. Heat is taken from urban central or decentral buses. --- scripts/prepare_sector_network.py | 34 +++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/scripts/prepare_sector_network.py b/scripts/prepare_sector_network.py index 03c45750..6dcd3ad3 100644 --- a/scripts/prepare_sector_network.py +++ b/scripts/prepare_sector_network.py @@ -208,17 +208,26 @@ def add_co2_tracking(n): efficiency=1., p_nom_extendable=True) - if options['dac']: - #direct air capture consumes electricity to take CO2 from the air to the underground store - #TODO do with cost from Breyer - later use elec and heat and capital cost - n.madd("Link",["DAC"], - bus0="co2 atmosphere", - bus1="co2 stored", - carrier="DAC", - marginal_cost=75., - efficiency=1., - p_nom_extendable=True, - lifetime=costs.at['direct air capture','lifetime']) +def add_dac(n): + + heat_buses = n.buses.index[n.buses.carrier.isin(["urban central heat", + "services urban decentral heat"])] + locations = n.buses.location[heat_buses] + + n.madd("Link", + locations, + suffix=" DAC", + bus0="co2 atmosphere", + bus1="co2 stored", + bus2=locations.values, + bus3=heat_buses, + carrier="DAC", + capital_cost=costs.at['direct air capture','fixed'], + efficiency=1., + efficiency2=-(costs.at['direct air capture','electricity-input'] + costs.at['direct air capture','compression-electricity-input']), + efficiency3=-(costs.at['direct air capture','heat-input'] - costs.at['direct air capture','compression-heat-output']), + p_nom_extendable=True, + lifetime=costs.at['direct air capture','lifetime']) def add_co2limit(n, Nyears=1.,limit=0.): @@ -1896,6 +1905,9 @@ if __name__ == "__main__": if "I" in opts and "H" in opts: add_waste_heat(n) + if options['dac']: + add_dac(n) + if "decentral" in opts: decentral(n) From b2c40dfe30c2681b2f6015f4e4f6ae7126a08cbb Mon Sep 17 00:00:00 2001 From: Tom Brown Date: Wed, 9 Dec 2020 18:47:50 +0100 Subject: [PATCH 5/5] Replace old "industry CC" assumption with DEA "cement capture" --- config.default.yaml | 2 +- scripts/prepare_sector_network.py | 24 ++++++++++++------------ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/config.default.yaml b/config.default.yaml index 52794c3d..325ba929 100644 --- a/config.default.yaml +++ b/config.default.yaml @@ -316,7 +316,7 @@ plotting: "DAC" : "#E74C3C" "co2 stored" : "#123456" "CO2 sequestration" : "#123456" - "CCS" : "k" + "CC" : "k" "co2" : "#123456" "co2 vent" : "#654321" "solid biomass for industry co2 from atmosphere" : "#654321" diff --git a/scripts/prepare_sector_network.py b/scripts/prepare_sector_network.py index 6dcd3ad3..34a02e0f 100644 --- a/scripts/prepare_sector_network.py +++ b/scripts/prepare_sector_network.py @@ -1527,11 +1527,11 @@ def add_industry(network): bus3="co2 stored", carrier="solid biomass for industry CC", p_nom_extendable=True, - capital_cost=costs.at["industry CC","fixed"]*costs.at['solid biomass','CO2 intensity']*8760, #8760 converts EUR/(tCO2/a) to EUR/(tCO2/h) + capital_cost=costs.at["cement capture","fixed"]*costs.at['solid biomass','CO2 intensity'], efficiency=0.9, - efficiency2=-costs.at['solid biomass','CO2 intensity']*options["cc_fraction"], - efficiency3=costs.at['solid biomass','CO2 intensity']*options["cc_fraction"], - lifetime=costs.at['industry CC','lifetime']) + efficiency2=-costs.at['solid biomass','CO2 intensity']*costs.at["cement capture","capture_rate"], + efficiency3=costs.at['solid biomass','CO2 intensity']*costs.at["cement capture","capture_rate"], + lifetime=costs.at['cement capture','lifetime']) network.madd("Bus", @@ -1563,11 +1563,11 @@ def add_industry(network): bus3="co2 stored", carrier="gas for industry CC", p_nom_extendable=True, - capital_cost=costs.at["industry CC","fixed"]*costs.at['gas','CO2 intensity']*8760, #8760 converts EUR/(tCO2/a) to EUR/(tCO2/h) + capital_cost=costs.at["cement capture","fixed"]*costs.at['gas','CO2 intensity'], efficiency=0.9, - efficiency2=costs.at['gas','CO2 intensity']*(1-options["cc_fraction"]), - efficiency3=costs.at['gas','CO2 intensity']*options["cc_fraction"], - lifetime=costs.at['industry CC','lifetime']) + efficiency2=costs.at['gas','CO2 intensity']*(1-costs.at["cement capture","capture_rate"]), + efficiency3=costs.at['gas','CO2 intensity']**costs.at["cement capture","capture_rate"], + lifetime=costs.at['cement capture','lifetime']) network.madd("Load", @@ -1709,10 +1709,10 @@ def add_industry(network): bus2="co2 stored", carrier="process emissions CC", p_nom_extendable=True, - capital_cost=costs.at["industry CC","fixed"]*8760, #8760 converts EUR/(tCO2/a) to EUR/(tCO2/h) - efficiency=(1-options["cc_fraction"]), - efficiency2=options["cc_fraction"], - lifetime=costs.at['industry CC','lifetime']) + capital_cost=costs.at["cement capture","fixed"], + efficiency=(1-costs.at["cement capture","capture_rate"]), + efficiency2=costs.at["cement capture","capture_rate"], + lifetime=costs.at['cement capture','lifetime'])