Skip to content

Commit bcb4ec8

Browse files
committed
streamline regret_runs; use only one co2 price in ST model
1 parent 7b52ba8 commit bcb4ec8

File tree

2 files changed

+83
-42
lines changed

2 files changed

+83
-42
lines changed

scripts/pypsa-de/additional_functionality.py

Lines changed: 31 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -58,17 +58,6 @@ def add_capacity_limits(
5858

5959
cname = f"capacity_{sense}-{ct}-{c.name}-{carrier.replace(' ', '-')}"
6060

61-
if snakemake.params.get("regret_run"):
62-
logger.info(
63-
f"Skipping capacity limit adjustment for {c.name} {carrier} with planning horizons {investment_year}, because of regret run."
64-
)
65-
if cname in n.global_constraints.index:
66-
logger.warning(
67-
f"Global constraint {cname} already exists. Dropping it."
68-
)
69-
n.global_constraints.drop(cname, inplace=True)
70-
continue
71-
7261
if cname in n.global_constraints.index:
7362
logger.warning(
7463
f"Global constraint {cname} already exists. Dropping and adding it again."
@@ -842,44 +831,46 @@ def additional_functionality(n, snapshots, snakemake):
842831
investment_year = int(snakemake.wildcards.planning_horizons[-4:])
843832
constraints = snakemake.params.solving["constraints"]
844833

845-
add_capacity_limits(
846-
n, investment_year, constraints["limits_capacity_min"], snakemake, "minimum"
847-
)
848-
849-
add_capacity_limits(
850-
n, investment_year, constraints["limits_capacity_max"], snakemake, "maximum"
851-
)
834+
if not snakemake.config.get("regret_run"):
835+
add_capacity_limits(
836+
n, investment_year, constraints["limits_capacity_min"], snakemake, "minimum"
837+
)
852838

853-
add_power_limits(n, investment_year, constraints["limits_power_max"])
839+
add_capacity_limits(
840+
n, investment_year, constraints["limits_capacity_max"], snakemake, "maximum"
841+
)
854842

855-
if snakemake.wildcards.clusters != "1":
856-
h2_import_limits(n, investment_year, constraints["limits_volume_max"])
843+
add_power_limits(n, investment_year, constraints["limits_power_max"])
857844

858-
electricity_import_limits(n, investment_year, constraints["limits_volume_max"])
845+
if snakemake.wildcards.clusters != "1":
846+
h2_import_limits(n, investment_year, constraints["limits_volume_max"])
859847

860-
if investment_year >= 2025:
861-
h2_production_limits(
862-
n,
863-
investment_year,
864-
constraints["limits_volume_min"],
865-
constraints["limits_volume_max"],
866-
)
848+
electricity_import_limits(
849+
n, investment_year, constraints["limits_volume_max"]
850+
)
867851

868-
add_h2_derivate_limit(n, investment_year, constraints["limits_volume_max"])
852+
if investment_year >= 2025:
853+
h2_production_limits(
854+
n,
855+
investment_year,
856+
constraints["limits_volume_min"],
857+
constraints["limits_volume_max"],
858+
)
859+
add_h2_derivate_limit(n, investment_year, constraints["limits_volume_max"])
860+
861+
if isinstance(constraints["co2_budget_national"], dict):
862+
add_national_co2_budgets(
863+
n,
864+
snakemake,
865+
constraints["co2_budget_national"],
866+
investment_year,
867+
)
868+
else:
869+
logger.warning("No national CO2 budget specified!")
869870

870871
# force_boiler_profiles_existing_per_load(n)
871872
force_boiler_profiles_existing_per_boiler(n)
872873

873-
if isinstance(constraints["co2_budget_national"], dict):
874-
add_national_co2_budgets(
875-
n,
876-
snakemake,
877-
constraints["co2_budget_national"],
878-
investment_year,
879-
)
880-
else:
881-
logger.warning("No national CO2 budget specified!")
882-
883874
if isinstance(constraints.get("decentral_heat_pump_budgets"), dict):
884875
add_decentral_heat_pump_budgets(
885876
n,

scripts/pypsa-de/solve_regret.py

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,10 +177,56 @@ def fix_capacities(realization, decision, scope="DE", strict=False):
177177
)
178178
np.random.seed(solve_opts.get("seed", 123))
179179

180+
strict = False
181+
180182
n = fix_capacities(
181-
realization, decision, scope=snakemake.params.scope_to_fix, strict=False
183+
realization, decision, scope=snakemake.params.scope_to_fix, strict=strict
184+
)
185+
if strict:
186+
snakemake.params.solving["options"]["load_shedding"] = True
187+
188+
n.add("Carrier", "H2 vent", color="#dd2e23", nice_name="H2 vent")
189+
190+
n.add(
191+
"Generator",
192+
n.buses.query("carrier=='H2'").index,
193+
" H2 vent",
194+
bus=n.buses.query("carrier=='H2'").index,
195+
carrier="H2 vent",
196+
sign=-1e-3, # Adjust sign to measure p and p_nom in kW instead of MW
197+
marginal_cost=100, # Eur/kWh
198+
p_nom=1e9, # kW
182199
)
183200

201+
snakemake.config["regret_run"] = True
202+
203+
if snakemake.config["regret_run"]:
204+
constraint_names = [ # TODO assert really everything gets dropped
205+
"H2_production_limit_upper-DE",
206+
"H2_production_limit_lower-DE",
207+
"capacity_minimum-DE-Generator-solar",
208+
"capacity_maximum-DE-Generator-onwind",
209+
"capacity_maximum-DE-Generator-offwind",
210+
"capacity_maximum-DE-Generator-solar",
211+
"capacity_maximum-DE-Store-co2-sequestered",
212+
"capacity_maximum-DE-Link-HVC-to-air",
213+
"H2_import_limit-DE",
214+
"H2_export_ban-DE",
215+
"Electricity_import_limit-DE",
216+
"renewable_oil_import_limit-DE",
217+
"methanol_import_limit-DE",
218+
"renewable_gas_import_limit-DE",
219+
"H2_derivate_import_limit-DE",
220+
"H2_derivate_meoh_gas_import_limit-DE",
221+
"H2_derivate_oil_meoh_import_limit-DE",
222+
"H2_derivate_oil_meoh_gas_import_limit-DE",
223+
"H2_derivate_oil_gas_import_limit-DE",
224+
]
225+
logger.info("Regret run detected. Dropping the following constraints:")
226+
logger.info(constraint_names)
227+
228+
n.global_constraints.drop(constraint_names, errors="ignore", inplace=True)
229+
184230
if solve_opts["post_discretization"].get("enable") and not solve_opts.get(
185231
"skip_iterations"
186232
):
@@ -221,9 +267,13 @@ def fix_capacities(realization, decision, scope="DE", strict=False):
221267
p_max_pu=0,
222268
p_nom_extendable=True,
223269
carrier="co2",
224-
marginal_cost=realization.global_constraints.loc["CO2Limit", "mu"],
270+
marginal_cost=(
271+
realization.global_constraints.loc["CO2Limit", "mu"]
272+
+ realization.global_constraints.loc["co2_limit-DE", "mu"]
273+
),
225274
)
226275
n.global_constraints.drop("CO2Limit", inplace=True)
276+
n.global_constraints.drop("co2_limit-DE", inplace=True)
227277

228278
with memory_logger(
229279
filename=getattr(snakemake.log, "memory", None), interval=logging_frequency

0 commit comments

Comments
 (0)