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 9 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
2 changes: 1 addition & 1 deletion .github/workflows/ci-linux.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ 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('pypsa-distribution/envs/environment.yaml') }}-${{ env.DATE }}-${{ env.CACHE_NUMBER }}
davide-f marked this conversation as resolved.
Show resolved Hide resolved

- name: Update environment due to outdated or unavailable cache
if: steps.cache.outputs.cache-hit != 'true'
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
11 changes: 8 additions & 3 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 @@ -181,7 +183,7 @@ 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,investment,40,EUR/MW/km,Hagspiel;
davide-f marked this conversation as resolved.
Show resolved Hide resolved
HVAC overhead,2030,lifetime,40,years,Hagspiel;
HVAC overhead,2030,FOM,2,%/year,Hagspiel;
HVDC overhead,2030,investment,400,EUR/MW/km,Hagspiel;
Expand All @@ -193,4 +195,7 @@ 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;
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
51 changes: 29 additions & 22 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 @@ -126,6 +133,7 @@ def load_costs(tech_costs, config, elec_config, Nyears=1):

costs.at["OCGT", "fuel"] = costs.at["gas", "fuel"]
costs.at["CCGT", "fuel"] = costs.at["gas", "fuel"]
costs.at["diesel", "fuel"] = costs.at["diesel", "fuel"]
davide-f marked this conversation as resolved.
Show resolved Hide resolved

costs["marginal_cost"] = costs["VOM"] + costs["fuel"] / costs["efficiency"]

Expand All @@ -149,17 +157,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 +264,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,22 +294,22 @@ 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)):
values = conventional_config[carrier][attr]

if f"conventional_{carrier}_{attr}" in conventional_inputs:
# Values affecting generators of technology k country-specific
# First map generator buses to countries; then map countries to p_max_pu
# Valori che influenzano i generatori di tecnologia k specifici per paese
davide-f marked this conversation as resolved.
Show resolved Hide resolved
# Prima mappa i bus dei generatori ai paesi; poi mappa i paesi ai p_max_pu
values = pd.read_csv(values, index_col=0).iloc[:, 0]
bus_values = n.buses.country.map(values)
n.generators[attr].update(
n.generators.loc[idx].bus.map(bus_values).dropna()
)
else:
# Single value affecting all generators of technology k indiscriminately of country
# Singolo valore che influenza tutti i generatori di tecnologia k indipendentemente dal paese
n.generators.loc[idx, attr] = values


Expand Down Expand Up @@ -357,6 +356,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["HVAC overhead", "capital_cost"]
)


if __name__ == "__main__":
if "snakemake" not in globals():
from _helpers_dist import mock_snakemake
Expand Down Expand Up @@ -419,4 +424,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