Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add function to scale carrier capacity #285

Merged
merged 10 commits into from
Nov 22, 2024
8 changes: 7 additions & 1 deletion config/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

# docs in https://pypsa-eur.readthedocs.io/en/latest/configuration.html#run
run:
prefix: 20241120-correct-wind
prefix: 20241121-fix-missing-gas-capa

name:
# - CurrentPolicies
Expand Down Expand Up @@ -672,3 +672,9 @@ onshore_nep_force:
offshore_nep_force:
cutin_year: 2025
cutout_year: 2030

scale_capacity:
2020:
DE:
CCGT: 10000
"urban central gas CHP": 22000
1 change: 1 addition & 0 deletions workflow/Snakefile
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ rule modify_prenetwork:
shipping_oil_efficiency=config_provider("sector", "shipping_oil_efficiency"),
shipping_methanol_share=config_provider("sector", "shipping_methanol_share"),
mwh_meoh_per_tco2=config_provider("sector", "MWh_MeOH_per_tCO2"),
scale_capacity=config_provider("scale_capacity"),
input:
costs_modifications="ariadne-data/costs_{planning_horizons}-modifications.csv",
network=RESULTS
Expand Down
6 changes: 6 additions & 0 deletions workflow/scripts/modify_cost_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,4 +146,10 @@ def carbon_component_fossils(costs, co2_price):
f"Scaling central water tank storage investment costs to KEA Technikkatalog: {costs.loc['central water tank storage', 'investment'].value} {costs.loc['central water tank storage', 'investment'].unit}."
)

# increase central gas CHP lifetime to 40 years
costs.at[("central gas CHP", "lifetime"), "value"] = 40
logger.info(
f"Setting lifetime of central gas CHP to {costs.at[("central gas CHP" , "lifetime") , "value"]} {costs.at[("central gas CHP" , "lifetime") , "unit"]}."
)

costs.to_csv(snakemake.output[0])
60 changes: 59 additions & 1 deletion workflow/scripts/modify_prenetwork.py
Original file line number Diff line number Diff line change
Expand Up @@ -1168,6 +1168,62 @@ def drop_duplicate_transmission_projects(n):
n.remove("Line", to_drop)


def scale_capacity(n, scaling):
"""
Scale the output capacity of energy system links based on predefined scaling limits.

Parameters:
- n: The network/model object representing the energy system.
- scaling: A dictionary with scaling limits structured as
{year: {region: {carrier: limit}}}.
"""
investment_year = int(snakemake.wildcards.planning_horizons)
if investment_year in scaling.keys():
for region in scaling[investment_year].keys():
for carrier in scaling[investment_year][region].keys():
limit = scaling[investment_year][region][carrier]
logger.info(
f"Scaling output capacity (bus1) of {carrier} in region {region} to {limit} MW"
)

links_i = n.links[
(n.links.carrier == carrier) & n.links.index.str.contains(region)
].index

installed_cap = n.links.loc[links_i].eval("p_nom * efficiency").sum()
if installed_cap == 0:
logger.warning(
f"No installed capacity for {carrier} in region {region}. Skipping adjustment."
)
continue

diff_cap = limit - installed_cap
avg_efficiency = n.links.loc[links_i, "efficiency"].mean()
if avg_efficiency == 0 or np.isnan(avg_efficiency):
logger.warning(
f"Invalid average efficiency for {carrier} in region {region}. Skipping adjustment."
)
continue

diff_cap_0 = diff_cap / avg_efficiency
p_nom_sum = n.links.loc[links_i, "p_nom"].sum()
if p_nom_sum == 0:
logger.warning(
f"Zero total p_nom for {carrier} in region {region}. Skipping adjustment."
)
continue

scaling_factors = n.links.loc[links_i].eval("p_nom / @p_nom_sum")
n.links.loc[links_i, "p_nom"] += scaling_factors * diff_cap_0

links_i_current = n.links.loc[links_i][
n.links.loc[links_i].p_nom_min != 0
].index
n.links.loc[links_i_current, "p_nom_min"] = n.links.loc[
links_i_current, "p_nom"
]


if __name__ == "__main__":
if "snakemake" not in globals():
import os
Expand All @@ -1184,7 +1240,7 @@ def drop_duplicate_transmission_projects(n):
opts="",
ll="vopt",
sector_opts="none",
planning_horizons="2025",
planning_horizons="2020",
run="KN2045_Bal_v4",
)

Expand Down Expand Up @@ -1266,4 +1322,6 @@ def drop_duplicate_transmission_projects(n):

force_connection_nep_offshore(n, current_year)

scale_capacity(n, snakemake.params.scale_capacity)

n.export_to_netcdf(snakemake.output.network)
Loading