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

Correct Total System Costs Calculation #40

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
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
211 changes: 192 additions & 19 deletions scripts/pypsa-de/export_ariadne_variables.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import pandas as pd
import pypsa
from numpy import isclose
from pypsa.statistics import get_transmission_carriers

from scripts._helpers import configure_logging, mock_snakemake
from scripts.add_electricity import calculate_annuity
Expand Down Expand Up @@ -106,7 +107,7 @@ def domestic_length_factor(n, carriers, region="DE"):

def _get_fuel_fractions(n, region, fuel):
kwargs = {
"groupby": n.statistics.groupers.get_name_bus_and_carrier,
"groupby": ["name", "bus", "carrier"],
"at_port": True,
"nice_names": False,
}
Expand Down Expand Up @@ -242,7 +243,7 @@ def _get_fuel_fractions(n, region, fuel):

def _get_h2_fossil_fraction(n):
kwargs = {
"groupby": n.statistics.groupers.get_name_bus_and_carrier,
"groupby": ["name", "bus", "carrier"],
"at_port": True,
"nice_names": False,
}
Expand Down Expand Up @@ -561,7 +562,7 @@ def _f(*args, **kwargs):

def _get_capacities(n, region, cap_func, cap_string="Capacity|"):
kwargs = {
"groupby": n.statistics.groupers.get_bus_and_carrier,
"groupby": ["bus", "carrier"],
"at_port": True,
"nice_names": False,
}
Expand Down Expand Up @@ -1118,7 +1119,7 @@ def _get_capacities(n, region, cap_func, cap_string="Capacity|"):

def get_CHP_E_and_H_usage(n, bus_carrier, region, fossil_fraction=1):
kwargs = {
"groupby": n.statistics.groupers.get_name_bus_and_carrier,
"groupby": ["name", "bus", "carrier"],
"nice_names": False,
}

Expand Down Expand Up @@ -1148,7 +1149,7 @@ def get_CHP_E_and_H_usage(n, bus_carrier, region, fossil_fraction=1):

def get_primary_energy(n, region):
kwargs = {
"groupby": n.statistics.groupers.get_name_bus_and_carrier,
"groupby": ["name", "bus", "carrier"],
"nice_names": False,
}

Expand Down Expand Up @@ -1480,7 +1481,7 @@ def get_primary_energy(n, region):

def get_secondary_energy(n, region, _industry_demand):
kwargs = {
"groupby": n.statistics.groupers.get_name_bus_and_carrier,
"groupby": ["name", "bus", "carrier"],
"nice_names": False,
}
var = pd.Series()
Expand Down Expand Up @@ -1922,7 +1923,7 @@ def get_final_energy(
var = pd.Series()

kwargs = {
"groupby": n.statistics.groupers.get_name_bus_and_carrier,
"groupby": ["name", "bus", "carrier"],
"nice_names": False,
}
h2_fossil_fraction = _get_h2_fossil_fraction(n)
Expand Down Expand Up @@ -2607,7 +2608,7 @@ def get_emissions(n, region, _energy_totals, industry_demand):
).sum()

kwargs = {
"groupby": n.statistics.groupers.get_name_bus_and_carrier,
"groupby": ["name", "bus", "carrier"],
"nice_names": False,
}

Expand Down Expand Up @@ -3102,7 +3103,7 @@ def get_nodal_flows(n, bus_carrier, region, query="index == index or index != in
pandas.DataFrame: The nodal flows for the specified bus carrier and region.
"""

groupby = n.statistics.groupers.get_name_bus_and_carrier
groupby = ["name", "bus", "carrier"]

result = (
n.statistics.withdrawal(
Expand Down Expand Up @@ -3136,7 +3137,7 @@ def get_nodal_supply(n, bus_carrier, query="index == index or index != index"):
pandas.DataFrame: The nodal flows for the specified bus carrier and region.
"""

groupby = n.statistics.groupers.get_name_bus_and_carrier
groupby = ["name", "bus", "carrier"]

result = (
n.statistics.supply(
Expand Down Expand Up @@ -3330,7 +3331,7 @@ def get_prices(n, region):
var = pd.Series()

kwargs = {
"groupby": n.statistics.groupers.get_name_bus_and_carrier,
"groupby": ["name", "bus", "carrier"],
"nice_names": False,
}
try:
Expand Down Expand Up @@ -4305,16 +4306,188 @@ def get_policy(n, investment_year):
def get_economy(n, region):
var = pd.Series()

s = n.statistics
g = s.groupers
grouper = g.get_country_and_carrier
system_cost = s.capex(groupby=grouper).add(s.opex(groupby=grouper))
def get_tsc(n, country):
n.statistics.set_parameters(drop_zero=False)
capex = n.statistics.capex(
groupby=pypsa.statistics.groupers["name", "carrier"], nice_names=False
)

# Cost|Total Energy System Cost in billion EUR2020/yr
var["Cost|Total Energy System Cost"] = round(
system_cost.groupby("country").sum()[region] / 1e9, 4
opex = n.statistics.opex(
groupby=pypsa.statistics.groupers["name", "carrier"], nice_names=False
)

# filter inter country transmission lines and links
inter_country_lines = n.lines.bus0.map(n.buses.country) != n.lines.bus1.map(
n.buses.country
)
inter_country_links = n.links.bus0.map(n.buses.country) != n.links.bus1.map(
n.buses.country
)
#
transmission_carriers = get_transmission_carriers(n).get_level_values("carrier")
transmission_lines = n.lines.carrier.isin(transmission_carriers)
transmission_links = n.links.carrier.isin(transmission_carriers)
#
country_transmission_lines = (
(n.lines.bus0.str.contains(country)) & ~(n.lines.bus1.str.contains(country))
) | (
~(n.lines.bus0.str.contains(country)) & (n.lines.bus1.str.contains(country))
)
country_tranmission_links = (
(n.links.bus0.str.contains(country)) & ~(n.links.bus1.str.contains(country))
) | (
~(n.links.bus0.str.contains(country)) & (n.links.bus1.str.contains(country))
)
#
inter_country_transmission_lines = (
inter_country_lines & transmission_lines & country_transmission_lines
)
inter_country_transmission_links = (
inter_country_links & transmission_links & country_tranmission_links
)
inter_country_transmission_lines_i = inter_country_transmission_lines[
inter_country_transmission_lines
].index
inter_country_transmission_links_i = inter_country_transmission_links[
inter_country_transmission_links
].index
inter_country_transmission_i = inter_country_transmission_lines_i.union(
inter_country_transmission_links_i
)

#
tsc = pd.concat([capex, opex], axis=1, keys=["capex", "opex"])
tsc = tsc.reset_index().set_index("name")
tsc.loc[inter_country_transmission_i, ["capex", "opex"]] = (
tsc.loc[inter_country_transmission_i, ["capex", "opex"]] / 2
)
tsc.rename(
index={
index: index + " " + country for index in inter_country_transmission_i
},
inplace=True,
)
# rename inter region links and lines
to_rename_links = n.links[
(n.links.bus0.str.contains(region))
& (n.links.bus1.str.contains(region))
& ~(n.links.index.str.contains(region))
].index
to_rename_lines = n.lines[
(n.lines.bus0.str.contains(region))
& (n.lines.bus1.str.contains(region))
& ~(n.lines.index.str.contains(region))
].index
tsc.rename(
index={index: index + " " + region for index in to_rename_links},
inplace=True,
)
tsc.rename(
index={index: index + " " + region for index in to_rename_lines},
inplace=True,
)

tsc = (
tsc.filter(like=country, axis=0)
.drop("component", axis=1)
.groupby("carrier")
.sum()
)

return tsc

def get_link_opex(n, carriers, region, sw):
# get flow of electricity/hydrogen...
# multiply it with the marginal costs
supplying = n.links[
(n.links.carrier.isin(carriers))
& (n.links.bus0.str.startswith(region))
& (~n.links.bus1.str.startswith(region))
].index

receiving = n.links[
(n.links.carrier.isin(carriers))
& (~n.links.bus0.str.startswith(region))
& (n.links.bus1.str.startswith(region))
].index

trade_out = 0
for index in supplying:
# price of energy in trade country
marg_price = n.buses_t.marginal_price[n.links.loc[index].bus0]
trade = n.links_t.p1[index].mul(sw)
trade_out += marg_price.mul(trade).sum()

trade_in = 0
for index in receiving:
# price of energy in Germany
marg_price = n.buses_t.marginal_price[n.links.loc[index].bus0]
trade = n.links_t.p1[index].mul(sw)
trade_in += marg_price.mul(trade).sum()
return abs(trade_in) - abs(trade_out)
# > 0: costs for Germany
# < 0: profit for Germany

def get_line_opex(n, region, sw):
supplying = n.lines[
(n.lines.carrier.isin(["AC"]))
& (n.lines.bus0.str.startswith(region))
& (~n.lines.bus1.str.startswith(region))
].index
receiving = n.lines[
(n.lines.carrier.isin(["AC"]))
& (~n.lines.bus0.str.startswith(region))
& (n.lines.bus1.str.startswith(region))
].index

# i have to clip the trade
net_out = 0
for index in supplying:
trade = n.lines_t.p1[index].mul(sw)
trade_out = trade.clip(lower=0) # positive
trade_in = trade.clip(upper=0) # negative
marg_price_DE = n.buses_t.marginal_price[n.lines.loc[index].bus0]
marg_price_EU = n.buses_t.marginal_price[n.lines.loc[index].bus1]
net_out += (
trade_out.mul(marg_price_DE).sum() + trade_in.mul(marg_price_EU).sum()
)
# net_out > 0: Germany is exporting more electricity
# net_out < 0: Germany is importing more electricity

net_in = 0
for index in receiving:
trade = n.lines_t.p1[index].mul(sw)
trade_in = trade.clip(lower=0) # positive
trade_out = trade.clip(upper=0) # negative
trade_out = trade_out.clip(upper=0)
marg_price_EU = n.buses_t.marginal_price[n.lines.loc[index].bus0]
marg_price_DE = n.buses_t.marginal_price[n.lines.loc[index].bus1]
net_in += (
trade_in.mul(marg_price_EU).sum() + trade_out.mul(marg_price_DE).sum()
)
# net_in > 0: Germany is importing more electricity
# net_in < 0: Germany is exporting more electricity

return -net_out + net_in

trade_carriers = [
"DC",
"H2 pipeline",
"H2 pipeline (Kernnetz)",
"H2 pipeline retrofitted" "renewable oil",
"renewable gas",
"methanol",
]

sw = n.snapshot_weightings.generators
tsc = get_tsc(n, region).sum().sum()
trade_costs = get_link_opex(n, trade_carriers, region, sw) + get_line_opex(
n, region, sw
)

# Cost|Total Energy System Cost in billion EUR2020/yr
var["Cost|Total Energy System Cost"] = round((tsc + trade_costs) / 1e9, 4)

return var


Expand Down Expand Up @@ -5468,7 +5641,7 @@ def get_data(
cap_func = n.statistics.optimal_capacity
cap_string = "Optimal Capacity|"
kwargs = {
"groupby": n.statistics.groupers.get_bus_and_carrier,
"groupby": ["bus", "carrier"],
"at_port": True,
"nice_names": False,
}
Expand Down