Update technology costs for wind

Calculate grid extension costs for offshore based on weighted average distance
from weather cell to substation.
This commit is contained in:
Jonas Hörsch 2018-10-26 21:32:04 +02:00
parent ee6085ed7e
commit b30f4a2fff
5 changed files with 39 additions and 11 deletions

View File

@ -112,7 +112,6 @@ rule build_renewable_potentials:
rule build_renewable_profiles: rule build_renewable_profiles:
input: input:
base_network="networks/base.nc",
potentials="resources/potentials_{technology}.nc", potentials="resources/potentials_{technology}.nc",
regions=lambda wildcards: ("resources/regions_onshore.geojson" regions=lambda wildcards: ("resources/regions_onshore.geojson"
if wildcards.technology in ('onwind', 'solar') if wildcards.technology in ('onwind', 'solar')

View File

@ -1,7 +1,7 @@
technology,year,parameter,value,unit,source technology,year,parameter,value,unit,source
solar-rooftop,2030,discount rate,0.04,per unit,standard for decentral solar-rooftop,2030,discount rate,0.04,per unit,standard for decentral
onwind,2030,lifetime,25,years,IEA2010 onwind,2030,lifetime,30,years,DEA https://ens.dk/en/our-services/projections-and-models/technology-data
offwind,2030,lifetime,25,years,IEA2010 offwind,2030,lifetime,30,years,DEA https://ens.dk/en/our-services/projections-and-models/technology-data
solar,2030,lifetime,25,years,IEA2010 solar,2030,lifetime,25,years,IEA2010
solar-rooftop,2030,lifetime,25,years,IEA2010 solar-rooftop,2030,lifetime,25,years,IEA2010
solar-utility,2030,lifetime,25,years,IEA2010 solar-utility,2030,lifetime,25,years,IEA2010
@ -16,8 +16,10 @@ lignite,2030,lifetime,40,years,IEA2010
geothermal,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 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 oil,2030,lifetime,30,years,ECF2010 in DIW DataDoc http://hdl.handle.net/10419/80348
onwind,2030,investment,1182,EUR/kWel,DIW DataDoc http://hdl.handle.net/10419/80348 onwind,2030,investment,910,EUR/kWel,DEA https://ens.dk/en/our-services/projections-and-models/technology-data
offwind,2030,investment,2506,EUR/kWel,DIW DataDoc http://hdl.handle.net/10419/80348 offwind,2030,investment,1640,EUR/kWel,DEA https://ens.dk/en/our-services/projections-and-models/technology-data
offwind-grid,2030,investment,255,EUR/kWel,Haertel 2017; assuming one onshore and one offshore node
offwind-grid-perlength,2030,investment,0.97,EUR/kWel/km,Haertel 2017
solar,2030,investment,600,EUR/kWel,DIW DataDoc http://hdl.handle.net/10419/80348 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 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 geothermal,2030,investment,3392,EUR/kWel,DIW DataDoc http://hdl.handle.net/10419/80348
@ -32,8 +34,8 @@ 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 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 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 oil,2030,investment,400,EUR/kWel,DIW DataDoc http://hdl.handle.net/10419/80348
onwind,2030,FOM,2.961083,%/year,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,3.192338,%/year,DIW DataDoc http://hdl.handle.net/10419/80348 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,2030,FOM,4.166667,%/year,DIW DataDoc http://hdl.handle.net/10419/80348
solar-rooftop,2030,FOM,2,%/year,ETIP PV solar-rooftop,2030,FOM,2,%/year,ETIP PV
solar-utility,2030,FOM,3,%/year,ETIP PV solar-utility,2030,FOM,3,%/year,ETIP PV
@ -47,8 +49,8 @@ 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 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 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 OCGT,2030,FOM,3.75,%/year,DIW DataDoc http://hdl.handle.net/10419/80348
onwind,2030,VOM,0.015,EUR/MWhel,RES costs made up to fix curtailment order onwind,2030,VOM,2.3,EUR/MWhel,DEA https://ens.dk/en/our-services/projections-and-models/technology-data
offwind,2030,VOM,0.02,EUR/MWhel,RES costs made up to fix curtailment order 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 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) 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 lignite,2030,VOM,7,EUR/MWhel,DIW DataDoc http://hdl.handle.net/10419/80348

1 technology year parameter value unit source
2 solar-rooftop 2030 discount rate 0.04 per unit standard for decentral
3 onwind 2030 lifetime 25 30 years IEA2010 DEA https://ens.dk/en/our-services/projections-and-models/technology-data
4 offwind 2030 lifetime 25 30 years IEA2010 DEA https://ens.dk/en/our-services/projections-and-models/technology-data
5 solar 2030 lifetime 25 years IEA2010
6 solar-rooftop 2030 lifetime 25 years IEA2010
7 solar-utility 2030 lifetime 25 years IEA2010
16 geothermal 2030 lifetime 40 years IEA2010
17 biomass 2030 lifetime 30 years ECF2010 in DIW DataDoc http://hdl.handle.net/10419/80348
18 oil 2030 lifetime 30 years ECF2010 in DIW DataDoc http://hdl.handle.net/10419/80348
19 onwind 2030 investment 1182 910 EUR/kWel DIW DataDoc http://hdl.handle.net/10419/80348 DEA https://ens.dk/en/our-services/projections-and-models/technology-data
20 offwind 2030 investment 2506 1640 EUR/kWel DIW DataDoc http://hdl.handle.net/10419/80348 DEA https://ens.dk/en/our-services/projections-and-models/technology-data
21 offwind-grid 2030 investment 255 EUR/kWel Haertel 2017; assuming one onshore and one offshore node
22 offwind-grid-perlength 2030 investment 0.97 EUR/kWel/km Haertel 2017
23 solar 2030 investment 600 EUR/kWel DIW DataDoc http://hdl.handle.net/10419/80348
24 biomass 2030 investment 2209 EUR/kWel DIW DataDoc http://hdl.handle.net/10419/80348
25 geothermal 2030 investment 3392 EUR/kWel DIW DataDoc http://hdl.handle.net/10419/80348
34 nuclear 2030 investment 6000 EUR/kWel DIW DataDoc http://hdl.handle.net/10419/80348
35 CCGT 2030 investment 800 EUR/kWel DIW DataDoc http://hdl.handle.net/10419/80348
36 oil 2030 investment 400 EUR/kWel DIW DataDoc http://hdl.handle.net/10419/80348
37 onwind 2030 FOM 2.961083 2.450549 %/year DIW DataDoc http://hdl.handle.net/10419/80348 DEA https://ens.dk/en/our-services/projections-and-models/technology-data
38 offwind 2030 FOM 3.192338 2.304878 %/year DIW DataDoc http://hdl.handle.net/10419/80348 DEA https://ens.dk/en/our-services/projections-and-models/technology-data
39 solar 2030 FOM 4.166667 %/year DIW DataDoc http://hdl.handle.net/10419/80348
40 solar-rooftop 2030 FOM 2 %/year ETIP PV
41 solar-utility 2030 FOM 3 %/year ETIP PV
49 ror 2030 FOM 2 %/year DIW DataDoc http://hdl.handle.net/10419/80348
50 CCGT 2030 FOM 2.5 %/year DIW DataDoc http://hdl.handle.net/10419/80348
51 OCGT 2030 FOM 3.75 %/year DIW DataDoc http://hdl.handle.net/10419/80348
52 onwind 2030 VOM 0.015 2.3 EUR/MWhel RES costs made up to fix curtailment order DEA https://ens.dk/en/our-services/projections-and-models/technology-data
53 offwind 2030 VOM 0.02 2.7 EUR/MWhel RES costs made up to fix curtailment order DEA https://ens.dk/en/our-services/projections-and-models/technology-data
54 solar 2030 VOM 0.01 EUR/MWhel RES costs made up to fix curtailment order
55 coal 2030 VOM 6 EUR/MWhel DIW DataDoc http://hdl.handle.net/10419/80348 PC (Advanced/SuperC)
56 lignite 2030 VOM 7 EUR/MWhel DIW DataDoc http://hdl.handle.net/10419/80348

View File

@ -161,6 +161,15 @@ def attach_wind_and_solar(n, costs):
n.add("Carrier", name=tech) n.add("Carrier", name=tech)
with xr.open_dataset(getattr(snakemake.input, 'profile_' + tech)) as ds: with xr.open_dataset(getattr(snakemake.input, 'profile_' + tech)) as ds:
capital_cost = costs.at[tech, 'capital_cost']
if tech + "-grid" in costs.index:
if tech + "-grid-perlength" in costs.index:
grid_cost = costs.at[tech + "-grid", "capital_cost"] + costs.at[tech + "-grid-perlength", 'capital_cost'] * ds['average_distance'].to_pandas()
logger.info("Added connection cost of {:0.0f}-{:0.0f} Eur/MW/a to {}".format(grid_cost.min(), grid_cost.max(), tech))
else:
grid_cost = costs.at[tech + "-grid", "capital_cost"]
logger.info("Added connection cost of {:0.0f} Eur/MW/a to {}".format(grid_cost, tech))
capital_cost = capital_cost + grid_cost
n.madd("Generator", ds.indexes['bus'], ' ' + tech, n.madd("Generator", ds.indexes['bus'], ' ' + tech,
bus=ds.indexes['bus'], bus=ds.indexes['bus'],
@ -169,7 +178,7 @@ def attach_wind_and_solar(n, costs):
p_nom_max=ds['p_nom_max'].to_pandas(), p_nom_max=ds['p_nom_max'].to_pandas(),
weight=ds['weight'].to_pandas(), weight=ds['weight'].to_pandas(),
marginal_cost=costs.at[tech, 'marginal_cost'], marginal_cost=costs.at[tech, 'marginal_cost'],
capital_cost=costs.at[tech, 'capital_cost'], capital_cost=capital_cost,
efficiency=costs.at[tech, 'efficiency'], efficiency=costs.at[tech, 'efficiency'],
p_max_pu=ds['profile'].transpose('time', 'bus').to_pandas()) p_max_pu=ds['profile'].transpose('time', 'bus').to_pandas())

View File

@ -24,6 +24,8 @@ for country in countries:
onshore_shape = country_shapes[country] onshore_shape = country_shapes[country]
onshore_locs = n.buses.loc[c_b & n.buses.substation_lv, ["x", "y"]] onshore_locs = n.buses.loc[c_b & n.buses.substation_lv, ["x", "y"]]
onshore_regions.append(gpd.GeoDataFrame({ onshore_regions.append(gpd.GeoDataFrame({
'x': onshore_locs['x'],
'y': onshore_locs['y'],
'geometry': voronoi_partition_pts(onshore_locs.values, onshore_shape), 'geometry': voronoi_partition_pts(onshore_locs.values, onshore_shape),
'country': country 'country': country
}, index=onshore_locs.index)) }, index=onshore_locs.index))
@ -32,6 +34,8 @@ for country in countries:
offshore_shape = offshore_shapes[country] offshore_shape = offshore_shapes[country]
offshore_locs = n.buses.loc[c_b & n.buses.substation_off, ["x", "y"]] offshore_locs = n.buses.loc[c_b & n.buses.substation_off, ["x", "y"]]
offshore_regions_c = gpd.GeoDataFrame({ offshore_regions_c = gpd.GeoDataFrame({
'x': offshore_locs['x'],
'y': offshore_locs['y'],
'geometry': voronoi_partition_pts(offshore_locs.values, offshore_shape), 'geometry': voronoi_partition_pts(offshore_locs.values, offshore_shape),
'country': country 'country': country
}, index=offshore_locs.index) }, index=offshore_locs.index)

View File

@ -6,6 +6,8 @@ import numpy as np
import xarray as xr import xarray as xr
import pandas as pd import pandas as pd
import geopandas as gpd import geopandas as gpd
from pypsa.geo import haversine
from vresutils.array import spdiag
import logging import logging
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -47,9 +49,21 @@ p_nom_max = xr.DataArray([np.nanmin(relativepotentials[row.nonzero()[1]])
for row in indicatormatrix.tocsr()], for row in indicatormatrix.tocsr()],
[capacities.coords['bus']]) * capacities [capacities.coords['bus']]) * capacities
# Determine weighted average distance to substation
matrix_weighted = indicatormatrix * spdiag(layout.stack(spatial=('y', 'x')))
cell_coords = cutout.grid_coordinates()
average_distance = []
for i, bus in enumerate(regions.index):
row = matrix_weighted[i]
distances = haversine(regions.loc[bus, ['x', 'y']], cell_coords[row.indices])[0]
average_distance.append((distances * (row.data / row.data.sum())).sum())
average_distance = xr.DataArray(average_distance, [regions.index.rename("bus")])
ds = xr.merge([(correction_factor * profile).rename('profile'), ds = xr.merge([(correction_factor * profile).rename('profile'),
capacities.rename('weight'), capacities.rename('weight'),
p_nom_max.rename('p_nom_max'), p_nom_max.rename('p_nom_max'),
layout.rename('potential')]) layout.rename('potential'),
average_distance.rename('average_distance')])
(ds.sel(bus=ds['profile'].mean('time') > config.get('min_p_max_pu', 0.)) (ds.sel(bus=ds['profile'].mean('time') > config.get('min_p_max_pu', 0.))
.to_netcdf(snakemake.output.profile)) .to_netcdf(snakemake.output.profile))