From 6139ec710d78b6990aa457ca6381592f7f03d225 Mon Sep 17 00:00:00 2001 From: toniseibold Date: Tue, 3 Dec 2024 13:54:23 +0100 Subject: [PATCH 1/7] adjusting aviation demand and emission accounting --- Changelog.md | 1 + config/config.yaml | 4 +++- workflow/scripts/additional_functionality.py | 15 +++++++++++++++ workflow/scripts/build_scenarios.py | 2 +- 4 files changed, 20 insertions(+), 2 deletions(-) diff --git a/Changelog.md b/Changelog.md index 3c0615fa..2630d2f5 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,4 +1,5 @@ # Changelog +- Adjusting aviation demand (from Aladin) and emission accounting (only domestic aviation for national target) - Restricting the maximum capacity of CurrentPolicies and minus scenarios to the 'uba Projektionsbericht' - Restricting Fischer Tropsch capacity addition with config[solving][limit_DE_FT_cap] - Except for Current Policies force a minimum of 5 GW of electrolysis capacity in Germany diff --git a/config/config.yaml b/config/config.yaml index 713449c9..efeb14ec 100644 --- a/config/config.yaml +++ b/config/config.yaml @@ -4,7 +4,7 @@ # docs in https://pypsa-eur.readthedocs.io/en/latest/configuration.html#run run: - prefix: 20241121-fix-missing-gas-capa + prefix: 20241203-fix-aviation name: # - CurrentPolicies @@ -284,6 +284,8 @@ costs: # docs in https://pypsa-eur.readthedocs.io/en/latest/configuration.html#sector sector: + domestic_aviation_factor: + DE: 0.07 # eurostat 2019 v2g: false solar_thermal: false district_heating: diff --git a/workflow/scripts/additional_functionality.py b/workflow/scripts/additional_functionality.py index b47a4f90..c93beff9 100644 --- a/workflow/scripts/additional_functionality.py +++ b/workflow/scripts/additional_functionality.py @@ -373,6 +373,7 @@ def add_co2limit_country(n, limit_countries, snakemake, debug=False): links = n.links.index[ (n.links.index.str[:2] == ct) & (n.links[f"bus{port}"] == "co2 atmosphere") + & (n.links.carrier != "kerosene for aviation") # first exclude aviation to multiply it with a domestic factor later ] logger.info( @@ -394,6 +395,20 @@ def add_co2limit_country(n, limit_countries, snakemake, debug=False): ).sum() ) + # Aviation demand + domestic_factor = snakemake.config["sector"]["domestic_aviation_factor"]["DE"] + aviation_links = n.links[ + (n.links.index.str[:2] == ct) + & (n.links.carrier == "kerosene for aviation") + ] + lhs.append + ( + n.model["Link-p"].loc[:, aviation_links.index] + * aviation_links.efficiency2 + * n.snapshot_weightings.generators + ).sum() * domestic_factor + logger.info(f"Adding domestic aviation emissions for {ct} with a factor of {domestic_factor}") + # Adding Efuel imports and exports to constraint incoming_oil = n.links.index[n.links.index == "EU renewable oil -> DE oil"] outgoing_oil = n.links.index[n.links.index == "DE renewable oil -> EU oil"] diff --git a/workflow/scripts/build_scenarios.py b/workflow/scripts/build_scenarios.py index 4fc00ce8..fb5b8188 100644 --- a/workflow/scripts/build_scenarios.py +++ b/workflow/scripts/build_scenarios.py @@ -19,7 +19,7 @@ def get_transport_growth(df, planning_horizons): # Aviation growth factor - using REMIND-EU v1.1 since Aladin v1 does not include bunkers - aviation_model = snakemake.params.leitmodelle["general"] + aviation_model = snakemake.params.leitmodelle["transport"] try: aviation = df.loc[aviation_model, "Final Energy|Bunkers|Aviation", "PJ/yr"] except KeyError: From 60b479af2c64557d13de00627f73da7e4ca00c93 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 3 Dec 2024 13:08:40 +0000 Subject: [PATCH 2/7] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- workflow/scripts/additional_functionality.py | 17 ++++++++++------- workflow/scripts/build_scenarios.py | 5 +++-- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/workflow/scripts/additional_functionality.py b/workflow/scripts/additional_functionality.py index c93beff9..c2de21bd 100644 --- a/workflow/scripts/additional_functionality.py +++ b/workflow/scripts/additional_functionality.py @@ -373,7 +373,9 @@ def add_co2limit_country(n, limit_countries, snakemake, debug=False): links = n.links.index[ (n.links.index.str[:2] == ct) & (n.links[f"bus{port}"] == "co2 atmosphere") - & (n.links.carrier != "kerosene for aviation") # first exclude aviation to multiply it with a domestic factor later + & ( + n.links.carrier != "kerosene for aviation" + ) # first exclude aviation to multiply it with a domestic factor later ] logger.info( @@ -398,16 +400,17 @@ def add_co2limit_country(n, limit_countries, snakemake, debug=False): # Aviation demand domestic_factor = snakemake.config["sector"]["domestic_aviation_factor"]["DE"] aviation_links = n.links[ - (n.links.index.str[:2] == ct) - & (n.links.carrier == "kerosene for aviation") + (n.links.index.str[:2] == ct) & (n.links.carrier == "kerosene for aviation") ] lhs.append ( - n.model["Link-p"].loc[:, aviation_links.index] - * aviation_links.efficiency2 - * n.snapshot_weightings.generators + n.model["Link-p"].loc[:, aviation_links.index] + * aviation_links.efficiency2 + * n.snapshot_weightings.generators ).sum() * domestic_factor - logger.info(f"Adding domestic aviation emissions for {ct} with a factor of {domestic_factor}") + logger.info( + f"Adding domestic aviation emissions for {ct} with a factor of {domestic_factor}" + ) # Adding Efuel imports and exports to constraint incoming_oil = n.links.index[n.links.index == "EU renewable oil -> DE oil"] diff --git a/workflow/scripts/build_scenarios.py b/workflow/scripts/build_scenarios.py index fb5b8188..9f682199 100644 --- a/workflow/scripts/build_scenarios.py +++ b/workflow/scripts/build_scenarios.py @@ -178,8 +178,9 @@ def write_to_scenario_yaml(input, output, scenarios, df): df.loc[:, fallback_reference_scenario, :], planning_horizons ) - - if reference_scenario.startswith("KN2045plus"): # Still waiting for REMIND uploads + if reference_scenario.startswith( + "KN2045plus" + ): # Still waiting for REMIND uploads fallback_reference_scenario = reference_scenario co2_budget_source = config[scenario]["co2_budget_DE_source"] From e1125d34c038874ef139dd4097a38dc94e96ff19 Mon Sep 17 00:00:00 2001 From: toniseibold Date: Tue, 3 Dec 2024 16:10:37 +0100 Subject: [PATCH 3/7] adjusting national climate target --- workflow/scripts/build_scenarios.py | 1 - 1 file changed, 1 deletion(-) diff --git a/workflow/scripts/build_scenarios.py b/workflow/scripts/build_scenarios.py index 9f682199..e8f24164 100644 --- a/workflow/scripts/build_scenarios.py +++ b/workflow/scripts/build_scenarios.py @@ -142,7 +142,6 @@ def get_co2_budget(df, source): targets_pypsa = ( targets_co2 - nonco2 - + df.loc["Emissions|CO2|Energy|Demand|Bunkers", "Mt CO2/yr"] ) target_fractions_pypsa = targets_pypsa.loc[targets_co2.index] / baseline_pypsa From 4ec955a7a6b97d566fcff2a98713c7652486eb72 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 3 Dec 2024 15:11:04 +0000 Subject: [PATCH 4/7] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- workflow/scripts/build_scenarios.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/workflow/scripts/build_scenarios.py b/workflow/scripts/build_scenarios.py index e8f24164..458ce6f6 100644 --- a/workflow/scripts/build_scenarios.py +++ b/workflow/scripts/build_scenarios.py @@ -139,10 +139,7 @@ def get_co2_budget(df, source): ## PyPSA disregards nonco2 GHG emissions, but includes bunkers - targets_pypsa = ( - targets_co2 - - nonco2 - ) + targets_pypsa = targets_co2 - nonco2 target_fractions_pypsa = targets_pypsa.loc[targets_co2.index] / baseline_pypsa From 5a625c039aba4cc0e7be3d5bf6c44ccc7bbb8cb2 Mon Sep 17 00:00:00 2001 From: toniseibold Date: Wed, 4 Dec 2024 15:56:46 +0100 Subject: [PATCH 5/7] calculating domestic aviation factor within additional_functionality --- config/config.yaml | 2 -- workflow/Snakefile | 2 ++ workflow/scripts/additional_functionality.py | 5 ++++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/config/config.yaml b/config/config.yaml index efeb14ec..a157aee0 100644 --- a/config/config.yaml +++ b/config/config.yaml @@ -284,8 +284,6 @@ costs: # docs in https://pypsa-eur.readthedocs.io/en/latest/configuration.html#sector sector: - domestic_aviation_factor: - DE: 0.07 # eurostat 2019 v2g: false solar_thermal: false district_heating: diff --git a/workflow/Snakefile b/workflow/Snakefile index 918b2a59..07e31c74 100644 --- a/workflow/Snakefile +++ b/workflow/Snakefile @@ -302,6 +302,7 @@ use rule solve_sector_network_myopic from pypsaeur with: custom_extra_functionality=os.path.join( os.path.dirname(workflow.snakefile), "scripts/additional_functionality.py" ), + energy_year=config_provider("energy", "energy_totals_year"), input: **{ k: v @@ -311,6 +312,7 @@ use rule solve_sector_network_myopic from pypsaeur with: network=RESULTS + "prenetworks-final/base_s_{clusters}_l{ll}_{opts}_{sector_opts}_{planning_horizons}.nc", co2_totals_name=resources("co2_totals.csv"), + energy_totals=resources("energy_totals.csv"), rule modify_existing_heating: diff --git a/workflow/scripts/additional_functionality.py b/workflow/scripts/additional_functionality.py index c2de21bd..7d8c5e8c 100644 --- a/workflow/scripts/additional_functionality.py +++ b/workflow/scripts/additional_functionality.py @@ -398,7 +398,10 @@ def add_co2limit_country(n, limit_countries, snakemake, debug=False): ) # Aviation demand - domestic_factor = snakemake.config["sector"]["domestic_aviation_factor"]["DE"] + energy_totals = pd.read_csv(snakemake.input.energy_totals, index_col=[0, 1]) + domestic_aviation = energy_totals.loc[("DE", snakemake.params.energy_year), "total domestic aviation"] + international_aviation = energy_totals.loc[("DE", snakemake.params.energy_year), "total international aviation"] + domestic_factor = domestic_aviation / (domestic_aviation + international_aviation) aviation_links = n.links[ (n.links.index.str[:2] == ct) & (n.links.carrier == "kerosene for aviation") ] From 08c5d52aedbcb8bff8ee0272f925993b4c1f06ab Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 4 Dec 2024 15:49:40 +0000 Subject: [PATCH 6/7] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- workflow/scripts/additional_functionality.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/workflow/scripts/additional_functionality.py b/workflow/scripts/additional_functionality.py index 7d8c5e8c..2d167bcc 100644 --- a/workflow/scripts/additional_functionality.py +++ b/workflow/scripts/additional_functionality.py @@ -399,9 +399,15 @@ def add_co2limit_country(n, limit_countries, snakemake, debug=False): # Aviation demand energy_totals = pd.read_csv(snakemake.input.energy_totals, index_col=[0, 1]) - domestic_aviation = energy_totals.loc[("DE", snakemake.params.energy_year), "total domestic aviation"] - international_aviation = energy_totals.loc[("DE", snakemake.params.energy_year), "total international aviation"] - domestic_factor = domestic_aviation / (domestic_aviation + international_aviation) + domestic_aviation = energy_totals.loc[ + ("DE", snakemake.params.energy_year), "total domestic aviation" + ] + international_aviation = energy_totals.loc[ + ("DE", snakemake.params.energy_year), "total international aviation" + ] + domestic_factor = domestic_aviation / ( + domestic_aviation + international_aviation + ) aviation_links = n.links[ (n.links.index.str[:2] == ct) & (n.links.carrier == "kerosene for aviation") ] From 57464e752b8f623f554285f4e09aa0526ebe6247 Mon Sep 17 00:00:00 2001 From: Michael Lindner Date: Wed, 4 Dec 2024 16:59:48 +0100 Subject: [PATCH 7/7] no longer use fallback_reference_scenario for aviation growth --- workflow/scripts/build_scenarios.py | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/workflow/scripts/build_scenarios.py b/workflow/scripts/build_scenarios.py index 458ce6f6..3f0a18ec 100644 --- a/workflow/scripts/build_scenarios.py +++ b/workflow/scripts/build_scenarios.py @@ -18,13 +18,11 @@ def get_transport_growth(df, planning_horizons): - # Aviation growth factor - using REMIND-EU v1.1 since Aladin v1 does not include bunkers - aviation_model = snakemake.params.leitmodelle["transport"] try: - aviation = df.loc[aviation_model, "Final Energy|Bunkers|Aviation", "PJ/yr"] + aviation = df.loc["Final Energy|Bunkers|Aviation", "PJ/yr"] except KeyError: aviation = ( - df.loc[aviation_model, "Final Energy|Bunkers|Aviation", "TWh/yr"] * 3.6 + df.loc["Final Energy|Bunkers|Aviation", "TWh/yr"] * 3.6 ) # TWh to PJ aviation_growth_factor = aviation / aviation[2020] @@ -156,10 +154,6 @@ def write_to_scenario_yaml(input, output, scenarios, df): fallback_reference_scenario = config[scenario]["iiasa_database"][ "fallback_reference_scenario" ] - if fallback_reference_scenario != reference_scenario: - logger.warning( - f"For aviation demand, using {fallback_reference_scenario} as fallback reference scenario for {scenario}." - ) planning_horizons = [ 2020, @@ -171,7 +165,7 @@ def write_to_scenario_yaml(input, output, scenarios, df): ] # for 2050 we still need data aviation_demand_factor = get_transport_growth( - df.loc[:, fallback_reference_scenario, :], planning_horizons + df.loc[snakemake.params.leitmodelle["transport"], reference_scenario, :], planning_horizons ) if reference_scenario.startswith(