From c54ddab4a331fdbe08f4938cb838bf2f128d93f0 Mon Sep 17 00:00:00 2001 From: Fabian Neumann Date: Thu, 24 Mar 2022 14:47:00 +0100 Subject: [PATCH 01/20] remove unused simple_hvdc_costs --- doc/release_notes.rst | 1 + scripts/add_electricity.py | 18 +++++++----------- scripts/make_summary.py | 2 +- scripts/prepare_network.py | 2 +- 4 files changed, 10 insertions(+), 13 deletions(-) diff --git a/doc/release_notes.rst b/doc/release_notes.rst index 3b20fbcf..7deee108 100644 --- a/doc/release_notes.rst +++ b/doc/release_notes.rst @@ -62,6 +62,7 @@ Upcoming Release * New network topology extracted from the ENTSO-E interactive map. +* The unused argument ``simple_hvdc_costs`` in :mod:`add_electricity` was removed. PyPSA-Eur 0.4.0 (22th September 2021) ===================================== diff --git a/scripts/add_electricity.py b/scripts/add_electricity.py index 7dffe60f..ad932cd8 100755 --- a/scripts/add_electricity.py +++ b/scripts/add_electricity.py @@ -227,7 +227,7 @@ def attach_load(n, regions, load, nuts3_shapes, countries, scaling=1.): n.madd("Load", substation_lv_i, bus=substation_lv_i, p_set=load) -def update_transmission_costs(n, costs, length_factor=1.0, simple_hvdc_costs=False): +def update_transmission_costs(n, costs, length_factor=1.0): # TODO: line length factor of lines is applied to lines and links. # Separate the function to distinguish. @@ -242,16 +242,12 @@ def update_transmission_costs(n, costs, length_factor=1.0, simple_hvdc_costs=Fal # may be missing. Therefore we have to return here. if n.links.loc[dc_b].empty: return - if simple_hvdc_costs: - costs = (n.links.loc[dc_b, 'length'] * length_factor * - costs.at['HVDC overhead', 'capital_cost']) - else: - costs = (n.links.loc[dc_b, 'length'] * length_factor * - ((1. - n.links.loc[dc_b, 'underwater_fraction']) * - costs.at['HVDC overhead', 'capital_cost'] + - n.links.loc[dc_b, 'underwater_fraction'] * - costs.at['HVDC submarine', 'capital_cost']) + - costs.at['HVDC inverter pair', 'capital_cost']) + costs = (n.links.loc[dc_b, 'length'] * length_factor * + ((1. - n.links.loc[dc_b, 'underwater_fraction']) * + costs.at['HVDC overhead', 'capital_cost'] + + n.links.loc[dc_b, 'underwater_fraction'] * + costs.at['HVDC submarine', 'capital_cost']) + + costs.at['HVDC inverter pair', 'capital_cost']) n.links.loc[dc_b, 'capital_cost'] = costs diff --git a/scripts/make_summary.py b/scripts/make_summary.py index 854e9463..af1ecf36 100644 --- a/scripts/make_summary.py +++ b/scripts/make_summary.py @@ -404,7 +404,7 @@ def make_summaries(networks_dict, paths, config, country='all'): Nyears = n.snapshot_weightings.objective.sum() / 8760. costs = load_costs(paths[0], config['costs'], config['electricity'], Nyears) - update_transmission_costs(n, costs, simple_hvdc_costs=False) + update_transmission_costs(n, costs) assign_carriers(n) diff --git a/scripts/prepare_network.py b/scripts/prepare_network.py index f984ace6..206e220b 100755 --- a/scripts/prepare_network.py +++ b/scripts/prepare_network.py @@ -104,7 +104,7 @@ def set_transmission_limit(n, ll_type, factor, costs, Nyears=1): ref = (lines_s_nom @ n.lines[col] + n.links.loc[links_dc_b, "p_nom"] @ n.links.loc[links_dc_b, col]) - update_transmission_costs(n, costs, simple_hvdc_costs=False) + update_transmission_costs(n, costs) if factor == 'opt' or float(factor) > 1.0: n.lines['s_nom_min'] = lines_s_nom From 70640cc336c9ed559c6ea04ed7517c7046b1484a Mon Sep 17 00:00:00 2001 From: Fabian Neumann Date: Sun, 3 Apr 2022 09:42:07 +0200 Subject: [PATCH 02/20] doc: fix tutorial config line references --- doc/tutorial.rst | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/doc/tutorial.rst b/doc/tutorial.rst index 17d4e3c1..76970aff 100644 --- a/doc/tutorial.rst +++ b/doc/tutorial.rst @@ -53,41 +53,43 @@ Likewise, the example's temporal scope can be restricted (e.g. to a single month .. literalinclude:: ../config.tutorial.yaml :language: yaml - :lines: 24-27 + :start-at: snapshots: + :end-before: enable: It is also possible to allow less or more carbon-dioxide emissions. Here, we limit the emissions of Germany 100 Megatonnes per year. .. literalinclude:: ../config.tutorial.yaml :language: yaml - :lines: 38,40 + :lines: 40,42 PyPSA-Eur also includes a database of existing conventional powerplants. We can select which types of powerplants we like to be included with fixed capacities: .. literalinclude:: ../config.tutorial.yaml :language: yaml - :lines: 38,54 + :lines: 40,56 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. .. literalinclude:: ../config.tutorial.yaml :language: yaml - :lines: 56-63 + :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-2 dataset. .. literalinclude:: ../config.tutorial.yaml :language: yaml - :lines: 65,108-109 + :lines: 67,110,111 Finally, it is possible to pick a solver. For instance, this tutorial uses the open-source solvers CBC and Ipopt and does not rely on the commercial solvers Gurobi or CPLEX (for which free academic licenses are available). .. literalinclude:: ../config.tutorial.yaml :language: yaml - :lines: 171,181-182 + :lines: 173,183,184 .. note:: @@ -126,11 +128,6 @@ orders ``snakemake`` to run the script ``solve_network`` that produces the solve .. until https://github.com/snakemake/snakemake/issues/46 closed -.. warning:: - On Windows the previous command may currently cause a ``MissingRuleException`` due to problems with output files in subfolders. - This is an `open issue `_ at `snakemake `_. - Windows users should add the option ``--keep-target-files`` to the command or instead run ``snakemake -j 1 solve_all_networks``. - This triggers a workflow of multiple preceding jobs that depend on each rule's inputs and outputs: .. graphviz:: @@ -271,7 +268,8 @@ the wildcards given in ``scenario`` in the configuration file ``config.yaml`` ar .. literalinclude:: ../config.tutorial.yaml :language: yaml - :lines: 14-18 + :start-at: scenario: + :end-before: countries: In this example we would not only solve a 6-node model of Germany but also a 2-node model. From a217415c396b7e1eea58c346b21f865366e15849 Mon Sep 17 00:00:00 2001 From: Fabian Neumann Date: Sun, 3 Apr 2022 09:42:35 +0200 Subject: [PATCH 03/20] env: bump minimum version number of atlite due to new cutouts with azimuth wind --- envs/environment.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/envs/environment.yaml b/envs/environment.yaml index 00b7830a..3c69b77b 100644 --- a/envs/environment.yaml +++ b/envs/environment.yaml @@ -11,7 +11,7 @@ dependencies: - pip - pypsa>=0.18.1 - - atlite>=0.2.5 + - atlite>=0.2.6 - dask # Dependencies of the workflow itself From 46acddd3697c9af84e6be5fcfef229e2a32609d3 Mon Sep 17 00:00:00 2001 From: Fabian Neumann Date: Mon, 4 Apr 2022 22:17:40 +0200 Subject: [PATCH 04/20] update TYNDP links which are already built --- data/links_tyndp.csv | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/data/links_tyndp.csv b/data/links_tyndp.csv index 8079be72..38203979 100644 --- a/data/links_tyndp.csv +++ b/data/links_tyndp.csv @@ -1,14 +1,15 @@ Name,Converterstation 1,Converterstation 2,Length (given) (km),Length (distance*1.2) (km),Power (MW),status,replaces,Ref,x1,y1,x2,y2 Biscay Gulf,Gatica (ES),Cubnezais (FR),370,,2200,in permitting,,https://tyndp.entsoe.eu/tyndp2018/projects/projects/16,-2.867,43.367,-0.408943,45.074191 Italy-France,Piossasco (IT),Grand Ile (FR),190,,1000,under construction,,https://tyndp.entsoe.eu/tyndp2018/projects/projects/21,7.468,44.9898,6.045,45.472 -IFA2,Tourbe (FR),Chilling (GB),,247.2,1000,under construction,,https://tyndp.entsoe.eu/tyndp2018/projects/projects/25,-0.172042,49.083593,-1.277269,50.839338 -Italy-Montenegro,Villanova (IT),Latsva (MT),445,,1200,under construction,Link.14539,https://tyndp.entsoe.eu/tyndp2018/projects/projects/28,14.125,42.3947222222222,18.7947222222222,42.3175 -NordLink,Tonstad (NO),Wilster (DE),514,,1400,under construction,,https://tyndp.entsoe.eu/tyndp2018/projects/projects/37,6.716948,58.662631,9.373979,53.922479 -COBRA cable,Endrup (DK),Eemshaven (NL),325,,700,under construction,,https://tyndp.entsoe.eu/tyndp2018/projects/projects/71,8.718392,55.523115,6.835494,53.438589 -Thames Estuary Cluster (NEMO-Link),Richborough (GB),Gezelle (BE),140,,1000,under construction,,https://tyndp.entsoe.eu/tyndp2018/projects/projects/74,1.324854,51.295891,3.23043,51.24902 -Anglo-Scottish -1,Hunterston (UK),Deeside (UK),422,,2400,built,,https://tyndp.entsoe.eu/tyndp2018/projects/projects/77,-4.898329,55.723331,-3.032972,53.199735 +IFA2,Tourbe (FR),Chilling (GB),,247.2,1000,built,,https://tyndp.entsoe.eu/tyndp2018/projects/projects/25,-0.172042,49.083593,-1.277269,50.839338 +Italy-Montenegro Phase 1,Villanova (IT),Latsva (MT),445,,600,built,Link.14539,https://tyndp.entsoe.eu/tyndp2018/projects/projects/28,14.125,42.3947222222222,18.7947222222222,42.3175 +Italy-Montenegro Phase 2,Villanova (IT),Latsva (MT),445,,600,under construction,Link.14539,https://tyndp.entsoe.eu/tyndp2018/projects/projects/28,14.125,42.3947222222222,18.7947222222222,42.3175 +NordLink,Tonstad (NO),Wilster (DE),514,,1400,built,,https://tyndp.entsoe.eu/tyndp2018/projects/projects/37,6.716948,58.662631,9.373979,53.922479 +COBRA cable,Endrup (DK),Eemshaven (NL),325,,700,built,,https://tyndp.entsoe.eu/tyndp2018/projects/projects/71,8.718392,55.523115,6.835494,53.438589 +Thames Estuary Cluster (NEMO-Link),Richborough (GB),Gezelle (BE),140,,1000,built,,https://tyndp.entsoe.eu/tyndp2018/projects/projects/74,1.324854,51.295891,3.23043,51.24902 +Anglo-Scottish-1,Hunterston (UK),Deeside (UK),422,,2400,built,,https://tyndp.entsoe.eu/tyndp2018/projects/projects/77,-4.898329,55.723331,-3.032972,53.199735 ALEGrO,Lixhe (BE),Oberzier (DE),100,,1000,built,,https://tyndp.entsoe.eu/tyndp2018/projects/projects/92,5.67933,50.7567965,6.474704,50.867532 -North Sea Link,Kvilldal (NO),Blythe (GB),720,,1400,under construction,,https://tyndp.entsoe.eu/tyndp2018/projects/projects/110,6.637527,59.515096,-1.510277,55.126957 +North Sea Link,Kvilldal (NO),Blythe (GB),720,,1400,built,,https://tyndp.entsoe.eu/tyndp2018/projects/projects/110,6.637527,59.515096,-1.510277,55.126957 HVDC SuedOstLink,Wolmirstedt (DE),Isar (DE),,557,2000,in permitting,,https://tyndp.entsoe.eu/tyndp2018/projects/projects/130,11.629014,52.252137,12.091596,48.080837 HVDC Line A-North,Emden East (DE),Osterath (DE),,284,2000,in permitting,,https://tyndp.entsoe.eu/tyndp2018/projects/projects/132,7.206009,53.359403,6.619451,51.272935 France-Alderney-Britain,Exeter (UK),Menuel (FR),220,,1400,in permitting,,https://tyndp.entsoe.eu/tyndp2018/projects/projects/153,-3.533899,50.718412,-1.469216,49.509594 From 2a34ab26c4f09deb637ed3c143c8a6d96e7346a2 Mon Sep 17 00:00:00 2001 From: Fabian Neumann Date: Tue, 5 Apr 2022 16:07:04 +0200 Subject: [PATCH 05/20] add TYNDP link replaces --- data/links_tyndp.csv | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/data/links_tyndp.csv b/data/links_tyndp.csv index 38203979..dd55e514 100644 --- a/data/links_tyndp.csv +++ b/data/links_tyndp.csv @@ -2,14 +2,13 @@ Name,Converterstation 1,Converterstation 2,Length (given) (km),Length (distance* Biscay Gulf,Gatica (ES),Cubnezais (FR),370,,2200,in permitting,,https://tyndp.entsoe.eu/tyndp2018/projects/projects/16,-2.867,43.367,-0.408943,45.074191 Italy-France,Piossasco (IT),Grand Ile (FR),190,,1000,under construction,,https://tyndp.entsoe.eu/tyndp2018/projects/projects/21,7.468,44.9898,6.045,45.472 IFA2,Tourbe (FR),Chilling (GB),,247.2,1000,built,,https://tyndp.entsoe.eu/tyndp2018/projects/projects/25,-0.172042,49.083593,-1.277269,50.839338 -Italy-Montenegro Phase 1,Villanova (IT),Latsva (MT),445,,600,built,Link.14539,https://tyndp.entsoe.eu/tyndp2018/projects/projects/28,14.125,42.3947222222222,18.7947222222222,42.3175 -Italy-Montenegro Phase 2,Villanova (IT),Latsva (MT),445,,600,under construction,Link.14539,https://tyndp.entsoe.eu/tyndp2018/projects/projects/28,14.125,42.3947222222222,18.7947222222222,42.3175 -NordLink,Tonstad (NO),Wilster (DE),514,,1400,built,,https://tyndp.entsoe.eu/tyndp2018/projects/projects/37,6.716948,58.662631,9.373979,53.922479 -COBRA cable,Endrup (DK),Eemshaven (NL),325,,700,built,,https://tyndp.entsoe.eu/tyndp2018/projects/projects/71,8.718392,55.523115,6.835494,53.438589 +Italy-Montenegro,Villanova (IT),Latsva (MT),445,,1200,built,Link.14802,https://tyndp.entsoe.eu/tyndp2018/projects/projects/28,14.125,42.3947222222222,18.7947222222222,42.3175 +NordLink,Tonstad (NO),Wilster (DE),514,,1400,built,Link.14848,https://tyndp.entsoe.eu/tyndp2018/projects/projects/37,6.716948,58.662631,9.373979,53.922479 +COBRA cable,Endrup (DK),Eemshaven (NL),325,,700,built,Link.14803,https://tyndp.entsoe.eu/tyndp2018/projects/projects/71,8.718392,55.523115,6.835494,53.438589 Thames Estuary Cluster (NEMO-Link),Richborough (GB),Gezelle (BE),140,,1000,built,,https://tyndp.entsoe.eu/tyndp2018/projects/projects/74,1.324854,51.295891,3.23043,51.24902 -Anglo-Scottish-1,Hunterston (UK),Deeside (UK),422,,2400,built,,https://tyndp.entsoe.eu/tyndp2018/projects/projects/77,-4.898329,55.723331,-3.032972,53.199735 -ALEGrO,Lixhe (BE),Oberzier (DE),100,,1000,built,,https://tyndp.entsoe.eu/tyndp2018/projects/projects/92,5.67933,50.7567965,6.474704,50.867532 -North Sea Link,Kvilldal (NO),Blythe (GB),720,,1400,built,,https://tyndp.entsoe.eu/tyndp2018/projects/projects/110,6.637527,59.515096,-1.510277,55.126957 +Anglo-Scottish-1,Hunterston (UK),Deeside (UK),422,,2400,built,Link.8009,https://tyndp.entsoe.eu/tyndp2018/projects/projects/77,-4.898329,55.723331,-3.032972,53.199735 +ALEGrO,Lixhe (BE),Oberzier (DE),100,,1000,built,Link.14801,https://tyndp.entsoe.eu/tyndp2018/projects/projects/92,5.67933,50.7567965,6.474704,50.867532 +North Sea Link,Kvilldal (NO),Blythe (GB),720,,1400,built,Link.14804,https://tyndp.entsoe.eu/tyndp2018/projects/projects/110,6.637527,59.515096,-1.510277,55.126957 HVDC SuedOstLink,Wolmirstedt (DE),Isar (DE),,557,2000,in permitting,,https://tyndp.entsoe.eu/tyndp2018/projects/projects/130,11.629014,52.252137,12.091596,48.080837 HVDC Line A-North,Emden East (DE),Osterath (DE),,284,2000,in permitting,,https://tyndp.entsoe.eu/tyndp2018/projects/projects/132,7.206009,53.359403,6.619451,51.272935 France-Alderney-Britain,Exeter (UK),Menuel (FR),220,,1400,in permitting,,https://tyndp.entsoe.eu/tyndp2018/projects/projects/153,-3.533899,50.718412,-1.469216,49.509594 @@ -24,4 +23,4 @@ HVDC Ultranet,Osterath (DE),Philippsburg (DE),,314,600,in permitting,,https://ty Gridlink,Kingsnorth (UK),Warande (FR),160,,1400,in permitting,,https://tyndp.entsoe.eu/tyndp2018/projects/projects/285,0.596111111111111,51.41972,2.376776,51.034368 NeuConnect,Grain (UK),Fedderwarden (DE),680,,1400,in permitting,,https://tyndp.entsoe.eu/tyndp2018/projects/projects/309,0.716666666666667,51.44,8.046524,53.562763 NordBalt,Klaipeda (LT),Nybro (SE),450,,700,built,,https://en.wikipedia.org/wiki/NordBalt,21.256667,55.681667,15.854167,56.767778 -Estlink 1,Harku (EE),Espoo (FI),105,,350,built,,https://en.wikipedia.org/wiki/Estlink,24.560278,59.384722,24.551667,60.203889 +Estlink 1,Harku (EE),Espoo (FI),105,,350,built,Link.14807,https://en.wikipedia.org/wiki/Estlink,24.560278,59.384722,24.551667,60.203889 From eca4a017dbb882645b49eb6114ff9731e4b476ce Mon Sep 17 00:00:00 2001 From: Fabian Neumann Date: Tue, 5 Apr 2022 16:07:30 +0200 Subject: [PATCH 06/20] implement TYNDP link overriding for link_id not oid --- scripts/base_network.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/scripts/base_network.py b/scripts/base_network.py index 50ec8e53..646a3e9c 100644 --- a/scripts/base_network.py +++ b/scripts/base_network.py @@ -196,14 +196,15 @@ def _add_links_from_tyndp(buses, links, links_tyndp, europe_shape): return buses, links has_replaces_b = links_tyndp.replaces.notnull() - oids = dict(Bus=_get_oid(buses), Link=_get_oid(links)) + logger.info("TYNDP links replacing links in dataset (overwriting): " + ", ".join(links_tyndp.loc[has_replaces_b, "Name"])) + ids = dict(Bus=buses.index, Link=links.index) keep_b = dict(Bus=pd.Series(True, index=buses.index), Link=pd.Series(True, index=links.index)) for reps in links_tyndp.loc[has_replaces_b, 'replaces']: for comps in reps.split(':'): - oids_to_remove = comps.split('.') - c = oids_to_remove.pop(0) - keep_b[c] &= ~oids[c].isin(oids_to_remove) + ids_to_remove = comps.split('.') + c = ids_to_remove.pop(0) + keep_b[c] &= ~ids[c].isin(ids_to_remove) buses = buses.loc[keep_b['Bus']] links = links.loc[keep_b['Link']] @@ -211,7 +212,7 @@ def _add_links_from_tyndp(buses, links, links_tyndp, europe_shape): # Corresponds approximately to 20km tolerances if links_tyndp["j"].notnull().any(): - logger.info("TYNDP links already in the dataset (skipping): " + ", ".join(links_tyndp.loc[links_tyndp["j"].notnull(), "Name"])) + logger.info("Additional TYNDP links already in the dataset (skipping): " + ", ".join(links_tyndp.loc[links_tyndp["j"].notnull(), "Name"])) links_tyndp = links_tyndp.loc[links_tyndp["j"].isnull()] if links_tyndp.empty: return buses, links From aa6e98a56375b6c8c2c16cfc541a48ca4b239277 Mon Sep 17 00:00:00 2001 From: Fabian Neumann Date: Tue, 5 Apr 2022 16:11:02 +0200 Subject: [PATCH 07/20] label built TYNDP links as not under_construction --- scripts/base_network.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/base_network.py b/scripts/base_network.py index 646a3e9c..9e8421ab 100644 --- a/scripts/base_network.py +++ b/scripts/base_network.py @@ -236,7 +236,7 @@ def _add_links_from_tyndp(buses, links, links_tyndp, europe_shape): carrier='DC', p_nom=links_tyndp["Power (MW)"], length=links_tyndp["Length (given) (km)"].fillna(links_tyndp["Length (distance*1.2) (km)"]), - under_construction=True, + under_construction=~(links_tyndp.status == 'built'), underground=False, geometry=(links_tyndp[["x1", "y1", "x2", "y2"]] .apply(lambda s: str(LineString([[s.x1, s.y1], [s.x2, s.y2]])), axis=1)), From bfcc20aa13578354e90fe851f4761dd70e726ba9 Mon Sep 17 00:00:00 2001 From: Fabian Neumann Date: Tue, 5 Apr 2022 17:10:12 +0200 Subject: [PATCH 08/20] Revert "update TYNDP links which are already built" --- data/links_tyndp.csv | 18 +++++++++--------- scripts/base_network.py | 13 ++++++------- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/data/links_tyndp.csv b/data/links_tyndp.csv index dd55e514..8079be72 100644 --- a/data/links_tyndp.csv +++ b/data/links_tyndp.csv @@ -1,14 +1,14 @@ Name,Converterstation 1,Converterstation 2,Length (given) (km),Length (distance*1.2) (km),Power (MW),status,replaces,Ref,x1,y1,x2,y2 Biscay Gulf,Gatica (ES),Cubnezais (FR),370,,2200,in permitting,,https://tyndp.entsoe.eu/tyndp2018/projects/projects/16,-2.867,43.367,-0.408943,45.074191 Italy-France,Piossasco (IT),Grand Ile (FR),190,,1000,under construction,,https://tyndp.entsoe.eu/tyndp2018/projects/projects/21,7.468,44.9898,6.045,45.472 -IFA2,Tourbe (FR),Chilling (GB),,247.2,1000,built,,https://tyndp.entsoe.eu/tyndp2018/projects/projects/25,-0.172042,49.083593,-1.277269,50.839338 -Italy-Montenegro,Villanova (IT),Latsva (MT),445,,1200,built,Link.14802,https://tyndp.entsoe.eu/tyndp2018/projects/projects/28,14.125,42.3947222222222,18.7947222222222,42.3175 -NordLink,Tonstad (NO),Wilster (DE),514,,1400,built,Link.14848,https://tyndp.entsoe.eu/tyndp2018/projects/projects/37,6.716948,58.662631,9.373979,53.922479 -COBRA cable,Endrup (DK),Eemshaven (NL),325,,700,built,Link.14803,https://tyndp.entsoe.eu/tyndp2018/projects/projects/71,8.718392,55.523115,6.835494,53.438589 -Thames Estuary Cluster (NEMO-Link),Richborough (GB),Gezelle (BE),140,,1000,built,,https://tyndp.entsoe.eu/tyndp2018/projects/projects/74,1.324854,51.295891,3.23043,51.24902 -Anglo-Scottish-1,Hunterston (UK),Deeside (UK),422,,2400,built,Link.8009,https://tyndp.entsoe.eu/tyndp2018/projects/projects/77,-4.898329,55.723331,-3.032972,53.199735 -ALEGrO,Lixhe (BE),Oberzier (DE),100,,1000,built,Link.14801,https://tyndp.entsoe.eu/tyndp2018/projects/projects/92,5.67933,50.7567965,6.474704,50.867532 -North Sea Link,Kvilldal (NO),Blythe (GB),720,,1400,built,Link.14804,https://tyndp.entsoe.eu/tyndp2018/projects/projects/110,6.637527,59.515096,-1.510277,55.126957 +IFA2,Tourbe (FR),Chilling (GB),,247.2,1000,under construction,,https://tyndp.entsoe.eu/tyndp2018/projects/projects/25,-0.172042,49.083593,-1.277269,50.839338 +Italy-Montenegro,Villanova (IT),Latsva (MT),445,,1200,under construction,Link.14539,https://tyndp.entsoe.eu/tyndp2018/projects/projects/28,14.125,42.3947222222222,18.7947222222222,42.3175 +NordLink,Tonstad (NO),Wilster (DE),514,,1400,under construction,,https://tyndp.entsoe.eu/tyndp2018/projects/projects/37,6.716948,58.662631,9.373979,53.922479 +COBRA cable,Endrup (DK),Eemshaven (NL),325,,700,under construction,,https://tyndp.entsoe.eu/tyndp2018/projects/projects/71,8.718392,55.523115,6.835494,53.438589 +Thames Estuary Cluster (NEMO-Link),Richborough (GB),Gezelle (BE),140,,1000,under construction,,https://tyndp.entsoe.eu/tyndp2018/projects/projects/74,1.324854,51.295891,3.23043,51.24902 +Anglo-Scottish -1,Hunterston (UK),Deeside (UK),422,,2400,built,,https://tyndp.entsoe.eu/tyndp2018/projects/projects/77,-4.898329,55.723331,-3.032972,53.199735 +ALEGrO,Lixhe (BE),Oberzier (DE),100,,1000,built,,https://tyndp.entsoe.eu/tyndp2018/projects/projects/92,5.67933,50.7567965,6.474704,50.867532 +North Sea Link,Kvilldal (NO),Blythe (GB),720,,1400,under construction,,https://tyndp.entsoe.eu/tyndp2018/projects/projects/110,6.637527,59.515096,-1.510277,55.126957 HVDC SuedOstLink,Wolmirstedt (DE),Isar (DE),,557,2000,in permitting,,https://tyndp.entsoe.eu/tyndp2018/projects/projects/130,11.629014,52.252137,12.091596,48.080837 HVDC Line A-North,Emden East (DE),Osterath (DE),,284,2000,in permitting,,https://tyndp.entsoe.eu/tyndp2018/projects/projects/132,7.206009,53.359403,6.619451,51.272935 France-Alderney-Britain,Exeter (UK),Menuel (FR),220,,1400,in permitting,,https://tyndp.entsoe.eu/tyndp2018/projects/projects/153,-3.533899,50.718412,-1.469216,49.509594 @@ -23,4 +23,4 @@ HVDC Ultranet,Osterath (DE),Philippsburg (DE),,314,600,in permitting,,https://ty Gridlink,Kingsnorth (UK),Warande (FR),160,,1400,in permitting,,https://tyndp.entsoe.eu/tyndp2018/projects/projects/285,0.596111111111111,51.41972,2.376776,51.034368 NeuConnect,Grain (UK),Fedderwarden (DE),680,,1400,in permitting,,https://tyndp.entsoe.eu/tyndp2018/projects/projects/309,0.716666666666667,51.44,8.046524,53.562763 NordBalt,Klaipeda (LT),Nybro (SE),450,,700,built,,https://en.wikipedia.org/wiki/NordBalt,21.256667,55.681667,15.854167,56.767778 -Estlink 1,Harku (EE),Espoo (FI),105,,350,built,Link.14807,https://en.wikipedia.org/wiki/Estlink,24.560278,59.384722,24.551667,60.203889 +Estlink 1,Harku (EE),Espoo (FI),105,,350,built,,https://en.wikipedia.org/wiki/Estlink,24.560278,59.384722,24.551667,60.203889 diff --git a/scripts/base_network.py b/scripts/base_network.py index 9e8421ab..50ec8e53 100644 --- a/scripts/base_network.py +++ b/scripts/base_network.py @@ -196,15 +196,14 @@ def _add_links_from_tyndp(buses, links, links_tyndp, europe_shape): return buses, links has_replaces_b = links_tyndp.replaces.notnull() - logger.info("TYNDP links replacing links in dataset (overwriting): " + ", ".join(links_tyndp.loc[has_replaces_b, "Name"])) - ids = dict(Bus=buses.index, Link=links.index) + oids = dict(Bus=_get_oid(buses), Link=_get_oid(links)) keep_b = dict(Bus=pd.Series(True, index=buses.index), Link=pd.Series(True, index=links.index)) for reps in links_tyndp.loc[has_replaces_b, 'replaces']: for comps in reps.split(':'): - ids_to_remove = comps.split('.') - c = ids_to_remove.pop(0) - keep_b[c] &= ~ids[c].isin(ids_to_remove) + oids_to_remove = comps.split('.') + c = oids_to_remove.pop(0) + keep_b[c] &= ~oids[c].isin(oids_to_remove) buses = buses.loc[keep_b['Bus']] links = links.loc[keep_b['Link']] @@ -212,7 +211,7 @@ def _add_links_from_tyndp(buses, links, links_tyndp, europe_shape): # Corresponds approximately to 20km tolerances if links_tyndp["j"].notnull().any(): - logger.info("Additional TYNDP links already in the dataset (skipping): " + ", ".join(links_tyndp.loc[links_tyndp["j"].notnull(), "Name"])) + logger.info("TYNDP links already in the dataset (skipping): " + ", ".join(links_tyndp.loc[links_tyndp["j"].notnull(), "Name"])) links_tyndp = links_tyndp.loc[links_tyndp["j"].isnull()] if links_tyndp.empty: return buses, links @@ -236,7 +235,7 @@ def _add_links_from_tyndp(buses, links, links_tyndp, europe_shape): carrier='DC', p_nom=links_tyndp["Power (MW)"], length=links_tyndp["Length (given) (km)"].fillna(links_tyndp["Length (distance*1.2) (km)"]), - under_construction=~(links_tyndp.status == 'built'), + under_construction=True, underground=False, geometry=(links_tyndp[["x1", "y1", "x2", "y2"]] .apply(lambda s: str(LineString([[s.x1, s.y1], [s.x2, s.y2]])), axis=1)), From 3acc4a22360cbf6c3f22c63880f55c465ee8244b Mon Sep 17 00:00:00 2001 From: Fabian Neumann Date: Tue, 12 Apr 2022 14:52:37 +0200 Subject: [PATCH 09/20] update country reference from Germany to Belgium in tutorial --- doc/tutorial.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/tutorial.rst b/doc/tutorial.rst index 76970aff..c37abb39 100644 --- a/doc/tutorial.rst +++ b/doc/tutorial.rst @@ -43,7 +43,7 @@ For more information on the data dependencies of PyPSA-Eur, continue reading :re How to customise PyPSA-Eur? =========================== -The model can be adapted to only include selected countries (e.g. Germany) instead of all European countries to limit the spatial scope. +The model can be adapted to only include selected countries (e.g. Belgium) instead of all European countries to limit the spatial scope. .. literalinclude:: ../config.tutorial.yaml :language: yaml From 49f1c0f6299401fc99ea2ebb849ff45be68397a4 Mon Sep 17 00:00:00 2001 From: Fabian Neumann Date: Fri, 15 Apr 2022 18:36:37 +0200 Subject: [PATCH 10/20] Merge pull request #348 from PyPSA/annuity add_electricity: remove vresutils.costdata.annuity dependency --- scripts/add_electricity.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/scripts/add_electricity.py b/scripts/add_electricity.py index ad932cd8..ceef2390 100755 --- a/scripts/add_electricity.py +++ b/scripts/add_electricity.py @@ -94,7 +94,6 @@ import geopandas as gpd import powerplantmatching as pm from powerplantmatching.export import map_country_bus -from vresutils.costdata import annuity from vresutils import transfer as vtransfer idx = pd.IndexSlice @@ -105,6 +104,18 @@ logger = logging.getLogger(__name__) def normed(s): return s/s.sum() +def calculate_annuity(n, r): + """Calculate the annuity factor for an asset with lifetime n years and + discount rate of r, e.g. annuity(20, 0.05) * 20 = 1.6""" + + if isinstance(r, pd.Series): + return pd.Series(1/n, index=r.index).where(r == 0, r/(1. - 1./(1.+r)**n)) + elif r > 0: + return r / (1. - 1./(1.+r)**n) + else: + return 1 / n + + def _add_missing_carriers_from_costs(n, costs, carriers): missing_carriers = pd.Index(carriers).difference(n.carriers.index) if missing_carriers.empty: return @@ -138,7 +149,7 @@ def load_costs(tech_costs, config, elec_config, Nyears=1.): "investment" : 0, "lifetime" : 25}) - costs["capital_cost"] = ((annuity(costs["lifetime"], costs["discount rate"]) + + costs["capital_cost"] = ((calculate_annuity(costs["lifetime"], costs["discount rate"]) + costs["FOM"]/100.) * costs["investment"] * Nyears) From dcac3ea6e1f8df9c8eca4e67c87512412310d252 Mon Sep 17 00:00:00 2001 From: martacki Date: Thu, 28 Apr 2022 12:59:25 +0200 Subject: [PATCH 11/20] respect stores in make_summary script --- scripts/make_summary.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scripts/make_summary.py b/scripts/make_summary.py index af1ecf36..a14000ef 100644 --- a/scripts/make_summary.py +++ b/scripts/make_summary.py @@ -171,6 +171,9 @@ def calculate_capacity(n,label,capacity): if 'p_nom_opt' in c.df.columns: c_capacities = abs(c.df.p_nom_opt.multiply(c.df.sign)).groupby(c.df.carrier).sum() capacity = include_in_summary(capacity, [c.list_name], label, c_capacities) + elif 'e_nom_opt' in c.df.columns: + c_capacities = abs(c.df.e_nom_opt.multiply(c.df.sign)).groupby(c.df.carrier).sum() + capacity = include_in_summary(capacity, [c.list_name], label, c_capacities) for c in n.iterate_components(n.passive_branch_components): c_capacities = c.df['s_nom_opt'].groupby(c.df.carrier).sum() From d12405d848ce83134bf0011f25d2394c020733d4 Mon Sep 17 00:00:00 2001 From: martacki Date: Fri, 29 Apr 2022 13:48:58 +0200 Subject: [PATCH 12/20] respect stores for energy_supply.csv --- scripts/make_summary.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/make_summary.py b/scripts/make_summary.py index a14000ef..972b245d 100644 --- a/scripts/make_summary.py +++ b/scripts/make_summary.py @@ -235,11 +235,11 @@ def calculate_supply(n, label, supply): def calculate_supply_energy(n, label, supply_energy): """calculate the total dispatch of each component at the buses where the loads are attached""" - load_types = n.loads.carrier.value_counts().index + load_types = n.buses.carrier.unique() for i in load_types: - buses = n.loads.bus[n.loads.carrier == i].values + buses = n.buses.query("carrier == @i").index bus_map = pd.Series(False,index=n.buses.index) From ac7c94337e98735906d87bb2da5c6b1d4bc2a5f2 Mon Sep 17 00:00:00 2001 From: martacki Date: Fri, 29 Apr 2022 13:51:54 +0200 Subject: [PATCH 13/20] respect stores for supply.csv --- scripts/make_summary.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/make_summary.py b/scripts/make_summary.py index 972b245d..c070d33f 100644 --- a/scripts/make_summary.py +++ b/scripts/make_summary.py @@ -188,11 +188,11 @@ def calculate_capacity(n,label,capacity): def calculate_supply(n, label, supply): """calculate the max dispatch of each component at the buses where the loads are attached""" - load_types = n.loads.carrier.value_counts().index + load_types = n.buses.carrier.unique() for i in load_types: - buses = n.loads.bus[n.loads.carrier == i].values + buses = n.buses.query("carrier == @i").index bus_map = pd.Series(False,index=n.buses.index) From 4706422f4b5e2da52031d59440909374cec35be6 Mon Sep 17 00:00:00 2001 From: Ebbe Kyhl <69363603+ebbekyhl@users.noreply.github.com> Date: Fri, 27 May 2022 16:14:01 +0200 Subject: [PATCH 14/20] Update version of powerplantmatching Hi, I recently became aware that I was using an older version (0.4.8) of the powerplantmatching. I tested my setup with the newer version (0.5.3), and it runs without any issues. The following is a comment/question on the powerplantmatching dataset, which maybe is relevant to mention: With regard to pumped-hydro storage (PHS), the newest version of powerplantmatching entails an energy storage capacity of 4.3 TWh (Europe-aggregate, assuming 6-hours duration for plants that do not have duration specified). In the earlier version 0.4.8, this was vastly overestimated at 10 TWh. As comparison, Geth et al. (2015) showed 1.3 TWh (including Norway and Switzerland) using 2012-numbers. PHS power capacity has increased from roughly 50 to 55 GW from 2014 to 2020 (iha, 2015, 2021), so energy storage capacity most likely is increased as well. But is it fair to say that energy storage capacity has been quadrupled since 2012 (from 1.3 TWh to 4.3 TWh)? Or how can we interpret this difference? Sources: Geth et al., 2015, https://doi.org/10.1016/j.rser.2015.07.145 iha, 2015, https://www.aler-renovaveis.org/contents/lerpublication/iha_2015_sept_hydropower-status-report.pdf iha, 2021, https://assets-global.website-files.com/5f749e4b9399c80b5e421384/60c37321987070812596e26a_IHA20212405-status-report-02_LR.pdf --- envs/environment.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/envs/environment.yaml b/envs/environment.yaml index 3c69b77b..eaad600f 100644 --- a/envs/environment.yaml +++ b/envs/environment.yaml @@ -24,7 +24,7 @@ dependencies: - yaml - pytables - lxml - - powerplantmatching>=0.4.8 + - powerplantmatching==0.5.3 - numpy - pandas - geopandas From b6032fb891c3506d1720b0609fa979e6d2d87321 Mon Sep 17 00:00:00 2001 From: Max Parzen Date: Sat, 28 May 2022 14:48:32 +0100 Subject: [PATCH 15/20] fix crs bug --- scripts/build_renewable_profiles.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/build_renewable_profiles.py b/scripts/build_renewable_profiles.py index a2b2eda6..41e1b54d 100644 --- a/scripts/build_renewable_profiles.py +++ b/scripts/build_renewable_profiles.py @@ -240,7 +240,7 @@ if __name__ == '__main__': # use named function np.greater with partially frozen argument instead # and exclude areas where: -max_depth > grid cell depth func = functools.partial(np.greater,-config['max_depth']) - excluder.add_raster(snakemake.input.gebco, codes=func, crs=4236, nodata=-1000) + excluder.add_raster(snakemake.input.gebco, codes=func, crs=4326, nodata=-1000) if 'min_shore_distance' in config: buffer = config['min_shore_distance'] From edb81a9e6a4ce2f7f53aeacf68d15aaa48799509 Mon Sep 17 00:00:00 2001 From: Max Parzen Date: Sat, 28 May 2022 14:50:44 +0100 Subject: [PATCH 16/20] add release note --- doc/release_notes.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/release_notes.rst b/doc/release_notes.rst index 3f131dc0..80211635 100644 --- a/doc/release_notes.rst +++ b/doc/release_notes.rst @@ -70,6 +70,8 @@ Upcoming Release * Use updated SARAH-2 and ERA5 cutouts with slightly wider scope to east and additional variables. +* Fix crs bug. Change crs 4236 to 4326. + PyPSA-Eur 0.4.0 (22th September 2021) ===================================== From 3bb8a7967a92b15f86ad5d914be1ada37bf60ff2 Mon Sep 17 00:00:00 2001 From: Ebbe Kyhl <69363603+ebbekyhl@users.noreply.github.com> Date: Mon, 30 May 2022 08:15:54 +0200 Subject: [PATCH 17/20] Powerplantmatching version 0.5.3 as lower bound --- envs/environment.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/envs/environment.yaml b/envs/environment.yaml index eaad600f..a2cba37f 100644 --- a/envs/environment.yaml +++ b/envs/environment.yaml @@ -24,7 +24,7 @@ dependencies: - yaml - pytables - lxml - - powerplantmatching==0.5.3 + - powerplantmatching>=0.5.3 - numpy - pandas - geopandas From 798c015bf6e8f34e35d5e9accd5eb0323487c655 Mon Sep 17 00:00:00 2001 From: Max Parzen Date: Fri, 3 Jun 2022 17:03:10 +0100 Subject: [PATCH 18/20] restrict rasterio version --- envs/environment.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/envs/environment.yaml b/envs/environment.yaml index a2cba37f..69025845 100644 --- a/envs/environment.yaml +++ b/envs/environment.yaml @@ -37,7 +37,7 @@ dependencies: - pyomo - matplotlib - proj - - fiona <= 1.18.20 # Till issue https://github.com/Toblerity/Fiona/issues/1085 is not solved + - fiona<=1.18.20 # Till issue https://github.com/Toblerity/Fiona/issues/1085 is not solved # Keep in conda environment when calling ipython - ipython @@ -45,7 +45,7 @@ dependencies: # GIS dependencies: - cartopy - descartes - - rasterio + - rasterio<=1.2.8 # 1.2.10 creates error https://github.com/PyPSA/atlite/issues/238 # PyPSA-Eur-Sec Dependencies - geopy From 21f627c74ec0b3153d60969f542052694b142e1c Mon Sep 17 00:00:00 2001 From: Max Parzen Date: Fri, 3 Jun 2022 17:05:32 +0100 Subject: [PATCH 19/20] update version --- envs/environment.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/envs/environment.yaml b/envs/environment.yaml index 69025845..f8060de1 100644 --- a/envs/environment.yaml +++ b/envs/environment.yaml @@ -45,7 +45,7 @@ dependencies: # GIS dependencies: - cartopy - descartes - - rasterio<=1.2.8 # 1.2.10 creates error https://github.com/PyPSA/atlite/issues/238 + - rasterio<=1.2.9 # 1.2.10 creates error https://github.com/PyPSA/atlite/issues/238 # PyPSA-Eur-Sec Dependencies - geopy From e974a30fd3dcf6cc8d005251b1247778cdffb933 Mon Sep 17 00:00:00 2001 From: Max Parzen Date: Fri, 3 Jun 2022 17:14:30 +0100 Subject: [PATCH 20/20] add release note --- doc/release_notes.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/release_notes.rst b/doc/release_notes.rst index 80211635..963a1175 100644 --- a/doc/release_notes.rst +++ b/doc/release_notes.rst @@ -72,6 +72,8 @@ Upcoming Release * Fix crs bug. Change crs 4236 to 4326. +* Update rasterio version to correctly calculate exclusion raster + PyPSA-Eur 0.4.0 (22th September 2021) =====================================