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

Add check for turning off transmission expnasion if limit reached #952

Merged
merged 2 commits into from
Mar 11, 2024

Conversation

koen-vg
Copy link
Contributor

@koen-vg koen-vg commented Feb 28, 2024

Changes proposed in this Pull Request

I recently ran into an issue with myopic optimisations where if the transmission expansion limit has been reached in one time horizon, this could run into model infeasibility when solving at the next time horizon. What happened was that the minimum transmission network capacity given by s_nom_min and p_nom_min combined equalled the global limit set in n.global_constraints up to 12 significant digits. But with the lower limit through *_nom_min so close to the upper limit given by the global constraint, the model ran into numerical problems and was declared infeasible.

I think the "morally correct" approach is to check of transmission is already at the limit, and if so, fix the capacities at those given by *_nom_min, make them non-extendable and remove the global limit. That's what I've implemented in this PR.

The implementation seems to be working fine on my side, though I haven't gotten around to testing it yet for the volume limit, only the cost limit. However, do let me know if anyone can think of any potential issues or better ways of dealing with this.

Checklist

  • I tested my contribution locally and it seems to work fine.
  • Code and workflow changes are sufficiently documented.
  • Changed dependencies are added to envs/environment.yaml.
  • Changes in configuration options are added in all of config.default.yaml.
  • Changes in configuration options are also documented in doc/configtables/*.csv.
  • A release note doc/release_notes.rst is added.

@fneum
Copy link
Member

fneum commented Mar 5, 2024

Sounds familiar. We also came across this issue for the volume limit recently and fixed it very similarly in add_brownfield.py.

def disable_grid_expansion_if_LV_limit_hit(n):
if "lv_limit" not in n.global_constraints.index:
return
total_expansion = (
n.lines.eval("s_nom_min * length").sum()
+ n.links.query("carrier == 'DC'").eval("p_nom_min * length").sum()
).sum()
lv_limit = n.global_constraints.at["lv_limit", "constant"]
# allow small numerical differences
if lv_limit - total_expansion < 1:
logger.info("LV is already reached, disabling expansion and LV limit")
extendable_acs = n.lines.query("s_nom_extendable").index
n.lines.loc[extendable_acs, "s_nom_extendable"] = False
n.lines.loc[extendable_acs, "s_nom"] = n.lines.loc[extendable_acs, "s_nom_min"]
extendable_dcs = n.links.query("carrier == 'DC' and p_nom_extendable").index
n.links.loc[extendable_dcs, "p_nom_extendable"] = False
n.links.loc[extendable_dcs, "p_nom"] = n.links.loc[extendable_dcs, "p_nom_min"]
n.global_constraints.drop("lv_limit", inplace=True)

I think this is the slightly better place to handle this since it only affects the myopic optimization.

Maybe you can expand this function to also cover the cost limit case? It should just be adding a "capital_cost * " prefix to the calculation if I am not wrong. What I liked about your PR is that it goes by global constraint type, not just the index name.

@koen-vg koen-vg force-pushed the transmission-expansion-limit-reached branch from 3ffcab3 to 61e4123 Compare March 7, 2024 08:28
@koen-vg
Copy link
Contributor Author

koen-vg commented Mar 7, 2024

Right, somehow I missed that this already existed but just for the volume limit! I've just force-pushed a sort of combination; you can see if you like it. Probably the for loop over global constraints of a particular type is slightly unnecessary but I don't think it hurts just in case. I think when checking where two things are numerically "close" it's better to normalise first so that this works for models of different scales.

@fneum fneum merged commit 0a0a35e into PyPSA:master Mar 11, 2024
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants