diff --git a/config/config.default.yaml b/config/config.default.yaml index 7b4500ae..48c92123 100644 --- a/config/config.default.yaml +++ b/config/config.default.yaml @@ -227,6 +227,12 @@ lines: max_extension: .inf length_factor: 1.25 under_construction: 'zero' # 'zero': set capacity to zero, 'remove': remove, 'keep': with full capacity + dynamic_line_rating: + activate: false + cutout: europe-2013-era5 + correction_factor: 0.95 + max_voltage_difference: false + max_line_rating: false # docs in https://pypsa-eur.readthedocs.io/en/latest/configuration.html#links links: diff --git a/config/test/config.electricity.yaml b/config/test/config.electricity.yaml index 6798e38c..b750bf62 100644 --- a/config/test/config.electricity.yaml +++ b/config/test/config.electricity.yaml @@ -60,6 +60,12 @@ renewable: clustering: exclude_carriers: ["OCGT", "offwind-ac", "coal"] +lines: + dynamic_line_rating: + activate: true + cutout: be-03-2013-era5 + max_line_rating: 1.3 + solving: solver: diff --git a/config/test/config.myopic.yaml b/config/test/config.myopic.yaml index 0bb85ec6..87f75777 100644 --- a/config/test/config.myopic.yaml +++ b/config/test/config.myopic.yaml @@ -62,6 +62,11 @@ renewable: solar: cutout: be-03-2013-era5 +lines: + dynamic_line_rating: + activate: true + max_line_rating: 1.3 + industry: St_primary_fraction: 2030: 0.6 diff --git a/config/test/config.overnight.yaml b/config/test/config.overnight.yaml index a2a0f5a4..01cdc728 100644 --- a/config/test/config.overnight.yaml +++ b/config/test/config.overnight.yaml @@ -59,6 +59,11 @@ renewable: solar: cutout: be-03-2013-era5 +lines: + dynamic_line_rating: + activate: true + max_line_rating: 1.3 + sector: gas_network: true H2_retrofit: true diff --git a/data/costs.csv b/data/costs.csv deleted file mode 100644 index 8953eb8a..00000000 --- a/data/costs.csv +++ /dev/null @@ -1,195 +0,0 @@ -technology,year,parameter,value,unit,source -solar-rooftop,2030,discount rate,0.04,per unit,standard for decentral -onwind,2030,lifetime,30,years,DEA https://ens.dk/en/our-services/projections-and-models/technology-data -offwind,2030,lifetime,30,years,DEA https://ens.dk/en/our-services/projections-and-models/technology-data -solar,2030,lifetime,25,years,IEA2010 -solar-rooftop,2030,lifetime,25,years,IEA2010 -solar-utility,2030,lifetime,25,years,IEA2010 -PHS,2030,lifetime,80,years,IEA2010 -hydro,2030,lifetime,80,years,IEA2010 -ror,2030,lifetime,80,years,IEA2010 -OCGT,2030,lifetime,30,years,IEA2010 -nuclear,2030,lifetime,45,years,ECF2010 in DIW DataDoc http://hdl.handle.net/10419/80348 -CCGT,2030,lifetime,30,years,IEA2010 -coal,2030,lifetime,40,years,IEA2010 -lignite,2030,lifetime,40,years,IEA2010 -geothermal,2030,lifetime,40,years,IEA2010 -biomass,2030,lifetime,30,years,ECF2010 in DIW DataDoc http://hdl.handle.net/10419/80348 -oil,2030,lifetime,30,years,ECF2010 in DIW DataDoc http://hdl.handle.net/10419/80348 -onwind,2030,investment,1040,EUR/kWel,DEA https://ens.dk/en/our-services/projections-and-models/technology-data -offwind,2030,investment,1640,EUR/kWel,DEA https://ens.dk/en/our-services/projections-and-models/technology-data -offwind-ac-station,2030,investment,250,EUR/kWel,DEA https://ens.dk/en/our-services/projections-and-models/technology-data -offwind-ac-connection-submarine,2030,investment,2685,EUR/MW/km,DEA https://ens.dk/en/our-services/projections-and-models/technology-data -offwind-ac-connection-underground,2030,investment,1342,EUR/MW/km,DEA https://ens.dk/en/our-services/projections-and-models/technology-data -offwind-dc-station,2030,investment,400,EUR/kWel,Haertel 2017; assuming one onshore and one offshore node + 13% learning reduction -offwind-dc-connection-submarine,2030,investment,2000,EUR/MW/km,DTU report based on Fig 34 of https://ec.europa.eu/energy/sites/ener/files/documents/2014_nsog_report.pdf -offwind-dc-connection-underground,2030,investment,1000,EUR/MW/km,Haertel 2017; average + 13% learning reduction -solar,2030,investment,600,EUR/kWel,DIW DataDoc http://hdl.handle.net/10419/80348 -biomass,2030,investment,2209,EUR/kWel,DIW DataDoc http://hdl.handle.net/10419/80348 -geothermal,2030,investment,3392,EUR/kWel,DIW DataDoc http://hdl.handle.net/10419/80348 -coal,2030,investment,1300,EUR/kWel,DIW DataDoc http://hdl.handle.net/10419/80348 PC (Advanced/SuperC) -lignite,2030,investment,1500,EUR/kWel,DIW DataDoc http://hdl.handle.net/10419/80348 -solar-rooftop,2030,investment,725,EUR/kWel,ETIP PV -solar-utility,2030,investment,425,EUR/kWel,ETIP PV -PHS,2030,investment,2000,EUR/kWel,DIW DataDoc http://hdl.handle.net/10419/80348 -hydro,2030,investment,2000,EUR/kWel,DIW DataDoc http://hdl.handle.net/10419/80348 -ror,2030,investment,3000,EUR/kWel,DIW DataDoc http://hdl.handle.net/10419/80348 -OCGT,2030,investment,400,EUR/kWel,DIW DataDoc http://hdl.handle.net/10419/80348 -nuclear,2030,investment,6000,EUR/kWel,DIW DataDoc http://hdl.handle.net/10419/80348 -CCGT,2030,investment,800,EUR/kWel,DIW DataDoc http://hdl.handle.net/10419/80348 -oil,2030,investment,400,EUR/kWel,DIW DataDoc http://hdl.handle.net/10419/80348 -onwind,2030,FOM,2.450549,%/year,DEA https://ens.dk/en/our-services/projections-and-models/technology-data -offwind,2030,FOM,2.304878,%/year,DEA https://ens.dk/en/our-services/projections-and-models/technology-data -solar,2030,FOM,4.166667,%/year,DIW DataDoc http://hdl.handle.net/10419/80348 -solar-rooftop,2030,FOM,2,%/year,ETIP PV -solar-utility,2030,FOM,3,%/year,ETIP PV -biomass,2030,FOM,4.526935,%/year,DIW DataDoc http://hdl.handle.net/10419/80348 -geothermal,2030,FOM,2.358491,%/year,DIW DataDoc http://hdl.handle.net/10419/80348 -coal,2030,FOM,1.923076,%/year,DIW DataDoc http://hdl.handle.net/10419/80348 PC (Advanced/SuperC) -lignite,2030,FOM,2.0,%/year,DIW DataDoc http://hdl.handle.net/10419/80348 PC (Advanced/SuperC) -oil,2030,FOM,1.5,%/year,DIW DataDoc http://hdl.handle.net/10419/80348 -PHS,2030,FOM,1,%/year,DIW DataDoc http://hdl.handle.net/10419/80348 -hydro,2030,FOM,1,%/year,DIW DataDoc http://hdl.handle.net/10419/80348 -ror,2030,FOM,2,%/year,DIW DataDoc http://hdl.handle.net/10419/80348 -CCGT,2030,FOM,2.5,%/year,DIW DataDoc http://hdl.handle.net/10419/80348 -OCGT,2030,FOM,3.75,%/year,DIW DataDoc http://hdl.handle.net/10419/80348 -onwind,2030,VOM,2.3,EUR/MWhel,DEA https://ens.dk/en/our-services/projections-and-models/technology-data -offwind,2030,VOM,2.7,EUR/MWhel,DEA https://ens.dk/en/our-services/projections-and-models/technology-data -solar,2030,VOM,0.01,EUR/MWhel,RES costs made up to fix curtailment order -coal,2030,VOM,6,EUR/MWhel,DIW DataDoc http://hdl.handle.net/10419/80348 PC (Advanced/SuperC) -lignite,2030,VOM,7,EUR/MWhel,DIW DataDoc http://hdl.handle.net/10419/80348 -CCGT,2030,VOM,4,EUR/MWhel,DIW DataDoc http://hdl.handle.net/10419/80348 -OCGT,2030,VOM,3,EUR/MWhel,DIW DataDoc http://hdl.handle.net/10419/80348 -nuclear,2030,VOM,8,EUR/MWhel,DIW DataDoc http://hdl.handle.net/10419/80348 -gas,2030,fuel,21.6,EUR/MWhth,IEA2011b -uranium,2030,fuel,3,EUR/MWhth,DIW DataDoc http://hdl.handle.net/10419/80348 -oil,2030,VOM,3,EUR/MWhel,DIW DataDoc http://hdl.handle.net/10419/80348 -nuclear,2030,fuel,3,EUR/MWhth,IEA2011b -biomass,2030,fuel,7,EUR/MWhth,IEA2011b -coal,2030,fuel,8.4,EUR/MWhth,IEA2011b -lignite,2030,fuel,2.9,EUR/MWhth,IEA2011b -oil,2030,fuel,50,EUR/MWhth,IEA WEM2017 97USD/boe = http://www.iea.org/media/weowebsite/2017/WEM_Documentation_WEO2017.pdf -PHS,2030,efficiency,0.75,per unit,DIW DataDoc http://hdl.handle.net/10419/80348 -hydro,2030,efficiency,0.9,per unit,DIW DataDoc http://hdl.handle.net/10419/80348 -ror,2030,efficiency,0.9,per unit,DIW DataDoc http://hdl.handle.net/10419/80348 -OCGT,2030,efficiency,0.39,per unit,DIW DataDoc http://hdl.handle.net/10419/80348 -CCGT,2030,efficiency,0.5,per unit,DIW DataDoc http://hdl.handle.net/10419/80348 -biomass,2030,efficiency,0.468,per unit,DIW DataDoc http://hdl.handle.net/10419/80348 -geothermal,2030,efficiency,0.239,per unit,DIW DataDoc http://hdl.handle.net/10419/80348 -nuclear,2030,efficiency,0.337,per unit,DIW DataDoc http://hdl.handle.net/10419/80348 -gas,2030,CO2 intensity,0.187,tCO2/MWth,https://www.eia.gov/environment/emissions/co2_vol_mass.php -coal,2030,efficiency,0.464,per unit,DIW DataDoc http://hdl.handle.net/10419/80348 PC (Advanced/SuperC) -lignite,2030,efficiency,0.447,per unit,DIW DataDoc http://hdl.handle.net/10419/80348 -oil,2030,efficiency,0.393,per unit,DIW DataDoc http://hdl.handle.net/10419/80348 CT -coal,2030,CO2 intensity,0.354,tCO2/MWth,https://www.eia.gov/environment/emissions/co2_vol_mass.php -lignite,2030,CO2 intensity,0.334,tCO2/MWth,https://www.eia.gov/environment/emissions/co2_vol_mass.php -oil,2030,CO2 intensity,0.248,tCO2/MWth,https://www.eia.gov/environment/emissions/co2_vol_mass.php -geothermal,2030,CO2 intensity,0.026,tCO2/MWth,https://www.eia.gov/environment/emissions/co2_vol_mass.php -electrolysis,2030,investment,350,EUR/kWel,Palzer Thesis -electrolysis,2030,FOM,4,%/year,NREL http://www.nrel.gov/docs/fy09osti/45873.pdf; budischak2013 -electrolysis,2030,lifetime,18,years,NREL http://www.nrel.gov/docs/fy09osti/45873.pdf; budischak2013 -electrolysis,2030,efficiency,0.8,per unit,NREL http://www.nrel.gov/docs/fy09osti/45873.pdf; budischak2013 -fuel cell,2030,investment,339,EUR/kWel,NREL http://www.nrel.gov/docs/fy09osti/45873.pdf; budischak2013 -fuel cell,2030,FOM,3,%/year,NREL http://www.nrel.gov/docs/fy09osti/45873.pdf; budischak2013 -fuel cell,2030,lifetime,20,years,NREL http://www.nrel.gov/docs/fy09osti/45873.pdf; budischak2013 -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 -methanation,2030,efficiency,0.6,per unit,Palzer; Breyer for DAC -helmeth,2030,investment,1000,EUR/kW,no source -helmeth,2030,lifetime,25,years,no source -helmeth,2030,FOM,3,%/year,no source -helmeth,2030,efficiency,0.8,per unit,HELMETH press release -DAC,2030,investment,250,EUR/(tCO2/a),Fasihi/Climeworks -DAC,2030,lifetime,30,years,Fasihi -DAC,2030,FOM,4,%/year,Fasihi -battery inverter,2030,investment,411,USD/kWel,budischak2013 -battery inverter,2030,lifetime,20,years,budischak2013 -battery inverter,2030,efficiency,0.9,per unit charge/discharge,budischak2013; Lund and Kempton (2008) http://dx.doi.org/10.1016/j.enpol.2008.06.007 -battery inverter,2030,FOM,3,%/year,budischak2013 -battery storage,2030,investment,192,USD/kWh,budischak2013 -battery storage,2030,lifetime,15,years,budischak2013 -decentral air-sourced heat pump,2030,investment,1050,EUR/kWth,HP; Palzer thesis -decentral air-sourced heat pump,2030,lifetime,20,years,HP; Palzer thesis -decentral air-sourced heat pump,2030,FOM,3.5,%/year,Palzer thesis -decentral air-sourced heat pump,2030,efficiency,3,per unit,default for costs -decentral air-sourced heat pump,2030,discount rate,0.04,per unit,Palzer thesis -decentral ground-sourced heat pump,2030,investment,1400,EUR/kWth,Palzer thesis -decentral ground-sourced heat pump,2030,lifetime,20,years,Palzer thesis -decentral ground-sourced heat pump,2030,FOM,3.5,%/year,Palzer thesis -decentral ground-sourced heat pump,2030,efficiency,4,per unit,default for costs -decentral ground-sourced heat pump,2030,discount rate,0.04,per unit,Palzer thesis -central air-sourced heat pump,2030,investment,700,EUR/kWth,Palzer thesis -central air-sourced heat pump,2030,lifetime,20,years,Palzer thesis -central air-sourced heat pump,2030,FOM,3.5,%/year,Palzer thesis -central air-sourced heat pump,2030,efficiency,3,per unit,default for costs -retrofitting I,2030,discount rate,0.04,per unit,Palzer thesis -retrofitting I,2030,lifetime,50,years,Palzer thesis -retrofitting I,2030,FOM,1,%/year,Palzer thesis -retrofitting I,2030,investment,50,EUR/m2/fraction reduction,Palzer thesis -retrofitting II,2030,discount rate,0.04,per unit,Palzer thesis -retrofitting II,2030,lifetime,50,years,Palzer thesis -retrofitting II,2030,FOM,1,%/year,Palzer thesis -retrofitting II,2030,investment,250,EUR/m2/fraction reduction,Palzer thesis -water tank charger,2030,efficiency,0.9,per unit,HP -water tank discharger,2030,efficiency,0.9,per unit,HP -decentral water tank storage,2030,investment,860,EUR/m3,IWES Interaktion -decentral water tank storage,2030,FOM,1,%/year,HP -decentral water tank storage,2030,lifetime,20,years,HP -decentral water tank storage,2030,discount rate,0.04,per unit,Palzer thesis -central water tank storage,2030,investment,30,EUR/m3,IWES Interaktion -central water tank storage,2030,FOM,1,%/year,HP -central water tank storage,2030,lifetime,40,years,HP -decentral resistive heater,2030,investment,100,EUR/kWhth,Schaber thesis -decentral resistive heater,2030,lifetime,20,years,Schaber thesis -decentral resistive heater,2030,FOM,2,%/year,Schaber thesis -decentral resistive heater,2030,efficiency,0.9,per unit,Schaber thesis -decentral resistive heater,2030,discount rate,0.04,per unit,Palzer thesis -central resistive heater,2030,investment,100,EUR/kWhth,Schaber thesis -central resistive heater,2030,lifetime,20,years,Schaber thesis -central resistive heater,2030,FOM,2,%/year,Schaber thesis -central resistive heater,2030,efficiency,0.9,per unit,Schaber thesis -decentral gas boiler,2030,investment,175,EUR/kWhth,Palzer thesis -decentral gas boiler,2030,lifetime,20,years,Palzer thesis -decentral gas boiler,2030,FOM,2,%/year,Palzer thesis -decentral gas boiler,2030,efficiency,0.9,per unit,Palzer thesis -decentral gas boiler,2030,discount rate,0.04,per unit,Palzer thesis -central gas boiler,2030,investment,63,EUR/kWhth,Palzer thesis -central gas boiler,2030,lifetime,22,years,Palzer thesis -central gas boiler,2030,FOM,1,%/year,Palzer thesis -central gas boiler,2030,efficiency,0.9,per unit,Palzer thesis -decentral CHP,2030,lifetime,25,years,HP -decentral CHP,2030,investment,1400,EUR/kWel,HP -decentral CHP,2030,FOM,3,%/year,HP -decentral CHP,2030,discount rate,0.04,per unit,Palzer thesis -central CHP,2030,lifetime,25,years,HP -central CHP,2030,investment,650,EUR/kWel,HP -central CHP,2030,FOM,3,%/year,HP -decentral solar thermal,2030,discount rate,0.04,per unit,Palzer thesis -decentral solar thermal,2030,FOM,1.3,%/year,HP -decentral solar thermal,2030,investment,270000,EUR/1000m2,HP -decentral solar thermal,2030,lifetime,20,years,HP -central solar thermal,2030,FOM,1.4,%/year,HP -central solar thermal,2030,investment,140000,EUR/1000m2,HP -central solar thermal,2030,lifetime,20,years,HP -HVAC overhead,2030,investment,400,EUR/MW/km,Hagspiel -HVAC overhead,2030,lifetime,40,years,Hagspiel -HVAC overhead,2030,FOM,2,%/year,Hagspiel -HVDC overhead,2030,investment,400,EUR/MW/km,Hagspiel -HVDC overhead,2030,lifetime,40,years,Hagspiel -HVDC overhead,2030,FOM,2,%/year,Hagspiel -HVDC submarine,2030,investment,2000,EUR/MW/km,DTU report based on Fig 34 of https://ec.europa.eu/energy/sites/ener/files/documents/2014_nsog_report.pdf -HVDC submarine,2030,lifetime,40,years,Hagspiel -HVDC submarine,2030,FOM,2,%/year,Hagspiel -HVDC inverter pair,2030,investment,150000,EUR/MW,Hagspiel -HVDC inverter pair,2030,lifetime,40,years,Hagspiel -HVDC inverter pair,2030,FOM,2,%/year,Hagspiel diff --git a/doc/configtables/lines.csv b/doc/configtables/lines.csv index ad5dd690..ec9ec007 100644 --- a/doc/configtables/lines.csv +++ b/doc/configtables/lines.csv @@ -5,3 +5,9 @@ s_nom_max,MW,"float","Global upper limit for the maximum capacity of each extend max_extension,MW,"float","Upper limit for the extended capacity of each extendable line." length_factor,--,float,"Correction factor to account for the fact that buses are *not* connected by lines through air-line distance." under_construction,--,"One of {'zero': set capacity to zero, 'remove': remove completely, 'keep': keep with full capacity}","Specifies how to handle lines which are currently under construction." +dynamic_line_rating,,, +-- activate,bool,"true or false","Whether to take dynamic line rating into account" +-- cutout,--,"Should be a folder listed in the configuration ``atlite: cutouts:`` (e.g. 'europe-2013-era5') or reference an existing folder in the directory ``cutouts``. Source module must be ERA5.","Specifies the directory where the relevant weather data ist stored." +-- correction_factor,--,"float","Factor to compensate for overestimation of wind speeds in hourly averaged wind data" +-- max_voltage_difference,deg,"float","Maximum voltage angle difference in degrees or 'false' to disable" +-- max_line_rating,--,"float","Maximum line rating relative to nominal capacity without DLR, e.g. 1.3 or 'false' to disable" diff --git a/envs/environment.yaml b/envs/environment.yaml index 7e119a2f..8409adb0 100644 --- a/envs/environment.yaml +++ b/envs/environment.yaml @@ -53,6 +53,7 @@ dependencies: - descartes - rasterio!=1.2.10 + - pip: - tsam>=1.1.0 - git+https://github.com/PyPSA/PyPSA.git@master diff --git a/rules/build_electricity.smk b/rules/build_electricity.smk index c7ef86a2..6964a87d 100644 --- a/rules/build_electricity.smk +++ b/rules/build_electricity.smk @@ -274,6 +274,30 @@ rule build_hydro_profile: "../scripts/build_hydro_profile.py" +if config["lines"]["dynamic_line_rating"]["activate"]: + + rule build_line_rating: + input: + base_network=RESOURCES + "networks/base.nc", + cutout="cutouts/" + + CDIR + + config["lines"]["dynamic_line_rating"]["cutout"] + + ".nc", + output: + output=RESOURCES + "networks/line_rating.nc", + log: + LOGS + "build_line_rating.log", + benchmark: + BENCHMARKS + "build_line_rating" + threads: ATLITE_NPROCESSES + resources: + mem_mb=ATLITE_NPROCESSES * 1000, + conda: + "../envs/environment.yaml" + script: + "../scripts/build_line_rating.py" + + rule add_electricity: params: length_factor=config["lines"]["length_factor"], @@ -295,6 +319,9 @@ rule add_electricity: if str(fn).startswith("data/") }, base_network=RESOURCES + "networks/base.nc", + line_rating=RESOURCES + "networks/line_rating.nc" + if config["lines"]["dynamic_line_rating"]["activate"] + else RESOURCES + "networks/base.nc", tech_costs=COSTS, regions=RESOURCES + "regions_onshore.geojson", powerplants=RESOURCES + "powerplants.csv", diff --git a/scripts/add_electricity.py b/scripts/add_electricity.py index 68d2d5fa..24567477 100755 --- a/scripts/add_electricity.py +++ b/scripts/add_electricity.py @@ -2,8 +2,6 @@ # SPDX-FileCopyrightText: : 2017-2023 The PyPSA-Eur Authors # # SPDX-License-Identifier: MIT - -# coding: utf-8 """ Adds electrical generators and existing hydro storage units to a base network. @@ -752,6 +750,30 @@ def estimate_renewable_capacities(n, year, tech_map, expansion_limit, countries) ) +def attach_line_rating( + n, rating, s_max_pu, correction_factor, max_voltage_difference, max_line_rating +): + # TODO: Only considers overhead lines + n.lines_t.s_max_pu = (rating / n.lines.s_nom[rating.columns]) * correction_factor + if max_voltage_difference: + x_pu = ( + n.lines.type.map(n.line_types["x_per_length"]) + * n.lines.length + / (n.lines.v_nom**2) + ) + # need to clip here as cap values might be below 1 + # -> would mean the line cannot be operated at actual given pessimistic ampacity + s_max_pu_cap = ( + np.deg2rad(max_voltage_difference) / (x_pu * n.lines.s_nom) + ).clip(lower=1) + n.lines_t.s_max_pu = n.lines_t.s_max_pu.clip( + lower=1, upper=s_max_pu_cap, axis=1 + ) + if max_line_rating: + n.lines_t.s_max_pu = n.lines_t.s_max_pu.clip(upper=max_line_rating) + n.lines_t.s_max_pu *= s_max_pu + + if __name__ == "__main__": if "snakemake" not in globals(): from _helpers import mock_snakemake @@ -834,6 +856,23 @@ if __name__ == "__main__": update_p_nom_max(n) + line_rating_config = snakemake.config["lines"]["dynamic_line_rating"] + if line_rating_config["activate"]: + rating = xr.open_dataarray(snakemake.input.line_rating).to_pandas().transpose() + s_max_pu = snakemake.config["lines"]["s_max_pu"] + correction_factor = line_rating_config["correction_factor"] + max_voltage_difference = line_rating_config["max_voltage_difference"] + max_line_rating = line_rating_config["max_line_rating"] + + attach_line_rating( + n, + rating, + s_max_pu, + correction_factor, + max_voltage_difference, + max_line_rating, + ) + sanitize_carriers(n, snakemake.config) n.meta = snakemake.config diff --git a/scripts/build_line_rating.py b/scripts/build_line_rating.py new file mode 100755 index 00000000..7ece1c9d --- /dev/null +++ b/scripts/build_line_rating.py @@ -0,0 +1,155 @@ +# -*- coding: utf-8 -*- +# SPDX-FileCopyrightText: : 2017-2020 The PyPSA-Eur Authors +# +# SPDX-License-Identifier: MIT + +# coding: utf-8 +""" +Adds dynamic line rating timeseries to the base network. + +Relevant Settings +----------------- + +.. code:: yaml + + lines: + cutout: + line_rating: + + +.. seealso:: + Documentation of the configuration file ``config.yaml` +Inputs +------ + +- ``data/cutouts``: +- ``networks/base.nc``: confer :ref:`base` + +Outputs +------- + +- ``resources/line_rating.nc`` + + +Description +----------- + +The rule :mod:`build_line_rating` calculates the line rating for transmission lines. +The line rating provides the maximal capacity of a transmission line considering the heat exchange with the environment. + +The following heat gains and losses are considered: + +- heat gain through resistive losses +- heat gain through solar radiation +- heat loss through radiation of the trasnmission line +- heat loss through forced convection with wind +- heat loss through natural convection + + +With a heat balance considering the maximum temperature threshold of the transmission line, +the maximal possible capacity factor "s_max_pu" for each transmission line at each time step is calculated. +""" + +import logging +import re + +import atlite +import geopandas as gpd +import numpy as np +import pandas as pd +import pypsa +import xarray as xr +from _helpers import configure_logging +from shapely.geometry import LineString as Line +from shapely.geometry import Point + + +def calculate_resistance(T, R_ref, T_ref=293, alpha=0.00403): + """ + Calculates the resistance at other temperatures than the reference + temperature. + + Parameters + ---------- + T : Temperature at which resistance is calculated in [°C] or [K] + R_ref : Resistance at reference temperature in [Ohm] or [Ohm/Per Length Unit] + T_ref : Reference temperature in [°C] or [K] + alpha: Temperature coefficient in [1/K] + Defaults are: + * T_ref : 20 °C + * alpha : 0.00403 1/K + + Returns + ------- + Resistance of at given temperature. + """ + R = R_ref * (1 + alpha * (T - T_ref)) + return R + + +def calculate_line_rating(n, cutout): + """ + Calculates the maximal allowed power flow in each line for each time step + considering the maximal temperature. + + Parameters + ---------- + n : pypsa.Network object containing information on grid + + Returns + ------- + xarray DataArray object with maximal power. + """ + relevant_lines = n.lines[(n.lines["underground"] == False)] + buses = relevant_lines[["bus0", "bus1"]].values + x = n.buses.x + y = n.buses.y + shapes = [Line([Point(x[b0], y[b0]), Point(x[b1], y[b1])]) for (b0, b1) in buses] + shapes = gpd.GeoSeries(shapes, index=relevant_lines.index) + if relevant_lines.r_pu.eq(0).all(): + # Overwrite standard line resistance with line resistance obtained from line type + r_per_length = n.line_types["r_per_length"] + R = ( + relevant_lines.join(r_per_length, on=["type"])["r_per_length"] / 1000 + ) # in meters + # If line type with bundles is given retrieve number of conductors per bundle + relevant_lines["n_bundle"] = ( + relevant_lines["type"] + .where(relevant_lines["type"].str.contains("bundle")) + .dropna() + .apply(lambda x: int(re.findall(r"(\d+)-bundle", x)[0])) + ) + # Set default number of bundles per line + relevant_lines["n_bundle"].fillna(1, inplace=True) + R *= relevant_lines["n_bundle"] + R = calculate_resistance(T=353, R_ref=R) + Imax = cutout.line_rating(shapes, R, D=0.0218, Ts=353, epsilon=0.8, alpha=0.8) + line_factor = relevant_lines.eval("v_nom * n_bundle * num_parallel") / 1e3 # in mW + da = xr.DataArray( + data=np.sqrt(3) * Imax * line_factor.values.reshape(-1, 1), + attrs=dict( + description="Maximal possible power in MW for given line considering line rating" + ), + ) + return da + + +if __name__ == "__main__": + if "snakemake" not in globals(): + from _helpers import mock_snakemake + + snakemake = mock_snakemake( + "build_line_rating", + network="elec", + simpl="", + clusters="5", + ll="v1.0", + opts="Co2L-4H", + ) + configure_logging(snakemake) + + n = pypsa.Network(snakemake.input.base_network) + cutout = atlite.Cutout(snakemake.input.cutout) + + da = calculate_line_rating(n, cutout) + da.to_netcdf(snakemake.output[0])