Skip to content

Commit

Permalink
Merge branch 'main' into add_demand_parser
Browse files Browse the repository at this point in the history
  • Loading branch information
ekatef committed Jun 4, 2024
2 parents 25451d7 + b23cb9b commit c1c80b4
Show file tree
Hide file tree
Showing 18 changed files with 146 additions and 18 deletions.
4 changes: 2 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ repos:

# Find common spelling mistakes in comments and docstrings
- repo: https://github.com/codespell-project/codespell
rev: v2.2.6
rev: v2.3.0
hooks:
- id: codespell
args: ['--ignore-regex="(\b[A-Z]+\b)"', '--ignore-words-list=fom,appartment,bage,ore,setis,tabacco,berfore,fo,FO']
Expand Down Expand Up @@ -72,7 +72,7 @@ repos:

# Format Snakemake rule / workflow files
- repo: https://github.com/snakemake/snakefmt
rev: v0.10.1
rev: v0.10.2
hooks:
- id: snakefmt

Expand Down
2 changes: 1 addition & 1 deletion Snakefile
Original file line number Diff line number Diff line change
Expand Up @@ -461,7 +461,7 @@ rule build_renewable_profiles:
powerplants="resources/" + RDIR + "powerplants.csv",
regions=lambda w: (
"resources/" + RDIR + "bus_regions/regions_onshore.geojson"
if w.technology in ("onwind", "solar", "hydro")
if w.technology in ("onwind", "solar", "hydro", "csp")
else "resources/" + RDIR + "bus_regions/regions_offshore.geojson"
),
cutout=lambda w: "cutouts/"
Expand Down
25 changes: 23 additions & 2 deletions config.default.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ electricity:
custom_powerplants: false # "false" use only powerplantmatching (ppm) data, "merge" combines ppm and custom powerplants, "replace" use only custom powerplants

conventional_carriers: [nuclear, oil, OCGT, CCGT, coal, lignite, geothermal, biomass]
renewable_carriers: [solar, onwind, offwind-ac, offwind-dc, hydro]
renewable_carriers: [solar, csp, onwind, offwind-ac, offwind-dc, hydro]

estimate_renewable_capacities:
stats: "irena" # False, = greenfield expansion, 'irena' uses IRENA stats to add expansion limits
Expand Down Expand Up @@ -313,6 +313,26 @@ renewable:
method: hydro_capacities # 'hydro_capacities' to rescale country hydro production by using hydro_capacities, 'eia' to rescale by eia data, false for no rescaling
year: 2013 # (optional) year of statistics used to rescale the runoff time series. When not provided, the weather year of the snapshots is used
multiplier: 1.1 # multiplier applied after the normalization of the hydro production; default 1.0
csp:
cutout: cutout-2013-era5
resource:
method: csp
installation: SAM_solar_tower
capacity_per_sqkm: 2.392 # From 1.7 to 4.6 addresses issue #361
# Determined by comparing uncorrected area-weighted full-load hours to those
# published in Supplementary Data to
# Pietzcker, Robert Carl, et al. "Using the sun to decarbonize the power
# sector: The economic potential of photovoltaics and concentrating solar
# power." Applied Energy 135 (2014): 704-720.
copernicus:
grid_codes: [20, 30, 40, 60, 90]
distancing_codes: [50]
distance_to_codes: 3000
natura: true
potential: simple # or conservative
clip_p_max_pu: 1.e-2
extendable: true
csp_model: advanced # simple or advanced

# TODO: Needs to be adjusted for Africa.
# Costs Configuration (Do not remove, needed for Sphynx documentation).
Expand Down Expand Up @@ -467,7 +487,8 @@ plotting:
"HVDC links": "#8a1caf"
"DC-DC": "#8a1caf"
"DC link": "#8a1caf"
"load": "#FF0000"
"load": "#ff0000"
"csp": "#fdd404"
nice_names:
OCGT: "Open-Cycle Gas"
CCGT: "Combined-Cycle Gas"
Expand Down
25 changes: 23 additions & 2 deletions config.tutorial.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ electricity:
custom_powerplants: false # "false" use only powerplantmatching (ppm) data, "merge" combines ppm and custom powerplants, "replace" use only custom powerplants

conventional_carriers: [nuclear, oil, OCGT, CCGT, coal, lignite, geothermal, biomass]
renewable_carriers: [solar, onwind, offwind-ac, offwind-dc, hydro]
renewable_carriers: [solar, csp, onwind, offwind-ac, offwind-dc, hydro]

estimate_renewable_capacities:
stats: "irena" # False, = greenfield expansion, 'irena' uses IRENA stats to add expansion limits
Expand Down Expand Up @@ -310,6 +310,26 @@ renewable:
method: hydro_capacities # 'hydro_capacities' to rescale country hydro production by using hydro_capacities, 'eia' to rescale by eia data, false for no rescaling
year: 2013 # (optional) year of statistics used to rescale the runoff time series. When not provided, the cutout weather year is used
multiplier: 1.1 # multiplier applied after the normalization of the hydro production; default 1.0
csp:
cutout: cutout-2013-era5-tutorial
resource:
method: csp
installation: SAM_solar_tower
capacity_per_sqkm: 2.392 # From 1.7 to 4.6 addresses issue #361
# Determined by comparing uncorrected area-weighted full-load hours to those
# published in Supplementary Data to
# Pietzcker, Robert Carl, et al. "Using the sun to decarbonize the power
# sector: The economic potential of photovoltaics and concentrating solar
# power." Applied Energy 135 (2014): 704-720.
copernicus:
grid_codes: [20, 30, 40, 60, 90]
distancing_codes: [50]
distance_to_codes: 3000
natura: true
potential: simple # or conservative
clip_p_max_pu: 1.e-2
extendable: true
csp_model: advanced # simple or advanced

# TODO: Needs to be adjusted for Africa
costs:
Expand Down Expand Up @@ -453,7 +473,8 @@ plotting:
"HVDC links": "#8a1caf"
"DC-DC": "#8a1caf"
"DC link": "#8a1caf"
"load": "#FF0000"
"load": "#ff0000"
"csp": "#fdd404"
nice_names:
OCGT: "Open-Cycle Gas"
CCGT: "Combined-Cycle Gas"
Expand Down
9 changes: 9 additions & 0 deletions data/costs.csv
Original file line number Diff line number Diff line change
Expand Up @@ -193,3 +193,12 @@ 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
csp-tower,2030,FOM,1.1,%/year,ATB CSP data (https://atb.nrel.gov/electricity/2021/concentrating_solar_power)
csp-tower,2030,investment,108.37,"EUR/kW_th,dp",ATB CSP data (https://atb.nrel.gov/electricity/2021/concentrating_solar_power) and NREL SAM v2021.12.2 (https://sam.nrel.gov/).
csp-tower,2030,lifetime,30.0,years,ATB CSP data (https://atb.nrel.gov/electricity/2021/concentrating_solar_power)
csp-tower TES,2030,FOM,1.1,%/year,see solar-tower.
csp-tower TES,2030,investment,14.52,EUR/kWh_th,ATB CSP data (https://atb.nrel.gov/electricity/2021/concentrating_solar_power) and NREL SAM v2021.12.2 (https://sam.nrel.gov/).
csp-tower TES,2030,lifetime,30.0,years,see solar-tower.
csp-tower power block,2030,FOM,1.1,%/year,see solar-tower.
csp-tower power block,2030,investment,759.17,EUR/kW_e,ATB CSP data (https://atb.nrel.gov/electricity/2021/concentrating_solar_power) and NREL SAM v2021.12.2 (https://sam.nrel.gov/).
csp-tower power block,2030,lifetime,30.0,years,see solar-tower.
15 changes: 15 additions & 0 deletions doc/configtables/csp.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
,Unit,Values,Description
cutout,--,Should be a file name listed in the configuration ``atlite: cutouts:`` (e.g. 'europe-2013-era5') or reference an existing folder in the directory ``cutouts``. Source module can be ERA5 or SARAH-2.,Specifies the directory where the relevant weather data is stored that is specified at ``atlite/cutouts`` configuration. Both ``sarah`` and ``era5`` work.
resource,,,
-- method,--,Must be 'csp',
-- installation,--,"Should be 'SAM_solar_tower' as defined in `atlite <https://github.com/PyPSA/atlite/tree/master/atlite/resources/cspinstallation>`__",Specifies the csp technology and its characteristic attributes.
capacity_per_sqkm,:math:`MW/km^2`,float,Allowable density of csp tower placement. Value relates to socio-technical acceptable density.
copernicus,,,
-- grid_codes,--,Any subset of the `Copernicus Land Cover code list <https://land.copernicus.eu/pan-european/corine-land-cover/clc2018>`_,Specifies areas based on CLC which generally eligible for csp tower placement.
-- distance,m,"int","(Optional) Distance to reserve as uneligible area around 'distance_grid_codes' for the renewable technology."
-- distance_grid_codes,--,"(Optional with 'distance') Any subset of the `Copernicus Land Cover code list <https://land.copernicus.eu/pan-european/corine-land-cover/clc2018>`_","Specifies from which a distance of 'distance' metres is unavailable as a buffer area."
natura,bool,"{true, false}",Switch to exclude `Natura 2000 <https://en.wikipedia.org/wiki/Natura_2000>`_ natural protection areas. Area is excluded if ``true``.
potential,--,"One of {'simple', 'conservative'}",Method to compute the maximal installable potential for a node; confer :ref:`renewableprofiles`
clip_p_max_pu,p.u.,float,To avoid too small values in the renewables` per-unit availability time series values below this threshold are set to zero.
extendable, bool, "{True, False}", "True: In nodes where there is no csp generation, adds a zero-capacity csp generator so that csp is considered for capacity expansion. It is done in the ``add_electricity`` rule."
csp_model,--, One of {'advanced' or 'simple'}, Specifies the CSP model to be used. The advanced model attach stores and links to the csp buses while the simple has no stores and links.
2 changes: 1 addition & 1 deletion doc/configtables/hydro.csv
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
,Unit,Values,Description
cutout,--,"Must be 'europe-2013-era5'","Specifies the directory where the relevant weather data ist stored."
cutout,--,"Must be 'europe-2013-era5'","Specifies the directory where the relevant weather data is stored."
resource,,,
-- method,,, "Specifies the Atlite method to calculate renewable potential."
-- hydrobasin,,, "Specifies the file location for hydrobasins. They are used to make the runoff calibration, defining a polygon to compute the available water surface using a surface integral."
Expand Down
2 changes: 1 addition & 1 deletion doc/configtables/offwind-ac.csv
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
,Unit,Values,Description
cutout,--,"Should be a file name 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."
cutout,--,"Should be a file name 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 is stored."
resource,,,
-- method,--,"Must be 'wind'","A superordinate technology type."
-- turbine,--,"One of turbine types included in `atlite <https://github.com/PyPSA/atlite/tree/master/atlite/resources/windturbine>`_","Specifies the turbine type and its characteristic power curve."
Expand Down
2 changes: 1 addition & 1 deletion doc/configtables/offwind-dc.csv
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
,Unit,Values,Description
cutout,--,"Should be a file name 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."
cutout,--,"Should be a file name 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 is stored."
resource,,,
-- method,--,"Must be 'wind'","A superordinate technology type."
-- turbine,--,"One of turbine types included in `atlite <https://github.com/PyPSA/atlite/tree/master/atlite/resources/windturbine>`__","Specifies the turbine type and its characteristic power curve."
Expand Down
2 changes: 1 addition & 1 deletion doc/configtables/onwind.csv
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
,Unit,Values,Description
cutout,--,"Should be a file name 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."
cutout,--,"Should be a file name 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 is stored."
resource,,,
-- method,--,"Must be 'wind'","A superordinate technology type."
-- turbine,--,"One of turbine types included in `atlite <https://github.com/PyPSA/atlite/tree/master/atlite/resources/windturbine>`__","Specifies the turbine type and its characteristic power curve."
Expand Down
2 changes: 1 addition & 1 deletion doc/configtables/solar.csv
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
,Unit,Values,Description
cutout,--,Should be a file name listed in the configuration ``atlite: cutouts:`` (e.g. 'europe-2013-era5') or reference an existing folder in the directory ``cutouts``. Source module can be ERA5 or SARAH-2.,Specifies the directory where the relevant weather data ist stored that is specified at ``atlite/cutouts`` configuration. Both ``sarah`` and ``era5`` work.
cutout,--,Should be a file name listed in the configuration ``atlite: cutouts:`` (e.g. 'europe-2013-era5') or reference an existing folder in the directory ``cutouts``. Source module can be ERA5 or SARAH-2.,Specifies the directory where the relevant weather data is stored that is specified at ``atlite/cutouts`` configuration. Both ``sarah`` and ``era5`` work.
resource,,,
-- method,--,Must be 'pv',A superordinate technology type.
-- panel,--,"One of {'Csi', 'CdTe', 'KANENA'} as defined in `atlite <https://github.com/PyPSA/atlite/tree/master/atlite/resources/solarpanel>`__",Specifies the solar panel technology and its characteristic attributes.
Expand Down
15 changes: 14 additions & 1 deletion doc/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ Specifies the minimum voltage magnitude in the base network and the offshore sub
``load_options``
=============================

Specifies the options to estimate future electricity demand (load). Different years might be considered for weather and the socio-economic pathway (GDP and population growth), to enhance modelling capabilities.
Specifies the options to estimate future electricity demand (load). Different years might be considered for weather and the socioeconomic pathway (GDP and population growth), to enhance modelling capabilities.

.. literalinclude:: ../config.default.yaml
:language: yaml
Expand Down Expand Up @@ -402,6 +402,19 @@ Specifies the options to obtain renewable potentials in every cutout. These are
:widths: 25,7,22,30
:file: configtables/hydro.csv

``csp``
---------------

.. literalinclude:: ../config.default.yaml
:language: yaml
:start-at: csp:
:end-at: csp_model:

.. csv-table::
:header-rows: 1
:widths: 25,7,22,30
:file: configtables/csp.csv

.. _costs_cf:

``costs``
Expand Down
2 changes: 2 additions & 0 deletions doc/release_notes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ E.g. if a new rule becomes available describe how to use it `snakemake -j1 run_t

* Resolve pandas deprecation warning. `PR #1023 <https://github.com/pypsa-meets-earth/pypsa-earth/pull/1023>`__

* Create files where the code outputs the value of the objective function. `PR #1033 <https://github.com/pypsa-meets-earth/pypsa-earth/pull/1033>`__

PyPSA-Earth 0.3.0
=================

Expand Down
14 changes: 11 additions & 3 deletions scripts/add_electricity.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,8 @@ def _add_missing_carriers_from_costs(n, costs, carriers):
costs.columns.to_series().loc[lambda s: s.str.endswith("_emissions")].values
)
suptechs = missing_carriers.str.split("-").str[0]
if "csp" in suptechs:
suptechs = suptechs.str.replace("csp", "csp-tower")
emissions = costs.loc[suptechs, emissions_cols].fillna(0.0)
emissions.index = missing_carriers
n.import_components_from_dataframe(emissions, "Carrier")
Expand Down Expand Up @@ -357,7 +359,9 @@ def attach_wind_and_solar(
)
)
else:
capital_cost = costs.at[tech, "capital_cost"]
capital_cost = costs.at[
"csp-tower" if tech == "csp" else tech, "capital_cost"
]

if not df.query("carrier == @tech").empty:
buses = n.buses.loc[ds.indexes["bus"]]
Expand All @@ -379,9 +383,13 @@ def attach_wind_and_solar(
p_nom_max=ds["p_nom_max"].to_pandas(),
p_max_pu=ds["profile"].transpose("time", "bus").to_pandas(),
weight=ds["weight"].to_pandas(),
marginal_cost=costs.at[suptech, "marginal_cost"],
marginal_cost=costs.at[
"csp-tower" if suptech == "csp" else suptech, "marginal_cost"
],
capital_cost=capital_cost,
efficiency=costs.at[suptech, "efficiency"],
efficiency=costs.at[
"csp-tower" if suptech == "csp" else suptech, "efficiency"
],
)


Expand Down
37 changes: 37 additions & 0 deletions scripts/add_extra_components.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,43 @@ def attach_stores(n, costs, config):
marginal_cost=costs.at["battery inverter", "marginal_cost"],
)

if ("csp" in config["renewable"].keys()) and (
config["renewable"]["csp"]["csp_model"] == "advanced"
):
# add buses for csp
n.madd("Bus", buses_i + " csp", carrier="csp", **bus_sub_dict)

csp_buses_i = n.buses.index[n.buses.index.str.contains("csp")]

# change bus of existing csp generators
old_csp_bus_vector = buses_i + " csp"
n.generators.loc[old_csp_bus_vector, "bus"] = csp_buses_i

# add stores for csp
n.madd(
"Store",
csp_buses_i,
bus=csp_buses_i,
carrier="csp",
e_cyclic=True,
e_nom_extendable=True,
capital_cost=costs.at["csp-tower TES", "capital_cost"],
marginal_cost=costs.at["csp-tower TES", "marginal_cost"],
)

# add links for csp
n.madd(
"Link",
csp_buses_i,
bus0=csp_buses_i,
bus1=buses_i,
carrier="csp",
efficiency=costs.at["csp-tower", "efficiency"],
capital_cost=costs.at["csp-tower", "capital_cost"],
p_nom_extendable=True,
marginal_cost=costs.at["csp-tower", "marginal_cost"],
)


def attach_hydrogen_pipelines(n, costs, config):
elec_opts = config["electricity"]
Expand Down
2 changes: 1 addition & 1 deletion scripts/simplify_network.py
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ def simplify_links(
exclude_carriers=[],
aggregation_strategies=dict(),
):
## Complex multi-node links are folded into end-points
# Complex multi-node links are folded into end-points
logger.info("Simplifying connected link components")

if n.links.empty:
Expand Down
2 changes: 2 additions & 0 deletions scripts/solve_network.py
Original file line number Diff line number Diff line change
Expand Up @@ -576,3 +576,5 @@ def solve_network(n, config, opts="", **kwargs):
)
n.meta = dict(snakemake.config, **dict(wildcards=dict(snakemake.wildcards)))
n.export_to_netcdf(snakemake.output[0])
logger.info(f"Objective function: {n.objective}")
logger.info(f"Objective constant: {n.objective_constant}")
2 changes: 1 addition & 1 deletion test/config.landlock.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ retrieve_databundle: # required to be "false" for nice CI test output
countries: ["BW"]

electricity:
renewable_carriers: [solar, onwind, hydro]
renewable_carriers: [solar, csp, onwind, hydro]

build_osm_network:
force_ac: true # When true, it forces all components (lines and substation) to be AC-only

0 comments on commit c1c80b4

Please sign in to comment.