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

Inconsistent treatment of MUST_RUN with VRE #565

Open
cfe316 opened this issue Oct 13, 2023 · 3 comments
Open

Inconsistent treatment of MUST_RUN with VRE #565

cfe316 opened this issue Oct 13, 2023 · 3 comments
Labels
help wanted Extra attention is needed

Comments

@cfe316
Copy link
Collaborator

cfe316 commented Oct 13, 2023

On the develop branch, we've recently introduced validation which makes MUST_RUN a type of resource distinct from all others. However, core/reserves mentions resources which are in intersect(VRE, MUST_RUN), which I think is meant to represent non-curtailable variable renewables. As of now, this set must be empty.

I wanted to raise this issue to stimulate discussion about a resolution.

@cfe316 cfe316 added the help wanted Extra attention is needed label Oct 13, 2023
@JesseJenkins
Copy link
Collaborator

I believe the core/reserves code is incorrect and reflects older usage of the MUST_RUN set which was originally a modifier similar to UCOMMIT, the set of thermal resources subject to unit commitment, but is now implemented as a separate resource type that can reflect must-run or entirely non-dispatchable resources including variable renewables (like rooftop solar) or baseloaded thermal plants or CHP plants whose generation reflects exogenous heating demand patterns, etc.

Here is the code in question:

# Reg up and down requirements are symmetric
	@expression(EP, eRegReq[t=1:T], inputs["pReg_Req_Load"]*sum(inputs["pD"][t,z] for z=1:Z) +
		inputs["pReg_Req_VRE"]*sum(inputs["pP_Max"][y,t]*EP[:eTotalCap][y] for y in intersect(inputs["VRE"], inputs["MUST_RUN"])))
	# Operating reserve up / contingency reserve requirements as ˚a percentage of load and scheduled variable renewable energy production in each hour
	# and the largest single contingency (generator or transmission line outage)
	@expression(EP, eRsvReq[t=1:T], inputs["pRsv_Req_Load"]*sum(inputs["pD"][t,z] for z=1:Z) +
				inputs["pRsv_Req_VRE"]*sum(inputs["pP_Max"][y,t]*EP[:eTotalCap][y] for y in intersect(inputs["VRE"], inputs["MUST_RUN"])))

The intended usage here I believe is union(inputs["VRE"], inputs["MUST_RUN"]) not intersect, with the intention being to set operating reserve requirements as a percentage of scheduled dispatchable and non-dispatchable renewables, with the idea that MUST_RUN primarly is used to reflect non-dispatchable distributed solar. This requirement is to reflect operating reserves required to manage forecast errors for wind and solar production.

We have two options for a fix: (1) drop the set of MUST_RUN resources from the calculation of operating reserve and assume that only utility-scale dispatchable renewables are used in determining reserve requirements; or (2) correct the code above to use union instead of intersect and then assume that the primary usage of MUST_RUN is to represent non-dispatchable variable renewables, rather than baseloaded must-run thermal generators (which do not contribute in this way to operating reserve requirements).

I am inclined to go for Option 1 above.

@cfe316
Copy link
Collaborator Author

cfe316 commented Oct 25, 2023

Thanks, Jesse. Option 1 would be an easy fix.

I do think it would be nicer if we had MUST_RUN as a modifier (like LDS) to represent either non-curtailable variable renewables or baseloaded thermal plants rather than as a separate resource type. I've seen users wanting baseloaded nuclear fission plants and also behind-the-meter solar. Both can be represented as MUST_RUN. For a VRE-like resource one can modify Generators_variability.csv and set fuel to None. But, this would lose out on any special handling of VRE-like things such as for reserves here.

In practice, the utility-scale variable renewables are significantly larger than the behind-the-meter ones in the cases I've run, so it's probably not a huge deal.

@cfe316
Copy link
Collaborator Author

cfe316 commented Oct 25, 2023

Reading the code comment again:
"a percentage of load and scheduled variable renewable energy production" indicates to me that intersect is intentional, indicating the MUST_RUN-VRE's only.

If we change the intent from this "scheduled VRE production" to "forecasted VRE production" by changing intersect(MUST_RUN, VRE) to just VRE, we're also significantly increasing the required value of eRsvReq.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

2 participants