Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
d78fcf7
restrict RES buildout
lindnemi Jan 23, 2025
14df88b
decrease FT efficiency
lindnemi Jan 23, 2025
c978b43
forbid net export of H2 and Efuels
lindnemi Jan 23, 2025
35b4598
allow BEV DSM only after 2025
lindnemi Jan 23, 2025
1159f39
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jan 23, 2025
9e590a9
consider SMR CC as fossil hydrogen
lindnemi Jan 23, 2025
350b0fe
increase offwind-connection FOM
lindnemi Jan 23, 2025
d4b6071
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jan 23, 2025
e5a3281
Merge branch 'main' into refining-scenarios
lindnemi Jan 23, 2025
308bbcb
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jan 23, 2025
def78e5
fix imports paths
lindnemi Jan 23, 2025
72c3f73
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jan 23, 2025
9804b6f
further refine offwind buildout
lindnemi Jan 24, 2025
e82cd22
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jan 24, 2025
8a6e002
add to previous commit (further refine offwind buildout)
lindnemi Jan 24, 2025
31ec853
Merge branch 'refining-scenarios' of github.com:PyPSA/pypsa-de into r…
lindnemi Jan 24, 2025
9844486
improve the bev_dsm config option
lindnemi Jan 24, 2025
15d3320
generalize mock_snakemake
lindnemi Jan 24, 2025
125037f
hotfix mock_snakemake for this script
lindnemi Jan 24, 2025
f20236d
add description to modified costs.csv
lindnemi Jan 24, 2025
e96f6f9
split efuel export bans by carrier
lindnemi Jan 24, 2025
603a3cd
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jan 24, 2025
ccac88c
Merge branch 'main' into refining-scenarios
Jan 25, 2025
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
2 changes: 1 addition & 1 deletion config/config.default.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -498,7 +498,7 @@ sector:
ICE_upper_degree_factor: 1.6
EV_lower_degree_factor: 0.98
EV_upper_degree_factor: 0.63
bev_dsm: true
bev_dsm: 2030
bev_availability: 0.5
bev_energy: 0.05
bev_charge_efficiency: 0.9
Expand Down
16 changes: 8 additions & 8 deletions 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: 20250122-demand-scenarios
prefix: 20250124-finalfixes
name:
# - CurrentPolicies
- KN2045_Bal_v4
Expand Down Expand Up @@ -438,25 +438,25 @@ solving:
DE:
2020: 54.5
2025: 69
2030: 157 # EEG2023 Ziel für 2035
2035: 250
2030: 115 # EEG2023 Ziel für 2030
2035: 160 # EEG2023 Ziel für 2040
2040: 250
2045: 250
offwind:
DE:
2020: 7.8
2025: 11.3
2030: 29.3 # uba Projektionsbericht and NEP without delayed BalWin 3
2035: 70
2040: 70
2035: 50 # Planned projects until 2035 (offshore_connection_points.csv) -1.3 GW for potential delays
2040: 65 # Planned projects until 2040 -1.5 GW for potential retirments
2045: 70
solar:
DE:
2020: 53.7
2025: 110 # EEG2023; assumes for 2026: 128 GW, assuming a fair share reached by end of 2025
2030: 309 # EEG2023 Ziel für 2035
2035: 1000
2040: 1000
2030: 235 # PV Ziel 2030 + 20 GW
2035: 400
2040: 800
2045: 1000
Store:
co2 sequestered:
Expand Down
8 changes: 2 additions & 6 deletions config/scenarios.manual.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,7 @@ CurrentPolicies:
2020: 7.8
2025: 11.3
2030: 17.3 # 12 less than NEP, because of 1 year delay
2035: 35 # 29.3 + a little extra
2040: 70
2045: 70
2035: 40 # 29.3 + half of extra projects
onwind:
DE:
2030: 94.5 # uba Projektionsbericht
Expand Down Expand Up @@ -605,9 +603,7 @@ KN2045minus_WorstCase:
2020: 7.8
2025: 11.3
2030: 17.3 # 12 less than NEP, because of 1 year delay
2035: 35 # 29.3 + a little extra
2040: 70
2045: 70
2035: 40 # 29.3 + half of extra projects
onwind:
DE:
2030: 94.5 # uba Projektionsbericht
Expand Down
2 changes: 1 addition & 1 deletion doc/configtables/sector.csv
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ ICE_lower_degree_factor,--,float,Share increase in energy demand in internal com
ICE_upper_degree_factor,--,float,Share increase in energy demand in internal combustion engine (ICE) for each degree difference between the hot environment and the maximum temperature.
EV_lower_degree_factor,--,float,Share increase in energy demand in electric vehicles (EV) for each degree difference between the cold environment and the minimum temperature.
EV_upper_degree_factor,--,float,Share increase in energy demand in electric vehicles (EV) for each degree difference between the hot environment and the maximum temperature.
bev_dsm,--,"{true, false}",Add the option for battery electric vehicles (BEV) to participate in demand-side management (DSM)
bev_dsm,--,"{true, false} or startyear as int",Add the option for battery electric vehicles (BEV) to participate in demand-side management (DSM). If an int is passed it is interpreted as the year from which on BEV DSM is available.
,,,
bev_availability,--,float,The share for battery electric vehicles (BEV) that are able to do demand side management (DSM)
bev_energy,--,float,The average size of battery electric vehicles (BEV) in MWh
Expand Down
2 changes: 1 addition & 1 deletion scripts/_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -471,7 +471,7 @@ def mock_snakemake(
else:
root_dir = Path(root_dir).resolve()

user_in_script_dir = Path.cwd().resolve() == script_dir
user_in_script_dir = Path.cwd().resolve().is_relative_to(Path(script_dir))
if str(submodule_dir) in __file__:
# the submodule_dir path is only need to locate the project dir
os.chdir(Path(__file__[: __file__.find(str(submodule_dir))]))
Expand Down
2 changes: 1 addition & 1 deletion scripts/prepare_sector_network.py
Original file line number Diff line number Diff line change
Expand Up @@ -2029,7 +2029,7 @@ def add_EVs(
efficiency=options["bev_charge_efficiency"],
)

if options["bev_dsm"]:
if options["bev_dsm"] and options["bev_dsm"] <= investment_year:
e_nom = (
number_cars
* options["bev_energy"]
Expand Down
60 changes: 60 additions & 0 deletions scripts/pypsa-de/additional_functionality.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,27 @@ def h2_import_limits(n, investment_year, limits_volume_max):
carrier_attribute="",
)

logger.info("Adding H2 export ban")

cname = f"H2_export_ban-{ct}"

n.model.add_constraints(lhs >= 0, name=f"GlobalConstraint-{cname}")

if cname in n.global_constraints.index:
logger.warning(
f"Global constraint {cname} already exists. Dropping and adding it again."
)
n.global_constraints.drop(cname, inplace=True)

n.add(
"GlobalConstraint",
cname,
constant=0,
sense=">=",
type="",
carrier_attribute="",
)


def h2_production_limits(n, investment_year, limits_volume_min, limits_volume_max):
for ct in limits_volume_max["electrolysis"]:
Expand Down Expand Up @@ -647,6 +668,45 @@ def add_h2_derivate_limit(n, investment_year, limits_volume_max):
carrier_attribute="",
)

# The following export bans for DE are added unconditionally, independent of config
ct = "DE"
logger.info("Adding net export bans for H2 derivatives in DE")

for incarrier, outcarrier in [
("EU methanol -> DE methanol", "DE methanol -> EU methanol"),
("EU renewable gas -> DE gas", "DE renewable gas -> EU gas"),
("EU renewable oil -> DE oil", "DE renewable oil -> EU oil"),
]:
incoming = n.links.index[n.links.index == incarrier]
outgoing = n.links.index[n.links.index == outcarrier]
incoming_p = (
n.model["Link-p"].loc[:, incoming] * n.snapshot_weightings.generators
).sum()
outgoing_p = (
n.model["Link-p"].loc[:, outgoing] * n.snapshot_weightings.generators
).sum()

lhs = incoming_p - outgoing_p

cname = f"renewable{incarrier.split()[-1]}_export_ban-{ct}"

n.model.add_constraints(lhs >= 0, name=f"GlobalConstraint-{cname}")

if cname in n.global_constraints.index:
logger.warning(
f"Global constraint {cname} already exists. Dropping and adding it again."
)
n.global_constraints.drop(cname, inplace=True)

n.add(
"GlobalConstraint",
cname,
constant=0,
sense=">=",
type="",
carrier_attribute="",
)


def adapt_nuclear_output(n):
logger.info(
Expand Down
7 changes: 6 additions & 1 deletion scripts/pypsa-de/export_ariadne_variables.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
import os
import re
import sys

sys.path.insert(0, os.path.abspath(os.path.dirname(__file__) + "/../.."))

from functools import reduce

import numpy as np
Expand Down Expand Up @@ -248,7 +251,9 @@ def _get_h2_fossil_fraction(n):
.sum()
)

h2_fossil_fraction = total_h2_supply.get("SMR") / total_h2_supply.sum()
h2_fossil_fraction = (
total_h2_supply.filter(like="SMR").sum() / total_h2_supply.sum()
)

return h2_fossil_fraction

Expand Down
24 changes: 24 additions & 0 deletions scripts/pypsa-de/modify_cost_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,4 +150,28 @@ def carbon_component_fossils(costs, co2_price):
f"Setting lifetime of central gas CHP to {costs.at[("central gas CHP" , "lifetime") , "value"]} {costs.at[("central gas CHP" , "lifetime") , "unit"]}."
)

# decrease Fischer-Tropsch efficiency
costs.at[("Fischer-Tropsch", "efficiency"), "value"] = (
1 / costs.at[("Fischer-Tropsch", "hydrogen-input"), "value"]
)
costs.at[("Fischer-Tropsch", "efficiency"), "source"] = "inverse of hydrogen-input"

# increase FOM of offshore wind connection (fix for costs.csv)
costs.loc[("offwind-dc-connection-submarine", "FOM"), "value"] = 0.35
costs.loc[("offwind-dc-connection-submarine", "FOM"), "unit"] = costs.at[
("offwind", "FOM"), "unit"
]
costs.loc[("offwind-dc-connection-underground", "FOM"), "value"] = 0.35
costs.loc[("offwind-dc-connection-underground", "FOM"), "unit"] = costs.at[
("offwind", "FOM"), "unit"
]
costs.loc[("offwind-ac-connection-submarine", "FOM"), "value"] = 0.35
costs.loc[("offwind-ac-connection-submarine", "FOM"), "unit"] = costs.at[
("offwind", "FOM"), "unit"
]
costs.loc[("offwind-ac-connection-underground", "FOM"), "value"] = 0.35
costs.loc[("offwind-ac-connection-underground", "FOM"), "unit"] = costs.at[
("offwind", "FOM"), "unit"
]

costs.to_csv(snakemake.output[0])
6 changes: 2 additions & 4 deletions scripts/pypsa-de/plot_ariadne_report.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,16 @@
import numpy as np
import pandas as pd
import pypsa
from export_ariadne_variables import get_discretized_value, process_postnetworks
from matplotlib.lines import Line2D
from matplotlib.patches import Patch
from matplotlib.ticker import FuncFormatter
from pypsa.plot import add_legend_lines
from pypsa.plot import add_legend_circles, add_legend_lines, add_legend_patches

from scripts._helpers import configure_logging, mock_snakemake, set_scenario_config
from scripts.export_ariadne_variables import get_discretized_value, process_postnetworks
from scripts.plot_power_network import load_projection
from scripts.plot_summary import preferred_order, rename_techs
from scripts.prepare_sector_network import prepare_costs
from scripts.pypsa.plot import add_legend_circles, add_legend_lines, add_legend_patches

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -2449,7 +2448,6 @@ def plot_elec_map_de(
frameon=True,
facecolor="white",
fontsize=14,

)

add_legend_patches(ax, colors, labels, legend_kw=legend_kw_patches)
Expand Down
1 change: 1 addition & 0 deletions scripts/pypsa-de/plot_ariadne_variables.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import pandas as pd

from scripts._helpers import mock_snakemake

TWh2PJ = 3.6


Expand Down
Loading