Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update dev #11

Open
wants to merge 46 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
394a765
Create LICENSE
chrisflei Mar 30, 2021
b3686dc
Update README.md
chrisflei Mar 30, 2021
42d09ae
Update README.md
chrisflei Apr 19, 2021
174b61a
Update README.md
chrisflei Apr 19, 2021
0fd10e1
remove high restrictions area for solar PV
chrisflei Jun 30, 2021
c334a66
plots updated
chrisflei Aug 31, 2021
75e1207
adjust to consider weightings
chrisflei Sep 11, 2021
302c69b
update xarray bug
chrisflei Sep 14, 2021
054c8e1
add weighing script
chrisflei Sep 14, 2021
c720eca
specify assumption made when spatially dissagregating power profiles
chrisflei Oct 21, 2021
e589e61
specify assumptions made when spatially dissagregating power and choi…
chrisflei Oct 21, 2021
7971fdf
Merge branch 'assumptions' of github.com:ENSYSTRA/EU-SES into assumpt…
chrisflei Oct 21, 2021
2c787b3
update to fit xarray version 0.14.1
chrisflei Oct 21, 2021
40e0545
Change sink temperature and method to calculate COP factor
chrisflei Oct 21, 2021
21999fe
add correction factor
chrisflei Oct 21, 2021
d7c7fc2
allow for use of either land area or population weighted weather data
chrisflei Oct 21, 2021
21036fb
correct bigM value
chrisflei Oct 21, 2021
32b5851
remove data_vars for heating components
chrisflei Oct 21, 2021
e9856f7
add optimisation results
chrisflei Oct 21, 2021
6fee1f9
new datasets for year 2011
chrisflei Oct 21, 2021
8178bb8
update function to load excel file
chrisflei Oct 26, 2021
38e51c8
update conda env file
chrisflei Oct 26, 2021
36b2cbe
remove datasets
chrisflei Oct 29, 2021
3e0a3f3
change temperature data to nuts 2 level taken from ERA-NUTS
chrisflei Oct 29, 2021
ef5174f
update datasets
chrisflei Oct 29, 2021
fc56548
update env calliope version
chrisflei Oct 29, 2021
ccc4744
update jrc hydropower database version
chrisflei Oct 29, 2021
34cabc9
update saved dataset
chrisflei Oct 29, 2021
7a55a0f
specify dim in locs
chrisflei Oct 29, 2021
86256bb
models at nuts 0 and nuts 2
chrisflei Oct 29, 2021
59828eb
new results
chrisflei Nov 3, 2021
80867cd
update results
chrisflei Nov 3, 2021
6307649
update results sk
chrisflei Nov 4, 2021
2b11a69
fix naming sk
chrisflei Nov 4, 2021
8e9054e
set preset to best set
chrisflei Nov 4, 2021
9e3aac0
update weighting variables
chrisflei Nov 4, 2021
7c5fc17
streamline directory
chrisflei Dec 22, 2021
9acfac8
solved models
chrisflei Jan 4, 2022
064419d
add seaborn and coincbc
chrisflei Jan 4, 2022
2878cdc
update three case studies
chrisflei Jan 7, 2022
0d03750
remove model results
chrisflei Jan 10, 2022
f86926a
update case study notebook
chrisflei Jan 10, 2022
2baad63
Merge pull request #12 from ENSYSTRA/assumptions
chrisflei Jan 10, 2022
fec2143
Update README.md
chrisflei Aug 10, 2022
e159e5e
Merge pull request #14 from ENSYSTRA/chrisflei-patch-1
chrisflei Aug 10, 2022
ddd760d
Update README.md
chrisflei Aug 10, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
628 changes: 201 additions & 427 deletions LICENSE

Large diffs are not rendered by default.

21 changes: 18 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# EU-SES - EUropean Sustainable Energy System for Python
[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.4575214.svg)](https://doi.org/10.5281/zenodo.4575214)
[![article DOI](https://img.shields.io/badge/article-10.12688/openreseurope.2021.04.19-yellow)](https://doi.org/10.12688/openreseurope.13420.1)

EU-SES is an energy system modelling tool that maximises the use of web-hosted pre-processed data sources. EU-SES offers an automated data-processing approach to build energy system models while maintaining the flexibility of selecting the spatial resolution of the model.

Expand Down Expand Up @@ -51,9 +52,11 @@ techs_removed = np.setdiff1d(example.ds.coords['tech'].values,techs_considered)
example.ds = example.ds.drop(techs_removed,dim='tech')

# The areas dataset and the preferred regionalisation method is used to build the regions dataset.
# The supported regionalisation methods include using national (poli_regions) and administrative boundaries (poli_regions_nuts1). It also possible to define the regions using the max-p regions method (max_p_regions).
# The supported regionalisation methods include using national (nuts0) and administrative boundaries (nuts1). It also possible to define the regions using the max-p regions method (max_p_regions).
# In this example the national boundaries method is selected.
example.create_regions('poli_regions')
# Before the dataset is loaded
example.ds.load()
example.create_regions('nuts0')

# Build a power and heat optimisation calliope model with a limitation on CO2 emission.
# The specifications of the technologies within the model are in the calliope_model folder.
Expand Down Expand Up @@ -94,4 +97,16 @@ This work was done by ESR 5 of the [ENSYSTRA](https://ensystra.eu/) project and


# License
The code is licensed under Creative Commons Attribution Share Alike 4.0 International.
Copyright 2021 Christian Fleischer

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
434 changes: 434 additions & 0 deletions Three case studies.ipynb

Large diffs are not rendered by default.

11 changes: 5 additions & 6 deletions calliope_model/model_config/techs_elec_heat.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -309,14 +309,13 @@ techs:
parent: transmission
carrier: power
constraints:
energy_cap_min: 2000
energy_cap_max: 8000
energy_cap_equals: 2000
lifetime: 40
energy_eff: 1
costs:
monetary:
energy_cap_per_distance: 40000 # value in per 100km , 400 €/MWkm https://doi.org/10.1016/j.energy.2017.06.004
interest_rate: 0.07
# costs:
# monetary:
# energy_cap_per_distance: 40000 # value in per 100km , 400 €/MWkm https://doi.org/10.1016/j.energy.2017.06.004
# interest_rate: 0.07

dc_transmission:
essentials:
Expand Down
Binary file added calliope_model/results/cs_ger_max_p.nc
Binary file not shown.
Binary file added calliope_model/results/cs_ger_nuts0.nc
Binary file not shown.
Binary file added calliope_model/results/cs_ger_nuts1.nc
Binary file not shown.
Binary file removed calliope_model/results/de_eu-calliope-3h.nc
Binary file not shown.
Binary file removed calliope_model/results/de_maxp-nopv-calliope-3h.nc
Binary file not shown.
Binary file removed calliope_model/results/de_maxp-pv-calliope-3h.nc
Binary file not shown.
Binary file removed calliope_model/results/de_nuts1-nopv-calliope-3h.nc
Binary file not shown.
Binary file removed calliope_model/results/de_nuts1-pv-calliope-3h.nc
Binary file not shown.
File renamed without changes.
333 changes: 333 additions & 0 deletions data/input_data/nuts2_gdp.csv

Large diffs are not rendered by default.

Binary file not shown.
105 changes: 15 additions & 90 deletions environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,97 +3,22 @@ channels:
- conda-forge
- defaults
dependencies:
- pip
- calliope=0.6.7
- gdal=2.4.1
- hdf4=4.2.13
- hdf5=1.10.4
- json-c=0.13.1
- numpy=1.19.1
- openjpeg=2.3.1
- openssl=1.1.1h
- pip=20.2.2
- xlrd=1.2.0
- fiona=1.8.6
- rasterio==1.0.25
- mapclassify=2.4.0
- coincbc=2.10.3
- seaborn=0.11.2
- pip:
- affine==2.3.0
- appdirs==1.4.4
- attrs==20.3.0
- backcall==0.2.0
- beautifulsoup4==4.9.1
- bottleneck==1.3.2
- calliope==0.6.5
- cftime==1.2.1
- chardet==3.0.4
- click==7.1.2
- click-plugins==1.1.1
- cligj==0.5.0
- cycler==0.10.0
- spopt==0.1.0
- datapackage==1.15.1
- decorator==4.4.2
- descartes==1.1.0
- geographiclib==1.50
- geopandas==0.8.1
- numpy==1.19.1
- openpyxl==3.0.6
- rasterio==1.1.5
- rasterstats==0.15.0
- geopy==2.0.0
- idna==2.10
- importlib-metadata==1.7.0
- ipykernel==5.3.4
- ipython==7.17.0
- ipython-genutils==0.2.0
- jedi==0.17.2
- jinja2==3.0.0a1
- joblib==0.16.0
- jsonschema==3.2.0
- jupyter-client==6.1.6
- jupyter-core==4.6.3
- kiwisolver==1.2.0
- libpysal==4.3.0
- markupsafe==2.0.0a1
- matplotlib==3.3.1
- munch==2.5.0
- natsort==7.0.1
- nbformat==5.0.7
- netcdf4==1.5.4
- networkx==2.4
- nose==1.3.7
- numexpr==2.7.1
- ortools==7.8.7959
- pandas==0.25.0
- parso==0.7.1
- pexpect==4.8.0
- pickleshare==0.7.5
- pillow==7.2.0
- plotly==3.10.0
- ply==3.11
- prompt-toolkit==3.0.6
- protobuf==3.13.0
- ptyprocess==0.6.0
- pygments==2.6.1
- pyomo==5.6.9
- pyparsing==2.4.7
- pyproj==2.6.1.post1
- pyrsistent==0.16.0
- python-dateutil==2.8.1
- pytz==2020.1
- pyutilib==5.8.0
- pyzmq==19.0.2
- rasterstats==0.14.0
- requests==2.24.0
- ruamel-yaml==0.16.10
- ruamel-yaml-clib==0.2.0
- scikit-learn==0.23.2
- seaborn==0.11.1
- scipy==1.5.2
- shapely==1.7.0
- simplejson==3.17.2
- six==1.15.0
- smopy==0.0.7
- snuggs==1.4.7
- soupsieve==2.0.1
- threadpoolctl==2.1.0
- tornado==6.0.4
- traitlets==5.0.0b1
- urllib3==1.25.10
- wcwidth==0.2.5
- xarray==0.14.1
- zipp==3.1.0
- https://github.com/ENSYSTRA/spopt/archive/master.zip
- matplotlib==3.4.3
- h5netcdf==0.11.0
- ipython==7.29.0
- xlrd==2.0.1
- jupyter==1.0.0
50 changes: 38 additions & 12 deletions euses/classification.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,45 +6,71 @@
import numpy as np
import spopt, libpysal

def wind_offshore_to_nuts2(ds):
def disaggregation(ds, disaggr_var = 'preset'):
if disaggr_var == 'preset':
disaggr_var = {'power':'population'}
time_range = ds.time.values
dsc = ds.copy()
cc_nuts0_id = dict(zip(np.unique(dsc['country_code'].values),dsc.coords['nuts_0'].values))
cc_nuts0_id['EL'] = 'GR'
cc_nuts0_id['EE'] = 'EE00'

ds['wind_offshore_cf'] = (('nuts_2','time'),(np.array([[t*0.0 for t in range(len(time_range))]]*len(ds.coords['nuts_2']))))
ds['power'] = (('nuts_2','time'),(np.array([[t*0.0 for t in range(len(time_range))]]*len(ds.coords['nuts_2']))))

ds_sum_var = dsc[disaggr_var['power']].groupby(dsc['country_code']).sum()
for nuts2_id in dsc.coords['nuts_2']:
cc_id = dsc['country_code'].loc[nuts2_id].values.item()
sum_var = ds_sum_var.loc[cc_id].item()
weighting_factor = dsc[disaggr_var['power']].loc[nuts2_id].values.item()/sum_var
power_profile = dsc['power'].loc[cc_nuts0_id[cc_id]] * weighting_factor
ds['power'].loc[nuts2_id] = power_profile

ds_c = ds.where(ds['offshore_wind'] > 0, drop = True)
for nuts2_id in ds_c.coords['nuts_2'].values:
nuts0_id = ds['country_code'].loc[nuts2_id].values.item()
ds['wind_offshore_cf'].loc[nuts2_id] = dsc['wind_offshore_cf'].loc[nuts0_id]


def aggregation(ds, groups):
def aggregation(ds, groups, aggr_var = 'preset'):

if aggr_var == 'preset':
aggr_var = {'wind_cf':'onshore_wind','pv_cf':'area_pv','cop_air':'population'}

aggr_var['wind_offshore_cf']='offshore_wind'
aggr_var['hydro_inflow']='hydro_capacity_all'
dsc = ds.copy()

dsc['hydro_capacity_all'] = dsc['hydro_capacity'].sum(dim='hydro_tech')
dsc['area_pv'] = dsc['rooftop_pv'] + dsc['utility_pv']
dsc['area'] = dsc['geometry']
dsc['area'].values = [a.area for a in dsc['geometry'].values]

sums_vars = ['power', 'population', 'heat', 'power_plants', 'onshore_wind','offshore_wind',
'rooftop_pv','utility_pv','hydro_capacity', 'hydro_storage']
area_weighted_vars = ['wind_cf', 'pv_cf', 'wind_offshore_cf',
'cop_air','hydro_inflow']
# area_weighted_vars = ['wind_cf', 'pv_cf', 'wind_offshore_cf',
# 'cop_air','hydro_inflow']

sep=','
new_coords = dsc.coords['nuts_2'].values
for nuts in groups:
if nuts[0] in dsc.coords['nuts_2']:
ds_is = dsc.sel(nuts_2=nuts)
group_area = sum([i.area for i in ds_is['geometry'].values])
offshore_area_sum = ds_is['offshore_wind'].sum()
# group_area = sum([i.area for i in ds_is['geometry'].values])
# offshore_area_sum = ds_is['offshore_wind'].sum()

for var in area_weighted_vars:
for var, weight_var in aggr_var.items():
sum_weighted_var = ds_is[weight_var].sum()
for n in nuts:
if var == 'wind_offshore_cf':
ds_is[var].loc[n] = dsc[var].loc[n] * dsc['offshore_wind'].loc[n] / offshore_area_sum
if sum_weighted_var == 0:
ds_is[var].loc[{'nuts_2':n}] = dsc[var].loc[{'nuts_2':n}]
else:
ds_is[var].loc[n] = dsc[var].loc[n] * dsc['geometry'].loc[n].values.item().area / group_area
dsc[var].loc[nuts[0]] = ds_is[var].sum(axis=0)
ds_is[var].loc[{'nuts_2':n}] = dsc[var].loc[{'nuts_2':n}] * dsc[weight_var].loc[{'nuts_2':n}].sum() / sum_weighted_var

dsc[var].loc[{'nuts_2':nuts[0]}] = ds_is[var].sum(dim='nuts_2')

for var in sums_vars:
dsc[var].loc[nuts[0]] = ds_is[var].sum(axis=0)
dsc[var].loc[{'nuts_2':nuts[0]}] = ds_is[var].sum(dim='nuts_2')

dsc['geometry'].loc[nuts[0]] = np.array(str(unary_union(ds_is['geometry'].loc[nuts].values)))

Expand Down
Loading