-
Notifications
You must be signed in to change notification settings - Fork 48
DC coupled PV and ElectricStorage #476
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
base: develop
Are you sure you want to change the base?
Conversation
| @constraint(m, [s in p.s.electric_utility.scenarios, tz in p.s.electric_utility.outage_start_time_steps, ts in p.s.electric_utility.outage_time_steps], | ||
| m[:dvStoragePower]["ElectricStorage"] >= m[:dvMGDischargeFromStorage][s, tz, ts] | ||
| + sum(m[:dvMGProductionToStorage][t, s, tz, ts] for t in p.techs.ac_coupled_with_storage) | ||
| + sum(m[:dvMGProductionToStorage][t, s, tz, ts] for t in p.techs.dc_coupled_with_storage) * p.s.storage.attr["ElectricStorage"].inverter_efficiency_fraction #TODO: remove term or leave for future flexibility? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If "ElectricStorage" in not in p.s.storage.types.dc_coupled, why would we need this here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is flow from dc coupled techs out inverter to ac coupled storage, which is currently is not allowed. With multiple storage and adding a bool input to say whether this flow is allowed, this term would be relevant, which is why I wrote that TODO.
| # Dispatch to and from MG electrical storage is no greater than power capacity | ||
| if "ElectricStorage" in p.s.storage.types.dc_coupled | ||
| @constraint(m, [s in p.s.electric_utility.scenarios, tz in p.s.electric_utility.outage_start_time_steps, ts in p.s.electric_utility.outage_time_steps], | ||
| m[:dvStoragePower]["ElectricStorage"] >= m[:dvMGDischargeFromStorage][s, tz, ts] / p.s.storage.attr["ElectricStorage"].inverter_efficiency_fraction |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I'm confused about why the if statement is needed here, whereas in many of the other constraints you were able to avoid if statements by adding flows indexed on ac_coupled to flows index on dc_coupled. And, why does the discharge from storage need to be divided by inverter_efficiency_fraction for the dc-coupled case? Shouldn't the discharge from storage be treated the same between ac- and dc-coupled cases, because in both cases the discharge passes through an inverter (and isn't that already captured in dvMGDischargeFromStorage)?
I could be misunderstanding some of this, but just checking!
| # Future development could make this an option by adding bool inputs an updating load balance/battery dispatch constraints to include these flows | ||
| if "ElectricStorage" in p.s.storage.types.dc_coupled | ||
| # Don't let AC coupled elec techs charge DC coupled battery. | ||
| for ts in 1:p.s.site.min_resil_time_steps |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, if you have a run with wind (AC production) and PV that is dc-coupled with storage, the wind cannot charge the battery? Do you have some test cases in this realm in runtests?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes that's the current set up. Could add an input bool to allow this though. Noting this as a test to add.
| - m[:dvMGCurtail][t, s, tz, ts] | ||
| for t in p.techs.dc_coupled_with_storage | ||
| ) | ||
| # (rectifier direction, though currently dvMGProductionToStorage for AC coupled techs must be 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the constraint above the only thing limiting this? Is this typical operational behavior for a system with DC-coupled PV + BESS and an AC-producing tech like wind or CHP?
| end | ||
|
|
||
| # Future development could make this an option by adding bool inputs an updating load balance/battery dispatch constraints to include these flows | ||
| if b in p.s.storage.types.dc_coupled |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment from me here as in "outage_constraints.jl"
|
General comment on things to document:
|
| r["size_kwh"] = round(value(m[Symbol("dvStorageEnergy"*_n)][b]), digits=2) | ||
| r["size_kw"] = round(value(m[Symbol("dvStoragePower"*_n)][b]), digits=2) | ||
|
|
||
| if b in p.s.storage.types.dc_coupled |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you add dc_coupled_inverter_size_kw to the results markdown section above?
| @@ -23,7 +23,10 @@ function add_electric_storage_results(m::JuMP.AbstractModel, p::REoptInputs, d:: | |||
| r = Dict{String, Any}() | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@hdunham is it accurate to say that the ElectricStorage size_kw (and dvStoragePower) is AC if dc_coupled is false and is DC if dc_coupled is true? Or is it always AC? Could you add whichever is true to the help text above?
| @constraint(m, [b in p.s.storage.types.elec, ts in p.time_steps_without_grid], | ||
| m[Symbol("dvOpResFromBatt"*_n)][b,ts] <= m[Symbol("dvStoragePower"*_n)][b] - m[Symbol("dvDischargeFromStorage"*_n)][b,ts] / p.s.storage.attr[b].discharge_efficiency | ||
| m[Symbol("dvOpResFromBatt"*_n)][b,ts] <= | ||
| m[Symbol("dvStoragePower"*_n)][b] * (b in p.s.storage.types.dc_coupled ? p.s.storage.attr[b].inverter_efficiency_fraction : 1.0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just to confirm my understanding here, dvStoragePower is AC if dc_coupled is false but is DC otherwise and thus needs to be converted from DC to AC with inverter_efficiency_fraction?
| m[:ProductionToLoadOR][t,ts]) * (1 - p.techs_operating_reserve_req_fraction[t]) | ||
| m[Symbol("dvOpResFromTechs"*_n)][t,ts] <= ( | ||
| p.production_factor[t, ts] * p.levelization_factor[t] * m[Symbol("dvSize"*_n)][t] | ||
| * (t in p.techs.dc_coupled_with_storage ? p.s.storage.attr["ElectricStorage"].rectifier_efficiency_fraction : 1.0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should also be inverter_ and not rectifier_ efficiency?
TODO:
Added
Removed