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

fix bugs in reserve constraint #645

Merged
merged 4 commits into from
Apr 21, 2023
Merged
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
34 changes: 23 additions & 11 deletions scripts/solve_network.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@

logger = logging.getLogger(__name__)
pypsa.pf.logger.setLevel(logging.WARNING)
from pypsa.descriptors import get_switchable_as_dense as get_as_dense


def add_land_use_constraint(n, config):
Expand Down Expand Up @@ -414,7 +415,7 @@ def add_operational_reserve_margin(n, sns, config):
0, np.inf, coords=[sns, n.generators.index], name="Generator-r"
)
reserve = n.model["Generator-r"]
lhs = reserve.sum("Generator")
summed_reserve = reserve.sum("Generator")

# Share of extendable renewable capacities
ext_i = n.generators.query("p_nom_extendable").index
Expand All @@ -426,10 +427,12 @@ def add_operational_reserve_margin(n, sns, config):
.loc[vres_i.intersection(ext_i)]
.rename({"Generator-ext": "Generator"})
)
lhs = lhs + (p_nom_vres * (-EPSILON_VRES * capacity_factor)).sum()
lhs = summed_reserve + (p_nom_vres * (-EPSILON_VRES * capacity_factor)).sum(
"Generator"
)

# Total demand per t
demand = n.loads_t.p_set.sum(axis=1)
demand = get_as_dense(n, "Load", "p_set").sum(axis=1)

# VRES potential of non extendable generators
capacity_factor = n.generators_t.p_max_pu[vres_i.difference(ext_i)]
Expand All @@ -441,17 +444,26 @@ def add_operational_reserve_margin(n, sns, config):

n.model.add_constraints(lhs >= rhs, name="reserve_margin")

# additional contraint that capacity is not exceeded
gen_i = n.generators.index
ext_i = n.generators.query("p_nom_extendable").index
fix_i = n.generators.query("not p_nom_extendable").index

dispatch = n.model["Generator-p"]
reserve = n.model["Generator-r"]

lhs = n.model.constraints["Generator-fix-p-upper"].lhs
lhs = lhs + reserve.loc[:, lhs.coords["Generator-fix"]].drop("Generator")
rhs = n.model.constraints["Generator-fix-p-upper"].rhs
n.model.add_constraints(lhs <= rhs, name="Generator-fix-p-upper-reserve")
capacity_variable = n.model["Generator-p_nom"].rename(
{"Generator-ext": "Generator"}
)
capacity_fixed = n.generators.p_nom[fix_i]

p_max_pu = get_as_dense(n, "Generator", "p_max_pu")

lhs = dispatch + reserve - capacity_variable * p_max_pu[ext_i]

rhs = (p_max_pu[fix_i] * capacity_fixed).reindex(columns=gen_i, fill_value=0)

lhs = n.model.constraints["Generator-ext-p-upper"].lhs
lhs = lhs + reserve.loc[:, lhs.coords["Generator-ext"]].drop("Generator")
rhs = n.model.constraints["Generator-ext-p-upper"].rhs
n.model.add_constraints(lhs >= rhs, name="Generator-ext-p-upper-reserve")
n.model.add_constraints(lhs <= rhs, name="Generator-p-reserve-upper")


def add_battery_constraints(n):
Expand Down