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 reserve margin constraints #517

Draft
wants to merge 33 commits into
base: 0.6
Choose a base branch
from

Conversation

FraSanvit
Copy link
Contributor

Summary of changes in this pull request:

  • add capacity values and operating reserve values (both time-varying)
  • add planning and operating reserve group constraints
  • allow time-series inputs in group constraints

Reviewer checklist:

  • Test(s) added to cover contribution
  • Documentation updated
  • Changelog updated
  • Coverage maintained or improved

Open questions:

  • Naming of the target reserves
  • Eligibility of technologies in providing the operating reserves

@jmorrisnrel
Copy link

I finally got a chance to review this functionality. Looking at the code the math of the constraints seems to make sense although I've been getting a number of errors/issues with running tests. I've included the simple model I've been using to test the behavior consisting of a flat 20MW demand and one supply generation capex tech. Perhaps I’m misusing the constraints or didn’t set up my environment correctly but some of the issues are definitely in the PR code here.

Planning reserve share isn't behaving like I'd expect:
Example: Putting a target_reserve_share_equals of 0.5 in a system with flat 20MW demand and a single generator, I would expect the resulting capacity to be 30 MW representing (1+0.5)x the peak load of 20MW (assuming a default cap_value of 1.0). Instead I get 10MW of generation capacity.
When I specify the tech in the group definition it drops the resulting capacity of the generator to 0 and doesn't meet any demand.

Other constraints throw a Pyomo error including the operating constraints:

target_reserve_abs_min/max/equals and target_reserve_adder_min/max/equals all throw an AttributeError when I try and include all loc/techs by leaving those filters blank or include techs in the group definition

The operating constraints likely fail because there is no default value set for the operating_reserve parameter in defaults.yaml

target_reserve_share_operating_min:

If I set the operating_reserve to 0 (just representing a flat reserve) I get similar strange behavior with the resulting capacities. Setting reserve_share_operating_equals to 0.5 I would similarly expect 30MW but instead get 0.5 kW. And a similar story of 20MW if I use _min.

target_reserve_abs_operating_min/max/equals has the same AttributeError as the planning reserve constraints.
inputs.zip

@sjpfenninger sjpfenninger changed the title Add reserves margin constraints Add reserve margin constraints Jan 8, 2024
@FraSanvit
Copy link
Contributor Author

Hi @jmorrisnrel!
I've created a repo with examples and a detailed guide on using the new functionalities. Also, I've tidied up and fixed some minor issues in the branch. Hope this can help.

@sjpfenninger sjpfenninger changed the base branch from feature-0.6-reserve-constraints to 0.6 January 10, 2024 09:37
if loc_tech_carrier not in loc_tech_carriers_transmission
]

rhs = (
Copy link

@jmorrisnrel jmorrisnrel Mar 8, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've been running into issues with the reserve margins when transmission is included in the model. It looks like (both directions) of transmission is included in the energy_cap calculations on the lhs of the reserve constraints, so adding a reserve doesn't result in generation capacity that would meet the reserve requirements. If I set target_reserve_share_equals in the sample model below (a single supply at one location and demand at another) the model either doesn't solve or only builds the supply to 1/3 of the reserve requirement with ensure_feasibility. Not sure if it would be possible to leave transmission out by default but allow you to specify transmission techs in the constraint and have them be added in if desired.

If I try and filter out the transmission techs, the group constraint doesn't seem to work at all. Setting target_resrve_share_equals again with a technology filter (and enabling ensure_feasibility) results in the model building no supply at all even with unmet demand.

Looking into the code it looks like the issue is because the rhs of the share and adder constraints uses the locs list derived from lhs_loc_tech_carriers which doesn't contain the demand location if there is nothing in the lhs there. With transmission included the demand loc is included because of the transmission link, but filtering out transmission to try and get the model to build enough generation for the reserve removes that link and results in the loc not being included.

sample_model.zip

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The group_cosntraint_loc_tech_carriers_{}_rhs attribute also seems to not include demand loc_techs for the appropriate reserve constraints as the code only looks for "share" and "demand"/"import" in the constraint name (constraint_sets.py:524). Grabbing the rhs loc_techs from get_group_lhs_and_rhs_loc_tech_carriers would need that code adjusted so that demand and consumption techs are included in the rhs for the non-absolute reserve constraints.

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.

3 participants