From 7ddc153bd23b4a74ca7f3e1849dcea6f04381ba3 Mon Sep 17 00:00:00 2001 From: Fabian Neumann Date: Mon, 2 Dec 2019 12:22:30 +0100 Subject: [PATCH] ec: attach hydrogen pipelines (#108) --- config.default.yaml | 1 + config.tutorial.yaml | 1 + data/costs.csv | 6 ++++++ doc/configtables/electricity.csv | 1 + scripts/add_extra_components.py | 35 +++++++++++++++++++++++++++++++- test/config.test1.yaml | 5 +++-- 6 files changed, 46 insertions(+), 3 deletions(-) diff --git a/config.default.yaml b/config.default.yaml index 5be7c91f..04df2158 100644 --- a/config.default.yaml +++ b/config.default.yaml @@ -37,6 +37,7 @@ electricity: Generator: [OCGT] StorageUnit: [battery, H2] Store: [] # battery, H2 + Link: [] max_hours: battery: 6 diff --git a/config.tutorial.yaml b/config.tutorial.yaml index 04803058..a8529529 100644 --- a/config.tutorial.yaml +++ b/config.tutorial.yaml @@ -34,6 +34,7 @@ electricity: Generator: [OCGT] StorageUnit: [battery, H2] Store: [] #battery, H2 + Link: [] max_hours: battery: 6 diff --git a/data/costs.csv b/data/costs.csv index 0e53afe9..62204c53 100644 --- a/data/costs.csv +++ b/data/costs.csv @@ -96,6 +96,12 @@ fuel cell,2030,lifetime,20,years,NREL http://www.nrel.gov/docs/fy09osti/45873.pd fuel cell,2030,efficiency,0.58,per unit,NREL http://www.nrel.gov/docs/fy09osti/45873.pdf; budischak2013 conservative 2020 hydrogen storage,2030,investment,11.2,USD/kWh,budischak2013 hydrogen storage,2030,lifetime,20,years,budischak2013 +hydrogen underground storage,2030,investment,0.5,EUR/kWh,maximum from https://www.nrel.gov/docs/fy10osti/46719.pdf +hydrogen underground storage,2030,lifetime,40,years,http://www.acatech.de/fileadmin/user_upload/Baumstruktur_nach_Website/Acatech/root/de/Publikationen/Materialien/ESYS_Technologiesteckbrief_Energiespeicher.pdf +H2 pipeline,2030,investment,267,EUR/MW/km,Welder et al https://doi.org/10.1016/j.ijhydene.2018.12.156 +H2 pipeline,2030,lifetime,40,years,Krieg2012 http://juser.fz-juelich.de/record/136392/files/Energie%26Umwelt_144.pdf +H2 pipeline,2030,FOM,5,%/year,Krieg2012 http://juser.fz-juelich.de/record/136392/files/Energie%26Umwelt_144.pdf +H2 pipeline,2030,efficiency,0.98,per unit,Krieg2012 http://juser.fz-juelich.de/record/136392/files/Energie%26Umwelt_144.pdf methanation,2030,investment,1000,EUR/kWH2,Schaber thesis methanation,2030,lifetime,25,years,Schaber thesis methanation,2030,FOM,3,%/year,Schaber thesis diff --git a/doc/configtables/electricity.csv b/doc/configtables/electricity.csv index 0df537ae..be447136 100644 --- a/doc/configtables/electricity.csv +++ b/doc/configtables/electricity.csv @@ -7,6 +7,7 @@ extendable_carriers,,, -- Generator,--,"Any subset of {'OCGT','CCGT'}","Places extendable conventional power plants (OCGT and/or CCGT) where gas power plants are located today without capacity limits." -- StorageUnit,--,"Any subset of {'battery','H2'}","Adds extendable storage units (battery and/or hydrogen) at every node/bus after clustering without capacity limits and with zero initial capacity." -- Store,--,"Any subset of {'battery','H2'}","Adds extendable storage units (battery and/or hydrogen) at every node/bus after clustering without capacity limits and with zero initial capacity." +-- Link,--,"Any subset of {'H2 pipeline'}","Adds extendable links (H2 pipelines only) at every connection where there are lines or HVDC links without capacity limits and with zero initial capacity. Hydrogen pipelines require hydrogen storage to be modelled as ``Store``." max_hours,,, -- battery,h,float,"Maximum state of charge capacity of the battery in terms of hours at full output capacity ``p_nom``. Cf. `PyPSA documentation `_." -- H2,h,float,"Maximum state of charge capacity of the hydrogen storage in terms of hours at full output capacity ``p_nom``. Cf. `PyPSA documentation `_." diff --git a/scripts/add_extra_components.py b/scripts/add_extra_components.py index 5c238a4c..8bc97b9d 100644 --- a/scripts/add_extra_components.py +++ b/scripts/add_extra_components.py @@ -50,8 +50,9 @@ logger = logging.getLogger(__name__) from _helpers import configure_logging import pandas as pd +import numpy as np import pypsa -from add_electricity import (load_costs, normed, add_nice_carrier_names, +from add_electricity import (load_costs, add_nice_carrier_names, _add_missing_carriers_from_costs) idx = pd.IndexSlice @@ -139,6 +140,37 @@ def attach_stores(n, costs): capital_cost=costs.at['battery inverter', 'capital_cost'], p_nom_extendable=True) +def attach_hydrogen_pipelines(n, costs): + elec_opts = snakemake.config['electricity'] + ext_carriers = elec_opts['extendable_carriers'] + as_stores = ext_carriers.get('Store', []) + + if 'H2 pipeline' not in ext_carriers.get('Link',[]): return + + assert 'H2' in as_stores, ("Attaching hydrogen pipelines requires hydrogen " + "storage to be modelled as Store-Link-Bus combination. See " + "`config.yaml` at `electricity: extendable_carriers: Store:`.") + + # determine bus pairs + attrs = ["bus0","bus1","length"] + candidates = pd.concat([n.lines[attrs], n.links.query('carrier=="DC"')[attrs]])\ + .reset_index(drop=True) + + # remove bus pair duplicates regardless of order of bus0 and bus1 + h2_links = candidates[~pd.DataFrame(np.sort(candidates[['bus0', 'bus1']])).duplicated()] + h2_links.index = h2_links.apply(lambda c: f"H2 pipeline {c.bus0}-{c.bus1}", axis=1) + + # add pipelines + n.madd("Link", + h2_links.index, + bus0=h2_links.bus0.values + " H2", + bus1=h2_links.bus1.values + " H2", + p_min_pu=-1, + p_nom_extendable=True, + length=h2_links.length.values, + capital_cost=costs.at['H2 pipeline','capital_cost']*h2_links.length, + efficiency=costs.at['H2 pipeline','efficiency'], + carrier="H2 pipeline") if __name__ == "__main__": # Detect running outside of snakemake and mock snakemake for testing @@ -160,6 +192,7 @@ if __name__ == "__main__": attach_storageunits(n, costs) attach_stores(n, costs) + attach_hydrogen_pipelines(n, costs) add_nice_carrier_names(n, config=snakemake.config) diff --git a/test/config.test1.yaml b/test/config.test1.yaml index 2631acc8..e31d2a9c 100644 --- a/test/config.test1.yaml +++ b/test/config.test1.yaml @@ -32,8 +32,9 @@ electricity: extendable_carriers: Generator: [OCGT] - StorageUnit: [battery, H2] - Store: [] #battery, H2 + StorageUnit: [battery] + Store: [H2] + Link: [H2 pipeline] max_hours: battery: 6