openTEPES 4.18.9__py3-none-any.whl → 4.18.10__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- openTEPES/__init__.py +1 -1
- openTEPES/openTEPES.py +3 -3
- openTEPES/openTEPES_InputData.py +6 -2
- openTEPES/openTEPES_Main.py +2 -2
- openTEPES/openTEPES_ModelFormulation.py +116 -91
- openTEPES/openTEPES_OutputResults.py +70 -61
- openTEPES/openTEPES_ProblemSolving.py +2 -2
- {opentepes-4.18.9.dist-info → opentepes-4.18.10.dist-info}/METADATA +1 -1
- {opentepes-4.18.9.dist-info → opentepes-4.18.10.dist-info}/RECORD +12 -12
- {opentepes-4.18.9.dist-info → opentepes-4.18.10.dist-info}/WHEEL +0 -0
- {opentepes-4.18.9.dist-info → opentepes-4.18.10.dist-info}/entry_points.txt +0 -0
- {opentepes-4.18.9.dist-info → opentepes-4.18.10.dist-info}/licenses/LICENSE +0 -0
openTEPES/__init__.py
CHANGED
|
@@ -14,7 +14,7 @@ Open Generation, Storage, and Transmission Operation and Expansion Planning Mode
|
|
|
14
14
|
>>> import openTEPES as oT
|
|
15
15
|
>>> oT.routine("9n", "C:\\Users\\UserName\\Documents\\GitHub\\openTEPES", "glpk")
|
|
16
16
|
"""
|
|
17
|
-
__version__ = "4.18.
|
|
17
|
+
__version__ = "4.18.10"
|
|
18
18
|
|
|
19
19
|
from .openTEPES_Main import main
|
|
20
20
|
from .openTEPES import *
|
openTEPES/openTEPES.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"""
|
|
2
|
-
Open Generation, Storage, and Transmission Operation and Expansion Planning Model with RES and ESS (openTEPES) - January
|
|
2
|
+
Open Generation, Storage, and Transmission Operation and Expansion Planning Model with RES and ESS (openTEPES) - January 25, 2026
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
5
|
# import dill as pickle
|
|
@@ -38,8 +38,8 @@ def openTEPES_run(DirName, CaseName, SolverName, pIndOutputResults, pIndLogConso
|
|
|
38
38
|
idxDict['y' ] = 1
|
|
39
39
|
|
|
40
40
|
#%% model declaration
|
|
41
|
-
mTEPES = ConcreteModel('Open Generation, Storage, and Transmission Operation and Expansion Planning Model with RES and ESS (openTEPES) - Version 4.18.
|
|
42
|
-
print( 'Open Generation, Storage, and Transmission Operation and Expansion Planning Model with RES and ESS (openTEPES) - Version 4.18.
|
|
41
|
+
mTEPES = ConcreteModel('Open Generation, Storage, and Transmission Operation and Expansion Planning Model with RES and ESS (openTEPES) - Version 4.18.10 - January 25, 2026')
|
|
42
|
+
print( 'Open Generation, Storage, and Transmission Operation and Expansion Planning Model with RES and ESS (openTEPES) - Version 4.18.10 - January 25, 2026', file=open(f'{_path}/openTEPES_version_{CaseName}.log','w'))
|
|
43
43
|
|
|
44
44
|
pIndOutputResults = [j for i,j in idxDict.items() if i == pIndOutputResults][0]
|
|
45
45
|
pIndLogConsole = [j for i,j in idxDict.items() if i == pIndLogConsole ][0]
|
openTEPES/openTEPES_InputData.py
CHANGED
|
@@ -677,6 +677,7 @@ def DataConfiguration(mTEPES):
|
|
|
677
677
|
mTEPES.psnchp = Set(initialize = [(p,sc,n,chp) for p,sc,n,chp in mTEPES.psn*mTEPES.chp if (p,chp) in mTEPES.pchp])
|
|
678
678
|
mTEPES.psnbo = Set(initialize = [(p,sc,n,bo) for p,sc,n,bo in mTEPES.psn*mTEPES.bo if (p,bo) in mTEPES.pbo ])
|
|
679
679
|
mTEPES.psnhp = Set(initialize = [(p,sc,n,hp) for p,sc,n,hp in mTEPES.psn*mTEPES.hp if (p,hp) in mTEPES.php ])
|
|
680
|
+
mTEPES.psneb = Set(initialize = [(p,sc,n,eb) for p,sc,n,eb in mTEPES.psn*mTEPES.eb if (p,eb) in mTEPES.peb ])
|
|
680
681
|
mTEPES.psnes = Set(initialize = [(p,sc,n,es) for p,sc,n,es in mTEPES.psn*mTEPES.es if (p,es) in mTEPES.pes ])
|
|
681
682
|
mTEPES.psneh = Set(initialize = [(p,sc,n,eh) for p,sc,n,eh in mTEPES.psn*mTEPES.eh if (p,eh) in mTEPES.peh ])
|
|
682
683
|
mTEPES.psnec = Set(initialize = [(p,sc,n,ec) for p,sc,n,ec in mTEPES.psn*mTEPES.ec if (p,ec) in mTEPES.pec ])
|
|
@@ -2082,7 +2083,6 @@ def SettingUpVariables(OptModel, mTEPES):
|
|
|
2082
2083
|
'''
|
|
2083
2084
|
nFixedVariables = 0
|
|
2084
2085
|
|
|
2085
|
-
# fix the must-run existing units and their output
|
|
2086
2086
|
# must-run units must produce at least their minimum output
|
|
2087
2087
|
[OptModel.vTotalOutput[p,sc,n,g].setlb(mTEPES.pMinPowerElec[p,sc,n,g]) for p,sc,n,g in mTEPES.psng if mTEPES.pMustRun[g] == 1 and g not in mTEPES.gc]
|
|
2088
2088
|
|
|
@@ -2119,8 +2119,12 @@ def SettingUpVariables(OptModel, mTEPES):
|
|
|
2119
2119
|
OptModel.vReserveUp [p,sc,n,nr].fix(0.0)
|
|
2120
2120
|
OptModel.vReserveDown [p,sc,n,nr].fix(0.0)
|
|
2121
2121
|
nFixedVariables += 3
|
|
2122
|
+
# fix the must-run existing units and their output
|
|
2123
|
+
if mTEPES.pMustRun[nr] == 1 and mTEPES.pMaxPower2ndBlock[p,sc,n,nr] == 0.0 and nr not in mTEPES.gc:
|
|
2124
|
+
OptModel.vTotalOutput[p,sc,n,nr].fix(mTEPES.pMinPowerElec[p,sc,n,nr])
|
|
2125
|
+
nFixedVariables += 1
|
|
2122
2126
|
if mTEPES.pIndRampReserves == 1:
|
|
2123
|
-
if mTEPES.pMaxPower2ndBlock[p,
|
|
2127
|
+
if mTEPES.pMaxPower2ndBlock[p,sc,n,nr] == 0.0 or mTEPES.pRampUp[nr] == 0.0:
|
|
2124
2128
|
OptModel.vRampReserveUp[p,sc,n,nr].fix(0.0)
|
|
2125
2129
|
OptModel.vRampReserveDw[p,sc,n,nr].fix(0.0)
|
|
2126
2130
|
nFixedVariables += 2
|
openTEPES/openTEPES_Main.py
CHANGED
|
@@ -660,7 +660,7 @@
|
|
|
660
660
|
# For more information on this, and how to apply and follow the GNU AGPL, see
|
|
661
661
|
# <https://www.gnu.org/licenses/>.
|
|
662
662
|
|
|
663
|
-
# Open Generation, Storage, and Transmission Operation and Expansion Planning Model with RES and ESS (openTEPES) - January
|
|
663
|
+
# Open Generation, Storage, and Transmission Operation and Expansion Planning Model with RES and ESS (openTEPES) - January 25, 2026
|
|
664
664
|
# simplicity and transparency in power systems planning
|
|
665
665
|
|
|
666
666
|
# Developed by
|
|
@@ -693,7 +693,7 @@ GREEN = "\033[32m"
|
|
|
693
693
|
BLUE = "\033[34m"
|
|
694
694
|
RESET = "\033[0m"
|
|
695
695
|
|
|
696
|
-
print(GREEN + 'Open Generation, Storage, and Transmission Operation and Expansion Planning Model with RES and ESS (openTEPES) - Version 4.18.
|
|
696
|
+
print(GREEN + 'Open Generation, Storage, and Transmission Operation and Expansion Planning Model with RES and ESS (openTEPES) - Version 4.18.10 - January 25, 2026' + RESET)
|
|
697
697
|
print(BLUE + '#### Academic research license - for non-commercial use only ####' + RESET + '\n')
|
|
698
698
|
|
|
699
699
|
parser = argparse.ArgumentParser(description='Introducing main parameters...')
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"""
|
|
2
|
-
Open Generation, Storage, and Transmission Operation and Expansion Planning Model with RES and ESS (openTEPES) - January
|
|
2
|
+
Open Generation, Storage, and Transmission Operation and Expansion Planning Model with RES and ESS (openTEPES) - January 23, 2026
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
5
|
import time
|
|
@@ -181,7 +181,7 @@ def GenerationOperationModelFormulationObjFunct(OptModel, mTEPES, pIndLogConsole
|
|
|
181
181
|
+ mTEPES.pLoadLevelDuration[p,sc,n]() * sum(mTEPES.pEmissionRate[bo] * 1e-3 * OptModel.vTotalOutputHeat[p,sc,n,bo] for bo in mTEPES.bo if (ar,bo) in mTEPES.a2g and (p,bo) in mTEPES.pbo)) #1e-3 to change from tCO2/MWh to MtCO2/GWh
|
|
182
182
|
else:
|
|
183
183
|
return Constraint.Skip
|
|
184
|
-
setattr(OptModel, f'eTotalEmissionArea_{p}_{sc}_{st}', Constraint(mTEPES.n
|
|
184
|
+
setattr(OptModel, f'eTotalEmissionArea_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.ar, rule=eTotalEmissionArea, doc='area total emission [MtCO2 eq]'))
|
|
185
185
|
|
|
186
186
|
def eTotalECostArea(OptModel,n,ar):
|
|
187
187
|
if sum(mTEPES.pEmissionVarCost[p,sc,n,g] for g in mTEPES.g if (ar,g) in mTEPES.a2g and (p,g) in mTEPES.pg):
|
|
@@ -189,14 +189,14 @@ def GenerationOperationModelFormulationObjFunct(OptModel, mTEPES, pIndLogConsole
|
|
|
189
189
|
+ sum(mTEPES.pEmissionVarCost[p,sc,n,bo] * OptModel.vTotalOutputHeat[p,sc,n,bo] for bo in mTEPES.bo if (ar,bo) in mTEPES.a2g and (p,bo) in mTEPES.pbo)))
|
|
190
190
|
else:
|
|
191
191
|
return Constraint.Skip
|
|
192
|
-
setattr(OptModel, f'eTotalECostArea_{p}_{sc}_{st}', Constraint(mTEPES.n
|
|
192
|
+
setattr(OptModel, f'eTotalECostArea_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.ar, rule=eTotalECostArea, doc='area emission cost [MEUR]'))
|
|
193
193
|
|
|
194
194
|
def eTotalRESEnergyArea(OptModel,n,ar):
|
|
195
195
|
if mTEPES.pRESEnergy[p,ar] and st == mTEPES.Last_st:
|
|
196
196
|
return OptModel.vTotalRESEnergyArea[p,sc,n,ar] == mTEPES.pLoadLevelDuration[p,sc,n]() * sum(OptModel.vTotalOutput[p,sc,n,re] for re in mTEPES.re if (ar,re) in mTEPES.a2g and (p,re) in mTEPES.pre)
|
|
197
197
|
else:
|
|
198
198
|
return Constraint.Skip
|
|
199
|
-
setattr(OptModel, f'eTotalRESEnergyArea_{p}_{sc}_{st}', Constraint(mTEPES.n
|
|
199
|
+
setattr(OptModel, f'eTotalRESEnergyArea_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.ar, rule=eTotalRESEnergyArea, doc='area RES energy [GWh]'))
|
|
200
200
|
|
|
201
201
|
def eTotalNCost(OptModel,n):
|
|
202
202
|
return OptModel.vTotalNCost[p,sc,n] == mTEPES.pLoadLevelDuration[p,sc,n]() * pEpsilon * sum(OptModel.vLineLosses[p,sc,n,ni,nf,cc] for ni,nf,cc in mTEPES.ll if (p,ni,nf,cc) in mTEPES.pll)
|
|
@@ -232,7 +232,7 @@ def GenerationOperationModelFormulationInvestment(OptModel, mTEPES, pIndLogConso
|
|
|
232
232
|
return OptModel.vCommitment[p,sc,n,gc] == OptModel.vGenerationInvest[p,gc]
|
|
233
233
|
else:
|
|
234
234
|
return Constraint.Skip
|
|
235
|
-
setattr(OptModel, f'eInstallGenComm_{p}_{sc}_{st}', Constraint(mTEPES.n
|
|
235
|
+
setattr(OptModel, f'eInstallGenComm_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.gc, rule=eInstallGenComm, doc='commitment if installed unit [p.u.]'))
|
|
236
236
|
|
|
237
237
|
if pIndLogConsole == 1:
|
|
238
238
|
print('eInstallGenComm ... ', len(getattr(OptModel, f'eInstallGenComm_{p}_{sc}_{st}')), ' rows')
|
|
@@ -245,7 +245,7 @@ def GenerationOperationModelFormulationInvestment(OptModel, mTEPES, pIndLogConso
|
|
|
245
245
|
return Constraint.Skip
|
|
246
246
|
else:
|
|
247
247
|
return Constraint.Skip
|
|
248
|
-
setattr(OptModel, f'eInstallESSComm_{p}_{sc}_{st}', Constraint(mTEPES.n
|
|
248
|
+
setattr(OptModel, f'eInstallESSComm_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.ec, rule=eInstallESSComm, doc='commitment if ESS unit [p.u.]'))
|
|
249
249
|
|
|
250
250
|
if pIndLogConsole == 1:
|
|
251
251
|
print('eInstallESSComm ... ', len(getattr(OptModel, f'eInstallESSComm_{p}_{sc}_{st}')), ' rows')
|
|
@@ -258,7 +258,7 @@ def GenerationOperationModelFormulationInvestment(OptModel, mTEPES, pIndLogConso
|
|
|
258
258
|
return Constraint.Skip
|
|
259
259
|
else:
|
|
260
260
|
return Constraint.Skip
|
|
261
|
-
setattr(OptModel, f'eInstallGenCap_{p}_{sc}_{st}', Constraint(mTEPES.n
|
|
261
|
+
setattr(OptModel, f'eInstallGenCap_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.gc, rule=eInstallGenCap, doc='output if installed gen unit [p.u.]'))
|
|
262
262
|
|
|
263
263
|
if pIndLogConsole == 1:
|
|
264
264
|
print('eInstallGenCap ... ', len(getattr(OptModel, f'eInstallGenCap_{p}_{sc}_{st}')), ' rows')
|
|
@@ -271,7 +271,7 @@ def GenerationOperationModelFormulationInvestment(OptModel, mTEPES, pIndLogConso
|
|
|
271
271
|
return Constraint.Skip
|
|
272
272
|
else:
|
|
273
273
|
return Constraint.Skip
|
|
274
|
-
setattr(OptModel, f'eInstallFHUCap_{p}_{sc}_{st}', Constraint(mTEPES.n
|
|
274
|
+
setattr(OptModel, f'eInstallFHUCap_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.bc, rule=eInstallFHUCap, doc='heat production if installed fuel heating unit [p.u.]'))
|
|
275
275
|
|
|
276
276
|
if pIndLogConsole == 1:
|
|
277
277
|
print('eInstallFHUCap ... ', len(getattr(OptModel, f'eInstallFHUCap_{p}_{sc}_{st}')), ' rows')
|
|
@@ -284,7 +284,7 @@ def GenerationOperationModelFormulationInvestment(OptModel, mTEPES, pIndLogConso
|
|
|
284
284
|
return Constraint.Skip
|
|
285
285
|
else:
|
|
286
286
|
return Constraint.Skip
|
|
287
|
-
setattr(OptModel, f'eInstallConESS_{p}_{sc}_{st}', Constraint(mTEPES.n
|
|
287
|
+
setattr(OptModel, f'eInstallConESS_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.ec, rule=eInstallConESS, doc='consumption if installed ESS unit [p.u.]'))
|
|
288
288
|
|
|
289
289
|
if pIndLogConsole == 1:
|
|
290
290
|
print('eInstallConESS ... ', len(getattr(OptModel, f'eInstallConESS_{p}_{sc}_{st}')), ' rows')
|
|
@@ -297,7 +297,7 @@ def GenerationOperationModelFormulationInvestment(OptModel, mTEPES, pIndLogConso
|
|
|
297
297
|
return Constraint.Skip
|
|
298
298
|
else:
|
|
299
299
|
return Constraint.Skip
|
|
300
|
-
setattr(OptModel, f'eUninstallGenComm_{p}_{sc}_{st}', Constraint(mTEPES.n
|
|
300
|
+
setattr(OptModel, f'eUninstallGenComm_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.gd, rule=eUninstallGenComm, doc='commitment if uninstalled unit [p.u.]'))
|
|
301
301
|
|
|
302
302
|
if pIndLogConsole == 1:
|
|
303
303
|
print('eUninstallGenComm ... ', len(getattr(OptModel, f'eUninstallGenComm_{p}_{sc}_{st}')), ' rows')
|
|
@@ -310,7 +310,7 @@ def GenerationOperationModelFormulationInvestment(OptModel, mTEPES, pIndLogConso
|
|
|
310
310
|
return Constraint.Skip
|
|
311
311
|
else:
|
|
312
312
|
return Constraint.Skip
|
|
313
|
-
setattr(OptModel, f'eUninstallGenCap_{p}_{sc}_{st}', Constraint(mTEPES.n
|
|
313
|
+
setattr(OptModel, f'eUninstallGenCap_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.gd, rule=eUninstallGenCap, doc='output if uninstalled gen unit [p.u.]'))
|
|
314
314
|
|
|
315
315
|
if pIndLogConsole == 1:
|
|
316
316
|
print('eUninstallGenCap ... ', len(getattr(OptModel, f'eUninstallGenCap_{p}_{sc}_{st}')), ' rows')
|
|
@@ -414,7 +414,7 @@ def GenerationOperationModelFormulationDemand(OptModel, mTEPES, pIndLogConsole,
|
|
|
414
414
|
return sum(OptModel.vCommitment[p,sc,n,nr] * mTEPES.pInertia[nr] for nr in mTEPES.nr if (ar,nr) in mTEPES.a2g) >= mTEPES.pSystemInertia[p,sc,n,ar]
|
|
415
415
|
else:
|
|
416
416
|
return Constraint.Skip
|
|
417
|
-
setattr(OptModel, f'eSystemInertia_{p}_{sc}_{st}', Constraint(mTEPES.n
|
|
417
|
+
setattr(OptModel, f'eSystemInertia_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.ar, rule=eSystemInertia, doc='system inertia [s]'))
|
|
418
418
|
|
|
419
419
|
if pIndLogConsole == 1:
|
|
420
420
|
print('eSystemInertia ... ', len(getattr(OptModel, f'eSystemInertia_{p}_{sc}_{st}')), ' rows')
|
|
@@ -429,7 +429,7 @@ def GenerationOperationModelFormulationDemand(OptModel, mTEPES, pIndLogConsole,
|
|
|
429
429
|
return Constraint.Skip
|
|
430
430
|
return sum(OptModel.vReserveUp [p,sc,n,nr] for nr in n2a[ar] if mTEPES.pIndOperReserveGen[nr] == 0 and (p,nr) in mTEPES.pnr) + sum(OptModel.vESSReserveUp [p,sc,n,eh] for eh in e2a[ar] if mTEPES.pIndOperReserveCon[eh] == 0 and (p,eh) in mTEPES.peh) == mTEPES.pOperReserveUp[p,sc,n,ar]
|
|
431
431
|
|
|
432
|
-
setattr(OptModel, f'eOperReserveUp_{p}_{sc}_{st}', Constraint(mTEPES.n
|
|
432
|
+
setattr(OptModel, f'eOperReserveUp_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.ar, rule=eOperReserveUp, doc='up operating reserve [GW]'))
|
|
433
433
|
|
|
434
434
|
if pIndLogConsole == 1:
|
|
435
435
|
print('eOperReserveUp ... ', len(getattr(OptModel, f'eOperReserveUp_{p}_{sc}_{st}')), ' rows')
|
|
@@ -444,7 +444,7 @@ def GenerationOperationModelFormulationDemand(OptModel, mTEPES, pIndLogConsole,
|
|
|
444
444
|
return Constraint.Skip
|
|
445
445
|
return sum(OptModel.vReserveDown[p,sc,n,nr] for nr in n2a[ar] if mTEPES.pIndOperReserveGen[nr] == 0 and (p,nr) in mTEPES.pnr) + sum(OptModel.vESSReserveDown[p,sc,n,eh] for eh in e2a[ar] if mTEPES.pIndOperReserveCon[eh] == 0 and (p,eh) in mTEPES.peh) == mTEPES.pOperReserveDw[p,sc,n,ar]
|
|
446
446
|
|
|
447
|
-
setattr(OptModel, f'eOperReserveDw_{p}_{sc}_{st}', Constraint(mTEPES.n
|
|
447
|
+
setattr(OptModel, f'eOperReserveDw_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.ar, rule=eOperReserveDw, doc='down operating reserve [GW]'))
|
|
448
448
|
|
|
449
449
|
if pIndLogConsole == 1:
|
|
450
450
|
print('eOperReserveDw ... ', len(getattr(OptModel, f'eOperReserveDw_{p}_{sc}_{st}')), ' rows')
|
|
@@ -462,7 +462,7 @@ def GenerationOperationModelFormulationDemand(OptModel, mTEPES, pIndLogConsole,
|
|
|
462
462
|
|
|
463
463
|
return OptModel.vReserveDown[p,sc,n,nr] >= OptModel.vReserveUp[p,sc,n,nr] * mTEPES.pMinRatioDwUp
|
|
464
464
|
|
|
465
|
-
setattr(OptModel, f'eReserveMinRatioDwUp_{p}_{sc}_{st}', Constraint(mTEPES.n
|
|
465
|
+
setattr(OptModel, f'eReserveMinRatioDwUp_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.nr, rule=eReserveMinRatioDwUp, doc='minimum ratio down to up operating reserve [GW]'))
|
|
466
466
|
|
|
467
467
|
if pIndLogConsole == 1:
|
|
468
468
|
print('eReserveMinRatioDwUp ... ', len(getattr(OptModel, f'eReserveMinRatioDwUp_{p}_{sc}_{st}')), ' rows')
|
|
@@ -480,7 +480,7 @@ def GenerationOperationModelFormulationDemand(OptModel, mTEPES, pIndLogConsole,
|
|
|
480
480
|
|
|
481
481
|
return OptModel.vReserveDown[p,sc,n,nr] <= OptModel.vReserveUp[p,sc,n,nr] * mTEPES.pMaxRatioDwUp
|
|
482
482
|
|
|
483
|
-
setattr(OptModel, f'eReserveMaxRatioDwUp_{p}_{sc}_{st}', Constraint(mTEPES.n
|
|
483
|
+
setattr(OptModel, f'eReserveMaxRatioDwUp_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.nr, rule=eReserveMaxRatioDwUp, doc='maximum ratio down to up operating reserve [GW]'))
|
|
484
484
|
|
|
485
485
|
if pIndLogConsole == 1:
|
|
486
486
|
print('eReserveMaxRatioDwUp ... ', len(getattr(OptModel, f'eReserveMaxRatioDwUp_{p}_{sc}_{st}')), ' rows')
|
|
@@ -497,7 +497,7 @@ def GenerationOperationModelFormulationDemand(OptModel, mTEPES, pIndLogConsole,
|
|
|
497
497
|
return Constraint.Skip
|
|
498
498
|
|
|
499
499
|
return OptModel.vESSReserveDown[p,sc,n,eh] >= OptModel.vESSReserveUp[p,sc,n,eh] * mTEPES.pMinRatioDwUp
|
|
500
|
-
setattr(OptModel, f'eRsrvMinRatioDwUpESS_{p}_{sc}_{st}', Constraint(mTEPES.n
|
|
500
|
+
setattr(OptModel, f'eRsrvMinRatioDwUpESS_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.eh, rule=eRsrvMinRatioDwUpESS, doc='minimum ratio down to up operating reserve [GW]'))
|
|
501
501
|
|
|
502
502
|
if pIndLogConsole == 1:
|
|
503
503
|
print('eRsrvMinRatioDwUpESS ... ', len(getattr(OptModel, f'eRsrvMinRatioDwUpESS_{p}_{sc}_{st}')), ' rows')
|
|
@@ -515,7 +515,7 @@ def GenerationOperationModelFormulationDemand(OptModel, mTEPES, pIndLogConsole,
|
|
|
515
515
|
|
|
516
516
|
return OptModel.vESSReserveDown[p,sc,n,eh] <= OptModel.vESSReserveUp[p,sc,n,eh] * mTEPES.pMaxRatioDwUp
|
|
517
517
|
|
|
518
|
-
setattr(OptModel, f'eRsrvMaxRatioDwUpESS_{p}_{sc}_{st}', Constraint(mTEPES.n
|
|
518
|
+
setattr(OptModel, f'eRsrvMaxRatioDwUpESS_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.eh, rule=eRsrvMaxRatioDwUpESS, doc='maximum ratio down to up operating reserve [GW]'))
|
|
519
519
|
|
|
520
520
|
if pIndLogConsole == 1:
|
|
521
521
|
print('eRsrvMaxRatioDwUpESS ... ', len(getattr(OptModel, f'eRsrvMaxRatioDwUpESS_{p}_{sc}_{st}')), ' rows')
|
|
@@ -587,7 +587,7 @@ def GenerationOperationModelFormulationDemand(OptModel, mTEPES, pIndLogConsole,
|
|
|
587
587
|
sum(OptModel.vLineLosses[p,sc,n,ni,nd,cc] for ni,cc in linl [nd] if (p,ni,nd,cc) in mTEPES.pll) + sum(OptModel.vFlowElec[p,sc,n,ni,nd,cc] for ni,cc in lin [nd] if (p,ni,nd,cc) in mTEPES.pla)) == mTEPES.pDemandElec[p,sc,n,nd]
|
|
588
588
|
else:
|
|
589
589
|
return Constraint.Skip
|
|
590
|
-
setattr(OptModel, f'eBalanceElec_{p}_{sc}_{st}', Constraint(mTEPES.n
|
|
590
|
+
setattr(OptModel, f'eBalanceElec_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.nd, rule=eBalanceElec, doc='electric load generation balance [GW]'))
|
|
591
591
|
|
|
592
592
|
if pIndLogConsole == 1:
|
|
593
593
|
print('eBalanceElec ... ', len(getattr(OptModel, f'eBalanceElec_{p}_{sc}_{st}')), ' rows')
|
|
@@ -694,7 +694,7 @@ def GenerationOperationModelFormulationStorage(OptModel, mTEPES, pIndLogConsole,
|
|
|
694
694
|
return mTEPES.pDuration[p,sc,n]()*mTEPES.pEfficiency[eh]*OptModel.vESSTotalCharge[p,sc,n,eh] <= sum(mTEPES.pDuration[p,sc,n2]()*OptModel.vTotalOutput[p,sc,n2,eh] for n2 in list(mTEPES.n2)[mTEPES.n.ord(n):mTEPES.n.ord(n)+mTEPES.pShiftTime[eh]])
|
|
695
695
|
else:
|
|
696
696
|
return Constraint.Skip
|
|
697
|
-
setattr(OptModel, f'eMaxShiftTime_{p}_{sc}_{st}', Constraint(mTEPES.n
|
|
697
|
+
setattr(OptModel, f'eMaxShiftTime_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.eh, rule=eMaxShiftTime, doc='Maximum shift time [GWh]'))
|
|
698
698
|
|
|
699
699
|
if pIndLogConsole == 1:
|
|
700
700
|
print('eMaxShiftTime ... ', len(getattr(OptModel, f'eMaxShiftTime_{p}_{sc}_{st}')), ' rows')
|
|
@@ -713,7 +713,7 @@ def GenerationOperationModelFormulationStorage(OptModel, mTEPES, pIndLogConsole,
|
|
|
713
713
|
# Hydro case equation
|
|
714
714
|
else:
|
|
715
715
|
return (OptModel.vCharge2ndBlock[p,sc,n,eh] + OptModel.vESSReserveDown[p,sc,n,eh]) / mTEPES.pMaxCharge2ndBlock[p,sc,n,eh] <= OptModel.vCommitmentCons[p,sc,n,eh]
|
|
716
|
-
setattr(OptModel, f'eMaxCharge_{p}_{sc}_{st}', Constraint(mTEPES.n
|
|
716
|
+
setattr(OptModel, f'eMaxCharge_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.eh, rule=eMaxCharge, doc='max charge of an ESS [p.u.]'))
|
|
717
717
|
|
|
718
718
|
if pIndLogConsole == 1:
|
|
719
719
|
print('eMaxCharge ... ', len(getattr(OptModel, f'eMaxCharge_{p}_{sc}_{st}')), ' rows')
|
|
@@ -732,7 +732,7 @@ def GenerationOperationModelFormulationStorage(OptModel, mTEPES, pIndLogConsole,
|
|
|
732
732
|
if not mTEPES.pMaxCharge2ndBlock[p,sc,n,eh]:
|
|
733
733
|
return Constraint.Skip
|
|
734
734
|
return OptModel.vCharge2ndBlock[p,sc,n,eh] - OptModel.vESSReserveUp[p,sc,n,eh] >= 0.0
|
|
735
|
-
setattr(OptModel, f'eMinCharge_{p}_{sc}_{st}', Constraint(mTEPES.n
|
|
735
|
+
setattr(OptModel, f'eMinCharge_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.eh, rule=eMinCharge, doc='min charge of an ESS [p.u.]'))
|
|
736
736
|
|
|
737
737
|
if pIndLogConsole == 1:
|
|
738
738
|
print('eMinCharge ... ', len(getattr(OptModel, f'eMinCharge_{p}_{sc}_{st}')), ' rows')
|
|
@@ -742,7 +742,7 @@ def GenerationOperationModelFormulationStorage(OptModel, mTEPES, pIndLogConsole,
|
|
|
742
742
|
# return OptModel.vTotalOutput[p,sc,n,eh] / mTEPES.pMaxPowerElec[p,sc,n,eh] + OptModel.vCharge2ndBlock[p,sc,n,eh] / mTEPES.pMaxCharge[p,sc,n,eh] <= 1
|
|
743
743
|
# else:
|
|
744
744
|
# return Constraint.Skip
|
|
745
|
-
# OptModel.eChargeDischarge = Constraint(mTEPES.n
|
|
745
|
+
# OptModel.eChargeDischarge = Constraint(mTEPES.n*mTEPES.eh, rule=eChargeDischarge, doc='incompatibility between charge and discharge [p.u.]')
|
|
746
746
|
|
|
747
747
|
# Generators with consumption capability cannot be consuming and generating simultaneously
|
|
748
748
|
def eChargeDischarge(OptModel,n,eh):
|
|
@@ -760,7 +760,7 @@ def GenerationOperationModelFormulationStorage(OptModel, mTEPES, pIndLogConsole,
|
|
|
760
760
|
# Hydro Generator
|
|
761
761
|
else:
|
|
762
762
|
return OptModel.vCommitment[p,sc,n,eh] + OptModel.vCommitmentCons[p,sc,n,eh] <= 1.0
|
|
763
|
-
setattr(OptModel, f'eChargeDischarge_{p}_{sc}_{st}', Constraint(mTEPES.n
|
|
763
|
+
setattr(OptModel, f'eChargeDischarge_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.eh, rule=eChargeDischarge, doc='incompatibility between charge and discharge [p.u.]'))
|
|
764
764
|
|
|
765
765
|
if pIndLogConsole == 1:
|
|
766
766
|
print('eChargeDischarge ... ', len(getattr(OptModel, f'eChargeDischarge_{p}_{sc}_{st}')), ' rows')
|
|
@@ -787,7 +787,7 @@ def GenerationOperationModelFormulationStorage(OptModel, mTEPES, pIndLogConsole,
|
|
|
787
787
|
return OptModel.vESSTotalCharge[p,sc,n,eh] == OptModel.vCharge2ndBlock[p,sc,n,eh] + mTEPES.pDwReserveActivation * OptModel.vESSReserveDown[p,sc,n,eh] - mTEPES.pUpReserveActivation * OptModel.vESSReserveUp[p,sc,n,eh]
|
|
788
788
|
else:
|
|
789
789
|
return OptModel.vESSTotalCharge[p,sc,n,eh] / mTEPES.pMinCharge[p,sc,n,eh] == OptModel.vCommitmentCons[p,sc,n,eh] + (OptModel.vCharge2ndBlock[p,sc,n,eh] + mTEPES.pDwReserveActivation * OptModel.vESSReserveDown[p,sc,n,eh] - mTEPES.pUpReserveActivation * OptModel.vESSReserveUp[p,sc,n,eh]) / mTEPES.pMinCharge[p,sc,n,eh]
|
|
790
|
-
setattr(OptModel, f'eESSTotalCharge_{p}_{sc}_{st}', Constraint(mTEPES.n
|
|
790
|
+
setattr(OptModel, f'eESSTotalCharge_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.eh, rule=eESSTotalCharge, doc='total charge of an ESS unit [GW]'))
|
|
791
791
|
|
|
792
792
|
if pIndLogConsole == 1:
|
|
793
793
|
print('eESSTotalCharge ... ', len(getattr(OptModel, f'eESSTotalCharge_{p}_{sc}_{st}')), ' rows')
|
|
@@ -800,7 +800,7 @@ def GenerationOperationModelFormulationStorage(OptModel, mTEPES, pIndLogConsole,
|
|
|
800
800
|
return Constraint.Skip
|
|
801
801
|
else:
|
|
802
802
|
return Constraint.Skip
|
|
803
|
-
setattr(OptModel, f'eChargeOutflows_{p}_{sc}_{st}', Constraint(mTEPES.n
|
|
803
|
+
setattr(OptModel, f'eChargeOutflows_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.eh, rule=eChargeOutflows, doc='incompatibility between charge and outflows use [p.u.]'))
|
|
804
804
|
|
|
805
805
|
if pIndLogConsole == 1:
|
|
806
806
|
print('eChargeOutflows ... ', len(getattr(OptModel, f'eChargeOutflows_{p}_{sc}_{st}')), ' rows')
|
|
@@ -1063,47 +1063,75 @@ def GenerationOperationModelFormulationCommitment(OptModel, mTEPES, pIndLogConso
|
|
|
1063
1063
|
a2n[nr].append(ar)
|
|
1064
1064
|
|
|
1065
1065
|
def eMaxOutput2ndBlock(OptModel,n,nr):
|
|
1066
|
-
if
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1066
|
+
if mTEPES.pMaxPower2ndBlock[p,sc,n,nr] == 0.0:
|
|
1067
|
+
return Constraint.Skip
|
|
1068
|
+
if (p,nr) in mTEPES.pnr and (nr not in mTEPES.es or (nr in mTEPES.es and (mTEPES.pTotalMaxCharge[nr] or mTEPES.pTotalEnergyInflows[nr]))):
|
|
1069
|
+
if sum(mTEPES.pOperReserveUp[p,sc,n,ar] for ar in a2n[nr]):
|
|
1070
|
+
if mTEPES.pIndRampReserves == 0 or sum(mTEPES.pRampReserveUp[p,sc,n,ar] for ar in mTEPES.ar) == 0.0:
|
|
1071
|
+
if mTEPES.pIndOperReserveGen[nr] != 1 and n != mTEPES.n.last():
|
|
1072
|
+
return (OptModel.vOutput2ndBlock[p,sc,n,nr] + OptModel.vReserveUp [p,sc,n,nr] ) / mTEPES.pMaxPower2ndBlock[p,sc,n,nr] <= OptModel.vCommitment[p,sc,n,nr] - OptModel.vStartUp[p,sc,n,nr] - OptModel.vShutDown[p,sc,mTEPES.n.next(n),nr]
|
|
1073
|
+
elif mTEPES.pIndOperReserveGen[nr] != 1 and n == mTEPES.n.last():
|
|
1074
|
+
return (OptModel.vOutput2ndBlock[p,sc,n,nr] + OptModel.vReserveUp [p,sc,n,nr] ) / mTEPES.pMaxPower2ndBlock[p,sc,n,nr] <= OptModel.vCommitment[p,sc,n,nr] - OptModel.vStartUp[p,sc,n,nr]
|
|
1075
|
+
else:
|
|
1076
|
+
return Constraint.Skip
|
|
1077
|
+
elif mTEPES.pIndRampReserves == 1 and sum(mTEPES.pRampReserveUp[p,sc,n,ar] for ar in mTEPES.ar) > 0.0:
|
|
1078
|
+
if mTEPES.pIndOperReserveGen[nr] != 1 and n != mTEPES.n.last():
|
|
1079
|
+
return (OptModel.vOutput2ndBlock[p,sc,n,nr] + OptModel.vReserveUp [p,sc,n,nr] + OptModel.vRampReserveUp [p,sc,n,nr]) / mTEPES.pMaxPower2ndBlock[p,sc,n,nr] <= OptModel.vCommitment[p,sc,n,nr] - OptModel.vStartUp[p,sc,n,nr] - OptModel.vShutDown[p,sc,mTEPES.n.next(n),nr]
|
|
1080
|
+
elif mTEPES.pIndOperReserveGen[nr] != 1 and n == mTEPES.n.last():
|
|
1081
|
+
return (OptModel.vOutput2ndBlock[p,sc,n,nr] + OptModel.vReserveUp [p,sc,n,nr] + OptModel.vRampReserveUp [p,sc,n,nr]) / mTEPES.pMaxPower2ndBlock[p,sc,n,nr] <= OptModel.vCommitment[p,sc,n,nr] - OptModel.vStartUp[p,sc,n,nr]
|
|
1082
|
+
else:
|
|
1083
|
+
return Constraint.Skip
|
|
1072
1084
|
else:
|
|
1073
1085
|
return Constraint.Skip
|
|
1074
|
-
|
|
1075
|
-
if mTEPES.
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1086
|
+
if sum(mTEPES.pOperReserveUp[p,sc,n,ar] for ar in a2n[nr]) == 0.0:
|
|
1087
|
+
if mTEPES.pIndRampReserves == 0 or sum(mTEPES.pRampReserveUp[p,sc,n,ar] for ar in mTEPES.ar) == 0.0:
|
|
1088
|
+
if n != mTEPES.n.last():
|
|
1089
|
+
return (OptModel.vOutput2ndBlock[p,sc,n,nr] ) / mTEPES.pMaxPower2ndBlock[p,sc,n,nr] <= OptModel.vCommitment[p,sc,n,nr] - OptModel.vStartUp[p,sc,n,nr] - OptModel.vShutDown[p,sc,mTEPES.n.next(n),nr]
|
|
1090
|
+
elif n == mTEPES.n.last():
|
|
1091
|
+
return (OptModel.vOutput2ndBlock[p,sc,n,nr] ) / mTEPES.pMaxPower2ndBlock[p,sc,n,nr] <= OptModel.vCommitment[p,sc,n,nr] - OptModel.vStartUp[p,sc,n,nr]
|
|
1092
|
+
else:
|
|
1093
|
+
return Constraint.Skip
|
|
1094
|
+
elif mTEPES.pIndRampReserves == 1 and sum(mTEPES.pRampReserveUp[p,sc,n,ar] for ar in mTEPES.ar) > 0.0:
|
|
1095
|
+
if n != mTEPES.n.last():
|
|
1096
|
+
return (OptModel.vOutput2ndBlock[p,sc,n,nr] + OptModel.vRampReserveUp [p,sc,n,nr]) / mTEPES.pMaxPower2ndBlock[p,sc,n,nr] <= OptModel.vCommitment[p,sc,n,nr] - OptModel.vStartUp[p,sc,n,nr] - OptModel.vShutDown[p,sc,mTEPES.n.next(n),nr]
|
|
1097
|
+
elif n == mTEPES.n.last():
|
|
1098
|
+
return (OptModel.vOutput2ndBlock[p,sc,n,nr] + OptModel.vRampReserveUp [p,sc,n,nr]) / mTEPES.pMaxPower2ndBlock[p,sc,n,nr] <= OptModel.vCommitment[p,sc,n,nr] - OptModel.vStartUp[p,sc,n,nr]
|
|
1099
|
+
else:
|
|
1100
|
+
return Constraint.Skip
|
|
1079
1101
|
else:
|
|
1080
1102
|
return Constraint.Skip
|
|
1081
|
-
else:
|
|
1082
|
-
return Constraint.Skip
|
|
1083
1103
|
else:
|
|
1084
1104
|
return Constraint.Skip
|
|
1085
|
-
setattr(OptModel, f'eMaxOutput2ndBlock_{p}_{sc}_{st}', Constraint(mTEPES.n
|
|
1105
|
+
setattr(OptModel, f'eMaxOutput2ndBlock_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.nr, rule=eMaxOutput2ndBlock, doc='max output of the second block of a committed unit [p.u.]'))
|
|
1086
1106
|
|
|
1087
1107
|
if pIndLogConsole == 1:
|
|
1088
1108
|
print('eMaxOutput2ndBlock ... ', len(getattr(OptModel, f'eMaxOutput2ndBlock_{p}_{sc}_{st}')), ' rows')
|
|
1089
1109
|
|
|
1090
1110
|
def eMinOutput2ndBlock(OptModel,n,nr):
|
|
1091
|
-
if
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
if
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1111
|
+
if mTEPES.pMaxPower2ndBlock[p,sc,n,nr] == 0.0:
|
|
1112
|
+
return Constraint.Skip
|
|
1113
|
+
if (p,nr) in mTEPES.pnr and (nr not in mTEPES.es or (nr in mTEPES.es and (mTEPES.pTotalMaxCharge[nr] or mTEPES.pTotalEnergyInflows[nr]))):
|
|
1114
|
+
if sum(mTEPES.pOperReserveDw[p,sc,n,ar] for ar in a2n[nr]):
|
|
1115
|
+
if mTEPES.pIndOperReserveGen[nr] != 1 and (mTEPES.pIndRampReserves == 0 or sum(mTEPES.pRampReserveDw[p,sc,n,ar] for ar in mTEPES.ar) == 0.0):
|
|
1116
|
+
return OptModel.vOutput2ndBlock[p,sc,n,nr] - OptModel.vReserveDown[p,sc,n,nr] >= 0.0
|
|
1117
|
+
elif mTEPES.pIndOperReserveGen[nr] != 1 and mTEPES.pIndRampReserves == 1 and sum(mTEPES.pRampReserveDw[p,sc,n,ar] for ar in mTEPES.ar) > 0.0:
|
|
1118
|
+
return OptModel.vOutput2ndBlock[p,sc,n,nr] - OptModel.vReserveDown[p,sc,n,nr] - OptModel.vRampReserveDw[p,sc,n,nr] >= 0.0
|
|
1119
|
+
else:
|
|
1120
|
+
return Constraint.Skip
|
|
1121
|
+
if sum(mTEPES.pOperReserveDw[p,sc,n,ar] for ar in a2n[nr]) == 0.0:
|
|
1122
|
+
if mTEPES.pIndRampReserves == 1 and sum(mTEPES.pRampReserveDw[p,sc,n,ar] for ar in mTEPES.ar) > 0.0:
|
|
1123
|
+
return OptModel.vOutput2ndBlock[p,sc,n,nr] - OptModel.vRampReserveDw[p,sc,n,nr] >= 0.0
|
|
1124
|
+
else:
|
|
1125
|
+
return Constraint.Skip
|
|
1098
1126
|
else:
|
|
1099
1127
|
return Constraint.Skip
|
|
1100
|
-
setattr(OptModel, f'eMinOutput2ndBlock_{p}_{sc}_{st}', Constraint(mTEPES.n
|
|
1128
|
+
setattr(OptModel, f'eMinOutput2ndBlock_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.nr, rule=eMinOutput2ndBlock, doc='min output of the second block of a committed unit [p.u.]'))
|
|
1101
1129
|
|
|
1102
1130
|
if pIndLogConsole == 1:
|
|
1103
1131
|
print('eMinOutput2ndBlock ... ', len(getattr(OptModel, f'eMinOutput2ndBlock_{p}_{sc}_{st}')), ' rows')
|
|
1104
1132
|
|
|
1105
1133
|
def eTotalOutput(OptModel,n,nr):
|
|
1106
|
-
if (p,nr) in mTEPES.pnr and (nr not in mTEPES.es or (nr in mTEPES.es and (mTEPES.pTotalMaxCharge[nr] or mTEPES.pTotalEnergyInflows[nr]))):
|
|
1134
|
+
if (p,nr) in mTEPES.pnr and (mTEPES.pMustRun[nr] == 0 or mTEPES.pMaxPower2ndBlock[p,sc,n,nr] or nr in mTEPES.gc) and (nr not in mTEPES.es or (nr in mTEPES.es and (mTEPES.pTotalMaxCharge[nr] or mTEPES.pTotalEnergyInflows[nr]))):
|
|
1107
1135
|
if mTEPES.pMaxPowerElec[p,sc,n,nr]:
|
|
1108
1136
|
if mTEPES.pMinPowerElec[p,sc,n,nr] == 0.0:
|
|
1109
1137
|
return OptModel.vTotalOutput[p,sc,n,nr] == OptModel.vOutput2ndBlock[p,sc,n,nr] + mTEPES.pUpReserveActivation * OptModel.vReserveUp[p,sc,n,nr] - mTEPES.pDwReserveActivation * OptModel.vReserveDown[p,sc,n,nr]
|
|
@@ -1113,7 +1141,7 @@ def GenerationOperationModelFormulationCommitment(OptModel, mTEPES, pIndLogConso
|
|
|
1113
1141
|
return Constraint.Skip
|
|
1114
1142
|
else:
|
|
1115
1143
|
return Constraint.Skip
|
|
1116
|
-
setattr(OptModel, f'eTotalOutput_{p}_{sc}_{st}', Constraint(mTEPES.n
|
|
1144
|
+
setattr(OptModel, f'eTotalOutput_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.nr, rule=eTotalOutput, doc='total output of a unit [GW]'))
|
|
1117
1145
|
|
|
1118
1146
|
if pIndLogConsole == 1:
|
|
1119
1147
|
print('eTotalOutput ... ', len(getattr(OptModel, f'eTotalOutput_{p}_{sc}_{st}')), ' rows')
|
|
@@ -1129,7 +1157,7 @@ def GenerationOperationModelFormulationCommitment(OptModel, mTEPES, pIndLogConso
|
|
|
1129
1157
|
return Constraint.Skip
|
|
1130
1158
|
else:
|
|
1131
1159
|
return Constraint.Skip
|
|
1132
|
-
setattr(OptModel, f'eUCStrShut_{p}_{sc}_{st}', Constraint(mTEPES.n
|
|
1160
|
+
setattr(OptModel, f'eUCStrShut_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.nr, rule=eUCStrShut, doc='relation among commitment startup and shutdown [p.u.]'))
|
|
1133
1161
|
|
|
1134
1162
|
if pIndLogConsole == 1:
|
|
1135
1163
|
print('eUCStrShut ... ', len(getattr(OptModel, f'eUCStrShut_{p}_{sc}_{st}')), ' rows')
|
|
@@ -1159,7 +1187,7 @@ def GenerationOperationModelFormulationCommitment(OptModel, mTEPES, pIndLogConso
|
|
|
1159
1187
|
return Constraint.Skip
|
|
1160
1188
|
return OptModel.vCommitment[p,sc,n,nr] <= OptModel.vMaxCommitmentYearly[p,sc,nr,group]
|
|
1161
1189
|
|
|
1162
|
-
setattr(OptModel, f'eMaxCommitmentYearly_{p}_{sc}_{st}', Constraint(mTEPES.n
|
|
1190
|
+
setattr(OptModel, f'eMaxCommitmentYearly_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.ExclusiveGroupsYearly*mTEPES.nr, rule=eMaxCommitmentYearly, doc='maximum of all the commitments [p.u.]'))
|
|
1163
1191
|
|
|
1164
1192
|
if pIndLogConsole == 1:
|
|
1165
1193
|
print('eMaxCommitmentYearly ... ', len(getattr(OptModel, f'eMaxCommitmentYearly_{p}_{sc}_{st}')), ' rows')
|
|
@@ -1178,14 +1206,13 @@ def GenerationOperationModelFormulationCommitment(OptModel, mTEPES, pIndLogConso
|
|
|
1178
1206
|
if len(mTEPES.GeneratorsInYearlyGroup[group] & {nr for (p, nr) in mTEPES.pnr}) <= 1:
|
|
1179
1207
|
return Constraint.Skip
|
|
1180
1208
|
return OptModel.vTotalOutput[p,sc,n,nr]/mTEPES.pMaxPowerElec[p,sc,n,nr] <= OptModel.vMaxCommitmentYearly[p,sc,nr,group]
|
|
1181
|
-
|
|
1182
|
-
setattr(OptModel, f'eMaxCommitGenYearly_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.ExclusiveGroupsYearly,mTEPES.nr, rule=eMaxCommitGenYearly, doc='maximum of all the capacity factors'))
|
|
1209
|
+
setattr(OptModel, f'eMaxCommitGenYearly_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.ExclusiveGroupsYearly*mTEPES.nr, rule=eMaxCommitGenYearly, doc='maximum of all the capacity factors'))
|
|
1183
1210
|
|
|
1184
1211
|
if pIndLogConsole == 1:
|
|
1185
1212
|
print('eMaxCommitGenYearly ... ', len(getattr(OptModel, f'eMaxCommitGenYearly_{p}_{sc}_{st}')), ' rows')
|
|
1186
1213
|
|
|
1187
1214
|
def eExclusiveGensYearly(OptModel,group):
|
|
1188
|
-
# Skip if there are one or
|
|
1215
|
+
# Skip if there are one or fewer generators in the group
|
|
1189
1216
|
if len(mTEPES.GeneratorsInYearlyGroup[group] & {nr for (p,nr) in mTEPES.pnr}) <= 1:
|
|
1190
1217
|
return Constraint.Skip
|
|
1191
1218
|
return sum(OptModel.vMaxCommitmentYearly[p,sc,nr,group] + (OptModel.vCommitmentCons[p,sc,nr] if nr in mTEPES.h else 0) for nr in mTEPES.GeneratorsInYearlyGroup[group] if (p,nr) in mTEPES.pnr ) <= 1
|
|
@@ -1209,8 +1236,7 @@ def GenerationOperationModelFormulationCommitment(OptModel, mTEPES, pIndLogConso
|
|
|
1209
1236
|
if len(mTEPES.GeneratorsInHourlyGroup[group] & {nr for (p,nr) in mTEPES.pnr}) <= 1:
|
|
1210
1237
|
return Constraint.Skip
|
|
1211
1238
|
return OptModel.vCommitment[p,sc,n,nr] <= OptModel.vMaxCommitmentHourly[p,sc,n,nr,group]
|
|
1212
|
-
|
|
1213
|
-
setattr(OptModel, f'eMaxCommitmentHourly_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.ExclusiveGroupsHourly, mTEPES.nr, rule=eMaxCommitmentHourly, doc='maximum of all the commitments [p.u.]'))
|
|
1239
|
+
setattr(OptModel, f'eMaxCommitmentHourly_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.ExclusiveGroupsHourly*mTEPES.nr, rule=eMaxCommitmentHourly, doc='maximum of all the commitments [p.u.]'))
|
|
1214
1240
|
|
|
1215
1241
|
if pIndLogConsole == 1:
|
|
1216
1242
|
print('eMaxCommitmentHourly ... ', len(getattr(OptModel, f'eMaxCommitmentHourly_{p}_{sc}_{st}')), ' rows')
|
|
@@ -1230,7 +1256,7 @@ def GenerationOperationModelFormulationCommitment(OptModel, mTEPES, pIndLogConso
|
|
|
1230
1256
|
return Constraint.Skip
|
|
1231
1257
|
return OptModel.vTotalOutput[p,sc,n,nr]/mTEPES.pMaxPowerElec[p,sc,n,nr] <= OptModel.vMaxCommitmentHourly[p,sc,n,nr,group]
|
|
1232
1258
|
|
|
1233
|
-
setattr(OptModel, f'eMaxCommitGenHourly_{p}_{sc}_{st}', Constraint(mTEPES.n
|
|
1259
|
+
setattr(OptModel, f'eMaxCommitGenHourly_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.ExclusiveGroupsHourly*mTEPES.nr, rule=eMaxCommitGenHourly, doc='maximum of all the capacity factors'))
|
|
1234
1260
|
|
|
1235
1261
|
if pIndLogConsole == 1:
|
|
1236
1262
|
print('eMaxCommitGenHourly ... ', len(getattr(OptModel, f'eMaxCommitGenHourly_{p}_{sc}_{st}')), ' rows')
|
|
@@ -1241,8 +1267,7 @@ def GenerationOperationModelFormulationCommitment(OptModel, mTEPES, pIndLogConso
|
|
|
1241
1267
|
if len(mTEPES.GeneratorsInHourlyGroup[group] & {gen for (period, gen) in mTEPES.pnr if period == p}) <= 1:
|
|
1242
1268
|
return Constraint.Skip
|
|
1243
1269
|
return sum(OptModel.vMaxCommitmentHourly[p,sc,n,nr,group] + (OptModel.vCommitmentCons[p,sc,n,nr] if nr in mTEPES.h else 0) for nr in mTEPES.GeneratorsInHourlyGroup[group] if (p, nr) in mTEPES.pnr ) <= 1
|
|
1244
|
-
|
|
1245
|
-
setattr(OptModel, f'eExclusiveGensHourly_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.ExclusiveGroupsHourly, rule=eExclusiveGensHourly, doc='mutually exclusive generators'))
|
|
1270
|
+
setattr(OptModel, f'eExclusiveGensHourly_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.ExclusiveGroupsHourly, rule=eExclusiveGensHourly, doc='mutually exclusive generators'))
|
|
1246
1271
|
|
|
1247
1272
|
if pIndLogConsole == 1:
|
|
1248
1273
|
print('eExclusiveGensHourly ... ', len(getattr(OptModel, f'eExclusiveGensHourly_{p}_{sc}_{st}')), ' rows')
|
|
@@ -1289,7 +1314,7 @@ def GenerationOperationModelFormulationRampMinTime(OptModel, mTEPES, pIndLogCons
|
|
|
1289
1314
|
return Constraint.Skip
|
|
1290
1315
|
else:
|
|
1291
1316
|
return Constraint.Skip
|
|
1292
|
-
setattr(OptModel, f'eRampUp_{p}_{sc}_{st}', Constraint(mTEPES.n
|
|
1317
|
+
setattr(OptModel, f'eRampUp_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.nr, rule=eRampUp, doc='maximum ramp up [p.u.]'))
|
|
1293
1318
|
|
|
1294
1319
|
if pIndLogConsole == 1:
|
|
1295
1320
|
print('eRampUp ... ', len(getattr(OptModel, f'eRampUp_{p}_{sc}_{st}')), ' rows')
|
|
@@ -1305,7 +1330,7 @@ def GenerationOperationModelFormulationRampMinTime(OptModel, mTEPES, pIndLogCons
|
|
|
1305
1330
|
return Constraint.Skip
|
|
1306
1331
|
else:
|
|
1307
1332
|
return Constraint.Skip
|
|
1308
|
-
setattr(OptModel, f'eRampDw_{p}_{sc}_{st}', Constraint(mTEPES.n
|
|
1333
|
+
setattr(OptModel, f'eRampDw_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.nr, rule=eRampDw, doc='maximum ramp down [p.u.]'))
|
|
1309
1334
|
|
|
1310
1335
|
if pIndLogConsole == 1:
|
|
1311
1336
|
print('eRampDw ... ', len(getattr(OptModel, f'eRampDw_{p}_{sc}_{st}')), ' rows')
|
|
@@ -1321,7 +1346,7 @@ def GenerationOperationModelFormulationRampMinTime(OptModel, mTEPES, pIndLogCons
|
|
|
1321
1346
|
return Constraint.Skip
|
|
1322
1347
|
else:
|
|
1323
1348
|
return Constraint.Skip
|
|
1324
|
-
setattr(OptModel, f'eRampUpChr_{p}_{sc}_{st}', Constraint(mTEPES.n
|
|
1349
|
+
setattr(OptModel, f'eRampUpChr_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.eh, rule=eRampUpCharge, doc='maximum ramp up charge [p.u.]'))
|
|
1325
1350
|
|
|
1326
1351
|
if pIndLogConsole == 1:
|
|
1327
1352
|
print('eRampUpChr ... ', len(getattr(OptModel, f'eRampUpChr_{p}_{sc}_{st}')), ' rows')
|
|
@@ -1337,7 +1362,7 @@ def GenerationOperationModelFormulationRampMinTime(OptModel, mTEPES, pIndLogCons
|
|
|
1337
1362
|
return Constraint.Skip
|
|
1338
1363
|
else:
|
|
1339
1364
|
return Constraint.Skip
|
|
1340
|
-
setattr(OptModel, f'eRampDwChr_{p}_{sc}_{st}', Constraint(mTEPES.n
|
|
1365
|
+
setattr(OptModel, f'eRampDwChr_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.eh, rule=eRampDwCharge, doc='maximum ramp down charge [p.u.]'))
|
|
1341
1366
|
|
|
1342
1367
|
if pIndLogConsole == 1:
|
|
1343
1368
|
print('eRampDwChr ... ', len(getattr(OptModel, f'eRampDwChr_{p}_{sc}_{st}')), ' rows')
|
|
@@ -1376,7 +1401,7 @@ def GenerationOperationModelFormulationRampMinTime(OptModel, mTEPES, pIndLogCons
|
|
|
1376
1401
|
return (- OptModel.vOutput2ndBlock[p,sc,mTEPES.n.prev(n),nr] + OptModel.vOutput2ndBlock[p,sc,n,nr]) / mTEPES.pDuration[p,sc,n]() / mTEPES.pMaxPower2ndBlock[p,sc,n,nr] <= OptModel.vRampUpState[p,sc,n,nr] - pEpsilon * OptModel.vRampDwState[p,sc,n,nr]
|
|
1377
1402
|
else:
|
|
1378
1403
|
return Constraint.Skip
|
|
1379
|
-
setattr(OptModel, f'eRampUpState_{p}_{sc}_{st}', Constraint(mTEPES.n
|
|
1404
|
+
setattr(OptModel, f'eRampUpState_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.nr, rule=eRampUpState, doc='ramp up state [p.u.]'))
|
|
1380
1405
|
|
|
1381
1406
|
if pIndLogConsole == 1:
|
|
1382
1407
|
print('eRampUpState ... ', len(getattr(OptModel, f'eRampUpState_{p}_{sc}_{st}')), ' rows')
|
|
@@ -1407,7 +1432,7 @@ def GenerationOperationModelFormulationRampMinTime(OptModel, mTEPES, pIndLogCons
|
|
|
1407
1432
|
return (OptModel.vOutput2ndBlock[p,sc,mTEPES.n.prev(n),nr] - OptModel.vOutput2ndBlock[p,sc,n,nr]) / mTEPES.pDuration[p,sc,n]() / mTEPES.pMaxPower2ndBlock[p,sc,n,nr] <= OptModel.vRampDwState[p,sc,n,nr] - pEpsilon * OptModel.vRampUpState[p,sc,n,nr]
|
|
1408
1433
|
else:
|
|
1409
1434
|
return Constraint.Skip
|
|
1410
|
-
setattr(OptModel, f'eRampDwState_{p}_{sc}_{st}', Constraint(mTEPES.n
|
|
1435
|
+
setattr(OptModel, f'eRampDwState_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.nr, rule=eRampDwState, doc='maximum ramp down [p.u.]'))
|
|
1411
1436
|
|
|
1412
1437
|
if pIndLogConsole == 1:
|
|
1413
1438
|
print('eRampDwState ... ', len(getattr(OptModel, f'eRampDwState_{p}_{sc}_{st}')), ' rows')
|
|
@@ -1420,7 +1445,7 @@ def GenerationOperationModelFormulationRampMinTime(OptModel, mTEPES, pIndLogCons
|
|
|
1420
1445
|
return Constraint.Skip
|
|
1421
1446
|
else:
|
|
1422
1447
|
return Constraint.Skip
|
|
1423
|
-
setattr(OptModel, f'eMinUpTime_{p}_{sc}_{st}', Constraint(mTEPES.n
|
|
1448
|
+
setattr(OptModel, f'eMinUpTime_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.t, rule=eMinUpTime , doc='minimum up time [p.u.]'))
|
|
1424
1449
|
|
|
1425
1450
|
if pIndLogConsole == 1:
|
|
1426
1451
|
print('eMinUpTime ... ', len(getattr(OptModel, f'eMinUpTime_{p}_{sc}_{st}')), ' rows')
|
|
@@ -1433,7 +1458,7 @@ def GenerationOperationModelFormulationRampMinTime(OptModel, mTEPES, pIndLogCons
|
|
|
1433
1458
|
return Constraint.Skip
|
|
1434
1459
|
else:
|
|
1435
1460
|
return Constraint.Skip
|
|
1436
|
-
setattr(OptModel, f'eMinDownTime_{p}_{sc}_{st}', Constraint(mTEPES.n
|
|
1461
|
+
setattr(OptModel, f'eMinDownTime_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.t, rule=eMinDownTime, doc='minimum down time [p.u.]'))
|
|
1437
1462
|
|
|
1438
1463
|
if pIndLogConsole == 1:
|
|
1439
1464
|
print('eMinDownTime ... ', len(getattr(OptModel, f'eMinDownTime_{p}_{sc}_{st}')), ' rows')
|
|
@@ -1444,7 +1469,7 @@ def GenerationOperationModelFormulationRampMinTime(OptModel, mTEPES, pIndLogCons
|
|
|
1444
1469
|
return OptModel.vRampUpState[p,sc,n,nr] + sum(OptModel.vRampDwState[p,sc,n2,nr] for n2 in list(mTEPES.n2)[mTEPES.n.ord(n)-mTEPES.pStableTime[nr]-1:mTEPES.n.ord(n)-1]) <= 1
|
|
1445
1470
|
else:
|
|
1446
1471
|
return Constraint.Skip
|
|
1447
|
-
setattr(OptModel, f'eMinStableTime_{p}_{sc}_{st}', Constraint(mTEPES.n
|
|
1472
|
+
setattr(OptModel, f'eMinStableTime_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.nr, rule=eMinStableTime, doc='minimum stable time [p.u.]'))
|
|
1448
1473
|
else:
|
|
1449
1474
|
MinStableTimeLoadLevels = []
|
|
1450
1475
|
if sum(mTEPES.pStableTime[nr] for nr in mTEPES.nr):
|
|
@@ -1480,7 +1505,7 @@ def NetworkSwitchingModelFormulation(OptModel, mTEPES, pIndLogConsole, p, sc, st
|
|
|
1480
1505
|
return OptModel.vLineCommit[p,sc,n,ni,nf,cc] == OptModel.vNetworkInvest[p,ni,nf,cc]
|
|
1481
1506
|
else:
|
|
1482
1507
|
return Constraint.Skip
|
|
1483
|
-
setattr(OptModel, f'eLineStateCand_{p}_{sc}_{st}', Constraint(mTEPES.n
|
|
1508
|
+
setattr(OptModel, f'eLineStateCand_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.lc, rule=eLineStateCand, doc='logical relation between investment and operation in candidates'))
|
|
1484
1509
|
|
|
1485
1510
|
if pIndLogConsole == 1:
|
|
1486
1511
|
print('eLineStateCand ... ', len(getattr(OptModel, f'eLineStateCand_{p}_{sc}_{st}')), ' rows')
|
|
@@ -1496,7 +1521,7 @@ def NetworkSwitchingModelFormulation(OptModel, mTEPES, pIndLogConsole, p, sc, st
|
|
|
1496
1521
|
return Constraint.Skip
|
|
1497
1522
|
else:
|
|
1498
1523
|
return Constraint.Skip
|
|
1499
|
-
setattr(OptModel, f'eSWOnOff_{p}_{sc}_{st}', Constraint(mTEPES.n
|
|
1524
|
+
setattr(OptModel, f'eSWOnOff_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.la, rule=eSWOnOff, doc='relation among switching decision activate and deactivate state'))
|
|
1500
1525
|
|
|
1501
1526
|
if pIndLogConsole == 1:
|
|
1502
1527
|
print('eSWOnOff ... ', len(getattr(OptModel, f'eSWOnOff_{p}_{sc}_{st}')), ' rows')
|
|
@@ -1509,7 +1534,7 @@ def NetworkSwitchingModelFormulation(OptModel, mTEPES, pIndLogConsole, p, sc, st
|
|
|
1509
1534
|
return Constraint.Skip
|
|
1510
1535
|
else:
|
|
1511
1536
|
return Constraint.Skip
|
|
1512
|
-
setattr(OptModel, f'eMinSwOnState_{p}_{sc}_{st}', Constraint(mTEPES.n
|
|
1537
|
+
setattr(OptModel, f'eMinSwOnState_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.la, rule=eMinSwOnState, doc='minimum switch on state [h]'))
|
|
1513
1538
|
|
|
1514
1539
|
if pIndLogConsole == 1:
|
|
1515
1540
|
print('eMinSwOnState ... ', len(getattr(OptModel, f'eMinSwOnState_{p}_{sc}_{st}')), ' rows')
|
|
@@ -1522,7 +1547,7 @@ def NetworkSwitchingModelFormulation(OptModel, mTEPES, pIndLogConsole, p, sc, st
|
|
|
1522
1547
|
return Constraint.Skip
|
|
1523
1548
|
else:
|
|
1524
1549
|
return Constraint.Skip
|
|
1525
|
-
setattr(OptModel, f'eMinSwOffState_{p}_{sc}_{st}', Constraint(mTEPES.n
|
|
1550
|
+
setattr(OptModel, f'eMinSwOffState_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.la, rule=eMinSwOffState, doc='minimum switch off state [h]'))
|
|
1526
1551
|
|
|
1527
1552
|
if pIndLogConsole == 1:
|
|
1528
1553
|
print('eMinSwOffState ... ', len(getattr(OptModel, f'eMinSwOffState_{p}_{sc}_{st}')), ' rows')
|
|
@@ -1543,7 +1568,7 @@ def NetworkOperationModelFormulation(OptModel, mTEPES, pIndLogConsole, p, sc, st
|
|
|
1543
1568
|
return OptModel.vFlowElec[p,sc,n,ni,nf,cc] / mTEPES.pMaxNTCMax[p,sc,n,ni,nf,cc] >= - OptModel.vLineCommit[p,sc,n,ni,nf,cc]
|
|
1544
1569
|
else:
|
|
1545
1570
|
return Constraint.Skip
|
|
1546
|
-
setattr(OptModel, f'eNetCapacity1_{p}_{sc}_{st}', Constraint(mTEPES.n
|
|
1571
|
+
setattr(OptModel, f'eNetCapacity1_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.la, rule=eNetCapacity1, doc='maximum flow by existing network capacity [p.u.]'))
|
|
1547
1572
|
|
|
1548
1573
|
if pIndLogConsole == 1:
|
|
1549
1574
|
print('eNetCapacity1 ... ', len(getattr(OptModel, f'eNetCapacity1_{p}_{sc}_{st}')), ' rows')
|
|
@@ -1553,7 +1578,7 @@ def NetworkOperationModelFormulation(OptModel, mTEPES, pIndLogConsole, p, sc, st
|
|
|
1553
1578
|
return OptModel.vFlowElec[p,sc,n,ni,nf,cc] / mTEPES.pMaxNTCMax[p,sc,n,ni,nf,cc] <= OptModel.vLineCommit[p,sc,n,ni,nf,cc]
|
|
1554
1579
|
else:
|
|
1555
1580
|
return Constraint.Skip
|
|
1556
|
-
setattr(OptModel, f'eNetCapacity2_{p}_{sc}_{st}', Constraint(mTEPES.n
|
|
1581
|
+
setattr(OptModel, f'eNetCapacity2_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.la, rule=eNetCapacity2, doc='maximum flow by existing network capacity [p.u.]'))
|
|
1557
1582
|
|
|
1558
1583
|
if pIndLogConsole == 1:
|
|
1559
1584
|
print('eNetCapacity2 ... ', len(getattr(OptModel, f'eNetCapacity2_{p}_{sc}_{st}')), ' rows')
|
|
@@ -1566,7 +1591,7 @@ def NetworkOperationModelFormulation(OptModel, mTEPES, pIndLogConsole, p, sc, st
|
|
|
1566
1591
|
return OptModel.vFlowElec[p,sc,n,ni,nf,cc] / mTEPES.pBigMFlowBck[ni,nf,cc]() - (OptModel.vTheta[p,sc,n,ni] - OptModel.vTheta[p,sc,n,nf]) / mTEPES.pLineX[ni,nf,cc] / mTEPES.pBigMFlowBck[ni,nf,cc]() * mTEPES.pSBase == 0
|
|
1567
1592
|
else:
|
|
1568
1593
|
return Constraint.Skip
|
|
1569
|
-
setattr(OptModel, f'eKirchhoff2ndLaw1_{p}_{sc}_{st}', Constraint(mTEPES.n
|
|
1594
|
+
setattr(OptModel, f'eKirchhoff2ndLaw1_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.laa, rule=eKirchhoff2ndLaw1, doc='flow for each AC candidate line [rad]'))
|
|
1570
1595
|
|
|
1571
1596
|
if pIndLogConsole == 1:
|
|
1572
1597
|
print('eKirchhoff2ndLaw1 ... ', len(getattr(OptModel, f'eKirchhoff2ndLaw1_{p}_{sc}_{st}')), ' rows')
|
|
@@ -1576,7 +1601,7 @@ def NetworkOperationModelFormulation(OptModel, mTEPES, pIndLogConsole, p, sc, st
|
|
|
1576
1601
|
return OptModel.vFlowElec[p,sc,n,ni,nf,cc] / mTEPES.pBigMFlowFrw[ni,nf,cc]() - (OptModel.vTheta[p,sc,n,ni] - OptModel.vTheta[p,sc,n,nf]) / mTEPES.pLineX[ni,nf,cc] / mTEPES.pBigMFlowFrw[ni,nf,cc]() * mTEPES.pSBase <= 1 - OptModel.vLineCommit[p,sc,n,ni,nf,cc]
|
|
1577
1602
|
else:
|
|
1578
1603
|
return Constraint.Skip
|
|
1579
|
-
setattr(OptModel, f'eKirchhoff2ndLaw2_{p}_{sc}_{st}', Constraint(mTEPES.n
|
|
1604
|
+
setattr(OptModel, f'eKirchhoff2ndLaw2_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.lca, rule=eKirchhoff2ndLaw2, doc='flow for each AC candidate line [rad]'))
|
|
1580
1605
|
|
|
1581
1606
|
if pIndLogConsole == 1:
|
|
1582
1607
|
print('eKirchhoff2ndLaw2 ... ', len(getattr(OptModel, f'eKirchhoff2ndLaw2_{p}_{sc}_{st}')), ' rows')
|
|
@@ -1586,7 +1611,7 @@ def NetworkOperationModelFormulation(OptModel, mTEPES, pIndLogConsole, p, sc, st
|
|
|
1586
1611
|
return OptModel.vLineLosses[p,sc,n,ni,nf,cc] >= - 0.5 * mTEPES.pLineLossFactor[ni,nf,cc] * OptModel.vFlowElec[p,sc,n,ni,nf,cc]
|
|
1587
1612
|
else:
|
|
1588
1613
|
return Constraint.Skip
|
|
1589
|
-
setattr(OptModel, f'eLineLosses1_{p}_{sc}_{st}', Constraint(mTEPES.n
|
|
1614
|
+
setattr(OptModel, f'eLineLosses1_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.ll, rule=eLineLosses1, doc='ohmic losses for all the lines [GW]'))
|
|
1590
1615
|
|
|
1591
1616
|
if pIndLogConsole == 1:
|
|
1592
1617
|
print('eLineLosses1 ... ', len(getattr(OptModel, f'eLineLosses1_{p}_{sc}_{st}')), ' rows')
|
|
@@ -1596,7 +1621,7 @@ def NetworkOperationModelFormulation(OptModel, mTEPES, pIndLogConsole, p, sc, st
|
|
|
1596
1621
|
return OptModel.vLineLosses[p,sc,n,ni,nf,cc] >= 0.5 * mTEPES.pLineLossFactor[ni,nf,cc] * OptModel.vFlowElec[p,sc,n,ni,nf,cc]
|
|
1597
1622
|
else:
|
|
1598
1623
|
return Constraint.Skip
|
|
1599
|
-
setattr(OptModel, f'eLineLosses2_{p}_{sc}_{st}', Constraint(mTEPES.n
|
|
1624
|
+
setattr(OptModel, f'eLineLosses2_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.ll, rule=eLineLosses2, doc='ohmic losses for all the lines [GW]'))
|
|
1600
1625
|
|
|
1601
1626
|
if pIndLogConsole == 1:
|
|
1602
1627
|
print('eLineLosses2 ... ', len(getattr(OptModel, f'eLineLosses2_{p}_{sc}_{st}')), ' rows')
|
|
@@ -1616,7 +1641,7 @@ def NetworkOperationModelFormulation(OptModel, mTEPES, pIndLogConsole, p, sc, st
|
|
|
1616
1641
|
return (OptModel.vNetPosition[p,sc,n,nd] == sum(OptModel.vTotalOutput[p,sc,n,g] for g in g2n[nd] if (p,g) in mTEPES.pg) - sum(OptModel.vESSTotalCharge[p,sc,n,eh] for eh in e2n[nd] if (p,eh) in mTEPES.peh) + OptModel.vENS[p,sc,n,nd] - mTEPES.pDemandElec[p,sc,n,nd])
|
|
1617
1642
|
else:
|
|
1618
1643
|
return Constraint.Skip
|
|
1619
|
-
setattr(OptModel, f'eNetPosition_{p}_{sc}_{st}', Constraint(mTEPES.n
|
|
1644
|
+
setattr(OptModel, f'eNetPosition_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.nd, rule=eNetPosition, doc='net position [GW]'))
|
|
1620
1645
|
|
|
1621
1646
|
def eFlowBasedCalcu1(OptModel,n,ni,nf,cc):
|
|
1622
1647
|
if mTEPES.pIndBinSingleNode() == 0 and mTEPES.pElecNetPeriodIni[ni,nf,cc] <= p and mTEPES.pElecNetPeriodFin[ni,nf,cc] >= p and mTEPES.pIndPTDF == 1 and mTEPES.pIndBinLinePTDF[ni,nf,cc] == 1:
|
|
@@ -1626,7 +1651,7 @@ def NetworkOperationModelFormulation(OptModel, mTEPES, pIndLogConsole, p, sc, st
|
|
|
1626
1651
|
return OptModel.vFlowElec[p,sc,n,ni,nf,cc] - sum(mTEPES.pPTDF[p,sc,n,ni,nf,cc,nd] * OptModel.vNetPosition[p,sc,n,nd] for nd in mTEPES.nd if (p,sc,n,ni,nf,cc,nd) in mTEPES.psnland) == 0
|
|
1627
1652
|
else:
|
|
1628
1653
|
return Constraint.Skip
|
|
1629
|
-
setattr(OptModel, f'eFlowBasedCalcu1_{p}_{sc}_{st}', Constraint(mTEPES.n
|
|
1654
|
+
setattr(OptModel, f'eFlowBasedCalcu1_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.la, rule=eFlowBasedCalcu1, doc='flow based calculation [p.u.]'))
|
|
1630
1655
|
|
|
1631
1656
|
if pIndLogConsole == 1:
|
|
1632
1657
|
print('eFlowBasedCalcu1 ... ', len(getattr(OptModel, f'eFlowBasedCalcu1_{p}_{sc}_{st}')), ' rows')
|
|
@@ -1636,7 +1661,7 @@ def NetworkOperationModelFormulation(OptModel, mTEPES, pIndLogConsole, p, sc, st
|
|
|
1636
1661
|
return OptModel.vFlowElec[p,sc,n,ni,nf,cc] - sum(mTEPES.pPTDF[p,sc,n,ni,nf,cc,nd] * OptModel.vNetPosition[p,sc,n,nd] for nd in mTEPES.nd if (p,sc,n,ni,nf,cc,nd) in mTEPES.psnland) <= 1 - OptModel.vLineCommit[p,sc,n,ni,nf,cc]
|
|
1637
1662
|
else:
|
|
1638
1663
|
return Constraint.Skip
|
|
1639
|
-
setattr(OptModel, f'eFlowBasedCalcu2_{p}_{sc}_{st}', Constraint(mTEPES.n
|
|
1664
|
+
setattr(OptModel, f'eFlowBasedCalcu2_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.lca, rule=eFlowBasedCalcu2, doc='flow based calculation [p.u.]'))
|
|
1640
1665
|
|
|
1641
1666
|
if pIndLogConsole == 1:
|
|
1642
1667
|
print('eFlowBasedCalcu2 ... ', len(getattr(OptModel, f'eFlowBasedCalcu2_{p}_{sc}_{st}')), ' rows')
|
|
@@ -1646,7 +1671,7 @@ def NetworkOperationModelFormulation(OptModel, mTEPES, pIndLogConsole, p, sc, st
|
|
|
1646
1671
|
# return OptModel.vFlowElec[p,sc,n,ni,nf,cc] <= mTEPES.pVariableTTCFrw[p,sc,n,ni,nf,cc]
|
|
1647
1672
|
# else:
|
|
1648
1673
|
# return Constraint.Skip
|
|
1649
|
-
# setattr(OptModel, f'eSecurityMargingTTCFrw_{p}_{sc}_{st}', Constraint(mTEPES.n
|
|
1674
|
+
# setattr(OptModel, f'eSecurityMargingTTCFrw_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.lca, rule=eSecurityMargingTTCFrw, doc='security margin TTC for flow based calculation [p.u.]'))
|
|
1650
1675
|
#
|
|
1651
1676
|
# if pIndLogConsole == 1:
|
|
1652
1677
|
# print('eSecurityMargingTTCFrw... ', len(getattr(OptModel, f'eSecurityMargingTTCFrw_{p}_{sc}_{st}')), ' rows')
|
|
@@ -1656,7 +1681,7 @@ def NetworkOperationModelFormulation(OptModel, mTEPES, pIndLogConsole, p, sc, st
|
|
|
1656
1681
|
# return OptModel.vFlowElec[p,sc,n,ni,nf,cc] >= - mTEPES.pVariableTTCBck[p,sc,n,ni,nf,cc]
|
|
1657
1682
|
# else:
|
|
1658
1683
|
# return Constraint.Skip
|
|
1659
|
-
# setattr(OptModel, f'eSecurityMargingTTCBck_{p}_{sc}_{st}', Constraint(mTEPES.n
|
|
1684
|
+
# setattr(OptModel, f'eSecurityMargingTTCBck_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.lca, rule=eSecurityMargingTTCBck, doc='security margin TTC for flow based calculation [p.u.]'))
|
|
1660
1685
|
#
|
|
1661
1686
|
# if pIndLogConsole == 1:
|
|
1662
1687
|
# print('eSecurityMargingTTCBck... ', len(getattr(OptModel, f'eSecurityMargingTTCBck_{p}_{sc}_{st}')), ' rows')
|
|
@@ -1757,7 +1782,7 @@ def CycleConstraints(OptModel, mTEPES, pIndLogConsole, p, sc, st):
|
|
|
1757
1782
|
sum(OptModel.vFlowElec[p,sc,n,ni,nf,cc] * mTEPES.pLineX[ni,nf,cc] / mTEPES.pSBase for nf,ni in list(zip(mTEPES.ncd[cyc], mTEPES.ncd[cyc][1:] + mTEPES.ncd[cyc][:1])) for cc in mTEPES.cc if (ni,nf,cc) in mTEPES.uctc) ) / mTEPES.pBigMTheta[cyc,nii,nff,cc] <= 1 - OptModel.vLineCommit[p,sc,n,nii,nff,cc]
|
|
1758
1783
|
else:
|
|
1759
1784
|
return Constraint.Skip
|
|
1760
|
-
setattr(OptModel, f'eCycleKirchhoff2ndLawCnd1_{p}_{sc}_{st}', Constraint(mTEPES.n
|
|
1785
|
+
setattr(OptModel, f'eCycleKirchhoff2ndLawCnd1_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.lcac, rule=eCycleKirchhoff2ndLawCnd1, doc='cycle flow for with some AC candidate lines [rad]'))
|
|
1761
1786
|
|
|
1762
1787
|
if pIndLogConsole == 1:
|
|
1763
1788
|
print('eCycleKirchhoff2ndLC1 ... ', len(getattr(OptModel, f'eCycleKirchhoff2ndLawCnd1_{p}_{sc}_{st}')), ' rows')
|
|
@@ -1768,7 +1793,7 @@ def CycleConstraints(OptModel, mTEPES, pIndLogConsole, p, sc, st):
|
|
|
1768
1793
|
sum(OptModel.vFlowElec[p,sc,n,ni,nf,cc] * mTEPES.pLineX[ni,nf,cc] / mTEPES.pSBase for nf,ni in list(zip(mTEPES.ncd[cyc], mTEPES.ncd[cyc][1:] + mTEPES.ncd[cyc][:1])) for cc in mTEPES.cc if (ni,nf,cc) in mTEPES.uctc) ) / mTEPES.pBigMTheta[cyc,nii,nff,cc] >= - 1 + OptModel.vLineCommit[p,sc,n,nii,nff,cc]
|
|
1769
1794
|
else:
|
|
1770
1795
|
return Constraint.Skip
|
|
1771
|
-
setattr(OptModel, f'eCycleKirchhoff2ndLawCnd2_{p}_{sc}_{st}', Constraint(mTEPES.n
|
|
1796
|
+
setattr(OptModel, f'eCycleKirchhoff2ndLawCnd2_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.lcac, rule=eCycleKirchhoff2ndLawCnd2, doc='cycle flow for with some AC candidate lines [rad]'))
|
|
1772
1797
|
|
|
1773
1798
|
if pIndLogConsole == 1:
|
|
1774
1799
|
print('eCycleKirchhoff2ndLC2 ... ', len(getattr(OptModel, f'eCycleKirchhoff2ndLawCnd2_{p}_{sc}_{st}')), ' rows')
|
|
@@ -1778,7 +1803,7 @@ def CycleConstraints(OptModel, mTEPES, pIndLogConsole, p, sc, st):
|
|
|
1778
1803
|
return (OptModel.vFlowElec[p,sc,n,ni,nf,cc] - OptModel.vFlowElec[p,sc,n,ni,nf,c2] * mTEPES.pLineX[ni,nf,c2] / mTEPES.pLineX[ni,nf,cc]) / max(mTEPES.pMaxNTCBck[p,sc,n,ni,nf,cc],mTEPES.pMaxNTCFrw[p,sc,n,ni,nf,cc]) <= 1 - OptModel.vLineCommit[p,sc,n,ni,nf,c2]
|
|
1779
1804
|
else:
|
|
1780
1805
|
return Constraint.Skip
|
|
1781
|
-
setattr(OptModel, f'eFlowParallelCandidate1_{p}_{sc}_{st}', Constraint(mTEPES.n
|
|
1806
|
+
setattr(OptModel, f'eFlowParallelCandidate1_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.pct, mTEPES.cc, mTEPES.c2, rule=eFlowParallelCandidate1, doc='unitary flow for each AC candidate parallel circuit [p.u.]'))
|
|
1782
1807
|
|
|
1783
1808
|
if pIndLogConsole == 1:
|
|
1784
1809
|
print('eFlowParallelCnddate1 ... ', len(getattr(OptModel, f'eFlowParallelCandidate1_{p}_{sc}_{st}')), ' rows')
|
|
@@ -1788,7 +1813,7 @@ def CycleConstraints(OptModel, mTEPES, pIndLogConsole, p, sc, st):
|
|
|
1788
1813
|
return (OptModel.vFlowElec[p,sc,n,ni,nf,cc] - OptModel.vFlowElec[p,sc,n,ni,nf,c2] * mTEPES.pLineX[ni,nf,c2] / mTEPES.pLineX[ni,nf,cc]) / max(mTEPES.pMaxNTCBck[p,sc,n,ni,nf,cc],mTEPES.pMaxNTCFrw[p,sc,n,ni,nf,cc]) >= - 1 + OptModel.vLineCommit[p,sc,n,ni,nf,c2]
|
|
1789
1814
|
else:
|
|
1790
1815
|
return Constraint.Skip
|
|
1791
|
-
setattr(OptModel, f'eFlowParallelCandidate2_{p}_{sc}_{st}', Constraint(mTEPES.n
|
|
1816
|
+
setattr(OptModel, f'eFlowParallelCandidate2_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.pct, mTEPES.cc, mTEPES.c2, rule=eFlowParallelCandidate2, doc='unitary flow for each AC candidate parallel circuit [p.u.]'))
|
|
1792
1817
|
|
|
1793
1818
|
if pIndLogConsole == 1:
|
|
1794
1819
|
print('eFlowParallelCnddate2 ... ', len(getattr(OptModel, f'eFlowParallelCandidate2_{p}_{sc}_{st}')), ' rows')
|
|
@@ -1829,7 +1854,7 @@ def NetworkH2OperationModelFormulation(OptModel, mTEPES, pIndLogConsole, p, sc,
|
|
|
1829
1854
|
sum(OptModel.vFlowH2[p,sc,n,nd,nf,cc] for nf,cc in lout[nd] if (p,nd,nf,cc) in mTEPES.ppa) + sum(OptModel.vFlowH2[p,sc,n,ni,nd,cc] for ni,cc in lin[nd] if (p,ni,nd,cc) in mTEPES.ppa)) == mTEPES.pDemandH2[p,sc,n,nd]*mTEPES.pDuration[p,sc,n]()
|
|
1830
1855
|
else:
|
|
1831
1856
|
return Constraint.Skip
|
|
1832
|
-
setattr(OptModel, f'eBalanceH2_{p}_{sc}_{st}', Constraint(mTEPES.n
|
|
1857
|
+
setattr(OptModel, f'eBalanceH2_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.nd, rule=eBalanceH2, doc='H2 load generation balance [tH2]'))
|
|
1833
1858
|
|
|
1834
1859
|
if pIndLogConsole == 1:
|
|
1835
1860
|
print('eBalanceH2 ... ', len(getattr(OptModel, f'eBalanceH2_{p}_{sc}_{st}')), ' rows')
|
|
@@ -1865,7 +1890,7 @@ def NetworkHeatOperationModelFormulation(OptModel, mTEPES, pIndLogConsole, p, sc
|
|
|
1865
1890
|
return OptModel.vTotalOutputHeat[p,sc,n,chp] == OptModel.vESSTotalCharge[p,sc,n,chp] / mTEPES.pProductionFunctionHeat[chp]
|
|
1866
1891
|
else:
|
|
1867
1892
|
return Constraint.Skip
|
|
1868
|
-
setattr(OptModel, f'eEnergy2Heat_{p}_{sc}_{st}', Constraint(mTEPES.n
|
|
1893
|
+
setattr(OptModel, f'eEnergy2Heat_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.chp, rule=eEnergy2Heat, doc='Energy to heat conversion [GW]'))
|
|
1869
1894
|
|
|
1870
1895
|
if pIndLogConsole == 1:
|
|
1871
1896
|
print('eEnergy2Heat ... ', len(getattr(OptModel, f'eEnergy2Heat_{p}_{sc}_{st}')), ' rows')
|
|
@@ -1876,7 +1901,7 @@ def NetworkHeatOperationModelFormulation(OptModel, mTEPES, pIndLogConsole, p, sc
|
|
|
1876
1901
|
sum(OptModel.vFlowHeat[p,sc,n,nd,nf,cc] for nf,cc in lout[nd] if (p,nd,nf,cc) in mTEPES.pha) + sum(OptModel.vFlowHeat[p,sc,n,ni,nd,cc] for ni,cc in lin[nd] if (p,ni,nd,cc) in mTEPES.pha)) == mTEPES.pDemandHeat[p,sc,n,nd]
|
|
1877
1902
|
else:
|
|
1878
1903
|
return Constraint.Skip
|
|
1879
|
-
setattr(OptModel, f'eBalanceHeat_{p}_{sc}_{st}', Constraint(mTEPES.n
|
|
1904
|
+
setattr(OptModel, f'eBalanceHeat_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.nd, rule=eBalanceHeat, doc='Heat load generation balance [GW]'))
|
|
1880
1905
|
|
|
1881
1906
|
if pIndLogConsole == 1:
|
|
1882
1907
|
print('eBalanceHeat ... ', len(getattr(OptModel, f'eBalanceHeat_{p}_{sc}_{st}')), ' rows')
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"""
|
|
2
|
-
Open Generation, Storage, and Transmission Operation and Expansion Planning Model with RES and ESS (openTEPES) - January
|
|
2
|
+
Open Generation, Storage, and Transmission Operation and Expansion Planning Model with RES and ESS (openTEPES) - January 25, 2026
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
5
|
import time
|
|
@@ -182,9 +182,18 @@ def _write_set_to_db(con, set_, name):
|
|
|
182
182
|
name : str
|
|
183
183
|
Base name used to build the table name `s_{name}`.
|
|
184
184
|
"""
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
185
|
+
from pyomo.common.sorting import sorted_robust
|
|
186
|
+
|
|
187
|
+
if set_.is_indexed():
|
|
188
|
+
rows = []
|
|
189
|
+
for idx in sorted_robust(set_.keys()):
|
|
190
|
+
for m in set_[idx].sorted_data():
|
|
191
|
+
rows.append((idx, m))
|
|
192
|
+
df = pd.DataFrame(rows, columns=["index", "member"])
|
|
193
|
+
else:
|
|
194
|
+
df = pd.DataFrame({"member": list(set_.sorted_data())})
|
|
195
|
+
|
|
196
|
+
_set_df(con, f"s_{name}", df)
|
|
188
197
|
|
|
189
198
|
|
|
190
199
|
def _write_constraint_to_db(con, constraint, name, model):
|
|
@@ -427,9 +436,9 @@ def InvestmentResults(DirName, CaseName, OptModel, mTEPES, pIndTechnologyOutput,
|
|
|
427
436
|
|
|
428
437
|
MarketResultsInv = pd.concat([MarketResultsInv, OutputResults], axis=1)
|
|
429
438
|
|
|
430
|
-
GenTechInvestCost = pd.Series(data=[sum(mTEPES.pDiscountedWeight[p] * mTEPES.pGenInvestCost[eb] * OptModel.vGenerationInvest[p,eb]() for eb in mTEPES.eb if eb in g2t[gt] and (p,eb) in mTEPES.peb
|
|
439
|
+
GenTechInvestCost = pd.Series(data=[sum(mTEPES.pDiscountedWeight[p] * mTEPES.pGenInvestCost[eb] * OptModel.vGenerationInvest[p,eb]() for eb in mTEPES.eb if eb in g2t[gt] and (p, eb) in mTEPES.peb ) for p,gt in mTEPES.p*mTEPES.gt], index=mTEPES.p*mTEPES.gt)
|
|
431
440
|
GenTechInvestCost *= 1e3
|
|
432
|
-
GenTechInjection = pd.Series(data=[sum(mTEPES.pDiscountedWeight[p] * mTEPES.pLoadLevelDuration[p,sc,n]() * OptModel.vTotalOutput[p,sc,n,eb]() for sc,n,eb in mTEPES.sc*mTEPES.n*mTEPES.eb if eb in g2t[gt] and (p,
|
|
441
|
+
GenTechInjection = pd.Series(data=[sum(mTEPES.pDiscountedWeight[p] * mTEPES.pLoadLevelDuration[p,sc,n]() * OptModel.vTotalOutput[p,sc,n,eb]() for sc,n,eb in mTEPES.sc*mTEPES.n*mTEPES.eb if eb in g2t[gt] and (p,sc,n,eb) in mTEPES.psneb) for p,gt in mTEPES.p*mTEPES.gt], index=mTEPES.p*mTEPES.gt)
|
|
433
442
|
GenTechInjection.name = 'Generation'
|
|
434
443
|
MarketResultsInv = pd.concat([MarketResultsInv, GenTechInjection], axis=1)
|
|
435
444
|
LCOE = GenTechInvestCost.div(GenTechInjection)
|
|
@@ -1047,7 +1056,7 @@ def ReservoirOperationResults(DirName, CaseName, OptModel, mTEPES, pIndTechnolog
|
|
|
1047
1056
|
|
|
1048
1057
|
#%% outputting the water volume values
|
|
1049
1058
|
OutputResults = []
|
|
1050
|
-
sPSSTNES = [(p,sc,st,n,rs) for p,sc,st,n,rs in mTEPES.
|
|
1059
|
+
sPSSTNES = [(p,sc,st,n,rs) for p,sc,st,n,rs in mTEPES.s2n*mTEPES.rs if (p,sc,n,rs) in mTEPES.psnrs]
|
|
1051
1060
|
OutputToFile = pd.Series(data=[abs(mTEPES.pDuals["".join([f"eHydroInventory_{p}_{sc}_{st}('{n}', '{rs}')"])])*1e3 for p,sc,st,n,rs in sPSSTNES], index=pd.Index(sPSSTNES))
|
|
1052
1061
|
if len(OutputToFile):
|
|
1053
1062
|
OutputToFile.to_frame(name='WaterValue').reset_index().pivot_table(index=['level_0','level_1','level_3'], columns='level_4', values='WaterValue').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_MarginalWaterValue_{CaseName}.csv', sep=',')
|
|
@@ -1545,7 +1554,7 @@ def OperationSummaryResults(DirName, CaseName, OptModel, mTEPES):
|
|
|
1545
1554
|
NetInvCostVRESInsCap = 0.0
|
|
1546
1555
|
# Rate of return for VRE technologies
|
|
1547
1556
|
# warning division and multiplication
|
|
1548
|
-
VRETechRevenue = sum(mTEPES.pDuals["".join([f"eBalanceElec_{p}_{sc}_{st}('{n}', '{nd}')"])]/mTEPES.pPeriodProb[p,sc]()/mTEPES.pLoadLevelDuration[p,sc,n]()*OptModel.vTotalOutput[p,sc,n,gc]() for p,sc,st,n,nd,gc in mTEPES.s2n*mTEPES.nd*mTEPES.gc if gc in g2n[nd] and gc in mTEPES.re and (p,
|
|
1557
|
+
VRETechRevenue = sum(mTEPES.pDuals["".join([f"eBalanceElec_{p}_{sc}_{st}('{n}', '{nd}')"])]/mTEPES.pPeriodProb[p,sc]()/mTEPES.pLoadLevelDuration[p,sc,n]()*OptModel.vTotalOutput[p,sc,n,gc]() for p,sc,st,n,nd,gc in mTEPES.s2n*mTEPES.nd*mTEPES.gc if gc in g2n[nd] and gc in mTEPES.re and (p,sc,n,gc) in mTEPES.psngc and sum(1 for g in g2n[nd]) + sum(1 for nf,cc in lout[nd]) + sum(1 for ni,cc in lin[nd]))
|
|
1549
1558
|
VREInvCostCapacity = sum(mTEPES.pDiscountedWeight[p]*mTEPES.pGenInvestCost[gc]*OptModel.vGenerationInvest[p,gc]() for p,gc in mTEPES.pgc if gc in mTEPES.re)
|
|
1550
1559
|
|
|
1551
1560
|
K1 = pd.Series(data={'Ratio Fossil Fuel Generation/Total Generation [%]' : FossilFuelGeneration / TotalGeneration *1e2}).to_frame(name='Value')
|
|
@@ -1869,7 +1878,7 @@ def MarginalResults(DirName, CaseName, OptModel, mTEPES, pIndPlotOutput):
|
|
|
1869
1878
|
OutputToFile.rename_axis(['Period', 'Scenario', 'LoadLevel', 'Area'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_MarginalIncrementalVariableCost_{CaseName}.csv', sep=',')
|
|
1870
1879
|
IncrementalGens = pd.Series('N/A', index=mTEPES.psnar).to_frame(name='Generator')
|
|
1871
1880
|
for p,sc,n,ar in mTEPES.psnar:
|
|
1872
|
-
if all(g not in mTEPES.eh and g not in mTEPES.bo and (p, g) in mTEPES.pg and (ar,
|
|
1881
|
+
if all(g not in mTEPES.eh and g not in mTEPES.bo and (p, g) in mTEPES.pg and (ar,g) in mTEPES.a2g for g in mTEPES.g):
|
|
1873
1882
|
if len(OutputToFile.loc[(p,sc,n,ar)]) > 1:
|
|
1874
1883
|
IncrementalGens.loc[p,sc,n,ar] = OutputToFile.loc[[(p,sc,n,ar)]].squeeze().idxmin()
|
|
1875
1884
|
else:
|
|
@@ -1990,7 +1999,7 @@ def MarginalResults(DirName, CaseName, OptModel, mTEPES, pIndPlotOutput):
|
|
|
1990
1999
|
#%% outputting the water values
|
|
1991
2000
|
if mTEPES.es:
|
|
1992
2001
|
OutputResults = []
|
|
1993
|
-
sPSSTNES = [(p,sc,st,n,es) for p,sc,st,n,es in mTEPES.
|
|
2002
|
+
sPSSTNES = [(p,sc,st,n,es) for p,sc,st,n,es in mTEPES.s2n*mTEPES.es if (p,sc,n,es) in mTEPES.psnes and (mTEPES.pTotalMaxCharge[es] or mTEPES.pTotalEnergyInflows[es])]
|
|
1994
2003
|
OutputToFile = pd.Series(data=[abs(mTEPES.pDuals["".join([f"eESSInventory_{p}_{sc}_{st}('{n}', '{es}')"])])*1e3 for p,sc,st,n,es in sPSSTNES], index=pd.Index(sPSSTNES))
|
|
1995
2004
|
if len(OutputToFile):
|
|
1996
2005
|
OutputToFile.to_frame(name='WaterValue').reset_index().pivot_table(index=['level_0','level_1','level_3'], columns='level_4', values='WaterValue').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_MarginalEnergyValue_{CaseName}.csv', sep=',')
|
|
@@ -2291,29 +2300,29 @@ def EconomicResults(DirName, CaseName, OptModel, mTEPES, pIndAreaOutput, pIndPlo
|
|
|
2291
2300
|
OutputToFile = pd.Series(data=[(mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelDuration[p,sc,n]() * mTEPES.pLinearVarCost [p,sc,n,nr] * OptModel.vTotalOutput[p,sc,n,nr]() +
|
|
2292
2301
|
mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelDuration[p,sc,n]() * mTEPES.pConstantVarCost[p,sc,n,nr] * OptModel.vCommitment [p,sc,n,nr]() +
|
|
2293
2302
|
mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelWeight [p,sc,n]() * mTEPES.pStartUpCost [ nr] * OptModel.vStartUp [p,sc,n,nr]() +
|
|
2294
|
-
mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelWeight [p,sc,n]() * mTEPES.pShutDownCost [ nr] * OptModel.vShutDown [p,sc,n,nr]()) for p,sc,n,nr in mTEPES.psnnr
|
|
2303
|
+
mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelWeight [p,sc,n]() * mTEPES.pShutDownCost [ nr] * OptModel.vShutDown [p,sc,n,nr]()) for p,sc,n,nr in mTEPES.psnnr], index=mTEPES.psnnr)
|
|
2295
2304
|
if mTEPES.psnnr:
|
|
2296
2305
|
OutputToFile.to_frame(name='MEUR').reset_index().pivot_table(index=['level_0','level_1','level_2'], columns='level_3', values='MEUR', aggfunc='sum').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_GenerationCostOperation_{CaseName}.csv', sep=',')
|
|
2297
2306
|
|
|
2298
2307
|
if mTEPES.re:
|
|
2299
|
-
OutputToFile = pd.Series(data=[mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelDuration[p,sc,n]() * mTEPES.pLinearOMCost [re] * OptModel.vTotalOutput [p,sc,n,re]() for p,sc,n,re in mTEPES.psnre
|
|
2308
|
+
OutputToFile = pd.Series(data=[mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelDuration[p,sc,n]() * mTEPES.pLinearOMCost [re] * OptModel.vTotalOutput [p,sc,n,re]() for p,sc,n,re in mTEPES.psnre], index=mTEPES.psnre)
|
|
2300
2309
|
OutputToFile.to_frame(name='MEUR').reset_index().pivot_table(index=['level_0','level_1','level_2'], columns='level_3', values='MEUR', aggfunc='sum').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_GenerationCostOandM_{CaseName}.csv', sep=',')
|
|
2301
2310
|
|
|
2302
2311
|
if mTEPES.nr:
|
|
2303
2312
|
if sum(mTEPES.pOperReserveUp[:,:,:,:]) + sum(mTEPES.pOperReserveDw[:,:,:,:]):
|
|
2304
2313
|
OutputToFile = pd.Series(data=[(mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelWeight[p,sc,n]() * mTEPES.pOperReserveCost[nr] * OptModel.vReserveUp [p,sc,n,nr]() +
|
|
2305
|
-
mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelWeight[p,sc,n]() * mTEPES.pOperReserveCost[nr] * OptModel.vReserveDown[p,sc,n,nr]()) for p,sc,n,nr in mTEPES.psnnr
|
|
2314
|
+
mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelWeight[p,sc,n]() * mTEPES.pOperReserveCost[nr] * OptModel.vReserveDown[p,sc,n,nr]()) for p,sc,n,nr in mTEPES.psnnr], index=mTEPES.psnnr)
|
|
2306
2315
|
OutputToFile.to_frame(name='MEUR').reset_index().pivot_table(index=['level_0','level_1','level_2'], columns='level_3', values='MEUR', aggfunc='sum').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_GenerationCostOperatingReserve_{CaseName}.csv', sep=',')
|
|
2307
2316
|
|
|
2308
2317
|
if mTEPES.psnehc:
|
|
2309
|
-
OutputToFile = pd.Series(data=[ mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelDuration[p,sc,n]() * mTEPES.pLinearVarCost[p,sc,n,eh] * OptModel.vESSTotalCharge[p,sc,n,eh]() for p,sc,n,eh in mTEPES.psnehc
|
|
2318
|
+
OutputToFile = pd.Series(data=[ mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelDuration[p,sc,n]() * mTEPES.pLinearVarCost[p,sc,n,eh] * OptModel.vESSTotalCharge[p,sc,n,eh]() for p,sc,n,eh in mTEPES.psnehc], index=mTEPES.psnehc)
|
|
2310
2319
|
OutputToFile.to_frame(name='MEUR').reset_index().pivot_table(index=['level_0','level_1','level_2'], columns='level_3', values='MEUR', aggfunc='sum').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_ConsumptionCostOperation_{CaseName}.csv', sep=',')
|
|
2311
2320
|
if sum(mTEPES.pIndOperReserveGen[eh] for eh in mTEPES.eh if mTEPES.pIndOperReserveGen[eh] == 0) + sum(mTEPES.pIndOperReserveCon[eh] for eh in mTEPES.eh if mTEPES.pIndOperReserveCon[eh] == 0):
|
|
2312
2321
|
OutputToFile = pd.Series(data=[(mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelWeight[p,sc,n]() * mTEPES.pOperReserveCost[eh] * OptModel.vESSReserveUp [p,sc,n,eh]() +
|
|
2313
|
-
mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelWeight[p,sc,n]() * mTEPES.pOperReserveCost[eh] * OptModel.vESSReserveDown[p,sc,n,eh]()) for p,sc,n,eh in mTEPES.psnehc
|
|
2322
|
+
mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelWeight[p,sc,n]() * mTEPES.pOperReserveCost[eh] * OptModel.vESSReserveDown[p,sc,n,eh]()) for p,sc,n,eh in mTEPES.psnehc], index=mTEPES.psnehc)
|
|
2314
2323
|
OutputToFile.to_frame(name='MEUR').reset_index().pivot_table(index=['level_0','level_1','level_2'], columns='level_3', values='MEUR', aggfunc='sum').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_ConsumptionCostOperatingReserve_{CaseName}.csv', sep=',')
|
|
2315
2324
|
|
|
2316
|
-
OutputToFile = pd.Series(data=[mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelDuration[p,sc,n]() * mTEPES.pEmissionVarCost[p,sc,n,g] * OptModel.vTotalOutput[p,sc,n,g]() for p,sc,n,g in mTEPES.psng
|
|
2325
|
+
OutputToFile = pd.Series(data=[mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelDuration[p,sc,n]() * mTEPES.pEmissionVarCost[p,sc,n,g] * OptModel.vTotalOutput[p,sc,n,g]() for p,sc,n,g in mTEPES.psng], index=mTEPES.psng)
|
|
2317
2326
|
OutputToFile.to_frame(name='MEUR').reset_index().pivot_table(index=['level_0','level_1','level_2'], columns='level_3', values='MEUR', aggfunc='sum').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_GenerationCostEmission_{CaseName}.csv', sep=',')
|
|
2318
2327
|
|
|
2319
2328
|
OutputToFile = pd.Series(data=[mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelDuration[p,sc,n]() * mTEPES.pENSCost() * OptModel.vENS [p,sc,n,nd]() for p,sc,n,nd in mTEPES.psnnd], index=mTEPES.psnnd)
|
|
@@ -2338,35 +2347,35 @@ def EconomicResults(DirName, CaseName, OptModel, mTEPES, pIndAreaOutput, pIndPlo
|
|
|
2338
2347
|
OutputResults7 = pd.DataFrame(data={'MEUR': [0.0]}, index=pd.Index([(p,sc,'Reliability Cost' ) for p,sc in mTEPES.ps]))
|
|
2339
2348
|
|
|
2340
2349
|
if mTEPES.nr:
|
|
2341
|
-
sPSNNR = [(p,sc,n,nr) for p,sc,n,nr in mTEPES.psnnr if nr in n2a[ar]
|
|
2350
|
+
sPSNNR = [(p,sc,n,nr) for p,sc,n,nr in mTEPES.psnnr if nr in n2a[ar]]
|
|
2342
2351
|
if sPSNNR:
|
|
2343
2352
|
OutputResults1 = pd.Series(data=[(mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelDuration[p,sc,n]() * mTEPES.pLinearVarCost [p,sc,n,nr] * OptModel.vTotalOutput[p,sc,n,nr]() +
|
|
2344
2353
|
mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelDuration[p,sc,n]() * mTEPES.pConstantVarCost[p,sc,n,nr] * OptModel.vCommitment [p,sc,n,nr]() +
|
|
2345
2354
|
mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelWeight [p,sc,n]() * mTEPES.pStartUpCost [ nr] * OptModel.vStartUp [p,sc,n,nr]() +
|
|
2346
2355
|
mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelWeight [p,sc,n]() * mTEPES.pShutDownCost [ nr] * OptModel.vShutDown [p,sc,n,nr]()) for p,sc,n,nr in sPSNNR], index=pd.Index(sPSNNR))
|
|
2347
2356
|
OutputResults1 = Transformation1(OutputResults1, 'Operation Cost Generation')
|
|
2348
|
-
sPSNNR = [(p,sc,n,nr) for p,sc,n,nr in mTEPES.psnnr if nr in n2a[ar]
|
|
2357
|
+
sPSNNR = [(p,sc,n,nr) for p,sc,n,nr in mTEPES.psnnr if nr in n2a[ar]]
|
|
2349
2358
|
if sum(mTEPES.pOperReserveUp[:,:,:,:]) + sum(mTEPES.pOperReserveDw[:,:,:,:]):
|
|
2350
2359
|
OutputResults2 = pd.Series(data=[(mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelWeight [p,sc,n]() * mTEPES.pOperReserveCost[ nr] * OptModel.vReserveUp [p,sc,n,nr]() +
|
|
2351
2360
|
mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelWeight [p,sc,n]() * mTEPES.pOperReserveCost[ nr] * OptModel.vReserveDown[p,sc,n,nr]()) for p,sc,n,nr in sPSNNR], index=pd.Index(sPSNNR))
|
|
2352
2361
|
OutputResults2 = Transformation1(OutputResults2, 'Operating Reserve Cost Generation')
|
|
2353
2362
|
|
|
2354
2363
|
if mTEPES.g :
|
|
2355
|
-
sPSNG = [(p,sc,n,g ) for p,sc,n,g in mTEPES.psng if g in g2a[ar]
|
|
2364
|
+
sPSNG = [(p,sc,n,g ) for p,sc,n,g in mTEPES.psng if g in g2a[ar]]
|
|
2356
2365
|
if sPSNG:
|
|
2357
2366
|
if sum(mTEPES.pEmissionVarCost[:,:,:,:]):
|
|
2358
2367
|
OutputResults6 = pd.Series(data=[ mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelDuration[p,sc,n]() * mTEPES.pEmissionVarCost[p,sc,n,g ] * OptModel.vTotalOutput[p,sc,n,g ]() for p,sc,n,g in sPSNG], index=pd.Index(sPSNG))
|
|
2359
2368
|
OutputResults6 = Transformation1(OutputResults6, 'Emission Cost')
|
|
2360
2369
|
|
|
2361
2370
|
if mTEPES.re:
|
|
2362
|
-
sPSNRE = [(p,sc,n,re) for p,sc,n,re in mTEPES.psnre if re in g2a[ar]
|
|
2371
|
+
sPSNRE = [(p,sc,n,re) for p,sc,n,re in mTEPES.psnre if re in g2a[ar]]
|
|
2363
2372
|
if sPSNRE:
|
|
2364
2373
|
if sum(mTEPES.pLinearOMCost[:]):
|
|
2365
2374
|
OutputResults3 = pd.Series(data=[mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelDuration[p,sc,n]() * mTEPES.pLinearOMCost [re] * OptModel.vTotalOutput [p,sc,n,re]() for p,sc,n,re in sPSNRE], index=pd.Index(sPSNRE))
|
|
2366
2375
|
OutputResults3 = Transformation1(OutputResults3, 'O&M Cost Generation')
|
|
2367
2376
|
|
|
2368
2377
|
if mTEPES.eh:
|
|
2369
|
-
sPSNES = [(p,sc,n,eh) for p,sc,n,eh in mTEPES.psnehc if eh in g2a[ar]
|
|
2378
|
+
sPSNES = [(p,sc,n,eh) for p,sc,n,eh in mTEPES.psnehc if eh in g2a[ar]]
|
|
2370
2379
|
if sPSNES:
|
|
2371
2380
|
if sum(mTEPES.pLinearVarCost [:,:,:,:]):
|
|
2372
2381
|
OutputResults4 = pd.Series(data=[ mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelDuration[p,sc,n]() * mTEPES.pLinearVarCost [p,sc,n,eh] * OptModel.vESSTotalCharge[p,sc,n,eh]() for p,sc,n,eh in sPSNES], index=pd.Index(sPSNES))
|
|
@@ -2387,42 +2396,42 @@ def EconomicResults(DirName, CaseName, OptModel, mTEPES, pIndAreaOutput, pIndPlo
|
|
|
2387
2396
|
OutputResults.loc[(OutputResults['Period'] == p) & (OutputResults['Scenario'] == sc), 'MEUR/year'] = OutputResults.loc[(OutputResults['Period'] == p) & (OutputResults['Scenario'] == sc), 'MEUR'] / mTEPES.pDiscountedWeight[p] / mTEPES.pScenProb[p,sc]()
|
|
2388
2397
|
OutputResults.to_csv(f'{_path}/oT_Result_CostSummary_{CaseName}_{ar}.csv', sep=',', index=False)
|
|
2389
2398
|
|
|
2390
|
-
sPSSTNG = [(p,sc,st,n, g) for p,sc,st,n, g in mTEPES.s2n*mTEPES.g if (p,sc,n
|
|
2399
|
+
sPSSTNG = [(p,sc,st,n, g) for p,sc,st,n, g in mTEPES.s2n*mTEPES.g if (p,sc,n,g) in mTEPES.psng]
|
|
2391
2400
|
sPSSTNND = [(p,sc,st,n,nd ) for p,sc,st,n,nd in mTEPES.s2n*mTEPES.nd if sum(1 for g in g2n[nd]) + sum(1 for nf,cc in lout[nd]) + sum(1 for ni,cc in lin[nd]) and (p,sc,n) in mTEPES.psn]
|
|
2392
|
-
sPSSTNNDG = [(p,sc,st,n,nd,g) for p,sc,st,n,nd,g in sPSSTNND*mTEPES.g
|
|
2393
|
-
OutputResults = pd.Series(data=[ mTEPES.pDuals["".join([f"eBalanceElec_{p}_{sc}_{st}('{n}', '{nd}')"])]/mTEPES.pPeriodProb[p,sc]()/mTEPES.pLoadLevelDuration[p,sc,n]()*OptModel.vTotalOutput [p,sc,n,g]() for p,sc,st,n,nd,g in sPSSTNNDG
|
|
2394
|
-
MeanOutput = pd.Series(data=[ OptModel.vTotalOutput [p,sc,n,g]() for p,sc,st,n, g in sPSSTNG
|
|
2401
|
+
sPSSTNNDG = [(p,sc,st,n,nd,g) for p,sc,st,n,nd,g in sPSSTNND*mTEPES.g if (p,sc,n,g) in mTEPES.psng and (nd,g) in mTEPES.n2g]
|
|
2402
|
+
OutputResults = pd.Series(data=[ mTEPES.pDuals["".join([f"eBalanceElec_{p}_{sc}_{st}('{n}', '{nd}')"])]/mTEPES.pPeriodProb[p,sc]()/mTEPES.pLoadLevelDuration[p,sc,n]()*OptModel.vTotalOutput [p,sc,n,g]() for p,sc,st,n,nd,g in sPSSTNNDG], index=pd.Index(sPSSTNNDG))
|
|
2403
|
+
MeanOutput = pd.Series(data=[ OptModel.vTotalOutput [p,sc,n,g]() for p,sc,st,n, g in sPSSTNG ], index=pd.Index(sPSSTNG )).groupby(level=4).mean()
|
|
2395
2404
|
MeanOutput *= 1e-3
|
|
2396
2405
|
OutputResults.to_frame(name='MEUR').reset_index().pivot_table(index=['level_0','level_1','level_3'], columns='level_5', values='MEUR').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_RevenueEnergyGeneration_{CaseName}.csv', sep=',')
|
|
2397
2406
|
OutputResults = pd.Series(data=[ mTEPES.pDuals["".join([f"eBalanceElec_{p}_{sc}_{st}('{n}', '{nd}')"])]/mTEPES.pPeriodProb[p,sc]()/mTEPES.pLoadLevelDuration[p,sc,n]()*OptModel.vTotalOutput [p,sc,n,g]()/MeanOutput[g] for p,sc,st,n,nd,g in sPSSTNNDG], index=pd.Index(sPSSTNNDG))
|
|
2398
2407
|
OutputResults.to_frame(name='EUR/MWh').reset_index().pivot_table(index=['level_0','level_1','level_3'], columns='level_5', values='EUR/MWh').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_GenerationCapturedSRMC_{CaseName}.csv', sep=',')
|
|
2399
2408
|
|
|
2400
2409
|
if mTEPES.eh:
|
|
2401
|
-
sPSSTNES = [(p,sc,st,n, eh) for p,sc,st,n, eh in mTEPES.s2n*mTEPES.eh if (p,sc,n
|
|
2402
|
-
sPSSTNNDEH = [(p,sc,st,n,nd,eh) for p,sc,st,n,nd,eh in sPSSTNND*mTEPES.eh if (
|
|
2403
|
-
OutputResults = pd.Series(data=[-mTEPES.pDuals["".join([f"eBalanceElec_{p}_{sc}_{st}('{n}', '{nd}')"])]/mTEPES.pPeriodProb[p,sc]()/mTEPES.pLoadLevelDuration[p,sc,n]()*OptModel.vESSTotalCharge[p,sc,n,eh]() for p,sc,st,n,nd,eh in sPSSTNNDEH
|
|
2404
|
-
MeanOutput = pd.Series(data=[ OptModel.vESSTotalCharge[p,sc,n,eh]() for p,sc,st,n, eh in sPSSTNES
|
|
2410
|
+
sPSSTNES = [(p,sc,st,n, eh) for p,sc,st,n, eh in mTEPES.s2n*mTEPES.eh if (p,sc,n,eh) in mTEPES.psneh]
|
|
2411
|
+
sPSSTNNDEH = [(p,sc,st,n,nd,eh) for p,sc,st,n,nd,eh in sPSSTNND*mTEPES.eh if (p,sc,n,eh) in mTEPES.psneh and (nd,eh) in mTEPES.n2g]
|
|
2412
|
+
OutputResults = pd.Series(data=[-mTEPES.pDuals["".join([f"eBalanceElec_{p}_{sc}_{st}('{n}', '{nd}')"])]/mTEPES.pPeriodProb[p,sc]()/mTEPES.pLoadLevelDuration[p,sc,n]()*OptModel.vESSTotalCharge[p,sc,n,eh]() for p,sc,st,n,nd,eh in sPSSTNNDEH], index=pd.Index(sPSSTNNDEH))
|
|
2413
|
+
MeanOutput = pd.Series(data=[ OptModel.vESSTotalCharge[p,sc,n,eh]() for p,sc,st,n, eh in sPSSTNES ], index=pd.Index(sPSSTNES )).groupby(level=4).mean()
|
|
2405
2414
|
MeanOutput *= 1e-3
|
|
2406
2415
|
OutputResults.to_frame(name='MEUR').reset_index().pivot_table(index=['level_0','level_1','level_3'], columns='level_5', values='MEUR').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_RevenueEnergyConsumption_{CaseName}.csv', sep=',')
|
|
2407
|
-
OutputResults = pd.Series(data=[-mTEPES.pDuals["".join([f"eBalanceElec_{p}_{sc}_{st}('{n}', '{nd}')"])]/mTEPES.pPeriodProb[p,sc]()/mTEPES.pLoadLevelDuration[p,sc,n]()*OptModel.vESSTotalCharge[p,sc,n,eh]()/MeanOutput[eh] for p,sc,st,n,nd,eh in sPSSTNNDEH
|
|
2416
|
+
OutputResults = pd.Series(data=[-mTEPES.pDuals["".join([f"eBalanceElec_{p}_{sc}_{st}('{n}', '{nd}')"])]/mTEPES.pPeriodProb[p,sc]()/mTEPES.pLoadLevelDuration[p,sc,n]()*OptModel.vESSTotalCharge[p,sc,n,eh]()/MeanOutput[eh] for p,sc,st,n,nd,eh in sPSSTNNDEH], index=pd.Index(sPSSTNNDEH))
|
|
2408
2417
|
OutputResults.to_frame(name='EUR/MWh').reset_index().pivot_table(index=['level_0','level_1','level_3'], columns='level_5', values='EUR/MWh').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_ConsumptionCapturedSRMC_{CaseName}.csv', sep=',')
|
|
2409
2418
|
|
|
2410
2419
|
if mTEPES.gc:
|
|
2411
2420
|
GenRev = []
|
|
2412
2421
|
ChargeRev = []
|
|
2413
|
-
sPSSTNNDGC1 = [(p,sc,st,n,nd,gc) for p,sc,st,n,nd,gc in mTEPES.s2n*mTEPES.n2g if gc in mTEPES.gc if (p,
|
|
2422
|
+
sPSSTNNDGC1 = [(p,sc,st,n,nd,gc) for p,sc,st,n,nd,gc in mTEPES.s2n*mTEPES.n2g if gc in mTEPES.gc if (p,sc,n,gc) in mTEPES.psngc]
|
|
2414
2423
|
OutputToGenRev = pd.Series(data=[mTEPES.pDuals["".join([f"eBalanceElec_{p}_{sc}_{st}('{n}', '{nd}')"])]/mTEPES.pPeriodProb[p,sc]()/mTEPES.pLoadLevelDuration[p,sc,n]()*OptModel.vTotalOutput [p,sc,n,gc]() for p,sc,st,n,nd,gc in sPSSTNNDGC1], index=pd.Index(sPSSTNNDGC1))
|
|
2415
2424
|
GenRev.append(OutputToGenRev)
|
|
2416
|
-
if len([(p,sc,n,nd,gc) for p,sc, n,nd,gc in mTEPES.psn*mTEPES.n2g if gc in mTEPES.gc for ot in mTEPES.ot if (p,sc,n
|
|
2417
|
-
sPSSTNNDGC2 = [(p,sc,st,n,nd,gc) for p,sc,st,n,nd,gc in sPSSTNNDGC1 for ot in mTEPES.ot if (p,sc,n
|
|
2425
|
+
if len([(p,sc,n,nd,gc) for p,sc, n,nd,gc in mTEPES.psn*mTEPES.n2g if gc in mTEPES.gc for ot in mTEPES.ot if (p,sc,n,gc) in mTEPES.psngc and gc in o2e[ot]]):
|
|
2426
|
+
sPSSTNNDGC2 = [(p,sc,st,n,nd,gc) for p,sc,st,n,nd,gc in sPSSTNNDGC1 for ot in mTEPES.ot if (p,sc,n,gc) in mTEPES.psngc and gc in o2e[ot]]
|
|
2418
2427
|
OutputChargeRevESS = pd.Series(data=[mTEPES.pDuals["".join([f"eBalanceElec_{p}_{sc}_{st}('{n}', '{nd}')"])]/mTEPES.pPeriodProb[p,sc]()/mTEPES.pLoadLevelDuration[p,sc,n]()*OptModel.vESSTotalCharge[p,sc,n,gc]() for p,sc,st,n,nd,gc in sPSSTNNDGC2], index=pd.Index(sPSSTNNDGC2))
|
|
2419
2428
|
ChargeRev.append(OutputChargeRevESS)
|
|
2420
|
-
if len([(p,sc,n,nd,gc) for p,sc, n,nd,gc in mTEPES.psn*mTEPES.n2g if gc in mTEPES.gc for rt in mTEPES.rt if (p,sc,n
|
|
2421
|
-
sPSSTNNDGC3 = [(p,sc,st,n,nd,gc) for p,sc,st,n,nd,gc in sPSSTNNDGC1 for rt in mTEPES.rt if (p,sc,n
|
|
2429
|
+
if len([(p,sc,n,nd,gc) for p,sc, n,nd,gc in mTEPES.psn*mTEPES.n2g if gc in mTEPES.gc for rt in mTEPES.rt if (p,sc,n,gc) in mTEPES.psngc and gc in r2r[rt]]):
|
|
2430
|
+
sPSSTNNDGC3 = [(p,sc,st,n,nd,gc) for p,sc,st,n,nd,gc in sPSSTNNDGC1 for rt in mTEPES.rt if (p,sc,n,gc) in mTEPES.psngc and gc in r2r[rt]]
|
|
2422
2431
|
OutputChargeRevRES = pd.Series(data=[mTEPES.pDuals["".join([f"eBalanceElec_{p}_{sc}_{st}('{n}', '{nd}')"])]/mTEPES.pPeriodProb[p,sc]()/mTEPES.pLoadLevelDuration[p,sc,n]() * 0.0 for p,sc,st,n,nd,gc in sPSSTNNDGC3], index=pd.Index(sPSSTNNDGC3))
|
|
2423
2432
|
ChargeRev.append(OutputChargeRevRES)
|
|
2424
|
-
if len([(p,sc,n,nd,gc) for p,sc, n,nd,gc in mTEPES.psn*mTEPES.n2g if gc in mTEPES.gc for ot in mTEPES.ot if (p,sc,n
|
|
2425
|
-
sPSSTNNDGC4 = [(p,sc,st,n,nd,gc) for p,sc,st,n,nd,gc in sPSSTNNDGC1 for ot in mTEPES.ot if (p,sc,n
|
|
2433
|
+
if len([(p,sc,n,nd,gc) for p,sc, n,nd,gc in mTEPES.psn*mTEPES.n2g if gc in mTEPES.gc for ot in mTEPES.ot if (p,sc,n,gc) in mTEPES.psngc and gc in o2e[ot]]):
|
|
2434
|
+
sPSSTNNDGC4 = [(p,sc,st,n,nd,gc) for p,sc,st,n,nd,gc in sPSSTNNDGC1 for ot in mTEPES.ot if (p,sc,n,gc) in mTEPES.psngc and gc in o2e[ot]]
|
|
2426
2435
|
OutputChargeRevThr = pd.Series(data=[mTEPES.pDuals["".join([f"eBalanceElec_{p}_{sc}_{st}('{n}', '{nd}')"])]/mTEPES.pPeriodProb[p,sc]()/mTEPES.pLoadLevelDuration[p,sc,n]() * 0.0 for p,sc,st,n,nd,gc in sPSSTNNDGC4], index=pd.Index(sPSSTNNDGC4))
|
|
2427
2436
|
ChargeRev.append(OutputChargeRevThr)
|
|
2428
2437
|
if len(GenRev):
|
|
@@ -2456,18 +2465,18 @@ def EconomicResults(DirName, CaseName, OptModel, mTEPES, pIndAreaOutput, pIndPlo
|
|
|
2456
2465
|
ResRev = pd.Series(data=[0.0 for gc in mTEPES.gc], index=mTEPES.gc, dtype='float64')
|
|
2457
2466
|
|
|
2458
2467
|
if sum(mTEPES.pOperReserveUp[:,:,:,:]) and sum(1 for ar,nr in mTEPES.ar*mTEPES.nr if nr in g2a[ar] and (mTEPES.pIndOperReserveGen[nr] == 0 or mTEPES.pIndOperReserveCon[nr] == 0)) + sum(1 for ar,es in mTEPES.ar*mTEPES.es if es in g2a[ar] and (mTEPES.pIndOperReserveGen[nr] == 0 or mTEPES.pIndOperReserveCon[nr] == 0)):
|
|
2459
|
-
if len([(p,sc,n,ar,nr) for p,sc, n,ar,nr in mTEPES.psn*mTEPES.ar*mTEPES.nr if nr in g2a[ar] and mTEPES.pOperReserveUp[p,sc,n,ar] and (p,sc,n,nr) in mTEPES.psnnr
|
|
2460
|
-
sPSSTNARNR = [(p,sc,st,n,ar,nr) for p,sc,st,n,ar,nr in mTEPES.s2n*mTEPES.ar*mTEPES.nr if nr in g2a[ar] and mTEPES.pOperReserveUp[p,sc,n,ar] and (p,sc,n,nr) in mTEPES.psnnr
|
|
2468
|
+
if len([(p,sc,n,ar,nr) for p,sc, n,ar,nr in mTEPES.psn*mTEPES.ar*mTEPES.nr if nr in g2a[ar] and mTEPES.pOperReserveUp[p,sc,n,ar] and (p,sc,n,nr) in mTEPES.psnnr]):
|
|
2469
|
+
sPSSTNARNR = [(p,sc,st,n,ar,nr) for p,sc,st,n,ar,nr in mTEPES.s2n*mTEPES.ar*mTEPES.nr if nr in g2a[ar] and mTEPES.pOperReserveUp[p,sc,n,ar] and (p,sc,n,nr) in mTEPES.psnnr]
|
|
2461
2470
|
OutputResults = pd.Series(data=[mTEPES.pDuals["".join([f"eOperReserveUp_{p}_{sc}_{st}('{n}', '{ar}')"])]/mTEPES.pPeriodProb[p,sc]()*OptModel.vReserveUp [p,sc,n,nr]() for p,sc,st,n,ar,nr in sPSSTNARNR], index=pd.Index(sPSSTNARNR))
|
|
2462
2471
|
OutputResults.to_frame(name='MEUR').reset_index().pivot_table(index=['level_0','level_1','level_3'], columns='level_5', values='MEUR').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_RevenueOperatingReserveUp_{CaseName}.csv', sep=',')
|
|
2463
2472
|
|
|
2464
|
-
if len([(p,sc,n,ar,eh) for p,sc, n,ar,eh in mTEPES.psn*mTEPES.ar*mTEPES.eh if eh in g2a[ar] and mTEPES.pOperReserveUp[p,sc,n,ar] and (p,sc,n,eh) in mTEPES.psnehc
|
|
2465
|
-
sPSSTNARES = [(p,sc,st,n,ar,eh) for p,sc,st,n,ar,eh in mTEPES.s2n*mTEPES.ar*mTEPES.eh if eh in g2a[ar] and mTEPES.pOperReserveUp[p,sc,n,ar] and (p,sc,n,eh) in mTEPES.psnehc
|
|
2473
|
+
if len([(p,sc,n,ar,eh) for p,sc, n,ar,eh in mTEPES.psn*mTEPES.ar*mTEPES.eh if eh in g2a[ar] and mTEPES.pOperReserveUp[p,sc,n,ar] and (p,sc,n,eh) in mTEPES.psnehc]):
|
|
2474
|
+
sPSSTNARES = [(p,sc,st,n,ar,eh) for p,sc,st,n,ar,eh in mTEPES.s2n*mTEPES.ar*mTEPES.eh if eh in g2a[ar] and mTEPES.pOperReserveUp[p,sc,n,ar] and (p,sc,n,eh) in mTEPES.psnehc]
|
|
2466
2475
|
OutputResults = pd.Series(data=[mTEPES.pDuals["".join([f"eOperReserveUp_{p}_{sc}_{st}('{n}', '{ar}')"])]/mTEPES.pPeriodProb[p,sc]()*OptModel.vESSReserveUp[p,sc,n,eh]() for p,sc,st,n,ar,eh in sPSSTNARES], index=pd.Index(sPSSTNARES))
|
|
2467
2476
|
OutputResults.to_frame(name='MEUR').reset_index().pivot_table(index=['level_0','level_1','level_3'], columns='level_5', values='MEUR').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_RevenueOperatingReserveUpESS_{CaseName}.csv', sep=',')
|
|
2468
2477
|
|
|
2469
|
-
if len([(p,sc,n,ar,ec) for p,sc, n,ar,ec in mTEPES.psn*mTEPES.ar*mTEPES.gc if ec in g2a[ar] and mTEPES.pOperReserveUp[p,sc,n,ar] and (p,sc,n,ec) in mTEPES.psnec
|
|
2470
|
-
sPSSTNAREC = [(p,sc,st,n,ar,ec) for p,sc,st,n,ar,ec in mTEPES.s2n*mTEPES.ar*mTEPES.ec if ec in g2a[ar] and mTEPES.pOperReserveUp[p,sc,n,ar] and (p,sc,n,ec) in mTEPES.psnec
|
|
2478
|
+
if len([(p,sc,n,ar,ec) for p,sc, n,ar,ec in mTEPES.psn*mTEPES.ar*mTEPES.gc if ec in g2a[ar] and mTEPES.pOperReserveUp[p,sc,n,ar] and (p,sc,n,ec) in mTEPES.psnec]):
|
|
2479
|
+
sPSSTNAREC = [(p,sc,st,n,ar,ec) for p,sc,st,n,ar,ec in mTEPES.s2n*mTEPES.ar*mTEPES.ec if ec in g2a[ar] and mTEPES.pOperReserveUp[p,sc,n,ar] and (p,sc,n,ec) in mTEPES.psnec]
|
|
2471
2480
|
OutputResults = pd.Series(data=[mTEPES.pDuals["".join([f"eOperReserveUp_{p}_{sc}_{st}('{n}', '{ar}')"])]/mTEPES.pPeriodProb[p,sc]()*(OptModel.vReserveUp[p,sc,n,ec]()+OptModel.vESSReserveUp[p,sc,n,ec]()) for p,sc,st,n,ar,ec in sPSSTNAREC], index=pd.Index(sPSSTNAREC), dtype='float64')
|
|
2472
2481
|
if len(OutputResults):
|
|
2473
2482
|
OutputToUpRev = OutputResults.to_frame('MEUR').reset_index().pivot_table(index=['level_0','level_1','level_3'], columns='level_5', values='MEUR').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).sum(axis=0)
|
|
@@ -2483,18 +2492,18 @@ def EconomicResults(DirName, CaseName, OptModel, mTEPES, pIndAreaOutput, pIndPlo
|
|
|
2483
2492
|
UpRev = pd.Series(data=[0.0 for gc in mTEPES.gc], index=mTEPES.gc, dtype='float64')
|
|
2484
2493
|
|
|
2485
2494
|
if sum(mTEPES.pOperReserveDw[:,:,:,:]) and sum(1 for ar,nr in mTEPES.ar*mTEPES.nr if nr in g2a[ar] and (mTEPES.pIndOperReserveGen[nr] == 0 or mTEPES.pIndOperReserveGen[nr] == 0 )) + sum(1 for ar,es in mTEPES.ar*mTEPES.es if es in g2a[ar] and (mTEPES.pIndOperReserveGen[es] == 0 or mTEPES.pIndOperReserveCon[es] == 0 )):
|
|
2486
|
-
if len([(p,sc,n,ar,nr) for p,sc, n,ar,nr in mTEPES.psn*mTEPES.ar*mTEPES.nr if nr in g2a[ar] and mTEPES.pOperReserveDw[p,sc,n,ar] and (p,sc,n,nr) in mTEPES.psnnr
|
|
2487
|
-
sPSSTNARNR = [(p,sc,st,n,ar,nr) for p,sc,st,n,ar,nr in mTEPES.s2n*mTEPES.ar*mTEPES.nr if nr in g2a[ar] and mTEPES.pOperReserveDw[p,sc,n,ar] and (p,sc,n,nr) in mTEPES.psnnr
|
|
2495
|
+
if len([(p,sc,n,ar,nr) for p,sc, n,ar,nr in mTEPES.psn*mTEPES.ar*mTEPES.nr if nr in g2a[ar] and mTEPES.pOperReserveDw[p,sc,n,ar] and (p,sc,n,nr) in mTEPES.psnnr]):
|
|
2496
|
+
sPSSTNARNR = [(p,sc,st,n,ar,nr) for p,sc,st,n,ar,nr in mTEPES.s2n*mTEPES.ar*mTEPES.nr if nr in g2a[ar] and mTEPES.pOperReserveDw[p,sc,n,ar] and (p,sc,n,nr) in mTEPES.psnnr]
|
|
2488
2497
|
OutputResults = pd.Series(data=[mTEPES.pDuals["".join([f"eOperReserveDw_{p}_{sc}_{st}('{n}', '{ar}')"])]/mTEPES.pPeriodProb[p,sc]()*OptModel.vReserveDown [p,sc,n,nr]() for p,sc,st,n,ar,nr in sPSSTNARNR], index=pd.Index(sPSSTNARNR))
|
|
2489
2498
|
OutputResults.to_frame(name='MEUR').reset_index().pivot_table(index=['level_0','level_1','level_3'], columns='level_5', values='MEUR').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_RevenueOperatingReserveDw_{CaseName}.csv', sep=',')
|
|
2490
2499
|
|
|
2491
|
-
if len([(p,sc,n,ar,eh) for p,sc, n,ar,eh in mTEPES.psn*mTEPES.ar*mTEPES.eh if eh in g2a[ar] and mTEPES.pOperReserveDw[p,sc,n,ar] and (p,sc,n,eh) in mTEPES.psnehc
|
|
2492
|
-
sPSSTNARES = [(p,sc,st,n,ar,eh) for p,sc,st,n,ar,eh in mTEPES.s2n*mTEPES.ar*mTEPES.eh if eh in g2a[ar] and mTEPES.pOperReserveDw[p,sc,n,ar] and (p,sc,n,eh) in mTEPES.psnehc
|
|
2500
|
+
if len([(p,sc,n,ar,eh) for p,sc, n,ar,eh in mTEPES.psn*mTEPES.ar*mTEPES.eh if eh in g2a[ar] and mTEPES.pOperReserveDw[p,sc,n,ar] and (p,sc,n,eh) in mTEPES.psnehc]):
|
|
2501
|
+
sPSSTNARES = [(p,sc,st,n,ar,eh) for p,sc,st,n,ar,eh in mTEPES.s2n*mTEPES.ar*mTEPES.eh if eh in g2a[ar] and mTEPES.pOperReserveDw[p,sc,n,ar] and (p,sc,n,eh) in mTEPES.psnehc]
|
|
2493
2502
|
OutputResults = pd.Series(data=[mTEPES.pDuals["".join([f"eOperReserveDw_{p}_{sc}_{st}('{n}', '{ar}')"])]/mTEPES.pPeriodProb[p,sc]()*OptModel.vESSReserveDown[p,sc,n,eh]() for p,sc,st,n,ar,eh in sPSSTNARES], index=pd.Index(sPSSTNARES))
|
|
2494
2503
|
OutputResults.to_frame(name='MEUR').reset_index().pivot_table(index=['level_0','level_1','level_3'], columns='level_5', values='MEUR').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_RevenueOperatingReserveDwESS_{CaseName}.csv', sep=',')
|
|
2495
2504
|
|
|
2496
|
-
if len([(p,sc,n,ar,ec) for p,sc, n,ar,ec in mTEPES.psn*mTEPES.ar*mTEPES.ec if ec in g2a[ar] and mTEPES.pOperReserveDw[p,sc,n,ar] and (p,sc,n,ec) in mTEPES.psnec
|
|
2497
|
-
sPSSTNAREC = [(p,sc,st,n,ar,ec) for p,sc,st,n,ar,ec in mTEPES.s2n*mTEPES.ar*mTEPES.ec if ec in g2a[ar] and mTEPES.pOperReserveDw[p,sc,n,ar] and (p,sc,n,ec) in mTEPES.psnec
|
|
2505
|
+
if len([(p,sc,n,ar,ec) for p,sc, n,ar,ec in mTEPES.psn*mTEPES.ar*mTEPES.ec if ec in g2a[ar] and mTEPES.pOperReserveDw[p,sc,n,ar] and (p,sc,n,ec) in mTEPES.psnec]):
|
|
2506
|
+
sPSSTNAREC = [(p,sc,st,n,ar,ec) for p,sc,st,n,ar,ec in mTEPES.s2n*mTEPES.ar*mTEPES.ec if ec in g2a[ar] and mTEPES.pOperReserveDw[p,sc,n,ar] and (p,sc,n,ec) in mTEPES.psnec]
|
|
2498
2507
|
OutputResults = pd.Series(data=[mTEPES.pDuals["".join([f"eOperReserveDw_{p}_{sc}_{st}('{n}', '{ar}')"])]/mTEPES.pPeriodProb[p,sc]()*(OptModel.vReserveDown[p,sc,n,ec]()+OptModel.vESSReserveDown[p,sc,n,ec]()) for p,sc,st,n,ar,ec in sPSSTNAREC], index=pd.Index(sPSSTNAREC), dtype='float64')
|
|
2499
2508
|
if len(OutputResults):
|
|
2500
2509
|
OutputToDwRev = OutputResults.to_frame('MEUR').reset_index().pivot_table(index=['level_0','level_1','level_3'], columns='level_5', values='MEUR').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).sum(axis=0)
|
|
@@ -2509,18 +2518,18 @@ def EconomicResults(DirName, CaseName, OptModel, mTEPES, pIndAreaOutput, pIndPlo
|
|
|
2509
2518
|
DwRev = pd.Series(data=[0.0 for gc in mTEPES.gc], index=mTEPES.gc, dtype='float64')
|
|
2510
2519
|
|
|
2511
2520
|
if mTEPES.pIndRampReserves == 1 and sum(mTEPES.pRampReserveUp[:,:,:,:]):
|
|
2512
|
-
if len([(p,sc,n,nr) for p,sc, n,nr in mTEPES.psn*mTEPES.nr if sum(mTEPES.pRampReserveUp[p,sc,n,ar] for ar in mTEPES.ar) and (p,sc,n,nr) in mTEPES.
|
|
2513
|
-
sPSSTNNR = [(p,sc,st,n,nr) for p,sc,st,n,nr in mTEPES.s2n*mTEPES.nr if sum(mTEPES.pRampReserveUp[p,sc,n,ar] for ar in mTEPES.ar) and (p,sc,n,nr) in mTEPES.
|
|
2521
|
+
if len([(p,sc,n,nr) for p,sc, n,nr in mTEPES.psn*mTEPES.nr if sum(mTEPES.pRampReserveUp[p,sc,n,ar] for ar in mTEPES.ar) and (p,sc,n,nr) in mTEPES.psnnrr]):
|
|
2522
|
+
sPSSTNNR = [(p,sc,st,n,nr) for p,sc,st,n,nr in mTEPES.s2n*mTEPES.nr if sum(mTEPES.pRampReserveUp[p,sc,n,ar] for ar in mTEPES.ar) and (p,sc,n,nr) in mTEPES.psnnrr]
|
|
2514
2523
|
OutputResults = pd.Series(data=[mTEPES.pDuals["".join([f"eSystemRampUp_{p}_{sc}_{st}{n}"])]/mTEPES.pPeriodProb[p,sc]()*OptModel.vRampReserveUp[p,sc,n,nr]() for p,sc,st,n,nr in sPSSTNNR], index=pd.Index(sPSSTNNR))
|
|
2515
2524
|
OutputResults.to_frame(name='MEUR').reset_index().pivot_table(index=['level_0','level_1','level_3'], columns='level_4', values='MEUR').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_RevenueRampReserveUp_{CaseName}.csv', sep=',')
|
|
2516
2525
|
|
|
2517
|
-
# if len([(p,sc,n,eh) for p,sc, n,eh in mTEPES.psn*mTEPES.eh if sum(mTEPES.pRampReserveUp[p,sc,n,ar] for ar in mTEPES.ar) and (p,sc,n,eh) in mTEPES.psnehc
|
|
2518
|
-
# sPSSTNES = [(p,sc,st,n,eh) for p,sc,st,n,eh in mTEPES.s2n*mTEPES.eh if sum(mTEPES.pRampReserveUp[p,sc,n,ar] for ar in mTEPES.ar) and (p,sc,n,eh) in mTEPES.psnehc
|
|
2526
|
+
# if len([(p,sc,n,eh) for p,sc, n,eh in mTEPES.psn*mTEPES.eh if sum(mTEPES.pRampReserveUp[p,sc,n,ar] for ar in mTEPES.ar) and (p,sc,n,eh) in mTEPES.psnehc]):
|
|
2527
|
+
# sPSSTNES = [(p,sc,st,n,eh) for p,sc,st,n,eh in mTEPES.s2n*mTEPES.eh if sum(mTEPES.pRampReserveUp[p,sc,n,ar] for ar in mTEPES.ar) and (p,sc,n,eh) in mTEPES.psnehc]
|
|
2519
2528
|
# OutputResults = pd.Series(data=[mTEPES.pDuals["".join([f"eSystemRampUp_{p}_{sc}_{st}{n}"])]/mTEPES.pPeriodProb[p,sc]()*OptModel.vRampReserveUp[p,sc,n,eh]() for p,sc,st,n,eh in sPSSTNES], index=pd.Index(sPSSTNES))
|
|
2520
2529
|
# OutputResults.to_frame(name='MEUR').reset_index().pivot_table(index=['level_0','level_1','level_3'], columns='level_4', values='MEUR').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_RevenueRampReserveUpESS_{CaseName}.csv', sep=',')
|
|
2521
2530
|
|
|
2522
|
-
if len([(p,sc,n,ec) for p,sc, n,ec in mTEPES.psn*mTEPES.gc if sum(mTEPES.pRampReserveUp[p,sc,n,ar] for ar in mTEPES.ar) and (p,sc,n,ec) in mTEPES.psnec
|
|
2523
|
-
sPSSTNEC = [(p,sc,st,n,ec) for p,sc,st,n,ec in mTEPES.s2n*mTEPES.ec if sum(mTEPES.pRampReserveUp[p,sc,n,ar] for ar in mTEPES.ar) and (p,sc,n,ec) in mTEPES.psnec
|
|
2531
|
+
if len([(p,sc,n,ec) for p,sc, n,ec in mTEPES.psn*mTEPES.gc if sum(mTEPES.pRampReserveUp[p,sc,n,ar] for ar in mTEPES.ar) and (p,sc,n,ec) in mTEPES.psnec]):
|
|
2532
|
+
sPSSTNEC = [(p,sc,st,n,ec) for p,sc,st,n,ec in mTEPES.s2n*mTEPES.ec if sum(mTEPES.pRampReserveUp[p,sc,n,ar] for ar in mTEPES.ar) and (p,sc,n,ec) in mTEPES.psnec]
|
|
2524
2533
|
OutputResults = pd.Series(data=[mTEPES.pDuals["".join([f"eSystemRampUp_{p}_{sc}_{st}{n}"])]/mTEPES.pPeriodProb[p,sc]()*OptModel.vRampReserveUp[p,sc,n,ec]() for p,sc,st,n,ec in sPSSTNEC], index=pd.Index(sPSSTNEC), dtype='float64')
|
|
2525
2534
|
if len(OutputResults):
|
|
2526
2535
|
OutputToUpRev = OutputResults.to_frame('MEUR').reset_index().pivot_table(index=['level_0','level_1','level_3'], columns='level_4', values='MEUR').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).sum(axis=0)
|
|
@@ -2536,18 +2545,18 @@ def EconomicResults(DirName, CaseName, OptModel, mTEPES, pIndAreaOutput, pIndPlo
|
|
|
2536
2545
|
RampUpRev = pd.Series(data=[0.0 for gc in mTEPES.gc], index=mTEPES.gc, dtype='float64')
|
|
2537
2546
|
|
|
2538
2547
|
if mTEPES.pIndRampReserves == 1 and sum(mTEPES.pRampReserveDw[:,:,:,:]):
|
|
2539
|
-
if len([(p,sc,n,nr) for p,sc, n,nr in mTEPES.psn*mTEPES.nr if sum(mTEPES.pRampReserveDw[p,sc,n,ar] for ar in mTEPES.ar) and (p,sc,n,nr) in mTEPES.psnnr
|
|
2540
|
-
sPSSTNNR = [(p,sc,st,n,nr) for p,sc,st,n,nr in mTEPES.s2n*mTEPES.nr if sum(mTEPES.pRampReserveDw[p,sc,n,ar] for ar in mTEPES.ar) and (p,sc,n,nr) in mTEPES.psnnr
|
|
2548
|
+
if len([(p,sc,n,nr) for p,sc, n,nr in mTEPES.psn*mTEPES.nr if sum(mTEPES.pRampReserveDw[p,sc,n,ar] for ar in mTEPES.ar) and (p,sc,n,nr) in mTEPES.psnnr]):
|
|
2549
|
+
sPSSTNNR = [(p,sc,st,n,nr) for p,sc,st,n,nr in mTEPES.s2n*mTEPES.nr if sum(mTEPES.pRampReserveDw[p,sc,n,ar] for ar in mTEPES.ar) and (p,sc,n,nr) in mTEPES.psnnr]
|
|
2541
2550
|
OutputResults = pd.Series(data=[mTEPES.pDuals["".join([f"eSystemRampDw_{p}_{sc}_{st}{n}"])]/mTEPES.pPeriodProb[p,sc]()*OptModel.vRampReserveDw[p,sc,n,nr]() for p,sc,st,n,nr in sPSSTNNR], index=pd.Index(sPSSTNNR))
|
|
2542
2551
|
OutputResults.to_frame(name='MEUR').reset_index().pivot_table(index=['level_0','level_1','level_3'], columns='level_4', values='MEUR').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_RevenueRampReserveDw_{CaseName}.csv', sep=',')
|
|
2543
2552
|
|
|
2544
|
-
# if len([(p,sc,n,eh) for p,sc, n,eh in mTEPES.psn*mTEPES.eh if sum(mTEPES.pRampReserveDw[p,sc,n,ar] for ar in mTEPES.ar) and (p,sc,n,eh) in mTEPES.psnehc
|
|
2545
|
-
# sPSSTNES = [(p,sc,st,n,eh) for p,sc,st,n,eh in mTEPES.s2n*mTEPES.eh if sum(mTEPES.pRampReserveDw[p,sc,n,ar] for ar in mTEPES.ar) and (p,sc,n,eh) in mTEPES.psnehc
|
|
2553
|
+
# if len([(p,sc,n,eh) for p,sc, n,eh in mTEPES.psn*mTEPES.eh if sum(mTEPES.pRampReserveDw[p,sc,n,ar] for ar in mTEPES.ar) and (p,sc,n,eh) in mTEPES.psnehc]):
|
|
2554
|
+
# sPSSTNES = [(p,sc,st,n,eh) for p,sc,st,n,eh in mTEPES.s2n*mTEPES.eh if sum(mTEPES.pRampReserveDw[p,sc,n,ar] for ar in mTEPES.ar) and (p,sc,n,eh) in mTEPES.psnehc]
|
|
2546
2555
|
# OutputResults = pd.Series(data=[mTEPES.pDuals["".join([f"eSystemRampDw_{p}_{sc}_{st}{n}"])]/mTEPES.pPeriodProb[p,sc]()*OptModel.vRampReserveDw[p,sc,n,eh]() for p,sc,st,n,eh in sPSSTNES], index=pd.Index(sPSSTNES))
|
|
2547
2556
|
# OutputResults.to_frame(name='MEUR').reset_index().pivot_table(index=['level_0','level_1','level_3'], columns='level_4', values='MEUR').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_RevenueRampReserveDwESS_{CaseName}.csv', sep=',')
|
|
2548
2557
|
|
|
2549
|
-
if len([(p,sc,n,ec) for p,sc, n,ec in mTEPES.psn*mTEPES.gc if sum(mTEPES.pRampReserveDw[p,sc,n,ar] for ar in mTEPES.ar) and (p,sc,n,ec) in mTEPES.psnec
|
|
2550
|
-
sPSSTNEC = [(p,sc,st,n,ec) for p,sc,st,n,ec in mTEPES.s2n*mTEPES.ec if sum(mTEPES.pRampReserveDw[p,sc,n,ar] for ar in mTEPES.ar) and (p,sc,n,ec) in mTEPES.psnec
|
|
2558
|
+
if len([(p,sc,n,ec) for p,sc, n,ec in mTEPES.psn*mTEPES.gc if sum(mTEPES.pRampReserveDw[p,sc,n,ar] for ar in mTEPES.ar) and (p,sc,n,ec) in mTEPES.psnec]):
|
|
2559
|
+
sPSSTNEC = [(p,sc,st,n,ec) for p,sc,st,n,ec in mTEPES.s2n*mTEPES.ec if sum(mTEPES.pRampReserveDw[p,sc,n,ar] for ar in mTEPES.ar) and (p,sc,n,ec) in mTEPES.psnec]
|
|
2551
2560
|
OutputResults = pd.Series(data=[mTEPES.pDuals["".join([f"eSystemRampDw_{p}_{sc}_{st}{n}"])]/mTEPES.pPeriodProb[p,sc]()*OptModel.vRampReserveUp[p,sc,n,ec]() for p,sc,st,n,ec in sPSSTNEC], index=pd.Index(sPSSTNEC), dtype='float64')
|
|
2552
2561
|
if len(OutputResults):
|
|
2553
2562
|
OutputToDwRev = OutputResults.to_frame('MEUR').reset_index().pivot_table(index=['level_0','level_1','level_3'], columns='level_4', values='MEUR').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).sum(axis=0)
|
|
@@ -31,7 +31,7 @@ def ProblemSolving(DirName, CaseName, SolverName, OptModel, mTEPES, pIndLogConso
|
|
|
31
31
|
# Solver.options['Seed' ] = 104729
|
|
32
32
|
# Solver.options['Presolve' ] = 2
|
|
33
33
|
# Solver.options['RINS' ] = 100
|
|
34
|
-
# Solver.options['BarConvTol' ] = 1e-
|
|
34
|
+
# Solver.options['BarConvTol' ] = 1e-12
|
|
35
35
|
# Solver.options['BarQCPConvTol' ] = 0.025
|
|
36
36
|
# Solver.options['IISFile' ] = f'{_path}/openTEPES_gurobi_'+CaseName+'.ilp' # should be uncommented to show results of IIS
|
|
37
37
|
Solver.options['MIPGap' ] = 0.01
|
|
@@ -57,7 +57,7 @@ def ProblemSolving(DirName, CaseName, SolverName, OptModel, mTEPES, pIndLogConso
|
|
|
57
57
|
if os.path.exists(FileName):
|
|
58
58
|
os.remove(FileName)
|
|
59
59
|
Solver.options['log_file' ] = f'{_path}/openTEPES_highs_{CaseName}_{p}_{sc}_{st}.log'
|
|
60
|
-
Solver.options['solver' ] = '
|
|
60
|
+
Solver.options['solver' ] = 'hipo'
|
|
61
61
|
Solver.options['simplex_strategy' ] = 3
|
|
62
62
|
Solver.options['run_crossover' ] = 'on'
|
|
63
63
|
Solver.options['mip_rel_gap' ] = 0.01
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: openTEPES
|
|
3
|
-
Version: 4.18.
|
|
3
|
+
Version: 4.18.10
|
|
4
4
|
Summary: Open Generation, Storage, and Transmission Operation and Expansion Planning Model with RES and ESS (openTEPES)
|
|
5
5
|
Home-page: https://opentepes.readthedocs.io/en/latest/index.html
|
|
6
6
|
Author: IIT-EnergySystemModels
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
openTEPES/__init__.py,sha256=
|
|
1
|
+
openTEPES/__init__.py,sha256=5L-SpCSyWwUjHcXqOMDHVG25n03wCz2ymKwUn3V1wqI,833
|
|
2
2
|
openTEPES/openTEPES.mapbox_token,sha256=xsXNkwGp2vzXqQy2zVkyLhhNcNWniK2BMeOFpc5SZHI,93
|
|
3
|
-
openTEPES/openTEPES.py,sha256=
|
|
4
|
-
openTEPES/openTEPES_InputData.py,sha256=
|
|
5
|
-
openTEPES/openTEPES_Main.py,sha256=
|
|
6
|
-
openTEPES/openTEPES_ModelFormulation.py,sha256=
|
|
7
|
-
openTEPES/openTEPES_OutputResults.py,sha256=
|
|
8
|
-
openTEPES/openTEPES_ProblemSolving.py,sha256=
|
|
3
|
+
openTEPES/openTEPES.py,sha256=K8jUPdByW1wy59Bh0T0_oqZ29Ds8q6cPnCKqH0xTkFc,27463
|
|
4
|
+
openTEPES/openTEPES_InputData.py,sha256=GldpcWf_BUW493LI69vsf5xJ0Oo7VGZI59VaAT9m9KU,246011
|
|
5
|
+
openTEPES/openTEPES_Main.py,sha256=dddDRIF1BAP7414CjznKfcSCvkHXRJYNak1k8JEc65M,40783
|
|
6
|
+
openTEPES/openTEPES_ModelFormulation.py,sha256=Jci1IPJoJOW6psladRbvIJDjdaPSmSMDU_chcp-iCb4,144057
|
|
7
|
+
openTEPES/openTEPES_OutputResults.py,sha256=LDs43z20dA05jdgtqkIBeF2o1_z1n7XagFjybPqWL84,241177
|
|
8
|
+
openTEPES/openTEPES_ProblemSolving.py,sha256=_3CU1dO-VE6g6gWE8hosyfVed-B9UFiMUKt6uDiy4NI,16764
|
|
9
9
|
openTEPES/openTEPES_gitinfo.py,sha256=6fA1fa-JcyusSc_HcjPiCgnV9zn-fZwdG-kK0a5Fxc8,2004
|
|
10
10
|
openTEPES/.idea/.name,sha256=jiwfcnJ20wztcvpny4SHcqmAIWK-w5tCqN9TWf0GOkw,11
|
|
11
11
|
openTEPES/.idea/misc.xml,sha256=m4-3O284ZBS8WZSQD0QWwk8YjuQYz92w6kr7NRFNips,298
|
|
@@ -384,8 +384,8 @@ openTEPES/sSEP/oT_Dict_Storage_sSEP.csv,sha256=H2rJXZvoMuT-25sI2GpG8IuiNKD-dxuty
|
|
|
384
384
|
openTEPES/sSEP/oT_Dict_Technology_sSEP.csv,sha256=MCTpplzz7_eVPKQfOw35c86ib6CTtW6UK6JrbCJ8wls,170
|
|
385
385
|
openTEPES/sSEP/oT_Dict_ZoneToArea_sSEP.csv,sha256=AUDCs5Bg6sw9f2pVjGP1o4IJjXFF_VrokOGf_V3QsEI,24
|
|
386
386
|
openTEPES/sSEP/oT_Dict_Zone_sSEP.csv,sha256=TBud-fvbFbiAsuutxTYe8wWlv_x1P8oyWXILMpYiXJc,13
|
|
387
|
-
opentepes-4.18.
|
|
388
|
-
opentepes-4.18.
|
|
389
|
-
opentepes-4.18.
|
|
390
|
-
opentepes-4.18.
|
|
391
|
-
opentepes-4.18.
|
|
387
|
+
opentepes-4.18.10.dist-info/entry_points.txt,sha256=gNNPrDaTsRuRJXI1FLNgqMX1CiJ45bEp1dEDH7ZB8Oc,49
|
|
388
|
+
opentepes-4.18.10.dist-info/licenses/LICENSE,sha256=4O7bphXVzRuYavtsWzpLGuM3E-fp3HTRna7F4yIfnS4,35184
|
|
389
|
+
opentepes-4.18.10.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
|
|
390
|
+
opentepes-4.18.10.dist-info/METADATA,sha256=qCa3FslFhw6oMv4dTbR3oj-e2oI0l5Ha5F9NgDQrj6s,19421
|
|
391
|
+
opentepes-4.18.10.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|