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

Refactor reserves #562

Merged
merged 31 commits into from
Nov 18, 2023
Merged

Refactor reserves #562

merged 31 commits into from
Nov 18, 2023

Conversation

cfe316
Copy link
Collaborator

@cfe316 cfe316 commented Oct 12, 2023

This doesn't quite compile yet for technical reasons related to add_similar_to_expression!.

I tried refactoring some of the reserve formulations in order to better understand how they should work for fusion, and I think others might appreciate the simplifications.

@cfe316 cfe316 force-pushed the refactor-reserves branch from 5d2c951 to 42fb14c Compare October 12, 2023 19:22
@cfe316 cfe316 marked this pull request as ready for review October 13, 2023 00:44
@cfe316
Copy link
Collaborator Author

cfe316 commented Oct 13, 2023

This works now. The results for the ISONE_Trizone case (which may be the only standard test case that uses Reserves) are identical when just changing the hydro_res formulation. They unfortunately change due to numerical issues with the storage_all_reserves formulation, but I've checked that the constraints are the same. For example see commit aa6b7a6.

Overall, using add_similar_to_expression! lets us avoid the combinatorial explosion of REG/RSV/CapacityReserveMargin. The same technique should be applied to other reserves formulations.

Copy link
Collaborator

@lbonaldo lbonaldo left a comment

Choose a reason for hiding this comment

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

Thanks @cfe316. This PR is an excellent refactoring. I checked the logic, and it looks correct to me. I added a few comments to the code that are mostly tiny fixes.

end
Copy link
Collaborator

Choose a reason for hiding this comment

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

Where is _sum_expression defined?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

That's weird, I don't know.

new_axes = (set, time_range)
expr = JuMP.Containers.DenseAxisArray(aff_exprs.data, new_axes...)
return expr
end
Copy link
Collaborator

@lbonaldo lbonaldo Nov 10, 2023

Choose a reason for hiding this comment

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

We should include a test to this functions and add it to expression_manipulation_test.jl

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I've added tests now.

@@ -160,136 +160,58 @@ function storage_all_reserves!(EP::Model, inputs::Dict, setup::Dict)

Copy link
Collaborator

Choose a reason for hiding this comment

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

CapacityReserveMargin = setup["CapacityReserveMargin"] > 0

src/model/resources/storage/storage_all.jl Outdated Show resolved Hide resolved
eff_down(y) = dfGen[y, :Eff_Down]

# Maximum storage contribution to reserves is a specified fraction of installed capacity
@constraint(EP, [y in STOR_REG, t in 1:T], vREG[y, t] <= dfGen[y,:Reg_Max] * eTotalCap[y])
Copy link
Collaborator

Choose a reason for hiding this comment

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

you could abstract also dfGen[y,:Reg_Max]

Suggested change
@constraint(EP, [y in STOR_REG, t in 1:T], vREG[y, t] <= dfGen[y,:Reg_Max] * eTotalCap[y])
reg_max(y) = dfGen[y,:Reg_Max]
@constraint(EP, [y in STOR_REG, t in 1:T], vREG[y, t] <= reg_max(y) * eTotalCap[y])


# Maximum storage contribution to reserves is a specified fraction of installed capacity
@constraint(EP, [y in STOR_REG, t in 1:T], vREG[y, t] <= dfGen[y,:Reg_Max] * eTotalCap[y])
@constraint(EP, [y in STOR_RSV, t in 1:T], vRSV[y, t] <= dfGen[y,:Rsv_Max] * eTotalCap[y])
Copy link
Collaborator

Choose a reason for hiding this comment

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

and dfGen[y,:Rsv_Max]

@cfe316 cfe316 force-pushed the refactor-reserves branch 2 times, most recently from 036933a to 55a9b88 Compare November 13, 2023 01:59
@cfe316
Copy link
Collaborator Author

cfe316 commented Nov 13, 2023

Here are the results of the refactor:

Costs / 1e9 for the RealSystemExample/ISONE_Trizone case, which includes THERM, HYDRO, VRE, MUST_RUN, and STOR generators.

5.865087 Reserves=0

Reserves=1
5.883106 original
5.883112 refactored

I then increased Reg_Req_Percent_Demand and Rsv_Req_Percent_Demand to 0.1 (10x and 3x increases).

6.281472 original
6.281460 refactored

These numbers are very similar; I'd say this was a success.

Copy link

codecov bot commented Nov 13, 2023

Codecov Report

Attention: 60 lines in your changes are missing coverage. Please review.

Comparison is base (6f7ec0d) 38.37% compared to head (72cc97a) 39.22%.

❗ Current head 72cc97a differs from pull request most recent head 13be2dd. Consider uploading reports for the commit 13be2dd to get more accurate results

Files Patch % Lines
src/model/resources/hydro/hydro_res.jl 0.00% 21 Missing ⚠️
src/model/resources/thermal/thermal_no_commit.jl 0.00% 21 Missing ⚠️
src/model/resources/storage/storage_asymmetric.jl 0.00% 10 Missing ⚠️
src/model/resources/storage/storage_symmetric.jl 80.95% 4 Missing ⚠️
...riable_renewable/curtailable_variable_renewable.jl 95.00% 2 Missing ⚠️
src/model/resources/storage/storage_all.jl 94.44% 2 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           develop     #562      +/-   ##
===========================================
+ Coverage    38.37%   39.22%   +0.84%     
===========================================
  Files          126      126              
  Lines         6480     6205     -275     
===========================================
- Hits          2487     2434      -53     
+ Misses        3993     3771     -222     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@lbonaldo
Copy link
Collaborator

Here are the results of the refactor:

Costs / 1e9 for the RealSystemExample/ISONE_Trizone case, which includes THERM, HYDRO, VRE, MUST_RUN, and STOR generators.

5.865087 Reserves=0

Reserves=1
5.883106 original
5.883112 refactored

I then increased Reg_Req_Percent_Demand and Rsv_Req_Percent_Demand to 0.1 (10x and 3x increases).

6.281472 original
6.281460 refactored

These numbers are very similar; I'd say this was a success.

@cfe316 Thank you for the new commits! Could you please also share the settings of the solver you used to run the example?

@cfe316 cfe316 merged commit 2ef54dc into GenXProject:develop Nov 18, 2023
7 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