Skip to content

Commit c96798b

Browse files
authored
Merge branch 'main' into pre-commit-ci-update-config
2 parents 17408da + 360ad5e commit c96798b

File tree

7 files changed

+185
-556
lines changed

7 files changed

+185
-556
lines changed

README.md

Lines changed: 50 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,44 @@
1-
# Kopernikus-Projekt Ariadne - Gesamtsystemmodell PyPSA-DE
1+
# PyPSA-DE - Hochaufgelöstes, sektorengekoppeltes Modell des deutschen Energiesystems
22

3-
Dieses Repository enthält das Gesamtsystemmodell PyPSA-DE für das Kopernikus-Projekt Ariadne, basierend auf der Toolbox PyPSA und dem Datensatz PyPSA-Eur. Das Modell bildet Deutschland mit hoher geographischer Auflösung, mit voller Sektorenkopplung und mit Integration in das europäische Energiesystem ab.
3+
PyPSA-DE ist ein sektorengekoppeltes Energiesystem-Modell auf Basis der Toolbox [PyPSA](https://github.com/PyPSA/pypsa) und des europäischen Modells [PyPSA-Eur](https://github.com/PyPSA/pypsa-eur). Der PyPSA-DE Workflow modelliert das deutsche Energiesystem mit deutschlandspezifischen Datensätzen (MaStR, Netzentwicklungsplan,...) im Verbund mit den direkten Stromnachbarn sowie Spanien und Italien. Der Ausbau und der Betrieb von Kraftwerken, des Strom- und Wasserstoffübertragunsnetzes und die Energieversorgung aller Sektoren werden dann in einem linearen Optimierungsproblem gelöst, mit hoher zeitlicher und räumlicher Auflösung. PyPSA-DE wurde im Rahmen des Kopernikus-Projekts [Ariadne](https://ariadneprojekt.de/) entwickelt in dem Szenarien für ein klimaneutrales Deutschland untersucht werden, und spielt eine zentrale Rolle im Ariadne Szenarienreport, als Leitmodell für den Sektor Energiewirtschaft und als eines von drei Gesamtsystemmodellen.
4+
5+
# PyPSA-DE - High resolution, sector-coupled model of the German Energy System
6+
7+
PyPSA-DE is a sector-coupled energy system model based on the toolbox [PyPSA](https://github.com/PyPSA/pypsa) and the European model [PyPSA-Eur](https://github.com/PyPSA/pypsa-eur). It solves a linear optimization problem to simulate the electricty and hydrogen transmission networks, as well as supply, demand and storage in all sectors of the energy system in Germany and its neighboring countries, as well as Italy and Spain, with high spatial and temporal resolution. PyPSA-DE was developed in the context of the Kopernikus-Projekt [Ariadne](https://ariadneprojekt.de/en/), which studies scenarios of a carbon-neutral German economcy, and plays a decisive role in the upcoming Ariadne Szenarienreport, as reference model for the energy sector.
48

59
This repository contains the entire scientific project, including data sources and code. The philosophy behind this repository is that no intermediary results are included, but all results are computed from raw data and code.
610

11+
[<img src="https://github.com/PyPSA/pypsa-de/blob/main/doc/img/INFRA_Stromnetzausbau.png?raw=true" width="400"/>](https://github.com/PyPSA/pypsa-de/blob/main/doc/img/INFRA_Stromnetzausbau.png?raw=true)
12+
713
## Getting ready
814

915
You need `conda` or `mamba` to run the analysis. Using conda, you can create an environment from within which you can run the analysis:
1016

11-
conda env create -f envs/environment.yaml
17+
```
18+
conda env create -f envs/{os}-pinned.yaml
19+
```
1220

13-
## For external users: Use config.public.yaml
21+
Where `{os}` should be replaced with your operating system, e.g. for linux the command would be:
1422

15-
The default workflow configured for this repository assumes access to the internal Ariadne2 database. Users that do not have the required login details can run the analysis based on the data published during the [first phase of the Ariadne project](https://data.ece.iiasa.ac.at/ariadne/).
23+
```
24+
conda env create -f envs/linux-pinned.yaml
25+
```
26+
27+
## Connecting to the Ariadne-Database
28+
29+
### For external users: Use config.public.yaml
30+
31+
The default workflow configured for this repository assumes access to the internal Ariadne2 database. The database will soon be publicly available. Until then, users that do not have the required login details can run the analysis based on the data published during the [first phase of the Ariadne project](https://data.ece.iiasa.ac.at/ariadne/).
1632

1733
This is possible by providing an additional config to the snakemake workflow. For every `snakemake COMMAND` specified in the instructions below, public users should use:
1834

1935
```
2036
snakemake COMMAND --configfile=config/config.public.yaml
2137
```
2238

23-
The additional config file specifies the required database, model, and scenario names for Ariadne1. If public users wish to edit the default scenario specifications, they should change `scenarios.public.yaml` instead of `scenarios.manual.yaml`. More details on using scenarios are given below.
39+
The additional config file specifies the required database, model, and scenario names for Ariadne1. If public users wish to edit the default scenario specifications, they can do so by changing `scenarios.public.yaml` to `scenarios.manual.yaml`. More details on using scenarios are given below.
2440

25-
## For internal users: Provide login details
41+
### For internal users: Provide login details
2642

2743
The snakemake rule `retrieve_ariadne_database` logs into the interal Ariadne IIASA Database via the [`pyam`](https://pyam-iamc.readthedocs.io/en/stable/tutorials/iiasa.html) package. The credentials for logging into this database have to be stored locally on your machine with `ixmp4`. To do this activate the project environment and run
2844

@@ -51,8 +67,7 @@ To run the analysis use
5167

5268
snakemake ariadne_all
5369

54-
This will run all analysis steps to reproduce results. If computational resources on your local machine are limit you may decrease the number of cores by adding, e.g. `-c4` to the call.
55-
70+
This will run all analysis steps to reproduce results. If computational resources on your local machine are limited you may decrease the number of cores by adding, e.g. `-c4` to the call to get only 4 cores. For more option please refer to the [snakemake](https://snakemake.readthedocs.io/en/stable/) documentation.
5671

5772
## Repo structure
5873

@@ -64,28 +79,45 @@ This will run all analysis steps to reproduce results. If computational resource
6479
* `resources`: place for intermediate/processing data for the workflow (does not exist initially)
6580
* `results`: will contain all results (does not exist initially)
6681
* `logs` and `benchmarks`
67-
* The `Snakefile` contains the snakemake workflow
82+
* The `Snakefile` contains the PyPSA-DE specific snakemake workflow
83+
84+
## Differences to PyPSA-EUR
6885

69-
## Some notable differences to PyPSA-EUR
86+
PyPSA-DE is a softfork of PyPSA-EUR. As such, large parts of the functionality are similar, and the [documentation](https://pypsa-eur.readthedocs.io/en/latest/) of PyPSA-Eur is a good starting point to get acquainted with the model. On topf of that, PyPSA-DE adds several data sources and workflow steps that improve the representation of the German Energy System. Below is a non-conclusive list of the most important changes.
7087

88+
- Default resolution of 16 regions in Germany and 13 region for neighboring countries
89+
- 10 pre-defined scenarios (1 Current Policies, 3 Net-Zero Scenarios (Balanced, Focus H2, Focus Electricity), 2 Demand Variations based on the Balanced Scenario, 4 Demand Variations Based on the Current Policies Scenario)
7190
- Specific cost assumption for Germany:
91+
7292
- Gas, Oil, Coal prices
7393
- electrolysis and heat-pump costs
74-
- Infrastructure costs according to the Netzentwicklungsplan 23 (NEP23)
94+
- Infrastructure costs [according to the Netzentwicklungsplan](https://github.com/PyPSA/pypsa-ariadne/pull/193) 2021 and 2023
7595
- option for pessimstic, mean and optimistic cost development
76-
- Transport and Industry demands as well as heating stock imported from the sectoral models in the Ariadne consortium
96+
- Transport and Industry demands as well as heating stock imported from the sectoral models in the Ariadne consortium ([Aladin](https://ariadneprojekt.de/modell-dokumentation-aladin/), [REMOD](https://ariadneprojekt.de/modell-dokumentation-remod/), [FORECAST](https://ariadneprojekt.de/modell-dokumentation-forecast/) and [REMIND](https://ariadneprojekt.de/modell-dokumentation-remind/))
7797
- More detailed data on CHPs in Germany
78-
- Option for building the German Wasserstoffkernnetz
7998
- The model has been validated against 2020 electricity data for Germany
8099
- National CO2-Targets according to the Klimaschutzgesetz
81100
- Additional constraints that limit maximum capacity of specific technologies
82-
- Import constraints
101+
- Import constraints on Efuels, hydrogen and electricity
83102
- Renewable build out according to the Wind-an-Land, Wind-auf-See and Solarstrategie laws
84-
- A comprehensive reporting module that exports Capacity Expansion, Primary/Secondary/Final Energy, CO2 Emissions per Sector, Trade, Investments, ...
103+
- A comprehensive reporting module that exports Capacity Expansion, Primary/Secondary/Final Energy, CO2 Emissions per Sector, Trade, Investments, and more.
85104
- Plotting functionality to compare different scenarios
86-
- Electricity Network development until 2030 (and for AC beyond) according to the Netzentwicklungsplan
87-
- Offshore development until 2030 according to the Offshore Netzentwicklungsplan
105+
- Electricity Network development until 2030 (and for AC beyond) according to the NEP23
106+
- Offshore development until 2030 according to the Offshore NEP23
88107
- Hydrogen network development until 2028 according to the Wasserstoffkernnetz. PCI / IPCEI projects for later years are included as well.
108+
- `costs:horizon` - specify if technology costs are expected to follow an `optimistic, mean` or `pessimistic` trajectory
109+
110+
## New Config Options
111+
112+
- `iiasa_database` - interaction with IIASA database. Specify a database, and `leitmodelle` for demand and co2 emissions data in specific sectors
113+
- `wasserstoff_kernnetz` - configure which parts of the Wasserstoff Kernnetz should be included in the model
114+
- `new_decentral_fossil_boiler_ban` - specify in which country and which years to ban fossil boilers
115+
- `coal_generation_ban` - specify in which country and which years to ban electricity generation from coal
116+
- `nuclear_generation_ban` - specify in which country and which years to ban electricity generation from nuclear
117+
- `first_technology_occurrence` - specify the year form which on specific technologies are available
118+
- `solving:constraints` - specify PyPSA-DE specific limits, e.g. on capacity, trade and generation
119+
- `co2_budget_DE_source` specify the carbon trajectory for Germany: Following the projections of the Umweltbundestamt (`UBA`) or targeting net zero with the Klimaschutzgesetz(`KSG`)
120+
- `costs:NEP` and `costs:transmission` - specify which year of the Netzentwicklungsplan should be used as basis for the transmission line costs (`2021,2023`) and if new HVDC links should be built with `overhead` or `underground` cables
89121

90122
## License
91123

Snakefile

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -583,9 +583,9 @@ rule plot_ariadne_variables:
583583
transmission_investment_csv=RESULTS + "ariadne/transmission_investment.csv",
584584
trassenlaenge_csv=RESULTS + "ariadne/trassenlaenge.csv",
585585
Kernnetz_Investment_plot=RESULTS + "ariadne/Kernnetz_Investment_plot.png",
586-
elec_trade=RESULTS + "ariadne/elec-trade-DE.png",
587-
h2_trade=RESULTS + "ariadne/h2-trade-DE.png",
588-
trade_balance=RESULTS + "ariadne/trade-balance-DE.png",
586+
elec_trade=RESULTS + "ariadne/elec-trade-DE.pdf",
587+
h2_trade=RESULTS + "ariadne/h2-trade-DE.pdf",
588+
trade_balance=RESULTS + "ariadne/trade-balance-DE.pdf",
589589
log:
590590
RESULTS + "logs/plot_ariadne_variables.log",
591591
script:
@@ -687,11 +687,11 @@ rule plot_ariadne_report:
687687
),
688688
output:
689689
elec_price_duration_curve=RESULTS
690-
+ "ariadne/report/elec_price_duration_curve.png",
691-
elec_price_duration_hist=RESULTS + "ariadne/report/elec_price_duration_hist.png",
692-
backup_capacity=RESULTS + "ariadne/report/backup_capacity.png",
693-
backup_generation=RESULTS + "ariadne/report/backup_generation.png",
694-
elec_prices_spatial_de=RESULTS + "ariadne/report/elec_prices_spatial_de.png",
690+
+ "ariadne/report/elec_price_duration_curve.pdf",
691+
elec_price_duration_hist=RESULTS + "ariadne/report/elec_price_duration_hist.pdf",
692+
backup_capacity=RESULTS + "ariadne/report/backup_capacity.pdf",
693+
backup_generation=RESULTS + "ariadne/report/backup_generation.pdf",
694+
elec_prices_spatial_de=RESULTS + "ariadne/report/elec_prices_spatial_de.pdf",
695695
results=directory(RESULTS + "ariadne/report"),
696696
elec_transmission=directory(RESULTS + "ariadne/report/elec_transmission"),
697697
h2_transmission=directory(RESULTS + "ariadne/report/h2_transmission"),
@@ -710,6 +710,6 @@ rule plot_ariadne_report:
710710
rule ariadne_report_only:
711711
input:
712712
expand(
713-
RESULTS + "ariadne/report/elec_price_duration_curve.png",
713+
RESULTS + "ariadne/report/elec_price_duration_curve.pdf",
714714
run=config_provider("run", "name"),
715715
),

config/config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -432,7 +432,7 @@ solving:
432432
H2 pipeline retrofitted: 0.05
433433
fractional_last_unit_size: true
434434
constraints:
435-
efuel_export_ban: true
435+
efuel_export_ban: false
436436
limits_capacity_max:
437437
Generator:
438438
onwind:

doc/img/INFRA_Stromnetzausbau.png

211 KB
Loading

envs/environment.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ dependencies:
1717
- jpype1
1818

1919
# Inhouse packages
20-
- pypsa>=0.32
20+
- pypsa<=0.31.0
2121
- atlite>=0.2.9
2222
- linopy
2323
- powerplantmatching>=0.5.15,<0.6

scripts/pypsa-de/additional_functionality.py

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -640,33 +640,42 @@ def add_h2_derivate_limit(n, investment_year, limits_volume_max):
640640
]
641641
].index
642642

643-
incoming_p = (
644-
n.model["Link-p"].loc[:, incoming] * n.snapshot_weightings.generators
645-
).sum()
646-
outgoing_p = (
647-
n.model["Link-p"].loc[:, outgoing] * n.snapshot_weightings.generators
648-
).sum()
643+
carrier_idx_dict = {
644+
"renewable_oil": 0,
645+
"methanol": 1,
646+
"renewable_gas": 2,
647+
"H2_derivate": [0, 1, 2],
648+
}
649+
for carrier, idx in carrier_idx_dict.items():
650+
cname = f"{carrier}_import_limit-{ct}"
651+
652+
incoming_p = (
653+
n.model["Link-p"].loc[:, incoming[idx]]
654+
* n.snapshot_weightings.generators
655+
).sum()
656+
outgoing_p = (
657+
n.model["Link-p"].loc[:, outgoing[idx]]
658+
* n.snapshot_weightings.generators
659+
).sum()
649660

650-
lhs = incoming_p - outgoing_p
661+
lhs = incoming_p - outgoing_p
651662

652-
cname = f"H2_derivate_import_limit-{ct}"
663+
n.model.add_constraints(lhs <= limit, name=f"GlobalConstraint-{cname}")
653664

654-
n.model.add_constraints(lhs <= limit, name=f"GlobalConstraint-{cname}")
665+
if cname in n.global_constraints.index:
666+
logger.warning(
667+
f"Global constraint {cname} already exists. Dropping and adding it again."
668+
)
669+
n.global_constraints.drop(cname, inplace=True)
655670

656-
if cname in n.global_constraints.index:
657-
logger.warning(
658-
f"Global constraint {cname} already exists. Dropping and adding it again."
671+
n.add(
672+
"GlobalConstraint",
673+
cname,
674+
constant=limit,
675+
sense="<=",
676+
type="",
677+
carrier_attribute="",
659678
)
660-
n.global_constraints.drop(cname, inplace=True)
661-
662-
n.add(
663-
"GlobalConstraint",
664-
cname,
665-
constant=limit,
666-
sense="<=",
667-
type="",
668-
carrier_attribute="",
669-
)
670679

671680
# Export bans on efuels are implemented in modify_prenetwork by restricting p_max_pu of the DE -> EU links
672681

0 commit comments

Comments
 (0)