pypsa-eur/doc/tutorial.rst
Fabian Neumann 013b705ee4
Clustering: build renewable profiles and add all assets after clustering (#1201)
* Cluster first: build renewable profiles and add all assets after clustering

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* correction: pass landfall_lengths through functions

* assign landfall_lenghts correctly

* remove parameter add_land_use_constraint

* fix network_dict

* calculate distance to shoreline, remove underwater_fraction

* adjust simplification parameter to exclude Crete from offshore wind connections

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* remove unused geth2015 hydro capacities

* removing remaining traces of {simpl} wildcard

* add release notes and update workflow graphics

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: lisazeyen <lisa.zeyen@web.de>
2024-09-13 15:37:01 +02:00

14 KiB

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> </head>

Tutorial: Electricity-Only

Note

If you have not done it yet, follow the :ref:`installation` steps first.

System Message: ERROR/3 (<stdin>, line 17); backlink

Unknown interpreted text role "ref".

In this tutorial, we will build a heavily simplified power system model for Belgium. But before getting started with PyPSA-Eur it makes sense to be familiar with its general modelling framework PyPSA.

Running the tutorial requires limited computational resources compared to the full model, which allows the user to explore most of its functionalities on a local machine. The tutorial will cover examples on how to configure and customise the PyPSA-Eur model and run the snakemake workflow step by step from network creation to the solved network. The configuration for the tutorial is located at config/test/config.electricity.yaml. It includes parts deviating from the default config file config/config.default.yaml. To run the tutorial with this configuration, execute

System Message: WARNING/2 (<stdin>, line 32)

Cannot analyze code. Pygments package not found.

.. code:: bash
    :class: full-width

    snakemake -call results/test-elec/networks/base_s_6_elec_lcopt_.nc --configfile config/test/config.electricity.yaml

This configuration is set to download a reduced cutout via the rule :mod:`retrieve_cutout`. For more information on the data dependencies of PyPSA-Eur, continue reading :ref:`data`.

System Message: ERROR/3 (<stdin>, line 37); backlink

Unknown interpreted text role "mod".

System Message: ERROR/3 (<stdin>, line 37); backlink

Unknown interpreted text role "ref".

How to configure runs?

The model can be adapted to only include selected countries (e.g. Belgium) instead of all European countries to limit the spatial scope.

System Message: ERROR/3 (<stdin>, line 45)

Unknown directive type "literalinclude".

.. literalinclude:: ../config/test/config.electricity.yaml
   :language: yaml
   :start-at: countries:
   :end-before: snapshots:

Likewise, the example's temporal scope can be restricted (e.g. to a single week).

System Message: ERROR/3 (<stdin>, line 52)

Unknown directive type "literalinclude".

.. literalinclude:: ../config/test/config.electricity.yaml
   :language: yaml
   :start-at: snapshots:
   :end-before: electricity:

It is also possible to allow less or more carbon-dioxide emissions. Here, we limit the emissions of Belgium to 100 Mt per year.

System Message: ERROR/3 (<stdin>, line 59)

Unknown directive type "literalinclude".

.. literalinclude:: ../config/test/config.electricity.yaml
   :language: yaml
   :start-at: electricity:
   :end-before: extendable_carriers:

PyPSA-Eur also includes a database of existing conventional powerplants. We can select which types of existing powerplants we like to be extendable:

System Message: ERROR/3 (<stdin>, line 67)

Unknown directive type "literalinclude".

.. literalinclude:: ../config/test/config.electricity.yaml
   :language: yaml
   :start-at: extendable_carriers:
   :end-before: renewable_carriers:

To accurately model the temporal and spatial availability of renewables such as wind and solar energy, we rely on historical weather data. It is advisable to adapt the required range of coordinates to the selection of countries.

System Message: ERROR/3 (<stdin>, line 76)

Unknown directive type "literalinclude".

.. literalinclude:: ../config/test/config.electricity.yaml
   :language: yaml
   :start-at: atlite:
   :end-before: renewable:

We can also decide which weather data source should be used to calculate potentials and capacity factor time-series for each carrier. For example, we may want to use the ERA-5 dataset for solar and not the default SARAH-3 dataset.

System Message: ERROR/3 (<stdin>, line 85)

Unknown directive type "literalinclude".

.. literalinclude:: ../config/test/config.electricity.yaml
   :language: yaml
   :start-at: solar:
   :end-at: cutout:

Finally, it is possible to pick a solver. For instance, this tutorial uses the open-source solver GLPK.

System Message: ERROR/3 (<stdin>, line 93)

Unknown directive type "literalinclude".

.. literalinclude:: ../config/test/config.electricity.yaml
   :language: yaml
   :start-at: solver:
   :end-before: plotting:

Note, that config/test/config.electricity.yaml only includes changes relative to the default configuration. There are many more configuration options, which are documented at :ref:`config`.

System Message: ERROR/3 (<stdin>, line 98); backlink

Unknown interpreted text role "ref".

How to use snakemake rules?

Open a terminal, go into the PyPSA-Eur directory, and activate the pypsa-eur environment with

System Message: WARNING/2 (<stdin>, line 108)

Cannot analyze code. Pygments package not found.

.. code:: bash

    mamba activate pypsa-eur

Let's say based on the modifications above we would like to solve a very simplified model clustered down to 6 buses and every 24 hours aggregated to one snapshot. The command

System Message: WARNING/2 (<stdin>, line 115)

Cannot analyze code. Pygments package not found.

.. code:: bash

    snakemake -call results/test-elec/networks/base_s_6_elec_lcopt_.nc --configfile config/test/config.electricity.yaml

orders snakemake to run the rule :mod:`solve_network` that produces the solved network and stores it in results/networks with the name base_s_6_elec_lcopt_.nc:

System Message: ERROR/3 (<stdin>, line 119); backlink

Unknown interpreted text role "mod".

System Message: ERROR/3 (<stdin>, line 121)

Unknown directive type "literalinclude".

.. literalinclude:: ../rules/solve_electricity.smk
   :start-at: rule solve_network:
   :end-before: rule solve_operations_network:

This triggers a workflow of multiple preceding jobs that depend on each rule's inputs and outputs:

System Message: ERROR/3 (<stdin>, line 127)

Unknown directive type "graphviz".

.. graphviz::
    :class: full-width
    :align: center

    digraph snakemake_dag {
        graph[bgcolor=white, margin=0];
        node[shape=box, style=rounded, fontname=sans,                 fontsize=10, penwidth=2];
        edge[penwidth=2, color=grey];
            0[label = "solve_network", color = "0.19 0.6 0.85", style="rounded"];
            1[label = "prepare_network\nll: copt\nopts: ", color = "0.24 0.6 0.85", style="rounded"];
            2[label = "add_electricity", color = "0.35 0.6 0.85", style="rounded"];
            3[label = "build_renewable_profiles", color = "0.15 0.6 0.85", style="rounded"];
            4[label = "determine_availability_matrix\ntechnology: solar", color = "0.39 0.6 0.85", style="rounded"];
            5[label = "retrieve_databundle", color = "0.65 0.6 0.85", style="rounded"];
            6[label = "build_shapes", color = "0.45 0.6 0.85", style="rounded"];
            7[label = "retrieve_naturalearth_countries", color = "0.03 0.6 0.85", style="rounded"];
            8[label = "retrieve_eez", color = "0.17 0.6 0.85", style="rounded"];
            9[label = "cluster_network\nclusters: 6", color = "0.38 0.6 0.85", style="rounded"];
            10[label = "simplify_network", color = "0.14 0.6 0.85", style="rounded"];
            11[label = "add_transmission_projects_and_dlr", color = "0.61 0.6 0.85", style="rounded"];
            12[label = "base_network", color = "0.36 0.6 0.85", style="rounded"];
            13[label = "retrieve_osm_prebuilt", color = "0.22 0.6 0.85", style="rounded"];
            14[label = "build_line_rating", color = "0.50 0.6 0.85", style="rounded"];
            15[label = "retrieve_cutout\ncutout: be-03-2013-era5", color = "0.02 0.6 0.85", style="rounded"];
            16[label = "build_transmission_projects", color = "0.08 0.6 0.85", style="rounded"];
            17[label = "build_electricity_demand_base", color = "0.11 0.6 0.85", style="rounded"];
            18[label = "build_electricity_demand", color = "0.60 0.6 0.85", style="rounded"];
            19[label = "retrieve_electricity_demand", color = "0.60 0.6 0.85", style="rounded"];
            20[label = "retrieve_synthetic_electricity_demand", color = "0.32 0.6 0.85", style="rounded"];
            21[label = "build_renewable_profiles", color = "0.15 0.6 0.85", style="rounded"];
            22[label = "determine_availability_matrix\ntechnology: solar-hsat", color = "0.39 0.6 0.85", style="rounded"];
            23[label = "build_renewable_profiles", color = "0.15 0.6 0.85", style="rounded"];
            24[label = "determine_availability_matrix\ntechnology: onwind", color = "0.39 0.6 0.85", style="rounded"];
            25[label = "build_renewable_profiles", color = "0.15 0.6 0.85", style="rounded"];
            26[label = "determine_availability_matrix\ntechnology: offwind-ac", color = "0.39 0.6 0.85", style="rounded"];
            27[label = "build_ship_raster", color = "0.12 0.6 0.85", style="rounded"];
            28[label = "retrieve_ship_raster", color = "0.44 0.6 0.85", style="rounded"];
            29[label = "build_renewable_profiles", color = "0.15 0.6 0.85", style="rounded"];
            30[label = "determine_availability_matrix\ntechnology: offwind-dc", color = "0.39 0.6 0.85", style="rounded"];
            31[label = "build_renewable_profiles", color = "0.15 0.6 0.85", style="rounded"];
            32[label = "determine_availability_matrix\ntechnology: offwind-float", color = "0.39 0.6 0.85", style="rounded"];
            33[label = "retrieve_cost_data\nyear: 2030", color = "0.01 0.6 0.85", style="rounded"];
            34[label = "build_powerplants", color = "0.52 0.6 0.85", style="rounded"];
            1 -> 0
            2 -> 1
            33 -> 1
            3 -> 2
            21 -> 2
            23 -> 2
            25 -> 2
            29 -> 2
            31 -> 2
            9 -> 2
            33 -> 2
            34 -> 2
            17 -> 2
            4 -> 3
            6 -> 3
            9 -> 3
            15 -> 3
            5 -> 4
            6 -> 4
            9 -> 4
            15 -> 4
            7 -> 6
            8 -> 6
            5 -> 6
            10 -> 9
            17 -> 9
            11 -> 10
            12 -> 10
            12 -> 11
            14 -> 11
            16 -> 11
            13 -> 12
            6 -> 12
            12 -> 14
            15 -> 14
            12 -> 16
            6 -> 16
            10 -> 17
            6 -> 17
            18 -> 17
            19 -> 18
            20 -> 18
            22 -> 21
            6 -> 21
            9 -> 21
            15 -> 21
            5 -> 22
            6 -> 22
            9 -> 22
            15 -> 22
            24 -> 23
            6 -> 23
            9 -> 23
            15 -> 23
            5 -> 24
            6 -> 24
            9 -> 24
            15 -> 24
            26 -> 25
            6 -> 25
            9 -> 25
            15 -> 25
            5 -> 26
            27 -> 26
            6 -> 26
            9 -> 26
            15 -> 26
            28 -> 27
            15 -> 27
            30 -> 29
            6 -> 29
            9 -> 29
            15 -> 29
            5 -> 30
            27 -> 30
            6 -> 30
            9 -> 30
            15 -> 30
            32 -> 31
            6 -> 31
            9 -> 31
            15 -> 31
            5 -> 32
            27 -> 32
            6 -> 32
            9 -> 32
            15 -> 32
            9 -> 34
    }


In the terminal, this will show up as a list of jobs to be run:

System Message: WARNING/2 (<stdin>, line 264)

Cannot analyze code. Pygments package not found.

.. code:: bash

    Building DAG of jobs...
    Job stats:
    job                                      count
    -------------------------------------  -------
    add_electricity                              1
    add_transmission_projects_and_dlr            1
    base_network                                 1
    build_electricity_demand                     1
    build_electricity_demand_base                1
    build_line_rating                            1
    build_powerplants                            1
    build_renewable_profiles                     6
    build_shapes                                 1
    build_ship_raster                            1
    build_transmission_projects                  1
    cluster_network                              1
    determine_availability_matrix                6
    prepare_network                              1
    retrieve_cost_data                           1
    retrieve_cutout                              1
    retrieve_databundle                          1
    retrieve_eez                                 1
    retrieve_electricity_demand                  1
    retrieve_naturalearth_countries              1
    retrieve_osm_prebuilt                        1
    retrieve_ship_raster                         1
    retrieve_synthetic_electricity_demand        1
    simplify_network                             1
    solve_network                                1
    total                                       35


snakemake then runs these jobs in the correct order.

A job (here simplify_network) will display its attributes and normally some logs below this block:

System Message: WARNING/2 (<stdin>, line 302)

Cannot analyze code. Pygments package not found.

.. code:: bash

    rule simplify_network:
        input: resources/test/networks/base_extended.nc, resources/test/regions_onshore.geojson, resources/test/regions_offshore.geojson
        output: resources/test/networks/base_s.nc, resources/test/regions_onshore_base_s.geojson, resources/test/regions_offshore_base_s.geojson, resources/test/busmap_base_s.csv
        log: logs/test/simplify_network.log
        jobid: 10
        benchmark: benchmarks/test/simplify_network_b
        reason: Forced execution
        resources: tmpdir=<TBD>, mem_mb=12000, mem_mib=11445

Once the whole worktree is finished, it should state so in the terminal.

You will notice that many intermediate stages are saved, namely the outputs of each individual snakemake rule.

You can produce any output file occurring in the Snakefile by running

System Message: WARNING/2 (<stdin>, line 319)

Cannot analyze code. Pygments package not found.

.. code:: bash

    snakemake -call <output file>

For example, you can explore the evolution of the PyPSA networks by running

  1. snakemake resources/networks/base.nc -call --configfile config/test/config.electricity.yaml
  2. snakemake resources/networks/base_s.nc -call --configfile config/test/config.electricity.yaml
  3. snakemake resources/networks/base_s_6.nc -call --configfile config/test/config.electricity.yaml
  4. snakemake resources/networks/base_s_6_elec_lcopt_.nc -call --configfile config/test/config.electricity.yaml

To run all combinations of wildcard values provided in the config/config.yaml under scenario:, you can use the collection rule solve_elec_networks.

System Message: WARNING/2 (<stdin>, line 333)

Cannot analyze code. Pygments package not found.

.. code:: bash

    snakemake -call solve_elec_networks --configfile config/test/config.electricity.yaml

If you now feel confident and want to tackle runs with larger temporal and spatial scope, clean-up the repository and after modifying the config/config.yaml file target the collection rule solve_elec_networks again without providing the test configuration file.

System Message: WARNING/2 (<stdin>, line 342)

Cannot analyze code. Pygments package not found.

.. code:: bash

    snakemake -call purge
    snakemake -call solve_elec_networks

Note

It is good practice to perform a dry-run using the option -n, before you commit to a run:

System Message: WARNING/2 (<stdin>, line 352)

Cannot analyze code. Pygments package not found.

.. code:: bash

    snakemake -call solve_elec_networks -n

How to analyse results?

The solved networks can be analysed just like any other PyPSA network (e.g. in Jupyter Notebooks).

System Message: WARNING/2 (<stdin>, line 362)

Cannot analyze code. Pygments package not found.

.. code:: python

    import pypsa

    n = pypsa.Network("results/networks/base_s_6_elec_lcopt_.nc")

For inspiration, read the examples section in the PyPSA documentation.

</html>