Merge pull request #1228 from PyPSA/co2-seq-per-period

Co2 sequestration potential depending on investment period
This commit is contained in:
lisazeyen 2024-08-20 15:33:18 +02:00 committed by GitHub
commit e273f4ec9d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 201 additions and 184 deletions

View File

@ -612,7 +612,14 @@ sector:
min_size: 3
max_size: 25
years_of_storage: 25
co2_sequestration_potential: 200
co2_sequestration_potential:
2020: 0
2025: 0
2030: 50
2035: 100
2040: 200
2045: 200
2050: 200
co2_sequestration_cost: 10
co2_sequestration_lifetime: 50
co2_spatial: false

View File

@ -108,7 +108,7 @@ regional_co2 _sequestration_potential,,,
-- min_size,Gt ,float,Any sites with lower potential than this value will be excluded
-- max_size,Gt ,float,The maximum sequestration potential for any one site.
-- years_of_storage,years,float,The years until potential exhausted at optimised annual rate
co2_sequestration_potential,MtCO2/a,float,The potential of sequestering CO2 in Europe per year
co2_sequestration_potential,--,Dictionary with planning horizons as keys.,The potential of sequestering CO2 in Europe per year and investment period
co2_sequestration_cost,currency/tCO2,float,The cost of sequestering a ton of CO2
co2_sequestration_lifetime,years,int,The lifetime of a CO2 sequestration site
co2_spatial,--,"{true, false}","Add option to spatially resolve carrier representing stored carbon dioxide. This allows for more detailed modelling of CCUTS, e.g. regarding the capturing of industrial process emissions, usage as feedstock for electrofuels, transport of carbon dioxide, and geological sequestration sites."

1 Unit Values Description
108 -- min_size Gt float Any sites with lower potential than this value will be excluded
109 -- max_size Gt float The maximum sequestration potential for any one site.
110 -- years_of_storage years float The years until potential exhausted at optimised annual rate
111 co2_sequestration_potential MtCO2/a -- float Dictionary with planning horizons as keys. The potential of sequestering CO2 in Europe per year The potential of sequestering CO2 in Europe per year and investment period
112 co2_sequestration_cost currency/tCO2 float The cost of sequestering a ton of CO2
113 co2_sequestration_lifetime years int The lifetime of a CO2 sequestration site
114 co2_spatial -- {true, false} Add option to spatially resolve carrier representing stored carbon dioxide. This allows for more detailed modelling of CCUTS, e.g. regarding the capturing of industrial process emissions, usage as feedstock for electrofuels, transport of carbon dioxide, and geological sequestration sites.

View File

@ -9,6 +9,7 @@ Release Notes
Upcoming Release
================
* Add investment period dependent CO2 sequestration potentials
* Add option to produce hydrogen from solid biomass (flag ``solid biomass to hydrogen``), combined with carbon capture

View File

@ -43,6 +43,7 @@ from _helpers import (
set_scenario_config,
update_config_from_wildcards,
)
from prepare_sector_network import get
from pypsa.descriptors import get_activity_mask
from pypsa.descriptors import get_switchable_as_dense as get_as_dense
@ -287,15 +288,22 @@ def add_solar_potential_constraints(n, config):
n.model.add_constraints(lhs <= rhs, name="solar_potential")
def add_co2_sequestration_limit(n, limit=200):
def add_co2_sequestration_limit(n, limit_dict):
"""
Add a global constraint on the amount of Mt CO2 that can be sequestered.
"""
if not n.investment_periods.empty:
periods = n.investment_periods
names = pd.Index([f"co2_sequestration_limit-{period}" for period in periods])
limit = pd.Series(
{
f"co2_sequestration_limit-{period}": limit_dict.get(period, 200)
for period in periods
}
)
names = limit.index
else:
limit = get(limit_dict, int(snakemake.wildcards.planning_horizons))
periods = [np.nan]
names = pd.Index(["co2_sequestration_limit"])
@ -515,8 +523,8 @@ def prepare_network(
n = add_max_growth(n)
if n.stores.carrier.eq("co2 sequestered").any():
limit = co2_sequestration_potential
add_co2_sequestration_limit(n, limit=limit)
limit_dict = co2_sequestration_potential
add_co2_sequestration_limit(n, limit_dict=limit_dict)
return n
@ -1117,19 +1125,20 @@ def solve_network(n, config, solving, **kwargs):
return n
# %%
if __name__ == "__main__":
if "snakemake" not in globals():
from _helpers import mock_snakemake
snakemake = mock_snakemake(
"solve_sector_network",
"solve_sector_network_perfect",
configfiles="../config/test/config.perfect.yaml",
simpl="",
opts="",
clusters="37",
clusters="5",
ll="v1.0",
sector_opts="CO2L0-1H-T-H-B-I-A-dist1",
planning_horizons="2030",
sector_opts="",
# planning_horizons="2030",
)
configure_logging(snakemake)
set_scenario_config(snakemake)