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

LDES project updates #447

Draft
wants to merge 171 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
171 commits
Select commit Hold shift + click to select a range
5b04b56
Add per kW and per kWh installed capacity based battery O&M
lixiangk1 Jan 23, 2024
8627a8d
Add O&M financials to ElectricStorage results
lixiangk1 Jan 24, 2024
564365f
Add battery self discharge, defaulted to zero
lixiangk1 Feb 29, 2024
ae61517
Merge branch 'develop' into battery_om
lixiangk1 Feb 29, 2024
3e1a3d6
Merge branch 'develop' into battery_om
lixiangk1 Mar 19, 2024
5542a5d
Merge branch 'develop' into battery_om
lixiangk1 Mar 28, 2024
c2f3c5d
Add battery self-discharge to MPC model
lixiangk1 Mar 28, 2024
37e3083
Enable BESS O&M for multiple sites
lixiangk1 Mar 29, 2024
9ee741e
Add code comments and tests for battery O&M and self-discharge; updat…
lixiangk1 Apr 2, 2024
e2a0cac
Update code comments
lixiangk1 Apr 2, 2024
66e848a
Merge branch 'develop' into battery_om
adfarth Apr 5, 2024
53014bc
Merge branch 'develop' into battery_om
lixiangk1 Apr 19, 2024
14f3ced
Update storage self-discharge input from daily to per timestep
lixiangk1 Apr 19, 2024
b67bdcc
Add duration constraint
lixiangk1 Apr 19, 2024
7c339a1
Fix ldes constraint, add duration input
lixiangk1 Apr 20, 2024
ac253e5
Allow battery wholesale export, preliminary implementation
toddleif Apr 28, 2024
d66297f
Added optional constraint for requiring start and end battery charge …
toddleif May 14, 2024
cdc4da8
Set initial SOC = final SOC for BESS and allow REopt to decide value,…
lixiangk1 May 20, 2024
0fbdb98
rename self discharge input for consistency
hdunham May 23, 2024
58b6769
Update CHANGELOG.md
hdunham May 23, 2024
0e739ab
simplify WHL_benefit expression
hdunham May 23, 2024
25f310f
correct self discharge term
hdunham May 23, 2024
4f987ac
simplify soc expressions
hdunham May 23, 2024
1f4ebe9
picking nits
hdunham May 23, 2024
e6f7cc4
only use 1 bin to prevent simultaneous charge/discharge
hdunham May 23, 2024
8f6ff4f
change binBattCharging definition too
hdunham May 23, 2024
515a684
dont need 0 index for binBattCharging
hdunham May 23, 2024
fbd6d46
rm unnecessary loop
hdunham May 30, 2024
9954293
rm manifest in test directory
hdunham May 30, 2024
019b6bc
fix extra ] typo
hdunham May 30, 2024
371a76b
fix variable def syntax
hdunham May 30, 2024
b84e917
make storage om test more comprehensive
hdunham May 30, 2024
5ce036a
consolidate storage om and self discharge tests
hdunham May 30, 2024
ad46c89
more concise
hdunham May 30, 2024
ce5977a
uncomment tests
hdunham May 30, 2024
51a7ff9
rm self discharge test now dupe
hdunham May 30, 2024
1d3181f
Update CHANGELOG.md
hdunham May 30, 2024
d6b9b6e
comment out battery charge/discharge binary
hdunham May 31, 2024
2b07689
comment out added battery power constraint
hdunham May 31, 2024
c6ff686
comment out dvStorageToGrid
hdunham May 31, 2024
0b1618b
Revert "comment out dvStorageToGrid"
hdunham May 31, 2024
eb6ed96
comment out dvStorageToGrid in WHL_benefit expression
hdunham May 31, 2024
c273972
Revert "comment out added battery power constraint"
hdunham May 31, 2024
3a8834a
Revert "comment out battery charge/discharge binary"
hdunham May 31, 2024
134adb6
add battery max_kw to bigM_hourly_load
hdunham Jun 1, 2024
5db75ae
change to bigM_hourly_load_plus_battery_power where used
hdunham Jun 4, 2024
0f13d77
add b index to dvStorageToGrid
hdunham Jun 4, 2024
7d2694e
add dvStorageToGrid to mpc model
hdunham Jun 4, 2024
31e912b
is_ldes and duration -> fixed_duration
hdunham Jun 4, 2024
0d37b7c
account for fixed_duration not in MPCElectricStorage
hdunham Jun 4, 2024
84293bd
account for require_start_and_end_charge_to_be_equal not in MPCElectr…
hdunham Jun 4, 2024
3bd6e24
add allow_simultaneous_charge_discharge input to ElectricStorage
hdunham Jun 5, 2024
d0b4671
move def of binBattCharging to be with rest of variable defs
hdunham Jun 5, 2024
f34f44c
missing comma
hdunham Jun 5, 2024
0336a2d
only prevent simultaneous battery charge/discharge when that input is…
hdunham Jun 5, 2024
300c95e
add allow_simultaneous_charge_discharge to MPCElectricStorage
hdunham Jun 5, 2024
9f4df44
rm dvStorageToGrid from general storage discharge power constraint
hdunham Jun 5, 2024
5f64284
make dvStorageToGrid multinode compat
hdunham Jun 5, 2024
4cf25f3
Merge branch 'develop' into ldes-analysis-fixed-duration
lixiangk1 Jun 7, 2024
6212406
add more export incentive and om tax/period combos to results
hdunham Jun 20, 2024
a79ae20
Merge branch 'develop' into battery_om
lixiangk1 Jul 7, 2024
5eea67e
Add capacity-based self-discharge, update tests
lixiangk1 Jul 9, 2024
8ad69fd
add can_export_to_grid ElectricStorage input
hdunham Aug 6, 2024
88cc28e
Revert "add can_export_to_grid ElectricStorage input"
hdunham Aug 6, 2024
f04b60d
add can_export_to_grid ElectricStorage input
hdunham Aug 6, 2024
c069122
fix storage export to zero if can_export_to_grid=false
hdunham Aug 6, 2024
1c85716
rename require_start_and_end_charge_to_be_equal to optimize_soc_init_…
hdunham Aug 6, 2024
0f2f246
still fix init and final soc for non elec storage and elec storage wh…
hdunham Aug 6, 2024
5c512b5
remove final soc constraint
hdunham Aug 7, 2024
9bde839
add can_export_to_grid to test inputs
hdunham Aug 7, 2024
bb90447
improve log msg
hdunham Aug 8, 2024
81927a2
use _n where missing in wind results processing
hdunham Aug 8, 2024
7edb8a3
round initial_capital_cost in wind and pv results
hdunham Aug 8, 2024
a885836
add initial_capital_cost output to steam turbine
hdunham Aug 8, 2024
80e7f6c
add initial_capital_cost output to generator
hdunham Aug 8, 2024
1428684
add initial_capital_cost output to electric heater
hdunham Aug 8, 2024
e8032d1
add initial_capital_cost output to chp
hdunham Aug 8, 2024
d13ff0b
add initial_capital_cost output to boiler
hdunham Aug 8, 2024
586b4c5
correct some initial_capital_cost calcs
hdunham Aug 8, 2024
8f42464
add initial_capital_cost output to thermal storage
hdunham Aug 8, 2024
f642462
Update CHANGELOG.md
hdunham Aug 8, 2024
b0a24c5
add initial_capital_cost output to absorption chiller
hdunham Aug 12, 2024
305075d
remove initial_capital_cost from chp results for now
hdunham Aug 12, 2024
dd13655
make b arg required in degradation functions
hdunham Aug 29, 2024
2960b23
add name field to ElectricStorage
hdunham Aug 29, 2024
c9115a5
loop elec stor, don't hardcode "ElectricStorage" (bigM_hourly_load_pl…
hdunham Aug 29, 2024
5f2ceb6
use b arg don't hardcode "ElectricStorage"
hdunham Aug 29, 2024
710f2f5
handle ElectricStorage being a list of dicts
hdunham Aug 29, 2024
1d3bce0
loop elec stor, don't hardcode "ElectricStorage" (steam turbine results)
hdunham Aug 29, 2024
b69edbf
(gen results) loop elec stor, don't hardcode "ElectricStorage"
hdunham Aug 29, 2024
949bcb8
(utility results) loop elec stor, don't hardcode "ElectricStorage"
hdunham Aug 29, 2024
293fcd7
(chp results) loop elec stor, don't hardcode "ElectricStorage"
hdunham Aug 29, 2024
1de9ca6
(elec stor results) use b arg don't hardcode "ElectricStorage"
hdunham Aug 29, 2024
793e8d7
(mpc/model.jl) don't hardcode "ElectricStorage"
hdunham Aug 29, 2024
e3a7656
correct error msg
hdunham Aug 29, 2024
3ce3e32
error in ERP if multiple elec stor
hdunham Aug 29, 2024
dcda12a
in ERP use d["ElectricStorage"]["name"] not "ElectricStorage" hardcoded
hdunham Aug 29, 2024
970bd2b
(outagesim) handle elec stor name and error if multiple
hdunham Aug 29, 2024
febc367
Revert "(outagesim) handle elec stor name and error if multiple"
hdunham Aug 30, 2024
8fb61ee
Revert "in ERP use d["ElectricStorage"]["name"] not "ElectricStorage"…
hdunham Aug 30, 2024
b1b8dd7
Revert "error in ERP if multiple elec stor"
hdunham Aug 30, 2024
1e06aac
Revert "correct error msg"
hdunham Aug 30, 2024
9d0c564
Revert "(mpc/model.jl) don't hardcode "ElectricStorage""
hdunham Aug 30, 2024
12889a5
Revert "(elec stor results) use b arg don't hardcode "ElectricStorage""
hdunham Aug 30, 2024
63ab4eb
Revert "(chp results) loop elec stor, don't hardcode "ElectricStorage""
hdunham Aug 30, 2024
c4f138a
Revert "(utility results) loop elec stor, don't hardcode "ElectricSto…
hdunham Aug 30, 2024
10d3264
Revert "(gen results) loop elec stor, don't hardcode "ElectricStorage""
hdunham Aug 30, 2024
34179ac
Revert "loop elec stor, don't hardcode "ElectricStorage" (steam turbi…
hdunham Aug 30, 2024
fc44e06
Revert "handle ElectricStorage being a list of dicts"
hdunham Aug 30, 2024
7161f6e
Revert "use b arg don't hardcode "ElectricStorage""
hdunham Aug 30, 2024
6139428
Revert "loop elec stor, don't hardcode "ElectricStorage" (bigM_hourly…
hdunham Aug 30, 2024
ac5a954
Revert "add name field to ElectricStorage"
hdunham Aug 30, 2024
29657c0
Revert "make b arg required in degradation functions"
hdunham Aug 30, 2024
aec28ca
(proforma) handle elec stor name and error if multiple
hdunham Aug 30, 2024
c978da3
make outage stor constraints take b arg
hdunham Aug 30, 2024
38efed4
pass b arg into MG elec stor constraints
hdunham Aug 30, 2024
a800d82
organize_multiple_elec_stor_results
hdunham Aug 30, 2024
29dda76
function name typo correction
hdunham Sep 3, 2024
3f9892c
create ElectricStorage struct before getting name so always there
hdunham Sep 3, 2024
e6f7f6b
correct var name
hdunham Sep 3, 2024
7dde72b
safe get ElectricStorage name because only included if multiple
hdunham Sep 3, 2024
fd206ab
add multiple elec stor test
hdunham Sep 3, 2024
52922e4
fix edit to constrain_degradation_variables
hdunham Sep 4, 2024
457acd1
debugging
hdunham Sep 4, 2024
9d5e3cd
cast as Real[] so sum of empty [] doesn't error
hdunham Sep 4, 2024
d3d90e0
rm debugging
hdunham Sep 4, 2024
a8f12a3
Merge branch 'develop' into ldes-analysis-fixed-duration
lixiangk1 Sep 7, 2024
3a577e4
Merge branch 'develop' into battery_om
lixiangk1 Sep 7, 2024
e674a1b
Merge branch 'ldes-analysis-fixed-duration' into multiple-elec-stor
hdunham Sep 10, 2024
53f7b57
fix auto merge errors 1
hdunham Sep 10, 2024
7d53be8
correct changelog merge
hdunham Sep 10, 2024
95aa65e
fix auto merge errors 2
hdunham Sep 10, 2024
ccb6412
fix auto merge errors 3
hdunham Sep 10, 2024
cc346fb
fix auto merge errors 4
hdunham Sep 10, 2024
8bbcd38
fix auto merge errors 5
hdunham Sep 10, 2024
fec2f30
fix auto merge errors 6
hdunham Sep 10, 2024
e7f8d16
add Logging to test project
hdunham Sep 10, 2024
a138d27
add b index to binBattCharging (new set approach)
hdunham Sep 25, 2024
a4dd661
Revert "add b index to binBattCharging (new set approach)"
hdunham Sep 25, 2024
06e85f0
Merge branch 'prevent-simul-charge-discharge' into multiple-elec-stor
hdunham Sep 25, 2024
dae181d
merge fix
hdunham Sep 25, 2024
728dfcb
rm binBattCharging
hdunham Sep 25, 2024
3d9eb90
update Multiple Electric Storage to include more edge cases
hdunham Sep 25, 2024
a896afb
uncomment tests
hdunham Sep 25, 2024
6921855
Merge branch 'ldes-analysis-fixed-duration' into multiple-elec-stor
hdunham Sep 25, 2024
275a088
Merge branch 'prevent-simul-charge-discharge' into multiple-elec-stor
hdunham Sep 25, 2024
c2de716
fix missing end from merge
hdunham Sep 25, 2024
b5840df
rm allow_simultaneous_charge_discharge
hdunham Sep 25, 2024
dc3ba22
Revert "Update expected Solar dataset test from updated NSRDB"
hdunham Sep 25, 2024
fef2dec
rm debugging write to file
hdunham Oct 8, 2024
a4f5bf2
Update CHANGELOG.md
hdunham Oct 8, 2024
45f2bf7
Merge branch 'develop' into multiple-elec-stor
hdunham Oct 8, 2024
20ee7e4
Merge branch 'prevent-simul-charge-discharge' into multiple-elec-stor
hdunham Oct 8, 2024
9659f0a
Merge branch 'develop' into multiple-elec-stor
hdunham Oct 11, 2024
d1f84f9
trigger tests
hdunham Oct 11, 2024
300755b
make storage_to_grid_series_kw array not denseaxisarray
hdunham Oct 15, 2024
ab1d65b
fix typo
hdunham Oct 16, 2024
1ff7a31
Update thermal decay variables to match electric storage self-discharge
lixiangk1 Oct 21, 2024
d42ae3a
Merge branch 'develop' into battery_om
lixiangk1 Oct 21, 2024
78793c0
Remove extra minus sign
lixiangk1 Oct 21, 2024
eaa270f
Merge branch 'battery_om' into multiple-elec-stor
lixiangk1 Oct 21, 2024
b80f465
Fix typo
lixiangk1 Oct 22, 2024
d4979c2
fix degradation merge
hdunham Oct 24, 2024
a10fb6b
add self discharge terms to elec no simultaneous charge/discharge con…
hdunham Oct 25, 2024
db87859
fix changelog merge
hdunham Oct 25, 2024
59a4586
fix changelog merge
hdunham Oct 25, 2024
6aa56d4
align changelog with multiple-elec-stor
hdunham Oct 25, 2024
7f92425
Merge branch 'battery_om' into multiple-elec-stor
hdunham Oct 25, 2024
22c909c
Merge branch 'develop' into multiple-elec-stor
hdunham Oct 25, 2024
c847aa0
rm fixed_duration constraint
hdunham Oct 25, 2024
dc729d8
fix conversion error
hdunham Oct 25, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,25 @@ Classify the change according to the following categories:
### Deprecated
### Removed

## Develop LDES
Copy link
Collaborator

Choose a reason for hiding this comment

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

@hdunham I'm seeing some discrepancies and overlap between this branch and:

I think it makes sense to merge each of those branches above into this PR. What do you think?

### Added
- Added input option **can_export_to_grid** (defaults to _false_) to `ElectricStorage` and decision variable **dvStorageToGrid**
- Added input option **optimize_soc_init_fraction** (defaults to _false_) to `ElectricStorage`, which makes the optimization choose the inital SOC (equal to final SOC) instead of using **soc_init_fraction**. The initial SOC is also constrained to equal the final SOC, which eliminates the "free energy" issue. We currently do not fix SOC when **soc_init_fraction** is used because this has caused infeasibility.
- Added output **initial_capital_cost** to all techs
- Added input **soc_based_per_ts_thermal_decay_fraction** to both `ColdThermalStorage` and `HotThermalStorage` for modeling SOC-based thermal decay rate
- Renamed **thermal_decay_rate_fraction** to **capacity_based_per_ts_thermal_decay_fraction** in both `ColdThermalStorage` and `HotThermalStorage` to clarify that the variable represents the capacity-based thermal decay rate
- Added ability to model multiple `ElectricStorage` at once. Inputs are provided as a _list_ of _dict_ under the `ElectricStorage` key and outputs are similarly formatted. This mirrors the existing multiple `PV` implementation. This functionality is not yet implemented for MPC scenarios.
### Fixed
- Added missing outputs **lifecycle_export_benefit_before_tax** and **year_one_export_benefit_after_tax** to `ElectricTariff`
- Add missing output **year_one_om_cost_before_tax** to `PV`

## Develop battery_om
### Added
- Added inputs **om_cost_per_kw** and **om_cost_per_kwh** to `ElectricStorage` for modeling capacity-based O&M
- Added outputs **lifecycle_om_cost_after_tax** and **year_one_om_cost_before_tax** to `ElectricStorage`
- Added input **soc_based_per_ts_self_discharge_fraction** to `ElectricStorage` for modeling SOC-based battery self-discharge
- Added input **capacity_based_per_ts_self_discharge_fraction** to `ElectricStorage` for modeling capacity-based battery self-discharge

## Develop - 2024-10-11
### Added
- Add new **ElectricStorage** parameters **max_duration_hours** and **min_duration_hours** to bound the energy duration of battery storage
Expand Down
10 changes: 4 additions & 6 deletions src/constraints/battery_degradation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ function add_degradation_variables(m, p)
end


function constrain_degradation_variables(m, p; b="ElectricStorage")
function constrain_degradation_variables(m, p, b)
days = 1:365*p.s.financial.analysis_years
ts_per_day = 24 / p.hours_per_time_step
ts_per_year = ts_per_day * 365
Expand Down Expand Up @@ -44,14 +44,12 @@ end


"""
add_degradation(m, p; b="ElectricStorage")
add_degradation(m, p, b)

NOTE the average SOC and EFC variables are in absolute units. For example, the SOH variable starts
at the battery capacity in kWh.
"""
function add_degradation(m, p; b="ElectricStorage")

# Indices
function add_degradation(m, p, b)
days = 1:365*p.s.financial.analysis_years
months = 1:p.s.financial.analysis_years*12

Expand All @@ -75,7 +73,7 @@ function add_degradation(m, p; b="ElectricStorage")
end

add_degradation_variables(m, p)
constrain_degradation_variables(m, p, b=b)
constrain_degradation_variables(m, p, b)

@constraint(m, [d in 2:days[end]],
m[:SOH][d] == m[:SOH][d-1] - p.hours_per_time_step * (
Expand Down
16 changes: 11 additions & 5 deletions src/constraints/electric_utility_constraints.jl
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,14 @@ function add_export_constraints(m, p; _n="")
if typeof(binNEM) <: Real # no need for wholesale binary
binWHL = 1
WHL_benefit = @expression(m, p.pwf_e * p.hours_per_time_step *
sum( sum(p.s.electric_tariff.export_rates[:WHL][ts] * m[Symbol("dvProductionToGrid"*_n)][t, :WHL, ts]
for t in p.techs_by_exportbin[:WHL]) for ts in p.time_steps)
#sum( sum(p.s.electric_tariff.export_rates[:WHL][ts] * m[Symbol("dvProductionToGrid"*_n)][t, :WHL, ts]
# for t in p.techs_by_exportbin[:WHL]) for ts in p.time_steps)
sum(p.s.electric_tariff.export_rates[:WHL][ts] *
(
sum(m[Symbol("dvStorageToGrid"*_n)][b, ts] for b in p.s.storage.types.elec) +
sum(m[Symbol("dvProductionToGrid"*_n)][t, :WHL, ts] for t in p.techs_by_exportbin[:WHL])
) for ts in p.time_steps
)
)
else
binWHL = @variable(m, binary = true)
Expand Down Expand Up @@ -273,13 +279,13 @@ function add_simultaneous_export_import_constraint(m, p; _n="")
}
)
else
bigM_hourly_load = maximum(p.s.electric_load.loads_kw)+maximum(p.s.space_heating_load.loads_kw)+maximum(p.s.process_heat_load.loads_kw)+maximum(p.s.dhw_load.loads_kw)+maximum(p.s.cooling_load.loads_kw_thermal)
bigM_hourly_load_plus_battery_power = maximum(p.s.electric_load.loads_kw)+maximum(p.s.space_heating_load.loads_kw)+maximum(p.s.process_heat_load.loads_kw)+maximum(p.s.dhw_load.loads_kw)+maximum(p.s.cooling_load.loads_kw_thermal)+sum(Real[p.s.storage.attr[b].max_kw for b in p.s.storage.types.elec])
@constraint(m, NoGridPurchasesBinary[ts in p.time_steps],
sum(m[Symbol("dvGridPurchase"*_n)][ts, tier] for tier in 1:p.s.electric_tariff.n_energy_tiers) +
sum(m[Symbol("dvGridToStorage"*_n)][b, ts] for b in p.s.storage.types.elec) <= bigM_hourly_load*(1-m[Symbol("binNoGridPurchases"*_n)][ts])
sum(m[Symbol("dvGridToStorage"*_n)][b, ts] for b in p.s.storage.types.elec) <= bigM_hourly_load_plus_battery_power*(1-m[Symbol("binNoGridPurchases"*_n)][ts])
)
@constraint(m, ExportOnlyAfterSiteLoadMetCon[ts in p.time_steps],
sum(m[Symbol("dvProductionToGrid"*_n)][t,u,ts] for t in p.techs.elec, u in p.export_bins_by_tech[t]) <= bigM_hourly_load * m[Symbol("binNoGridPurchases"*_n)][ts]
sum(m[Symbol("dvProductionToGrid"*_n)][t,u,ts] for t in p.techs.elec, u in p.export_bins_by_tech[t]) <= bigM_hourly_load_plus_battery_power * m[Symbol("binNoGridPurchases"*_n)][ts]
)
end
end
Expand Down
28 changes: 14 additions & 14 deletions src/constraints/outage_constraints.jl
Original file line number Diff line number Diff line change
Expand Up @@ -273,56 +273,56 @@ function add_binMGCHPIsOnInTS_constraints(m, p; _n="")
# TODO? make binMGCHPIsOnInTS indexed on p.techs.chp
end

function add_MG_storage_dispatch_constraints(m,p)
function add_MG_elec_storage_dispatch_constraints(m,p,b)
# initial SOC at start of each outage equals the grid-optimal SOC
@constraint(m, [s in p.s.electric_utility.scenarios, tz in p.s.electric_utility.outage_start_time_steps],
m[:dvMGStoredEnergy][s, tz, 0] <= m[:dvStoredEnergy]["ElectricStorage", tz]
m[:dvMGStoredEnergy][s, tz, 0] <= m[:dvStoredEnergy][b, tz]
)

# state of charge
@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[:dvMGStoredEnergy][s, tz, ts] == m[:dvMGStoredEnergy][s, tz, ts-1] + p.hours_per_time_step * (
p.s.storage.attr["ElectricStorage"].charge_efficiency * sum(m[:dvMGProductionToStorage][t, s, tz, ts] for t in p.techs.elec)
- m[:dvMGDischargeFromStorage][s, tz, ts] / p.s.storage.attr["ElectricStorage"].discharge_efficiency
p.s.storage.attr[b].charge_efficiency * sum(m[:dvMGProductionToStorage][t, s, tz, ts] for t in p.techs.elec)
- m[:dvMGDischargeFromStorage][s, tz, ts] / p.s.storage.attr[b].discharge_efficiency
)
)

# Prevent simultaneous charge and discharge by limitting charging alone to not make the SOC exceed 100%
@constraint(m, [ts in p.time_steps_without_grid],
m[:dvStorageEnergy]["ElectricStorage"] >= m[:dvMGStoredEnergy][s, tz, ts-1] + p.hours_per_time_step * (
p.s.storage.attr["ElectricStorage"].charge_efficiency * sum(m[:dvMGProductionToStorage][t, s, tz, ts] for t in p.techs.elec)
m[:dvStorageEnergy][b] >= m[:dvMGStoredEnergy][s, tz, ts-1] + p.hours_per_time_step * (
p.s.storage.attr[b].charge_efficiency * sum(m[:dvMGProductionToStorage][t, s, tz, ts] for t in p.techs.elec)
)
)

# Min SOC
if p.s.storage.attr["ElectricStorage"].soc_min_applies_during_outages
if p.s.storage.attr[b].soc_min_applies_during_outages
# Minimum state of charge
@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[:dvMGStoredEnergy][s, tz, ts] >= p.s.storage.attr["ElectricStorage"].soc_min_fraction * m[:dvStorageEnergy]["ElectricStorage"]
m[:dvMGStoredEnergy][s, tz, ts] >= p.s.storage.attr[b].soc_min_fraction * m[:dvStorageEnergy][b]
)
end

# Dispatch to MG electrical storage is no greater than inverter capacity
# and can't charge the battery unless binMGStorageUsed = 1
@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"] >= sum(m[:dvMGProductionToStorage][t, s, tz, ts] for t in p.techs.elec)
m[:dvStoragePower][b] >= sum(m[:dvMGProductionToStorage][t, s, tz, ts] for t in p.techs.elec)
)

# Dispatch from MG storage is no greater than inverter capacity
# and can't discharge from storage unless binMGStorageUsed = 1
@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]
m[:dvStoragePower][b] >= m[:dvMGDischargeFromStorage][s, tz, ts]
)

# Dispatch to and from electrical storage is no greater than power capacity
@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]
m[:dvStoragePower][b] >= m[:dvMGDischargeFromStorage][s, tz, ts]
+ sum(m[:dvMGProductionToStorage][t, s, tz, ts] for t in p.techs.elec)
)

# State of charge upper bound is storage system size
@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[:dvStorageEnergy]["ElectricStorage"] >= m[:dvMGStoredEnergy][s, tz, ts]
m[:dvStorageEnergy][b] >= m[:dvMGStoredEnergy][s, tz, ts]
)

if solver_is_compatible_with_indicator_constraints(p.s.settings.solver_name)
Expand All @@ -335,11 +335,11 @@ function add_MG_storage_dispatch_constraints(m,p)
)
else
@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],
sum(m[:dvMGProductionToStorage][t, s, tz, ts] for t in p.techs.elec) <= p.s.storage.attr["ElectricStorage"].max_kw * m[:binMGStorageUsed]
sum(m[:dvMGProductionToStorage][t, s, tz, ts] for t in p.techs.elec) <= p.s.storage.attr[b].max_kw * m[:binMGStorageUsed]
)

@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[:dvMGDischargeFromStorage][s, tz, ts] <= p.s.storage.attr["ElectricStorage"].max_kw * m[:binMGStorageUsed]
m[:dvMGDischargeFromStorage][s, tz, ts] <= p.s.storage.attr[b].max_kw * m[:binMGStorageUsed]
)
end
end
Expand Down
Loading
Loading