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 Model Energg Demand and Fix Problem of Submodels #55

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions .github/workflows/ci-linux.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,12 @@ jobs:
id: cache
with:
path: ${{ matrix.prefix }}
key: ${{ matrix.label }}-conda-${{ hashFiles('pypsa-earth/envs/environment.yaml') }}-${{ env.DATE }}-${{ env.CACHE_NUMBER }}
key: ${{ matrix.label }}-conda-${{ hashFiles('envs/environment.yaml') }}-${{ env.DATE }}-${{ env.CACHE_NUMBER }}

- name: Update environment due to outdated or unavailable cache
if: steps.cache.outputs.cache-hit != 'true'
run: |
mamba env update -n pypsa-earth -f pypsa-earth/envs/environment.yaml
mamba env update -n pypsa-earth -f envs/environment.yaml
conda activate pypsa-earth
pip install rampdemand

Expand Down
3 changes: 2 additions & 1 deletion Snakefile
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ rule ramp_build_demand_profile:
rule build_demand:
params:
tier=config["tier"],
snapshots=config["snapshots"],
build_demand_model=config["build_demand_type"],
input:
**{
Expand Down Expand Up @@ -225,7 +226,7 @@ rule build_renewable_profiles:
"data/copernicus/PROBAV_LC100_global_v3.0.1_2019-nrt_Discrete-Classification-map_EPSG-4326.tif"
),
gebco=pypsaearth("data/gebco/GEBCO_2021_TID.nc"),
country_shapes=pypsaearth("resources/shapes/country_shapes.geojson"),
country_shapes="resources/shapes/microgrid_shapes.geojson",
offshore_shapes=pypsaearth("resources/shapes/offshore_shapes.geojson"),
hydro_capacities="pypsa-earth/data/hydro_capacities.csv",
eia_hydro_generation="pypsa-earth/data/eia_hydro_annual_generation.csv",
Expand Down
12 changes: 6 additions & 6 deletions config.distribution.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ countries: ["NG"]
year: "2019" # Year setting allows the choice of which data to download (es. Worldpop_data)

snapshots:
start: "2013-01-01"
end: "2014-01-01"
start: "2013-03-01"
end: "2013-03-07"
inclusive: "left" # end is not inclusive

ramp:
Expand All @@ -58,9 +58,9 @@ house_area_limit:
build_demand_type:
type: 0
# type allows to select the mode by which the microgrid demand profile is generated.
# 1 = a predetermined hourly profile is used
# 2 = an average hourly profile is calculated by exploiting the ramp tool
# 3 = an average hourly profile and its standard deviation is calculated using the ramp tool,
# 0 = a predetermined hourly profile is used
# 1 = an average hourly profile is calculated by exploiting the ramp tool
# 2 = an average hourly profile and its standard deviation is calculated using the ramp tool,
# and both quantities are used to calculate demand.

# definition of the Coordinate Reference Systems
Expand All @@ -79,7 +79,7 @@ electricity:
H2: 168

extendable_carriers:
Generator: [solar, onwind]
Generator: [solar, onwind, diesel]
StorageUnit: ["lithium", "lead acid"]
conventional_carriers: [diesel]

Expand Down
12 changes: 10 additions & 2 deletions data/costs.csv
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,9 @@ 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;
lithium,2030,investment,192,USD/kWh,budischak2013;
lead acid,2030,lifetime,15,years,budischak2013;
lithium,2030,lifetime,15,years,b;
lead acid,2030,lifetime,5,years,b;
lead acid,2030,investment,150,USD/kWh,bu;
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;
Expand Down Expand Up @@ -193,4 +195,10 @@ 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;
diesel,2030,investment,400,EUR/kWel,DIW DataDoc http://hdl.handle.net/10419/80348;
diesel,2030,investment,400,EUR/kWel,DIW;
diesel,2030,efficiency,0.30,per unit,DIW ;
diesel,2030,VOM,0.5,EUR/MWhel,DIW;
diesel,2030,fuel,100,USD/MWhth,DIW;
MVAC overhead,2030,investment,40,EUR/MW/km, ;
MVAC overhead,2030,lifetime,40,years, ;
MVAC overhead,2030,FOM,2,%/year, ;
Binary file modified data/ramp/Tier1.xlsx
Binary file not shown.
Binary file modified data/ramp/Tier2.xlsx
Binary file not shown.
Binary file modified data/ramp/Tier3.xlsx
Binary file not shown.
Binary file modified data/ramp/Tier4.xlsx
Binary file not shown.
Binary file modified data/ramp/Tier5.xlsx
Binary file not shown.
91 changes: 91 additions & 0 deletions envs/environment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# SPDX-FileCopyrightText: PyPSA-Earth and PyPSA-Eur Authors
#
# SPDX-License-Identifier: AGPL-3.0-or-later

name: pypsa-earth
channels:
- conda-forge
- bioconda
- gurobi
dependencies:
- python>=3.8
- pip
- mamba # esp for windows build

- pypsa>=0.24, <0.25
# - atlite>=0.2.4 # until https://github.com/PyPSA/atlite/issues/244 is not merged
- dask
- powerplantmatching
- earth-osm>=2.1
- atlite

# Dependencies of the workflow itself
- xlrd
- openpyxl
- seaborn
- snakemake-minimal<8
- memory_profiler
- ruamel.yaml<=0.17.26
- pytables
- lxml
- numpy
- pandas
- geopandas>=0.11.0, <=0.14.3
- fiona<1.10.0
- xarray>=2023.11.0, <2023.12.0
- netcdf4
- networkx
- scipy
- pydoe2
- shapely!=2.0.4
- pre-commit
- pyomo
- matplotlib<=3.5.2
- reverse-geocode
- country_converter
- pyogrio
- numba
- py7zr

# Keep in conda environment when calling ipython
- ipython
# Jupyter notebook requirement
- ipykernel
- jupyterlab

# GIS dependencies:
- cartopy
- descartes
- rasterio!=1.2.10, <=1.3.11
- rioxarray

# Plotting
- geoviews
- hvplot
- graphviz
- contextily
- graphviz

# PyPSA-Eur-Sec Dependencies
- geopy
- tqdm
- pytz
- country_converter

# Cloud download
# - googledrivedownloader # Commented until https://github.com/ndrplz/google-drive-downloader/pull/28 is merged: PR installed using pip

# Default solver for tests (required for CI)
- glpk
- ipopt
- gurobi

- pip:
- earth-osm>=2.2 # until conda release it out
- powerplantmatching>=0.5.19 # until conda release it out
- rampdemand
- git+https://github.com/davide-f/google-drive-downloader@master # google drive with fix for virus scan
- git+https://github.com/FRESNA/vresutils@master # until new pip release > 0.3.1 (strictly)
- tsam>=1.1.0
- chaospy # lastest version only available on pip
- fake_useragent
2 changes: 1 addition & 1 deletion resources/powerplants.csv
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
,Name,Fueltype,Technology,Set,Country,Capacity,Efficiency,Duration,Volume_Mm3,DamHeight_m,StorageCapacity_MWh,DateIn,DateRetrofit,DateOut,lat,lon,EIC,projectID,bus
1,New_Diesel_Generator,Diesel,,PP,SL,14.0,,0.0,0.0,0.0,0.0,1986,1986.0,2031,-21.1667,27.5167,{nan},{'GPD': {'WRI1023018'}},bus_9
1,New_Diesel_Generator,Diesel,,PP,SL,0.0,,0.0,0.0,0.0,0.0,1986,1986.0,2031,-21.1667,27.5167,{nan},{'GPD': {'WRI1023018'}},bus_9
46 changes: 26 additions & 20 deletions scripts/add_electricity.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,13 +87,20 @@ def _add_missing_carriers_from_costs(n, costs, carriers):

def load_costs(tech_costs, config, elec_config, Nyears=1):
"""
set all asset costs and other parameters
Set all asset costs and other parameters.
"""
idx = pd.IndexSlice
costs = pd.read_csv(tech_costs, index_col=list(range(3))).sort_index()

# correct units to MW and EUR
costs.loc[costs.unit.str.contains("/kW"), "value"] *= 1e3
costs.loc[costs.unit.str.contains("USD"), "value"] *= config["USD2013_to_EUR2013"]
costs.loc[
costs.unit.str.contains("/kWel"), "value"
] *= 1e3 # Convert EUR/kW to EUR/MW
costs.loc[
costs.unit.str.contains("/kWh"), "value"
] *= 1e3 # Convert EUR/kWh to EUR/MWh
costs.loc[costs.unit.str.contains("USD"), "value"] *= config[
"USD2013_to_EUR2013"
] # Convert USD to EUR

costs = (
costs.loc[idx[:, config["year"], :], "value"]
Expand Down Expand Up @@ -149,17 +156,13 @@ def costs_for_storage(store, link1, link2=None, max_hours=1.0):

max_hours = elec_config["max_hours"]
costs.loc["battery"] = costs_for_storage(
costs.loc[
"lithium"
], # line 119 in file costs.csv' which was battery storage was modified into lithium (same values left)
costs.loc["lithium"],
costs.loc["battery inverter"],
max_hours=max_hours["battery"],
)
max_hours = elec_config["max_hours"]

costs.loc["battery"] = costs_for_storage(
costs.loc[
"lead acid"
], # line 120 in file 'costs.csv' which was battery storage was modified into lithium (same values left)
costs.loc["lead acid"],
costs.loc["battery inverter"],
max_hours=max_hours["battery"],
)
Expand Down Expand Up @@ -260,33 +263,28 @@ def attach_conventional_generators(
conventional_config,
conventional_inputs,
):
# Create a set of all conventional and extendable carriers
carriers = set(conventional_carriers) | set(extendable_carriers["Generator"])

# Add any missing carriers from the costs data to the "carriers" variable
_add_missing_carriers_from_costs(n, costs, carriers)

# Filter the ppl dataframe to only include the relevant carriers
ppl = (
ppl.query("carrier in @carriers")
.join(costs, on="carrier", rsuffix="_r")
.rename(index=lambda s: "C" + str(s))
)
ppl["efficiency"] = ppl.efficiency.fillna(ppl.efficiency)

# Get the index of the buses in the power network
buses_i = n.buses.index

# Add conventional generators to each bus in the power network (one for microgrid)

n.madd(
"Generator",
ppl.index,
carrier=ppl.carrier,
bus=ppl.bus,
p_nom_min=ppl.p_nom.where(ppl.carrier.isin(conventional_carriers), 0),
p_nom=ppl.p_nom.where(ppl.carrier.isin(conventional_carriers), 0),
p_nom_extendable=ppl.carrier.isin(extendable_carriers["Generator"]),
p_nom_extendable=ppl.carrier.isin(extendable_carriers["Generator"])
| (ppl.carrier == "diesel"),
efficiency=ppl.efficiency,
marginal_cost=ppl.marginal_cost,
capital_cost=ppl.capital_cost,
Expand All @@ -295,7 +293,7 @@ def attach_conventional_generators(
)

for carrier in conventional_config:
# Generators with technology affected
# Generatori con tecnologia influenzata
idx = n.generators.query("carrier == @carrier").index

for attr in list(set(conventional_config[carrier]) & set(n.generators)):
Expand All @@ -310,7 +308,7 @@ def attach_conventional_generators(
n.generators.loc[idx].bus.map(bus_values).dropna()
)
else:
# Single value affecting all generators of technology k indiscriminately of country
# Single value affecting all k technology generators regardless of country.
n.generators.loc[idx, attr] = values


Expand Down Expand Up @@ -357,6 +355,12 @@ def attach_load(n, load_file, tech_modelling):
n.madd("Load", demand_df.columns, bus=demand_df.columns, p_set=demand_df)


def update_transmission_costs(n, costs, length_factor=1.0, simple_hvdc_costs=False):
n.lines["capital_cost"] = (
n.lines["length"] * length_factor * costs.at["MVAC overhead", "capital_cost"]
)


if __name__ == "__main__":
if "snakemake" not in globals():
from _helpers_dist import mock_snakemake
Expand Down Expand Up @@ -419,4 +423,6 @@ def attach_load(n, load_file, tech_modelling):
snakemake.config["tech_modelling"]["load_carriers"],
)

update_transmission_costs(n, costs, length_factor=1.0, simple_hvdc_costs=False)

n.export_to_netcdf(snakemake.output[0])
Loading
Loading