Merge branch 'master' into fneum/line-rating
This commit is contained in:
commit
f0b44a91ec
@ -796,6 +796,11 @@ plotting:
|
||||
solar: "#f9d002"
|
||||
solar PV: "#f9d002"
|
||||
solar thermal: '#ffbf2b'
|
||||
residential rural solar thermal: '#f1c069'
|
||||
services rural solar thermal: '#eabf61'
|
||||
residential urban decentral solar thermal: '#e5bc5a'
|
||||
services urban decentral solar thermal: '#dfb953'
|
||||
urban central solar thermal: '#d7b24c'
|
||||
solar rooftop: '#ffea80'
|
||||
# gas
|
||||
OCGT: '#e0986c'
|
||||
@ -804,9 +809,15 @@ plotting:
|
||||
gas boiler: '#db6a25'
|
||||
gas boilers: '#db6a25'
|
||||
gas boiler marginal: '#db6a25'
|
||||
residential rural gas boiler: '#d4722e'
|
||||
residential urban decentral gas boiler: '#cb7a36'
|
||||
services rural gas boiler: '#c4813f'
|
||||
services urban decentral gas boiler: '#ba8947'
|
||||
urban central gas boiler: '#b0904f'
|
||||
gas: '#e05b09'
|
||||
fossil gas: '#e05b09'
|
||||
natural gas: '#e05b09'
|
||||
biogas to gas: '#e36311'
|
||||
CCGT: '#a85522'
|
||||
CCGT marginal: '#a85522'
|
||||
allam: '#B98F76'
|
||||
@ -819,6 +830,11 @@ plotting:
|
||||
# oil
|
||||
oil: '#c9c9c9'
|
||||
oil boiler: '#adadad'
|
||||
residential rural oil boiler: '#a9a9a9'
|
||||
services rural oil boiler: '#a5a5a5'
|
||||
residential urban decentral oil boiler: '#a1a1a1'
|
||||
urban central oil boiler: '#9d9d9d'
|
||||
services urban decentral oil boiler: '#999999'
|
||||
agriculture machinery oil: '#949494'
|
||||
shipping oil: "#808080"
|
||||
land transport oil: '#afafaf'
|
||||
@ -844,13 +860,20 @@ plotting:
|
||||
solid biomass for industry CC: '#47411c'
|
||||
solid biomass for industry co2 from atmosphere: '#736412'
|
||||
solid biomass for industry co2 to stored: '#47411c'
|
||||
urban central solid biomass CHP: '#9d9042'
|
||||
urban central solid biomass CHP CC: '#6c5d28'
|
||||
biomass boiler: '#8A9A5B'
|
||||
residential rural biomass boiler: '#a1a066'
|
||||
residential urban decentral biomass boiler: '#b0b87b'
|
||||
services rural biomass boiler: '#c6cf98'
|
||||
services urban decentral biomass boiler: '#dde5b5'
|
||||
biomass to liquid: '#32CD32'
|
||||
BioSNG: '#123456'
|
||||
# power transmission
|
||||
lines: '#6c9459'
|
||||
transmission lines: '#6c9459'
|
||||
electricity distribution grid: '#97ad8c'
|
||||
low voltage: '#97ad8c'
|
||||
# electricity demand
|
||||
Electric load: '#110d63'
|
||||
electric demand: '#110d63'
|
||||
@ -861,24 +884,48 @@ plotting:
|
||||
# battery + EVs
|
||||
battery: '#ace37f'
|
||||
battery storage: '#ace37f'
|
||||
battery charger: '#88a75b'
|
||||
battery discharger: '#5d4e29'
|
||||
home battery: '#80c944'
|
||||
home battery storage: '#80c944'
|
||||
home battery charger: '#5e8032'
|
||||
home battery discharger: '#3c5221'
|
||||
BEV charger: '#baf238'
|
||||
V2G: '#e5ffa8'
|
||||
land transport EV: '#baf238'
|
||||
Li ion: '#baf238'
|
||||
# hot water storage
|
||||
water tanks: '#e69487'
|
||||
residential rural water tanks: '#f7b7a3'
|
||||
services rural water tanks: '#f3afa3'
|
||||
residential urban decentral water tanks: '#f2b2a3'
|
||||
services urban decentral water tanks: '#f1b4a4'
|
||||
urban central water tanks: '#e9977d'
|
||||
hot water storage: '#e69487'
|
||||
hot water charging: '#e69487'
|
||||
hot water discharging: '#e69487'
|
||||
hot water charging: '#e8998b'
|
||||
urban central water tanks charger: '#b57a67'
|
||||
residential rural water tanks charger: '#b4887c'
|
||||
residential urban decentral water tanks charger: '#b39995'
|
||||
services rural water tanks charger: '#b3abb0'
|
||||
services urban decentral water tanks charger: '#b3becc'
|
||||
hot water discharging: '#e99c8e'
|
||||
urban central water tanks discharger: '#b9816e'
|
||||
residential rural water tanks discharger: '#ba9685'
|
||||
residential urban decentral water tanks discharger: '#baac9e'
|
||||
services rural water tanks discharger: '#bbc2b8'
|
||||
services urban decentral water tanks discharger: '#bdd8d3'
|
||||
# heat demand
|
||||
Heat load: '#cc1f1f'
|
||||
heat: '#cc1f1f'
|
||||
heat demand: '#cc1f1f'
|
||||
rural heat: '#ff5c5c'
|
||||
residential rural heat: '#ff7c7c'
|
||||
services rural heat: '#ff9c9c'
|
||||
central heat: '#cc1f1f'
|
||||
urban central heat: '#d15959'
|
||||
decentral heat: '#750606'
|
||||
residential urban decentral heat: '#a33c3c'
|
||||
services urban decentral heat: '#cc1f1f'
|
||||
low-temperature heat for industry: '#8f2727'
|
||||
process heat: '#ff0000'
|
||||
agriculture heat: '#d9a5a5'
|
||||
@ -886,14 +933,26 @@ plotting:
|
||||
heat pumps: '#2fb537'
|
||||
heat pump: '#2fb537'
|
||||
air heat pump: '#36eb41'
|
||||
residential urban decentral air heat pump: '#48f74f'
|
||||
services urban decentral air heat pump: '#5af95d'
|
||||
urban central air heat pump: '#6cfb6b'
|
||||
ground heat pump: '#2fb537'
|
||||
residential rural ground heat pump: '#48f74f'
|
||||
services rural ground heat pump: '#5af95d'
|
||||
Ambient: '#98eb9d'
|
||||
CHP: '#8a5751'
|
||||
urban central gas CHP: '#8d5e56'
|
||||
CHP CC: '#634643'
|
||||
urban central gas CHP CC: '#6e4e4c'
|
||||
CHP heat: '#8a5751'
|
||||
CHP electric: '#8a5751'
|
||||
district heating: '#e8beac'
|
||||
resistive heater: '#d8f9b8'
|
||||
residential rural resistive heater: '#bef5b5'
|
||||
residential urban decentral resistive heater: '#b2f1a9'
|
||||
services rural resistive heater: '#a5ed9d'
|
||||
services urban decentral resistive heater: '#98e991'
|
||||
urban central resistive heater: '#8cdf85'
|
||||
retrofitting: '#8487e8'
|
||||
building retrofitting: '#8487e8'
|
||||
# hydrogen
|
||||
@ -905,13 +964,16 @@ plotting:
|
||||
SMR CC: '#4f1745'
|
||||
H2 liquefaction: '#d647bd'
|
||||
hydrogen storage: '#bf13a0'
|
||||
H2 Store: '#bf13a0'
|
||||
H2 storage: '#bf13a0'
|
||||
land transport fuel cell: '#6b3161'
|
||||
H2 pipeline: '#f081dc'
|
||||
H2 pipeline retrofitted: '#ba99b5'
|
||||
H2 Fuel Cell: '#c251ae'
|
||||
H2 fuel cell: '#c251ae'
|
||||
H2 turbine: '#991f83'
|
||||
H2 Electrolysis: '#ff29d9'
|
||||
H2 electrolysis: '#ff29d9'
|
||||
# ammonia
|
||||
NH3: '#46caf0'
|
||||
ammonia: '#46caf0'
|
||||
@ -960,9 +1022,11 @@ plotting:
|
||||
waste: '#e3d37d'
|
||||
other: '#000000'
|
||||
geothermal: '#ba91b1'
|
||||
AC: "#70af1d"
|
||||
AC-AC: "#70af1d"
|
||||
AC line: "#70af1d"
|
||||
links: "#8a1caf"
|
||||
HVDC links: "#8a1caf"
|
||||
DC: "#8a1caf"
|
||||
DC-DC: "#8a1caf"
|
||||
DC link: "#8a1caf"
|
||||
|
@ -16,6 +16,8 @@ Upcoming Release
|
||||
|
||||
* Bugfix: Correct typo in the CPLEX solver configuration in ``config.default.yaml``.
|
||||
|
||||
* Bugfix: Error in ``add_electricity`` where carriers were added multiple times to the network, resulting in a non-unique carriers error.
|
||||
|
||||
* Renamed script file from PyPSA-EUR ``build_load_data`` to ``build_electricity_demand`` and ``retrieve_load_data`` to ``retrieve_electricity_demand``.
|
||||
|
||||
* Fix docs readthedocs built
|
||||
@ -24,12 +26,17 @@ Upcoming Release
|
||||
hydrogen fuel cell. Add switches for both re-electrification options under
|
||||
``sector: hydrogen_turbine:`` and ``sector: hydrogen_fuel_cell:``.
|
||||
|
||||
* A new function named ``sanitize_carrier`` ensures that all unique carrier names are present in the network's carriers attribute, and adds nice names and colors for each carrier according to the provided configuration dictionary.
|
||||
|
||||
* Additional tech_color are added to include previously unlisted carriers.
|
||||
|
||||
* Remove ``vresutils`` dependency.
|
||||
|
||||
* Add option to include a piecewise linear approximation of transmission losses,
|
||||
e.g. by setting ``solving: options: transmission_losses: 2`` for an
|
||||
approximation with two tangents.
|
||||
|
||||
|
||||
PyPSA-Eur 0.8.0 (18th March 2023)
|
||||
=================================
|
||||
|
||||
|
@ -59,6 +59,9 @@ rule build_powerplants:
|
||||
|
||||
|
||||
rule base_network:
|
||||
params:
|
||||
countries=config["countries"],
|
||||
snapshots=config["snapshots"],
|
||||
input:
|
||||
eg_buses="data/entsoegridkit/buses.csv",
|
||||
eg_lines="data/entsoegridkit/lines.csv",
|
||||
|
@ -19,8 +19,6 @@ if config["enable"].get("retrieve_databundle", True):
|
||||
datafiles.extend(["natura/Natura2000_end2015.shp", "GEBCO_2014_2D.nc"])
|
||||
|
||||
rule retrieve_databundle:
|
||||
params:
|
||||
tutorial=config["tutorial"],
|
||||
output:
|
||||
expand("data/bundle/{file}", file=datafiles),
|
||||
log:
|
||||
|
@ -283,7 +283,7 @@ def get_aggregation_strategies(aggregation_strategies):
|
||||
# when custom values are specified in the config.
|
||||
|
||||
import numpy as np
|
||||
from pypsa.networkclustering import _make_consense
|
||||
from pypsa.clustering.spatial import _make_consense
|
||||
|
||||
bus_strategies = dict(country=_make_consense("Bus", "country"))
|
||||
bus_strategies.update(aggregation_strategies.get("buses", {}))
|
||||
|
@ -121,18 +121,68 @@ def calculate_annuity(n, r):
|
||||
return 1 / n
|
||||
|
||||
|
||||
def _add_missing_carriers_from_costs(n, costs, carriers):
|
||||
missing_carriers = pd.Index(carriers).difference(n.carriers.index)
|
||||
if missing_carriers.empty:
|
||||
return
|
||||
def add_missing_carriers(n, carriers):
|
||||
"""
|
||||
Function to add missing carriers to the network without raising errors.
|
||||
"""
|
||||
missing_carriers = set(carriers) - set(n.carriers.index)
|
||||
if len(missing_carriers) > 0:
|
||||
n.madd("Carrier", missing_carriers)
|
||||
|
||||
emissions_cols = (
|
||||
costs.columns.to_series().loc[lambda s: s.str.endswith("_emissions")].values
|
||||
|
||||
def sanitize_carriers(n, config):
|
||||
"""
|
||||
Sanitize the carrier information in a PyPSA Network object.
|
||||
|
||||
The function ensures that all unique carrier names are present in the network's
|
||||
carriers attribute, and adds nice names and colors for each carrier according
|
||||
to the provided configuration dictionary.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
n : pypsa.Network
|
||||
A PyPSA Network object that represents an electrical power system.
|
||||
config : dict
|
||||
A dictionary containing configuration information, specifically the
|
||||
"plotting" key with "nice_names" and "tech_colors" keys for carriers.
|
||||
|
||||
Returns
|
||||
-------
|
||||
None
|
||||
The function modifies the 'n' PyPSA Network object in-place, updating the
|
||||
carriers attribute with nice names and colors.
|
||||
|
||||
Warnings
|
||||
--------
|
||||
Raises a warning if any carrier's "tech_colors" are not defined in the config dictionary.
|
||||
"""
|
||||
|
||||
for c in n.iterate_components():
|
||||
if "carrier" in c.df:
|
||||
add_missing_carriers(n, c.df)
|
||||
|
||||
carrier_i = n.carriers.index
|
||||
nice_names = (
|
||||
pd.Series(config["plotting"]["nice_names"])
|
||||
.reindex(carrier_i)
|
||||
.fillna(carrier_i.to_series().str.title())
|
||||
)
|
||||
suptechs = missing_carriers.str.split("-").str[0]
|
||||
emissions = costs.loc[suptechs, emissions_cols].fillna(0.0)
|
||||
emissions.index = missing_carriers
|
||||
n.import_components_from_dataframe(emissions, "Carrier")
|
||||
n.carriers["nice_name"] = n.carriers.nice_name.where(
|
||||
n.carriers.nice_name != "", nice_names
|
||||
)
|
||||
colors = pd.Series(config["plotting"]["tech_colors"]).reindex(carrier_i)
|
||||
if colors.isna().any():
|
||||
missing_i = list(colors.index[colors.isna()])
|
||||
logger.warning(f"tech_colors for carriers {missing_i} not defined in config.")
|
||||
n.carriers["color"] = n.carriers.color.where(n.carriers.color != "", colors)
|
||||
|
||||
|
||||
def add_co2_emissions(n, costs, carriers):
|
||||
"""
|
||||
Add CO2 emissions to the network's carriers attribute.
|
||||
"""
|
||||
suptechs = n.carriers.loc[carriers].index.str.split("-").str[0]
|
||||
n.carriers.loc[carriers, "co2_emissions"] = costs.co2_emissions[suptechs].values
|
||||
|
||||
|
||||
def load_costs(tech_costs, config, max_hours, Nyears=1.0):
|
||||
@ -307,57 +357,56 @@ def update_transmission_costs(n, costs, length_factor=1.0):
|
||||
|
||||
|
||||
def attach_wind_and_solar(
|
||||
n, costs, input_profiles, technologies, extendable_carriers, line_length_factor=1
|
||||
n, costs, input_profiles, carriers, extendable_carriers, line_length_factor=1
|
||||
):
|
||||
# TODO: rename tech -> carrier, technologies -> carriers
|
||||
_add_missing_carriers_from_costs(n, costs, technologies)
|
||||
add_missing_carriers(n, carriers)
|
||||
|
||||
for tech in technologies:
|
||||
if tech == "hydro":
|
||||
for car in carriers:
|
||||
if car == "hydro":
|
||||
continue
|
||||
|
||||
with xr.open_dataset(getattr(input_profiles, "profile_" + tech)) as ds:
|
||||
with xr.open_dataset(getattr(input_profiles, "profile_" + car)) as ds:
|
||||
if ds.indexes["bus"].empty:
|
||||
continue
|
||||
|
||||
suptech = tech.split("-", 2)[0]
|
||||
if suptech == "offwind":
|
||||
supcar = car.split("-", 2)[0]
|
||||
if supcar == "offwind":
|
||||
underwater_fraction = ds["underwater_fraction"].to_pandas()
|
||||
connection_cost = (
|
||||
line_length_factor
|
||||
* ds["average_distance"].to_pandas()
|
||||
* (
|
||||
underwater_fraction
|
||||
* costs.at[tech + "-connection-submarine", "capital_cost"]
|
||||
* costs.at[car + "-connection-submarine", "capital_cost"]
|
||||
+ (1.0 - underwater_fraction)
|
||||
* costs.at[tech + "-connection-underground", "capital_cost"]
|
||||
* costs.at[car + "-connection-underground", "capital_cost"]
|
||||
)
|
||||
)
|
||||
capital_cost = (
|
||||
costs.at["offwind", "capital_cost"]
|
||||
+ costs.at[tech + "-station", "capital_cost"]
|
||||
+ costs.at[car + "-station", "capital_cost"]
|
||||
+ connection_cost
|
||||
)
|
||||
logger.info(
|
||||
"Added connection cost of {:0.0f}-{:0.0f} Eur/MW/a to {}".format(
|
||||
connection_cost.min(), connection_cost.max(), tech
|
||||
connection_cost.min(), connection_cost.max(), car
|
||||
)
|
||||
)
|
||||
else:
|
||||
capital_cost = costs.at[tech, "capital_cost"]
|
||||
capital_cost = costs.at[car, "capital_cost"]
|
||||
|
||||
n.madd(
|
||||
"Generator",
|
||||
ds.indexes["bus"],
|
||||
" " + tech,
|
||||
" " + car,
|
||||
bus=ds.indexes["bus"],
|
||||
carrier=tech,
|
||||
p_nom_extendable=tech in extendable_carriers["Generator"],
|
||||
carrier=car,
|
||||
p_nom_extendable=car in extendable_carriers["Generator"],
|
||||
p_nom_max=ds["p_nom_max"].to_pandas(),
|
||||
weight=ds["weight"].to_pandas(),
|
||||
marginal_cost=costs.at[suptech, "marginal_cost"],
|
||||
marginal_cost=costs.at[supcar, "marginal_cost"],
|
||||
capital_cost=capital_cost,
|
||||
efficiency=costs.at[suptech, "efficiency"],
|
||||
efficiency=costs.at[supcar, "efficiency"],
|
||||
p_max_pu=ds["profile"].transpose("time", "bus").to_pandas(),
|
||||
)
|
||||
|
||||
@ -371,8 +420,9 @@ def attach_conventional_generators(
|
||||
conventional_params,
|
||||
conventional_inputs,
|
||||
):
|
||||
carriers = set(conventional_carriers) | set(extendable_carriers["Generator"])
|
||||
_add_missing_carriers_from_costs(n, costs, carriers)
|
||||
carriers = list(set(conventional_carriers) | set(extendable_carriers["Generator"]))
|
||||
add_missing_carriers(n, carriers)
|
||||
add_co2_emissions(n, costs, carriers)
|
||||
|
||||
ppl = (
|
||||
ppl.query("carrier in @carriers")
|
||||
@ -428,7 +478,8 @@ def attach_conventional_generators(
|
||||
|
||||
|
||||
def attach_hydro(n, costs, ppl, profile_hydro, hydro_capacities, carriers, **params):
|
||||
_add_missing_carriers_from_costs(n, costs, carriers)
|
||||
add_missing_carriers(n, carriers)
|
||||
add_co2_emissions(n, costs, carriers)
|
||||
|
||||
ppl = (
|
||||
ppl.query('carrier == "hydro"')
|
||||
@ -560,7 +611,8 @@ def attach_extendable_generators(n, costs, ppl, carriers):
|
||||
logger.warning(
|
||||
"The function `attach_extendable_generators` is deprecated in v0.5.0."
|
||||
)
|
||||
_add_missing_carriers_from_costs(n, costs, carriers)
|
||||
add_missing_carriers(n, carriers)
|
||||
add_co2_emissions(n, costs, carriers)
|
||||
|
||||
for tech in carriers:
|
||||
if tech.startswith("OCGT"):
|
||||
@ -642,7 +694,7 @@ def attach_OPSD_renewables(n, tech_map):
|
||||
buses = n.buses.loc[gens.bus.unique()]
|
||||
gens_per_bus = gens.groupby("bus").p_nom.count()
|
||||
|
||||
caps = map_country_bus(df.query("Fueltype == @fueltype"), buses)
|
||||
caps = map_country_bus(df.query("Fueltype == @fueltype and lat == lat"), buses)
|
||||
caps = caps.groupby(["bus"]).Capacity.sum()
|
||||
caps = caps / gens_per_bus.reindex(caps.index, fill_value=1)
|
||||
|
||||
@ -715,21 +767,6 @@ def attach_line_rating(
|
||||
n.lines_t.s_max_pu *= s_max_pu
|
||||
|
||||
|
||||
def add_nice_carrier_names(n, config):
|
||||
carrier_i = n.carriers.index
|
||||
nice_names = (
|
||||
pd.Series(config["plotting"]["nice_names"])
|
||||
.reindex(carrier_i)
|
||||
.fillna(carrier_i.to_series().str.title())
|
||||
)
|
||||
n.carriers["nice_name"] = nice_names
|
||||
colors = pd.Series(config["plotting"]["tech_colors"]).reindex(carrier_i)
|
||||
if colors.isna().any():
|
||||
missing_i = list(colors.index[colors.isna()])
|
||||
logger.warning(f"tech_colors for carriers {missing_i} not defined in config.")
|
||||
n.carriers["color"] = colors
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if "snakemake" not in globals():
|
||||
from _helpers import mock_snakemake
|
||||
@ -829,7 +866,8 @@ if __name__ == "__main__":
|
||||
max_line_rating,
|
||||
)
|
||||
|
||||
add_nice_carrier_names(n, snakemake.config)
|
||||
sanitize_carriers(n, snakemake.config)
|
||||
|
||||
|
||||
n.meta = snakemake.config
|
||||
n.export_to_netcdf(snakemake.output[0])
|
||||
|
@ -22,6 +22,7 @@ import numpy as np
|
||||
import pypsa
|
||||
import xarray as xr
|
||||
from _helpers import override_component_attrs, update_config_with_sector_opts
|
||||
from add_electricity import sanitize_carriers
|
||||
from prepare_sector_network import cluster_heat_buses, define_spatial, prepare_costs
|
||||
|
||||
cc = coco.CountryConverter()
|
||||
@ -665,4 +666,6 @@ if __name__ == "__main__":
|
||||
|
||||
n.meta = dict(snakemake.config, **dict(wildcards=dict(snakemake.wildcards)))
|
||||
|
||||
sanitize_carriers(n, snakemake.config)
|
||||
|
||||
n.export_to_netcdf(snakemake.output[0])
|
||||
|
@ -56,11 +56,7 @@ import numpy as np
|
||||
import pandas as pd
|
||||
import pypsa
|
||||
from _helpers import configure_logging
|
||||
from add_electricity import (
|
||||
_add_missing_carriers_from_costs,
|
||||
add_nice_carrier_names,
|
||||
load_costs,
|
||||
)
|
||||
from add_electricity import load_costs, sanitize_carriers
|
||||
|
||||
idx = pd.IndexSlice
|
||||
|
||||
@ -70,7 +66,7 @@ logger = logging.getLogger(__name__)
|
||||
def attach_storageunits(n, costs, extendable_carriers, max_hours):
|
||||
carriers = extendable_carriers["StorageUnit"]
|
||||
|
||||
_add_missing_carriers_from_costs(n, costs, carriers)
|
||||
n.madd("Carrier", carriers)
|
||||
|
||||
buses_i = n.buses.index
|
||||
|
||||
@ -101,7 +97,7 @@ def attach_storageunits(n, costs, extendable_carriers, max_hours):
|
||||
def attach_stores(n, costs, extendable_carriers):
|
||||
carriers = extendable_carriers["Store"]
|
||||
|
||||
_add_missing_carriers_from_costs(n, costs, carriers)
|
||||
n.madd("Carrier", carriers)
|
||||
|
||||
buses_i = n.buses.index
|
||||
bus_sub_dict = {k: n.buses[k].values for k in ["x", "y", "country"]}
|
||||
@ -161,6 +157,8 @@ def attach_stores(n, costs, extendable_carriers):
|
||||
marginal_cost=costs.at["battery", "marginal_cost"],
|
||||
)
|
||||
|
||||
n.madd("Carrier", ["battery charger", "battery discharger"])
|
||||
|
||||
n.madd(
|
||||
"Link",
|
||||
b_buses_i + " charger",
|
||||
@ -211,6 +209,8 @@ def attach_hydrogen_pipelines(n, costs, extendable_carriers):
|
||||
h2_links.index = h2_links.apply(lambda c: f"H2 pipeline {c.bus0}-{c.bus1}", axis=1)
|
||||
|
||||
# add pipelines
|
||||
n.add("Carrier", "H2 pipeline")
|
||||
|
||||
n.madd(
|
||||
"Link",
|
||||
h2_links.index,
|
||||
@ -245,7 +245,7 @@ if __name__ == "__main__":
|
||||
attach_stores(n, costs, extendable_carriers)
|
||||
attach_hydrogen_pipelines(n, costs, extendable_carriers)
|
||||
|
||||
add_nice_carrier_names(n, snakemake.config)
|
||||
sanitize_carriers(n, snakemake.config)
|
||||
|
||||
n.meta = dict(snakemake.config, **dict(wildcards=dict(snakemake.wildcards)))
|
||||
n.export_to_netcdf(snakemake.output[0])
|
||||
|
@ -714,6 +714,7 @@ def base_network(
|
||||
n.name = "PyPSA-Eur"
|
||||
|
||||
n.set_snapshots(pd.date_range(freq="h", **config["snapshots"]))
|
||||
n.madd("Carrier", ["AC", "DC"])
|
||||
|
||||
n.import_components_from_dataframe(buses, "Bus")
|
||||
n.import_components_from_dataframe(lines, "Line")
|
||||
|
@ -149,6 +149,7 @@ if __name__ == "__main__":
|
||||
logging.warning(f"No powerplants known in: {', '.join(countries_wo_ppl)}")
|
||||
|
||||
substations = n.buses.query("substation_lv")
|
||||
ppl = ppl.dropna(subset=["lat", "lon"])
|
||||
ppl = map_country_bus(ppl, substations)
|
||||
|
||||
bus_null_b = ppl["bus"].isnull()
|
||||
|
@ -188,7 +188,7 @@ import geopandas as gpd
|
||||
import numpy as np
|
||||
import xarray as xr
|
||||
from _helpers import configure_logging
|
||||
from dask.distributed import Client, LocalCluster
|
||||
from dask.distributed import Client
|
||||
from pypsa.geo import haversine
|
||||
from shapely.geometry import LineString
|
||||
|
||||
@ -204,6 +204,7 @@ if __name__ == "__main__":
|
||||
|
||||
nprocesses = int(snakemake.threads)
|
||||
noprogress = snakemake.config["run"].get("disable_progressbar", True)
|
||||
noprogress = noprogress or not snakemake.config["atlite"]["show_progress"]
|
||||
params = snakemake.params.renewable[snakemake.wildcards.technology]
|
||||
resource = params["resource"] # pv panel params / wind turbine params
|
||||
correction_factor = params.get("correction_factor", 1.0)
|
||||
@ -216,8 +217,10 @@ if __name__ == "__main__":
|
||||
if correction_factor != 1.0:
|
||||
logger.info(f"correction_factor is set as {correction_factor}")
|
||||
|
||||
cluster = LocalCluster(n_workers=nprocesses, threads_per_worker=1)
|
||||
client = Client(cluster, asynchronous=True)
|
||||
if nprocesses > 1:
|
||||
client = Client(n_workers=nprocesses, threads_per_worker=1)
|
||||
else:
|
||||
client = None
|
||||
|
||||
cutout = atlite.Cutout(snakemake.input.cutout)
|
||||
regions = gpd.read_file(snakemake.input.regions)
|
||||
@ -289,7 +292,8 @@ if __name__ == "__main__":
|
||||
|
||||
potential = capacity_per_sqkm * availability.sum("bus") * area
|
||||
func = getattr(cutout, resource.pop("method"))
|
||||
resource["dask_kwargs"] = {"scheduler": client}
|
||||
if client is not None:
|
||||
resource["dask_kwargs"] = {"scheduler": client}
|
||||
capacity_factor = correction_factor * func(capacity_factor=True, **resource)
|
||||
layout = capacity_factor * area * capacity_per_sqkm
|
||||
profile, capacities = func(
|
||||
|
@ -89,7 +89,7 @@ Description
|
||||
**Is it possible to run the model without the** ``simplify_network`` **rule?**
|
||||
|
||||
No, the network clustering methods in the PyPSA module
|
||||
`pypsa.networkclustering <https://github.com/PyPSA/PyPSA/blob/master/pypsa/networkclustering.py>`_
|
||||
`pypsa.clustering.spatial <https://github.com/PyPSA/PyPSA/blob/master/pypsa/clustering/spatial.py>`_
|
||||
do not work reliably with multiple voltage levels and transformers.
|
||||
|
||||
.. tip::
|
||||
@ -134,7 +134,7 @@ import pyomo.environ as po
|
||||
import pypsa
|
||||
import seaborn as sns
|
||||
from _helpers import configure_logging, get_aggregation_strategies, update_p_nom_max
|
||||
from pypsa.networkclustering import (
|
||||
from pypsa.clustering.spatial import (
|
||||
busmap_by_greedy_modularity,
|
||||
busmap_by_hac,
|
||||
busmap_by_kmeans,
|
||||
@ -484,7 +484,7 @@ if __name__ == "__main__":
|
||||
# Fast-path if no clustering is necessary
|
||||
busmap = n.buses.index.to_series()
|
||||
linemap = n.lines.index.to_series()
|
||||
clustering = pypsa.networkclustering.Clustering(
|
||||
clustering = pypsa.clustering.spatial.Clustering(
|
||||
n, busmap, linemap, linemap, pd.Series(dtype="O")
|
||||
)
|
||||
else:
|
||||
|
@ -298,6 +298,8 @@ if __name__ == "__main__":
|
||||
break
|
||||
|
||||
for o in opts:
|
||||
if "+" not in o:
|
||||
continue
|
||||
oo = o.split("+")
|
||||
suptechs = map(lambda c: c.split("-", 2)[0], n.carriers.index)
|
||||
if oo[0].startswith(tuple(suptechs)):
|
||||
|
@ -22,7 +22,7 @@ from _helpers import (
|
||||
override_component_attrs,
|
||||
update_config_with_sector_opts,
|
||||
)
|
||||
from add_electricity import calculate_annuity
|
||||
from add_electricity import calculate_annuity, sanitize_carriers
|
||||
from build_energy_totals import build_co2_totals, build_eea_co2, build_eurostat_co2
|
||||
from networkx.algorithms import complement
|
||||
from networkx.algorithms.connectivity.edge_augmentation import k_edge_augmentation
|
||||
@ -3425,4 +3425,6 @@ if __name__ == "__main__":
|
||||
|
||||
n.meta = dict(snakemake.config, **dict(wildcards=dict(snakemake.wildcards)))
|
||||
|
||||
sanitize_carriers(n, snakemake.config)
|
||||
|
||||
n.export_to_netcdf(snakemake.output[0])
|
||||
|
@ -53,7 +53,7 @@ if __name__ == "__main__":
|
||||
snakemake
|
||||
) # TODO Make logging compatible with progressbar (see PR #102)
|
||||
|
||||
if snakemake.params.tutorial:
|
||||
if snakemake.config["tutorial"]:
|
||||
url = "https://zenodo.org/record/3517921/files/pypsa-eur-tutorial-data-bundle.tar.xz"
|
||||
else:
|
||||
url = "https://zenodo.org/record/3517935/files/pypsa-eur-data-bundle.tar.xz"
|
||||
|
@ -95,13 +95,13 @@ import scipy as sp
|
||||
from _helpers import configure_logging, get_aggregation_strategies, update_p_nom_max
|
||||
from add_electricity import load_costs
|
||||
from cluster_network import cluster_regions, clustering_for_n_clusters
|
||||
from pypsa.io import import_components_from_dataframe, import_series_from_dataframe
|
||||
from pypsa.networkclustering import (
|
||||
from pypsa.clustering.spatial import (
|
||||
aggregategenerators,
|
||||
aggregateoneport,
|
||||
busmap_by_stubs,
|
||||
get_clustering_from_busmap,
|
||||
)
|
||||
from pypsa.io import import_components_from_dataframe, import_series_from_dataframe
|
||||
from scipy.sparse.csgraph import connected_components, dijkstra
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
@ -235,8 +235,7 @@ def add_CCL_constraints(n, config):
|
||||
p_nom = n.model["Generator-p_nom"]
|
||||
|
||||
gens = n.generators.query("p_nom_extendable").rename_axis(index="Generator-ext")
|
||||
grouper = [gens.bus.map(n.buses.country), gens.carrier]
|
||||
grouper = xr.DataArray(pd.MultiIndex.from_arrays(grouper), dims=["Generator-ext"])
|
||||
grouper = pd.concat([gens.bus.map(n.buses.country), gens.carrier])
|
||||
lhs = p_nom.groupby(grouper).sum().rename(bus="country")
|
||||
|
||||
minimum = xr.DataArray(agg_p_nom_minmax["min"].dropna()).rename(dim_0="group")
|
||||
|
Loading…
Reference in New Issue
Block a user