Skip to content

Commit 776337c

Browse files
authored
Improve @expressions performance by pre processing sets (#815)
1 parent 288ffec commit 776337c

19 files changed

+163
-79
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1313
- Default option, `"EnableJuMPDirectMode"`, to build the model more efficiently.
1414
Models running with, non-default, solvers Cbc and Clp will fail unless
1515
`"EnableJuMPDirectMode"` is set to false (#835).
16+
- Improve `@expressions` performance by pre-processing sets (#815).
1617

1718
## [0.4.4] - 2025-02-04
1819

Project.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "GenX"
22
uuid = "5d317b1e-30ec-4ed6-a8ce-8d2d88d7cfac"
33
authors = ["Bonaldo, Luca", "Chakrabarti, Sambuddha", "Cheng, Fangwei", "Ding, Yifu", "Jenkins, Jesse D.", "Luo, Qian", "Macdonald, Ruaridh", "Mallapragada, Dharik", "Manocha, Aneesha", "Mantegna, Gabe ", "Morris, Jack", "Patankar, Neha", "Pecci, Filippo", "Schwartz, Aaron", "Schwartz, Jacob", "Schivley, Greg", "Sepulveda, Nestor", "Xu, Qingyu", "Zhou, Justin"]
4-
version = "0.4.4-dev.4"
4+
version = "0.4.4-dev.5"
55

66
[deps]
77
CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b"

src/model/core/co2.jl

+4-1
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,10 @@ function co2!(EP::Model, inputs::Dict)
134134
end
135135

136136
# emissions by zone
137+
RESOURCES_BY_ZONE = map(1:Z) do z
138+
return resources_in_zone_by_rid(gen, z)
139+
end
137140
@expression(EP, eEmissionsByZone[z = 1:Z, t = 1:T],
138-
sum(eEmissionsByPlant[y, t] for y in resources_in_zone_by_rid(gen, z)))
141+
sum(eEmissionsByPlant[y, t] for y in RESOURCES_BY_ZONE[z]))
139142
return EP
140143
end

src/model/core/discharge/discharge.jl

+5-2
Original file line numberDiff line numberDiff line change
@@ -45,16 +45,19 @@ function discharge!(EP::Model, inputs::Dict, setup::Dict)
4545
+sum(inputs["omega"][t] * esr(gen[y], tag = ESR) * EP[:vP][y, t]
4646
for y in ids_with_policy(gen, esr, tag = ESR), t in 1:T)
4747
-sum(inputs["dfESR"][z, ESR] * inputs["omega"][t] * inputs["pD"][t, z]
48-
for t in 1:T, z in findall(x -> x > 0, inputs["dfESR"][:, ESR])))
48+
for z in findall(x -> x > 0, inputs["dfESR"][:, ESR]), t in 1:T))
4949
add_similar_to_expression!(EP[:eESR], eESRDischarge)
5050
end
5151

5252
# Hourly Matching Policy
5353
if setup["HourlyMatching"] == 1
5454
QUALIFIED_SUPPLY = inputs["QUALIFIED_SUPPLY"] # Resources that are qualified to contribute to hourly matching constraint
55+
QUALIFIED_SUPPLY_BY_ZONE = map(1:Z) do z
56+
return intersect(QUALIFIED_SUPPLY, resources_in_zone_by_rid(gen, z))
57+
end
5558
@expression(EP, eHMDischarge[t = 1:T, z = 1:Z],
5659
sum(EP[:vP][y, t]
57-
for y in intersect(resources_in_zone_by_rid(gen, z), QUALIFIED_SUPPLY)))
60+
for y in QUALIFIED_SUPPLY_BY_ZONE[z]))
5861
add_similar_to_expression!(EP[:eHM], eHMDischarge)
5962
end
6063
end

src/model/core/discharge/investment_discharge.jl

+10-5
Original file line numberDiff line numberDiff line change
@@ -69,34 +69,39 @@ function investment_discharge!(EP::Model, inputs::Dict, setup::Dict)
6969
@expression(EP, eExistingCap[y in 1:G], existing_cap_mw(gen[y]))
7070
end
7171

72+
NEW_RET_RETROFIT_CAP = intersect(NEW_CAP, RET_CAP, RETROFIT_CAP) # Resources eligible for new capacity, retirements and being retrofitted
73+
RET_ONLY_CAP = intersect(setdiff(RET_CAP, NEW_CAP), setdiff(RET_CAP, RETROFIT_CAP)) # Resources eligible for only capacity retirements
74+
RET_NEW_CAP = setdiff(intersect(RET_CAP, NEW_CAP), RETROFIT_CAP) # Resources eligible for retirement and new capacity
75+
RET_RETROFIT_CAP = setdiff(intersect(RET_CAP, RETROFIT_CAP), NEW_CAP) # Resources eligible for retirement and retrofitting
76+
NEW_ONLY_CAP = intersect(setdiff(NEW_CAP, RET_CAP), setdiff(NEW_CAP, RETROFIT_CAP)) # Resources eligible for only new capacity
7277
@expression(EP, eTotalCap[y in 1:G],
73-
if y in intersect(NEW_CAP, RET_CAP, RETROFIT_CAP) # Resources eligible for new capacity, retirements and being retrofitted
78+
if y in NEW_RET_RETROFIT_CAP
7479
if y in COMMIT
7580
eExistingCap[y] +
7681
cap_size(gen[y]) * (EP[:vCAP][y] - EP[:vRETCAP][y] - EP[:vRETROFITCAP][y])
7782
else
7883
eExistingCap[y] + EP[:vCAP][y] - EP[:vRETCAP][y] - EP[:vRETROFITCAP][y]
7984
end
80-
elseif y in intersect(setdiff(RET_CAP, NEW_CAP), setdiff(RET_CAP, RETROFIT_CAP)) # Resources eligible for only capacity retirements
85+
elseif y in RET_ONLY_CAP
8186
if y in COMMIT
8287
eExistingCap[y] - cap_size(gen[y]) * EP[:vRETCAP][y]
8388
else
8489
eExistingCap[y] - EP[:vRETCAP][y]
8590
end
86-
elseif y in setdiff(intersect(RET_CAP, NEW_CAP), RETROFIT_CAP) # Resources eligible for retirement and new capacity
91+
elseif y in RET_NEW_CAP
8792
if y in COMMIT
8893
eExistingCap[y] + cap_size(gen[y]) * (EP[:vCAP][y] - EP[:vRETCAP][y])
8994
else
9095
eExistingCap[y] + EP[:vCAP][y] - EP[:vRETCAP][y]
9196
end
92-
elseif y in setdiff(intersect(RET_CAP, RETROFIT_CAP), NEW_CAP) # Resources eligible for retirement and retrofitting
97+
elseif y in RET_RETROFIT_CAP
9398
if y in COMMIT
9499
eExistingCap[y] -
95100
cap_size(gen[y]) * (EP[:vRETROFITCAP][y] + EP[:vRETCAP][y])
96101
else
97102
eExistingCap[y] - (EP[:vRETROFITCAP][y] + EP[:vRETCAP][y])
98103
end
99-
elseif y in intersect(setdiff(NEW_CAP, RET_CAP), setdiff(NEW_CAP, RETROFIT_CAP)) # Resources eligible for only new capacity
104+
elseif y in NEW_ONLY_CAP
100105
if y in COMMIT
101106
eExistingCap[y] + cap_size(gen[y]) * EP[:vCAP][y]
102107
else

src/model/core/fuel.jl

+10-3
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,10 @@ function fuel!(EP::Model, inputs::Dict, setup::Dict)
9696
SINGLE_FUEL = inputs["SINGLE_FUEL"]
9797
ALLAM_CYCLE_LOX = inputs["ALLAM_CYCLE_LOX"]
9898

99+
RESOURCES_BY_ZONE = map(1:Z) do z
100+
return resources_in_zone_by_rid(gen, z)
101+
end
102+
99103
fuels = inputs["fuels"]
100104
fuel_costs = inputs["fuel_costs"]
101105
omega = inputs["omega"]
@@ -195,7 +199,7 @@ function fuel!(EP::Model, inputs::Dict, setup::Dict)
195199
sum(omega[t] * EP[:eCFuelStart][y, t] for t in 1:T))
196200
# zonal level total fuel cost for output
197201
@expression(EP, eZonalCFuelStart[z = 1:Z],
198-
sum(EP[:ePlantCFuelStart][y] for y in resources_in_zone_by_rid(gen, z)))
202+
sum(EP[:ePlantCFuelStart][y] for y in RESOURCES_BY_ZONE[z]))
199203

200204
# Fuel cost for power generation
201205
# for multi-fuel resources
@@ -219,7 +223,7 @@ function fuel!(EP::Model, inputs::Dict, setup::Dict)
219223
sum(omega[t] * EP[:eCFuelOut][y, t] for t in 1:T))
220224
# zonal level total fuel cost for output
221225
@expression(EP, eZonalCFuelOut[z = 1:Z],
222-
sum(EP[:ePlantCFuelOut][y] for y in resources_in_zone_by_rid(gen, z)))
226+
sum(EP[:ePlantCFuelOut][y] for y in RESOURCES_BY_ZONE[z]))
223227

224228
# system level total fuel cost for output
225229
@expression(EP, eTotalCFuelOut, sum(eZonalCFuelOut[z] for z in 1:Z))
@@ -238,9 +242,12 @@ function fuel!(EP::Model, inputs::Dict, setup::Dict)
238242
MULTI_FUELS)))
239243
end
240244

245+
RESOURCES_BY_SINGLE_FUEL = map(1:NUM_FUEL) do f
246+
return intersect(setdiff(resources_with_fuel(gen, fuels[f]), ALLAM_CYCLE_LOX), SINGLE_FUEL)
247+
end
241248
@expression(EP, eFuelConsumption_single[f in 1:NUM_FUEL, t in 1:T],
242249
sum(EP[:vFuel][y, t] + EP[:eStartFuel][y, t]
243-
for y in intersect(setdiff(resources_with_fuel(gen, fuels[f]), ALLAM_CYCLE_LOX), SINGLE_FUEL)))
250+
for y in RESOURCES_BY_SINGLE_FUEL[f]))
244251

245252
@expression(EP, eFuelConsumption[f in 1:NUM_FUEL, t in 1:T],
246253
if !isempty(MULTI_FUELS)

src/model/resources/curtailable_variable_renewable/curtailable_variable_renewable.jl

+5-5
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,9 @@ function curtailable_variable_renewable!(EP::Model, inputs::Dict, setup::Dict)
3737

3838
## Power Balance Expressions ##
3939

40+
VRE_BY_ZONE = [intersect(VRE, resources_in_zone_by_rid(gen, z)) for z in 1:Z]
4041
@expression(EP, ePowerBalanceDisp[t = 1:T, z = 1:Z],
41-
sum(EP[:vP][y, t] for y in intersect(VRE, resources_in_zone_by_rid(gen, z))))
42+
sum(EP[:vP][y, t] for y in VRE_BY_ZONE[z]))
4243
add_similar_to_expression!(EP[:ePowerBalance], EP[:ePowerBalanceDisp])
4344

4445
# Capacity Reserves Margin policy
@@ -80,10 +81,9 @@ function curtailable_variable_renewable!(EP::Model, inputs::Dict, setup::Dict)
8081
fix.(EP[:vP][y, :], 0.0, force = true)
8182
end
8283
##CO2 Polcy Module VRE Generation by zone
83-
@expression(EP, eGenerationByVRE[z = 1:Z, t = 1:T], # the unit is GW
84-
sum(EP[:vP][y, t]
85-
for y in intersect(inputs["VRE"], resources_in_zone_by_rid(gen, z))))
86-
add_similar_to_expression!(EP[:eGenerationByZone], eGenerationByVRE)
84+
# We use the transpose here because eGenerationByZone is [1:Z, 1:T] and
85+
# ePowerBalanceDisp is [1:T, 1:Z].
86+
add_similar_to_expression!(EP[:eGenerationByZone], ePowerBalanceDisp')
8787
end
8888

8989
@doc raw"""

src/model/resources/flexible_demand/flexible_demand.jl

+4-1
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,12 @@ function flexible_demand!(EP::Model, inputs::Dict, setup::Dict)
6565
### Expressions ###
6666

6767
## Power Balance Expressions ##
68+
FLEX_BY_ZONE = map(1:Z) do z
69+
return intersect(FLEX, resources_in_zone_by_rid(gen, z))
70+
end
6871
@expression(EP, ePowerBalanceDemandFlex[t = 1:T, z = 1:Z],
6972
sum(-EP[:vP][y, t] + EP[:vCHARGE_FLEX][y, t]
70-
for y in intersect(FLEX, resources_in_zone_by_rid(gen, z))))
73+
for y in FLEX_BY_ZONE[z]))
7174
add_similar_to_expression!(EP[:ePowerBalance], ePowerBalanceDemandFlex)
7275

7376
# Capacity Reserves Margin policy

src/model/resources/hydro/hydro_res.jl

+5-2
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,11 @@ function hydro_res!(EP::Model, inputs::Dict, setup::Dict)
103103
### Expressions ###
104104

105105
## Power Balance Expressions ##
106+
HYDRO_RES_BY_ZONE = map(1:Z) do z
107+
return intersect(HYDRO_RES, resources_in_zone_by_rid(gen, z))
108+
end
106109
@expression(EP, ePowerBalanceHydroRes[t = 1:T, z = 1:Z],
107-
sum(EP[:vP][y, t] for y in intersect(HYDRO_RES, resources_in_zone_by_rid(gen, z))))
110+
sum(EP[:vP][y, t] for y in HYDRO_RES_BY_ZONE[z]))
108111
add_similar_to_expression!(EP[:ePowerBalance], ePowerBalanceHydroRes)
109112

110113
# Capacity Reserves Margin policy
@@ -180,7 +183,7 @@ function hydro_res!(EP::Model, inputs::Dict, setup::Dict)
180183
end
181184
##CO2 Polcy Module Hydro Res Generation by zone
182185
@expression(EP, eGenerationByHydroRes[z = 1:Z, t = 1:T], # the unit is GW
183-
sum(EP[:vP][y, t] for y in intersect(HYDRO_RES, resources_in_zone_by_rid(gen, z))))
186+
sum(EP[:vP][y, t] for y in HYDRO_RES_BY_ZONE[z]))
184187
add_similar_to_expression!(EP[:eGenerationByZone], eGenerationByHydroRes)
185188
end
186189

src/model/resources/hydrogen/electrolyzer.jl

+5-2
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,12 @@ function electrolyzer!(EP::Model, inputs::Dict, setup::Dict)
8585
### Expressions ###
8686

8787
## Power Balance Expressions ##
88+
ELECTROLYZERS_BY_ZONE = map(1:Z) do z
89+
return intersect(ELECTROLYZERS, resources_in_zone_by_rid(gen, z))
90+
end
8891
@expression(EP, ePowerBalanceElectrolyzers[t in 1:T, z in 1:Z],
8992
sum(EP[:vUSE][y, t]
90-
for y in intersect(ELECTROLYZERS, resources_in_zone_by_rid(gen, z))))
93+
for y in ELECTROLYZERS_BY_ZONE[z]))
9194

9295
# Electrolyzers consume electricity so their vUSE is subtracted from power balance
9396
EP[:ePowerBalance] -= ePowerBalanceElectrolyzers
@@ -154,7 +157,7 @@ function electrolyzer!(EP::Model, inputs::Dict, setup::Dict)
154157
if setup["HydrogenHourlyMatching"] == 1 && setup["HourlyMatching"] == 1
155158
@expression(EP, eHMElectrolyzer[t in 1:T, z in 1:Z],
156159
-sum(EP[:vUSE][y, t]
157-
for y in intersect(resources_in_zone_by_rid(gen, z), ELECTROLYZERS)))
160+
for y in ELECTROLYZERS_BY_ZONE[z]))
158161
add_similar_to_expression!(EP[:eHM], eHMElectrolyzer)
159162
end
160163

src/model/resources/must_run/must_run.jl

+5-3
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,11 @@ function must_run!(EP::Model, inputs::Dict, setup::Dict)
2727
### Expressions ###
2828

2929
## Power Balance Expressions ##
30-
30+
MUST_RUN_BY_ZONE = map(1:Z) do z
31+
return intersect(MUST_RUN, resources_in_zone_by_rid(gen, z))
32+
end
3133
@expression(EP, ePowerBalanceNdisp[t = 1:T, z = 1:Z],
32-
sum(EP[:vP][y, t] for y in intersect(MUST_RUN, resources_in_zone_by_rid(gen, z))))
34+
sum(EP[:vP][y, t] for y in MUST_RUN_BY_ZONE[z]))
3335
add_similar_to_expression!(EP[:ePowerBalance], ePowerBalanceNdisp)
3436

3537
# Capacity Reserves Margin policy
@@ -50,6 +52,6 @@ function must_run!(EP::Model, inputs::Dict, setup::Dict)
5052
EP[:vP][y, t]==inputs["pP_Max"][y, t] * EP[:eTotalCap][y])
5153
##CO2 Polcy Module Must Run Generation by zone
5254
@expression(EP, eGenerationByMustRun[z = 1:Z, t = 1:T], # the unit is GW
53-
sum(EP[:vP][y, t] for y in intersect(MUST_RUN, resources_in_zone_by_rid(gen, z))))
55+
sum(EP[:vP][y, t] for y in MUST_RUN_BY_ZONE[z]))
5456
add_similar_to_expression!(EP[:eGenerationByZone], eGenerationByMustRun)
5557
end

src/model/resources/storage/investment_charge.jl

+6-3
Original file line numberDiff line numberDiff line change
@@ -74,12 +74,15 @@ function investment_charge!(EP::Model, inputs::Dict, setup::Dict)
7474
existing_charge_cap_mw(gen[y]))
7575
end
7676

77+
NEW_AND_RET_CAP_CHARGE = intersect(NEW_CAP_CHARGE, RET_CAP_CHARGE)
78+
NEW_NOT_RET_CAP_CHARGE = setdiff(NEW_CAP_CHARGE, RET_CAP_CHARGE)
79+
RET_NOT_NEW_CAP_CHARGE = setdiff(RET_CAP_CHARGE, NEW_CAP_CHARGE)
7780
@expression(EP, eTotalCapCharge[y in STOR_ASYMMETRIC],
78-
if (y in intersect(NEW_CAP_CHARGE, RET_CAP_CHARGE))
81+
if (y in NEW_AND_RET_CAP_CHARGE)
7982
eExistingCapCharge[y] + vCAPCHARGE[y] - vRETCAPCHARGE[y]
80-
elseif (y in setdiff(NEW_CAP_CHARGE, RET_CAP_CHARGE))
83+
elseif (y in NEW_NOT_RET_CAP_CHARGE)
8184
eExistingCapCharge[y] + vCAPCHARGE[y]
82-
elseif (y in setdiff(RET_CAP_CHARGE, NEW_CAP_CHARGE))
85+
elseif (y in RET_NOT_NEW_CAP_CHARGE)
8386
eExistingCapCharge[y] - vRETCAPCHARGE[y]
8487
else
8588
eExistingCapCharge[y]

src/model/resources/storage/investment_energy.jl

+6-3
Original file line numberDiff line numberDiff line change
@@ -75,12 +75,15 @@ function investment_energy!(EP::Model, inputs::Dict, setup::Dict)
7575
@expression(EP, eExistingCapEnergy[y in STOR_ALL], existing_cap_mwh(gen[y]))
7676
end
7777

78+
NEW_AND_RET_CAP_ENERGY = intersect(NEW_CAP_ENERGY, RET_CAP_ENERGY)
79+
NEW_NOT_RET_CAP_ENERGY = setdiff(NEW_CAP_ENERGY, RET_CAP_ENERGY)
80+
RET_NOT_NEW_CAP_ENERGY = setdiff(RET_CAP_ENERGY, NEW_CAP_ENERGY)
7881
@expression(EP, eTotalCapEnergy[y in STOR_ALL],
79-
if (y in intersect(NEW_CAP_ENERGY, RET_CAP_ENERGY))
82+
if (y in NEW_AND_RET_CAP_ENERGY)
8083
eExistingCapEnergy[y] + vCAPENERGY[y] - vRETCAPENERGY[y]
81-
elseif (y in setdiff(NEW_CAP_ENERGY, RET_CAP_ENERGY))
84+
elseif (y in NEW_NOT_RET_CAP_ENERGY)
8285
eExistingCapEnergy[y] + vCAPENERGY[y]
83-
elseif (y in setdiff(RET_CAP_ENERGY, NEW_CAP_ENERGY))
86+
elseif (y in RET_NOT_NEW_CAP_ENERGY)
8487
eExistingCapEnergy[y] - vRETCAPENERGY[y]
8588
else
8689
eExistingCapEnergy[y]

src/model/resources/storage/storage_all.jl

+8-3
Original file line numberDiff line numberDiff line change
@@ -95,10 +95,13 @@ function storage_all!(EP::Model, inputs::Dict, setup::Dict)
9595

9696
## Power Balance Expressions ##
9797

98+
STOR_ALL_BY_ZONE = map(1:Z) do z
99+
return intersect(STOR_ALL, resources_in_zone_by_rid(gen, z))
100+
end
98101
# Term to represent net dispatch from storage in any period
99102
@expression(EP, ePowerBalanceStor[t = 1:T, z = 1:Z],
100103
sum(vP[y, t] - vCHARGE[y, t]
101-
for y in intersect(resources_in_zone_by_rid(gen, z), STOR_ALL)))
104+
for y in STOR_ALL_BY_ZONE[z]))
102105
add_similar_to_expression!(EP[:ePowerBalance], ePowerBalanceStor)
103106

104107
### Constraints ###
@@ -136,9 +139,11 @@ function storage_all!(EP::Model, inputs::Dict, setup::Dict)
136139

137140
# Hourly matching constraints
138141
if HourlyMatching == 1
142+
QUALIFIED_STOR_ALL_BY_ZONE = map(1:Z) do z
143+
return intersect(QUALIFIED_SUPPLY, STOR_ALL, resources_in_zone_by_rid(gen, z))
144+
end
139145
@expression(EP, eHMCharge[t = 1:T, z = 1:Z],
140-
-sum(vCHARGE[y, t]
141-
for y in intersect(resources_in_zone_by_rid(gen, z), QUALIFIED_SUPPLY, STOR_ALL)))
146+
-sum(vCHARGE[y, t] for y in QUALIFIED_STOR_ALL_BY_ZONE[z]))
142147
add_similar_to_expression!(EP[:eHM], eHMCharge)
143148
end
144149

src/model/resources/thermal/thermal.jl

+4-1
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,12 @@ function thermal!(EP::Model, inputs::Dict, setup::Dict)
2424
thermal_no_commit!(EP, inputs, setup)
2525
end
2626
##CO2 Polcy Module Thermal Generation by zone
27+
THERM_ALL_BY_ZONE = map(1:Z) do z
28+
return intersect(THERM_ALL, resources_in_zone_by_rid(gen, z))
29+
end
2730
@expression(EP, eGenerationByThermAll[z = 1:Z, t = 1:T], # the unit is GW
2831
sum(EP[:vP][y, t]
29-
for y in intersect(inputs["THERM_ALL"], resources_in_zone_by_rid(gen, z))))
32+
for y in THERM_ALL_BY_ZONE[z]))
3033
add_similar_to_expression!(EP[:eGenerationByZone], eGenerationByThermAll)
3134

3235
# Capacity Reserves Margin policy

src/model/resources/thermal/thermal_commit.jl

+4-1
Original file line numberDiff line numberDiff line change
@@ -153,9 +153,12 @@ function thermal_commit!(EP::Model, inputs::Dict, setup::Dict)
153153
end
154154

155155
## Power Balance Expressions ##
156+
THERM_COMMIT_BY_ZONE = map(1:Z) do z
157+
return intersect(THERM_COMMIT, resources_in_zone_by_rid(gen, z))
158+
end
156159
@expression(EP, ePowerBalanceThermCommit[t = 1:T, z = 1:Z],
157160
sum(EP[:vP][y, t]
158-
for y in intersect(THERM_COMMIT, resources_in_zone_by_rid(gen, z))))
161+
for y in THERM_COMMIT_BY_ZONE[z]))
159162
add_similar_to_expression!(EP[:ePowerBalance], ePowerBalanceThermCommit)
160163

161164
### Constraints ###

src/model/resources/thermal/thermal_no_commit.jl

+4-1
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,12 @@ function thermal_no_commit!(EP::Model, inputs::Dict, setup::Dict)
5656
### Expressions ###
5757

5858
## Power Balance Expressions ##
59+
THERM_NO_COMMIT_BY_ZONE = map(1:Z) do z
60+
return intersect(THERM_NO_COMMIT, resources_in_zone_by_rid(gen, z))
61+
end
5962
@expression(EP, ePowerBalanceThermNoCommit[t = 1:T, z = 1:Z],
6063
sum(EP[:vP][y, t]
61-
for y in intersect(THERM_NO_COMMIT, resources_in_zone_by_rid(gen, z))))
64+
for y in THERM_NO_COMMIT_BY_ZONE[z]))
6265
add_similar_to_expression!(EP[:ePowerBalance], ePowerBalanceThermNoCommit)
6366

6467
### Constraints ###

0 commit comments

Comments
 (0)