Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions doc/design/carbon-management.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@ years. Storage sites can be resolved regionally from a geological database
of potentials, with a choice between offshore formations only, which are
larger and far from settlements, and onshore formations as well.

Regional geological potentials are divided by `years_of_storage` to obtain
the modeled annual potential. A fixed-capacity, negative-dispatch Generator
enforces each region's potential and charges the sequestration cost.

!!! warning "The sequestration limit shapes the result"
The limit is a deliberate choice: it keeps sequestration for
hard-to-abate emissions and prevents it from becoming a backstop that
Expand Down
4 changes: 4 additions & 0 deletions doc/release_notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,12 @@
<!-- Upcoming Release -->
<!-- ================= -->


* Fix: Regional CO2 sequestration allowances no longer accumulate across myopic planning horizons. Sequestration Stores are replaced by fixed-capacity Generators with energy-sum limits and infinite lifetimes, preventing brownfield carry-over from duplicating regional potentials. Sequestration costs are charged on Generator dispatch instead of the connecting Links. This can change sequestration locations and CO2 pipeline expansion ([#2369](https://github.com/PyPSA/pypsa-eur/pull/2369), fixes [#2368](https://github.com/PyPSA/pypsa-eur/issues/2368)).

* Fix: `lines: types` must now define a line type for the 380 kV level; the config validation fails early with a clear message instead of the workflow failing later ([#2166](https://github.com/PyPSA/pypsa-eur/issues/2166)).


* Feature: New switches `industry: solid_biomass_for_industry_cc`, `industry: gas_for_industry_cc` and `industry: process_emissions_cc` to disable the carbon capture options for solid biomass for industry, gas for industry and industrial process emissions. All default to `true`, which matches the previous behaviour ([#2357](https://github.com/PyPSA/pypsa-eur/pull/2357)).

* Feature: New option `sector: electrolysis` to allow hydrogen electrolysis to be configurable ([#2358](https://github.com/PyPSA/pypsa-eur/pull/2358)).
Expand Down
54 changes: 24 additions & 30 deletions scripts/prepare_sector_network.py
Original file line number Diff line number Diff line change
Expand Up @@ -660,31 +660,6 @@ def add_co2_tracking(
carrier="co2 expansion",
unit="t_co2",
)
n.add(
"Link",
sequestration_buses,
bus0=spatial.co2.dense,
bus1=sequestration_buses,
carrier="co2 sequestered",
marginal_cost=options["co2_sequestration_cost"],
efficiency=1.0,
p_nom=np.inf,
p_nom_extendable=False,
)

else:
n.add(
"Link",
sequestration_buses,
bus0=spatial.co2.nodes,
bus1=sequestration_buses,
carrier="co2 sequestered",
marginal_cost=options["co2_sequestration_cost"],
Comment thread
toniseibold marked this conversation as resolved.
efficiency=1.0,
p_nom=np.inf,
p_nom_extendable=False,
)

if options["regional_co2_sequestration_potential"]["enable"]:
if sequestration_potential_file is None:
raise ValueError(
Expand Down Expand Up @@ -713,14 +688,33 @@ def add_co2_tracking(
else:
e_nom_max = np.inf

p_nom = (
e_nom_max if options["regional_co2_sequestration_potential"]["enable"] else 1e7
)
n.add(
"Store",
"Link",
sequestration_buses,
bus0=spatial.co2.dense if co2_liquefaction else spatial.co2.nodes,
bus1=sequestration_buses,
carrier="co2 sequestered",
efficiency=1.0,
p_nom=p_nom,
p_nom_extendable=False,
lifetime=np.inf,
)

n.add(
"Generator",
sequestration_buses,
e_nom_extendable=True,
e_nom_max=e_nom_max,
marginal_cost=-0.1,
bus=sequestration_buses,
lifetime=options["co2_sequestration_lifetime"],
p_nom=p_nom,
p_nom_extendable=False,
p_min_pu=-1.0,
p_max_pu=0,
e_sum_min=-e_nom_max,
e_sum_max=0,
marginal_cost=-options["co2_sequestration_cost"],
lifetime=np.inf, # Lifetime inf means assets from previous horizons get dropped in add_brownfield
carrier="co2 sequestered",
)

Expand Down
2 changes: 1 addition & 1 deletion scripts/solve_network.py
Original file line number Diff line number Diff line change
Expand Up @@ -554,7 +554,7 @@ def prepare_network(
if limit_max_growth is not None and limit_max_growth["enable"]:
add_max_growth(n, limit_max_growth)

if n.stores.carrier.eq("co2 sequestered").any():
if n.generators.carrier.eq("co2 sequestered").any():
limit_dict = co2_sequestration_potential
add_co2_sequestration_limit(
n, limit_dict=limit_dict, planning_horizons=planning_horizons
Expand Down
Loading