Merge pull request #862 from PyPSA/reformulate-co2-constraint
Reformulate co2 constraint
This commit is contained in:
commit
dd1e07ef60
@ -24,8 +24,11 @@ scenario:
|
|||||||
- 2p0-4380H-T-H-B-I-A-solar+p3-dist1
|
- 2p0-4380H-T-H-B-I-A-solar+p3-dist1
|
||||||
planning_horizons:
|
planning_horizons:
|
||||||
- 2020
|
- 2020
|
||||||
|
- 2025
|
||||||
- 2030
|
- 2030
|
||||||
|
- 2035
|
||||||
- 2040
|
- 2040
|
||||||
|
- 2045
|
||||||
- 2050
|
- 2050
|
||||||
|
|
||||||
|
|
||||||
|
@ -16,6 +16,10 @@ Upcoming Release
|
|||||||
|
|
||||||
* Remove option for wave energy as technology data is not maintained.
|
* Remove option for wave energy as technology data is not maintained.
|
||||||
|
|
||||||
|
* Define global constraint for CO2 emissions on the final state of charge of the
|
||||||
|
CO2 atmosphere store. This gives a more sparse constraint that should improve
|
||||||
|
the performance of the solving process.
|
||||||
|
|
||||||
* Bugfix: Assure entering of code block which corrects Norwegian heat demand.
|
* Bugfix: Assure entering of code block which corrects Norwegian heat demand.
|
||||||
|
|
||||||
* Add warning when BEV availability weekly profile has negative values in `build_transport_demand`.
|
* Add warning when BEV availability weekly profile has negative values in `build_transport_demand`.
|
||||||
@ -24,6 +28,7 @@ Upcoming Release
|
|||||||
|
|
||||||
* Cluster residential and services heat buses by default. Can be disabled with ``cluster_heat_buses: false``.
|
* Cluster residential and services heat buses by default. Can be disabled with ``cluster_heat_buses: false``.
|
||||||
|
|
||||||
|
|
||||||
PyPSA-Eur 0.9.0 (5th January 2024)
|
PyPSA-Eur 0.9.0 (5th January 2024)
|
||||||
==================================
|
==================================
|
||||||
|
|
||||||
|
@ -761,6 +761,7 @@ def add_co2limit(n, nyears=1.0, limit=0.0):
|
|||||||
"CO2Limit",
|
"CO2Limit",
|
||||||
carrier_attribute="co2_emissions",
|
carrier_attribute="co2_emissions",
|
||||||
sense="<=",
|
sense="<=",
|
||||||
|
type="co2_atmosphere",
|
||||||
constant=co2_limit,
|
constant=co2_limit,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -3606,8 +3607,8 @@ if __name__ == "__main__":
|
|||||||
configfiles="test/config.overnight.yaml",
|
configfiles="test/config.overnight.yaml",
|
||||||
simpl="",
|
simpl="",
|
||||||
opts="",
|
opts="",
|
||||||
clusters="5",
|
clusters="37",
|
||||||
ll="v1.5",
|
ll="v1.0",
|
||||||
sector_opts="CO2L0-24H-T-H-B-I-A-solar+p3-dist1",
|
sector_opts="CO2L0-24H-T-H-B-I-A-solar+p3-dist1",
|
||||||
planning_horizons="2030",
|
planning_horizons="2030",
|
||||||
)
|
)
|
||||||
|
@ -208,7 +208,7 @@ def add_co2_sequestration_limit(n, config, limit=200):
|
|||||||
|
|
||||||
|
|
||||||
def add_carbon_constraint(n, snapshots):
|
def add_carbon_constraint(n, snapshots):
|
||||||
glcs = n.global_constraints.query('type == "co2_limit"')
|
glcs = n.global_constraints.query('type == "co2_atmosphere"')
|
||||||
if glcs.empty:
|
if glcs.empty:
|
||||||
return
|
return
|
||||||
for name, glc in glcs.iterrows():
|
for name, glc in glcs.iterrows():
|
||||||
@ -797,6 +797,29 @@ def add_pipe_retrofit_constraint(n):
|
|||||||
n.model.add_constraints(lhs == rhs, name="Link-pipe_retrofit")
|
n.model.add_constraints(lhs == rhs, name="Link-pipe_retrofit")
|
||||||
|
|
||||||
|
|
||||||
|
def add_co2_atmosphere_constraint(n, snapshots):
|
||||||
|
glcs = n.global_constraints[n.global_constraints.type == "co2_atmosphere"]
|
||||||
|
|
||||||
|
if glcs.empty:
|
||||||
|
return
|
||||||
|
for name, glc in glcs.iterrows():
|
||||||
|
carattr = glc.carrier_attribute
|
||||||
|
emissions = n.carriers.query(f"{carattr} != 0")[carattr]
|
||||||
|
|
||||||
|
if emissions.empty:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# stores
|
||||||
|
n.stores["carrier"] = n.stores.bus.map(n.buses.carrier)
|
||||||
|
stores = n.stores.query("carrier in @emissions.index and not e_cyclic")
|
||||||
|
if not stores.empty:
|
||||||
|
last_i = snapshots[-1]
|
||||||
|
lhs = n.model["Store-e"].loc[last_i, stores.index]
|
||||||
|
rhs = glc.constant
|
||||||
|
|
||||||
|
n.model.add_constraints(lhs <= rhs, name=f"GlobalConstraint-{name}")
|
||||||
|
|
||||||
|
|
||||||
def extra_functionality(n, snapshots):
|
def extra_functionality(n, snapshots):
|
||||||
"""
|
"""
|
||||||
Collects supplementary constraints which will be passed to
|
Collects supplementary constraints which will be passed to
|
||||||
@ -839,6 +862,8 @@ def extra_functionality(n, snapshots):
|
|||||||
add_carbon_constraint(n, snapshots)
|
add_carbon_constraint(n, snapshots)
|
||||||
add_carbon_budget_constraint(n, snapshots)
|
add_carbon_budget_constraint(n, snapshots)
|
||||||
add_retrofit_gas_boiler_constraint(n, snapshots)
|
add_retrofit_gas_boiler_constraint(n, snapshots)
|
||||||
|
else:
|
||||||
|
add_co2_atmosphere_constraint(n, snapshots)
|
||||||
|
|
||||||
if snakemake.params.custom_extra_functionality:
|
if snakemake.params.custom_extra_functionality:
|
||||||
source_path = snakemake.params.custom_extra_functionality
|
source_path = snakemake.params.custom_extra_functionality
|
||||||
@ -912,13 +937,13 @@ if __name__ == "__main__":
|
|||||||
from _helpers import mock_snakemake
|
from _helpers import mock_snakemake
|
||||||
|
|
||||||
snakemake = mock_snakemake(
|
snakemake = mock_snakemake(
|
||||||
"solve_sector_network_perfect",
|
"solve_sector_network",
|
||||||
configfiles="../config/test/config.perfect.yaml",
|
configfiles="../config/test/config.perfect.yaml",
|
||||||
simpl="",
|
simpl="",
|
||||||
opts="",
|
opts="",
|
||||||
clusters="5",
|
clusters="37",
|
||||||
ll="v1.5",
|
ll="v1.0",
|
||||||
sector_opts="8760H-T-H-B-I-A-solar+p3-dist1",
|
sector_opts="CO2L0-1H-T-H-B-I-A-solar+p3-dist1",
|
||||||
planning_horizons="2030",
|
planning_horizons="2030",
|
||||||
)
|
)
|
||||||
configure_logging(snakemake)
|
configure_logging(snakemake)
|
||||||
|
Loading…
Reference in New Issue
Block a user