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

Small fixes #167

Merged
merged 10 commits into from
Sep 27, 2021
5 changes: 3 additions & 2 deletions config.default.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ electricity:

# regulate what components with which carriers are kept from PyPSA-Eur;
# some technologies are removed because they are implemented differently
# (e.g. battery or H2 storage) or have different year-dependent costs
# (e.g. battery or H2 storage) or have different year-dependent costs
# in PyPSA-Eur-Sec
pypsa_eur:
Bus:
Expand Down Expand Up @@ -335,7 +335,7 @@ solving:

plotting:
map:
boundaries: [-11, 30, 34, 71]
boundaries: [-11, 30, 34, 71]
color_geomap:
ocean: white
land: whitesmoke
Expand Down Expand Up @@ -420,6 +420,7 @@ plotting:
lines: k
transmission lines: k
H2: m
H2 liquefaction: m
hydrogen storage: m
battery: slategray
battery storage: slategray
Expand Down
19 changes: 10 additions & 9 deletions scripts/add_existing_baseyear.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def add_build_year_to_new_assets(n, baseyear):
# Give assets with lifetimes and no build year the build year baseyear
for c in n.iterate_components(["Link", "Generator", "Store"]):

assets = c.df.index[~c.df.lifetime.isna() & c.df.build_year.isna()]
assets = c.df.index[~c.df.lifetime.isna() & c.df.build_year==0]
c.df.loc[assets, "build_year"] = baseyear

# add -baseyear to name
Expand Down Expand Up @@ -60,7 +60,7 @@ def add_existing_renewables(df_agg):
}

for tech in ['solar', 'onwind', 'offwind']:

carrier = carriers[tech]

df = pd.read_csv(snakemake.input[f"existing_{tech}"], index_col=0).fillna(0.)
Expand Down Expand Up @@ -112,9 +112,9 @@ def add_power_capacities_installed_before_baseyear(n, grouping_years, costs, bas
Parameters
----------
n : pypsa.Network
grouping_years :
grouping_years :
intervals to group existing capacities
costs :
costs :
to read lifetime to estimate YearDecomissioning
baseyear : int
"""
Expand Down Expand Up @@ -209,7 +209,7 @@ def add_power_capacities_installed_before_baseyear(n, grouping_years, costs, bas
build_year=grouping_year,
lifetime=costs.at[generator, 'lifetime']
)

else:

n.madd("Link",
Expand Down Expand Up @@ -268,7 +268,7 @@ def add_heating_capacities_installed_before_baseyear(n, baseyear, grouping_years
df.fillna(0., inplace=True)

# convert GW to MW
df *= 1e3
df *= 1e3

cc = pd.read_csv(snakemake.input.country_codes, index_col=0)

Expand Down Expand Up @@ -327,7 +327,7 @@ def add_heating_capacities_installed_before_baseyear(n, baseyear, grouping_years
efficiency = cop[heat_pump_type][nodes[name]]
else:
efficiency = costs.at[costs_name, 'efficiency']

for i, grouping_year in enumerate(grouping_years):

if int(grouping_year) + default_lifetime <= int(baseyear):
Expand Down Expand Up @@ -378,7 +378,7 @@ def add_heating_capacities_installed_before_baseyear(n, baseyear, grouping_years
build_year=int(grouping_year),
lifetime=costs.at[name_type + ' gas boiler', 'lifetime']
)

n.madd("Link",
nodes[name],
suffix=f" {name} oil boiler-{grouping_year}",
Expand Down Expand Up @@ -410,7 +410,8 @@ def add_heating_capacities_installed_before_baseyear(n, baseyear, grouping_years
simpl='',
clusters=45,
lv=1.0,
sector_opts='Co2L0-168H-T-H-B-I-solar3-dist1',
opts='',
sector_opts='Co2L0-168H-T-H-B-I-solar+p3-dist1',
planning_horizons=2020,
)

Expand Down
11 changes: 6 additions & 5 deletions scripts/plot_network.py
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ def plot_h2_map(network):
title='Electrolyzer capacity',
handler_map=make_handler_map_to_scale_circles_as_in(ax)
)

ax.add_artist(l2)

handles = []
Expand Down Expand Up @@ -523,10 +523,11 @@ def plot_series(network, carrier="AC", name="test"):
snakemake = mock_snakemake(
'plot_network',
simpl='',
clusters=48,
lv=1.0,
sector_opts='Co2L0-168H-T-H-B-I-solar3-dist1',
planning_horizons=2050,
clusters=45,
lv=1.5,
opts='',
sector_opts='Co2L0-168H-T-H-B-I-solar+p3-dist1',
planning_horizons=2030,
)

overrides = override_component_attrs(snakemake.input.overrides)
Expand Down
58 changes: 31 additions & 27 deletions scripts/prepare_sector_network.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ def co2_emissions_year(countries, opts, year):
co2_emissions = co2_totals.loc[countries, sectors].sum().sum()

# convert MtCO2 to GtCO2
co2_emissions *= 0.001
co2_emissions *= 0.001

return co2_emissions

Expand All @@ -102,14 +102,14 @@ def build_carbon_budget(o, fn):

#emissions at the beginning of the path (last year available 2018)
e_0 = co2_emissions_year(countries, opts, year=2018)

planning_horizons = snakemake.config['scenario']['planning_horizons']
t_0 = planning_horizons[0]

if "be" in o:

# final year in the path
t_f = t_0 + (2 * carbon_budget / e_0).round(0)
t_f = t_0 + (2 * carbon_budget / e_0).round(0)

def beta_decay(t):
cdf_term = (t - t_0) / (t_f - t_0)
Expand Down Expand Up @@ -270,6 +270,9 @@ def patch_electricity_network(n):
update_wind_solar_costs(n, costs)
n.loads["carrier"] = "electricity"
n.buses["location"] = n.buses.index
# remove trailing white space of load index until new PyPSA version after v0.18.
n.loads.rename(lambda x: x.strip(), inplace=True)
n.loads_t.p_set.rename(lambda x: x.strip(), axis=1, inplace=True)


def add_co2_tracking(n, options):
Expand Down Expand Up @@ -768,7 +771,7 @@ def insert_electricity_distribution_grid(n, costs):
capital_cost=costs.at['solar-rooftop', 'fixed'],
efficiency=n.generators.loc[solar, 'efficiency'],
p_max_pu=n.generators_t.p_max_pu[solar],
lifetime=costs.at['solar-rooftop', 'lifetime']
lifetime=costs.at['solar-rooftop', 'lifetime']
)

n.add("Carrier", "home battery")
Expand Down Expand Up @@ -816,7 +819,7 @@ def insert_gas_distribution_costs(n, costs):
# TODO options?

f_costs = options['gas_distribution_grid_cost_factor']

print("Inserting gas distribution grid with investment cost factor of", f_costs)

capital_cost = costs.loc['electricity distribution grid']["fixed"] * f_costs
Expand All @@ -825,7 +828,7 @@ def insert_gas_distribution_costs(n, costs):
gas_b = n.links.index[n.links.carrier.str.contains("gas boiler") &
(~n.links.carrier.str.contains("urban central"))]
n.links.loc[gas_b, "capital_cost"] += capital_cost

# micro CHPs
mchp = n.links.index[n.links.carrier.str.contains("micro gas")]
n.links.loc[mchp, "capital_cost"] += capital_cost
Expand Down Expand Up @@ -1073,7 +1076,7 @@ def add_land_transport(n, costs):
suffix=" EV battery",
carrier="Li ion"
)

p_set = electric_share * (transport[nodes] + cycling_shift(transport[nodes], 1) + cycling_shift(transport[nodes], 2)) / 3

n.madd("Load",
Expand All @@ -1084,8 +1087,8 @@ def add_land_transport(n, costs):
p_set=p_set
)

p_nom = nodal_transport_data["number cars"] * options.get("bev_charge_rate", 0.011) * electric_share

p_nom = nodal_transport_data["number cars"] * options.get("bev_charge_rate", 0.011) * electric_share

n.madd("Link",
nodes,
Expand Down Expand Up @@ -1117,7 +1120,7 @@ def add_land_transport(n, costs):

if electric_share > 0 and options["bev_dsm"]:

e_nom = nodal_transport_data["number cars"] * options.get("bev_energy", 0.05) * options["bev_availability"] * electric_share
e_nom = nodal_transport_data["number cars"] * options.get("bev_energy", 0.05) * options["bev_availability"] * electric_share

n.madd("Store",
nodes,
Expand Down Expand Up @@ -1197,7 +1200,7 @@ def add_heat(n, costs):
"services urban decentral",
"urban central"
]

for name in heat_systems:

name_type = "central" if name == "urban central" else "decentral"
Expand Down Expand Up @@ -1279,16 +1282,16 @@ def add_heat(n, costs):
p_nom_extendable=True
)


if isinstance(options["tes_tau"], dict):
tes_time_constant_days = options["tes_tau"][name_type]
else:
logger.warning("Deprecated: a future version will require you to specify 'tes_tau' ",
"for 'decentral' and 'central' separately.")
tes_time_constant_days = options["tes_tau"] if name_type == "decentral" else 180.

# conversion from EUR/m^3 to EUR/MWh for 40 K diff and 1.17 kWh/m^3/K
capital_cost = costs.at[name_type + ' water tank storage', 'fixed'] / 0.00117 / 40
capital_cost = costs.at[name_type + ' water tank storage', 'fixed'] / 0.00117 / 40

n.madd("Store",
nodes[name] + f" {name} water tanks",
Expand Down Expand Up @@ -1501,9 +1504,9 @@ def create_nodes_for_heat_sector():
# rural are areas with low heating density and individual heating
# urban are areas with high heating density
# urban can be split into district heating (central) and individual heating (decentral)

sectors = ["residential", "services"]

nodes = {}
for sector in sectors:
nodes[sector + " rural"] = pop_layout.index
Expand All @@ -1514,10 +1517,10 @@ def create_nodes_for_heat_sector():
nodes[sector + " urban decentral"] = pop_layout.index[pop_layout.ct.isin(urban_decentral_ct)]
else:
nodes[sector + " urban decentral"] = pop_layout.index

# for central nodes, residential and services are aggregated
nodes["urban central"] = pop_layout.index.symmetric_difference(nodes["residential urban decentral"])

return nodes


Expand Down Expand Up @@ -1752,17 +1755,17 @@ def add_industry(n, costs):
if shipping_hydrogen_share < 1:

shipping_oil_share = 1 - shipping_hydrogen_share

p_set = shipping_oil_share * nodal_energy_totals.loc[nodes, all_navigation].sum(axis=1) * 1e6 / 8760.

n.madd("Load",
nodes,
suffix=" shipping oil",
bus="EU oil",
carrier="shipping oil",
p_set=p_set
)

co2 = shipping_oil_share * nodal_energy_totals.loc[nodes, all_navigation].sum().sum() * 1e6 / 8760 * costs.at["oil", "CO2 intensity"]

n.add("Load",
Expand All @@ -1781,7 +1784,7 @@ def add_industry(n, costs):
)

if "EU oil Store" not in n.stores.index:

#could correct to e.g. 0.001 EUR/kWh * annuity and O&M
n.add("Store",
"EU oil Store",
Expand Down Expand Up @@ -1948,7 +1951,7 @@ def add_waste_heat(n):


def decentral(n):
"""Removes the electricity transmission system."""
"""Removes the electricity transmission system."""
n.lines.drop(n.lines.index, inplace=True)
n.links.drop(n.links.index[n.links.carrier.isin(["DC", "B2B"])], inplace=True)

Expand Down Expand Up @@ -1981,7 +1984,7 @@ def maybe_adjust_costs_and_potentials(n, opts):
if attr == 'p_nom_max':
comps = {"Generator", "Link", "StorageUnit"}
elif attr == 'e_nom_max':
comps = {"Store"}
comps = {"Store"}
else:
comps = {"Generator", "Link", "StorageUnit", "Store"}
for c in n.iterate_components(comps):
Expand All @@ -2007,10 +2010,11 @@ def limit_individual_line_extension(n, maxext):
snakemake = mock_snakemake(
'prepare_sector_network',
simpl='',
clusters=48,
clusters=45,
lv=1.0,
opts='',
sector_opts='Co2L0-168H-T-H-B-I-solar3-dist1',
planning_horizons=2020,
planning_horizons=2030,
)

logging.basicConfig(level=snakemake.config['logging_level'])
Expand All @@ -2036,7 +2040,7 @@ def limit_individual_line_extension(n, maxext):
patch_electricity_network(n)

if snakemake.config["foresight"] == 'myopic':

add_lifetime_wind_solar(n, costs)

conventional = snakemake.config['existing_capacities']['conventional_carriers']
Expand Down