openTEPES 4.18.10__py3-none-any.whl → 4.18.12__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/9n/oT_Data_Parameter_9n.csv +1 -1
- openTEPES/__init__.py +1 -1
- openTEPES/openTEPES.py +3 -3
- openTEPES/openTEPES_InputData.py +12 -9
- openTEPES/openTEPES_Main.py +1 -1
- openTEPES/openTEPES_ModelFormulation.py +10 -10
- openTEPES/openTEPES_OutputResults.py +67 -63
- openTEPES/openTEPES_ProblemSolving.py +2 -2
- {opentepes-4.18.10.dist-info → opentepes-4.18.12.dist-info}/METADATA +1 -1
- {opentepes-4.18.10.dist-info → opentepes-4.18.12.dist-info}/RECORD +13 -13
- {opentepes-4.18.10.dist-info → opentepes-4.18.12.dist-info}/WHEEL +0 -0
- {opentepes-4.18.10.dist-info → opentepes-4.18.12.dist-info}/entry_points.txt +0 -0
- {opentepes-4.18.10.dist-info → opentepes-4.18.12.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
ENSCost,HNSCost,HTNSCost,CO2Cost,UpReserveActivation,DwReserveActivation,MinRatioDwUp,MaxRatioDwUp,SBase,ReferenceNode,TimeStep,EconomicBaseYear,AnnualDiscountRate
|
|
2
|
-
10000,10000,10000,25,0.25,0.3,0,1,100,Node_4,
|
|
2
|
+
10000,10000,10000,25,0.25,0.3,0,1,100,Node_4,2,2020,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.12"
|
|
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 28, 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.12 - January 28, 2026')
|
|
42
|
+
print( 'Open Generation, Storage, and Transmission Operation and Expansion Planning Model with RES and ESS (openTEPES) - Version 4.18.12 - January 28, 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
|
@@ -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 28, 2026
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
5
|
import time
|
|
@@ -515,7 +515,7 @@ def DataConfiguration(mTEPES):
|
|
|
515
515
|
|
|
516
516
|
StartTime = time.time()
|
|
517
517
|
#%% Getting the branches from the electric network data
|
|
518
|
-
sBr = [(ni,nf) for
|
|
518
|
+
sBr = [(ni,nf) for ni,nf,cc in mTEPES.dFrame['dfNetwork'].index]
|
|
519
519
|
# Dropping duplicate keys
|
|
520
520
|
sBrList = [(ni,nf) for n,(ni,nf) in enumerate(sBr) if (ni,nf) not in sBr[:n]]
|
|
521
521
|
|
|
@@ -527,7 +527,7 @@ def DataConfiguration(mTEPES):
|
|
|
527
527
|
mTEPES.n = Set(doc='load levels' , initialize=[nn for nn in mTEPES.nn if sum(mTEPES.dPar['pDuration'] [p,sc,nn] for p,sc in mTEPES.ps) > 0])
|
|
528
528
|
mTEPES.n2 = Set(doc='load levels' , initialize=[nn for nn in mTEPES.nn if sum(mTEPES.dPar['pDuration'] [p,sc,nn] for p,sc in mTEPES.ps) > 0])
|
|
529
529
|
mTEPES.g = Set(doc='generating units' , initialize=[gg for gg in mTEPES.gg if (mTEPES.dPar['pRatedMaxPowerElec'] [gg] > 0.0 or mTEPES.dPar['pRatedMaxCharge'][gg] > 0.0 or mTEPES.dPar['pRatedMaxPowerHeat'] [gg] > 0.0) and mTEPES.dPar['pElecGenPeriodIni'][gg] <= mTEPES.p.last() and mTEPES.dPar['pElecGenPeriodFin'][gg] >= mTEPES.p.first() and mTEPES.dPar['pGenToNode'].reset_index().set_index(['Generator']).isin(mTEPES.nd)['Node'][gg]]) # excludes generators with empty node
|
|
530
|
-
mTEPES.
|
|
530
|
+
mTEPES.tr = Set(doc='thermal units' , initialize=[g for g in mTEPES.g if mTEPES.dPar['pRatedLinearOperCost'][g ] > 0.0])
|
|
531
531
|
mTEPES.re = Set(doc='RES units' , initialize=[g for g in mTEPES.g if mTEPES.dPar['pRatedLinearOperCost'][g ] == 0.0 and mTEPES.dPar['pRatedMaxStorage'][g] == 0.0 and mTEPES.dPar['pProductionFunctionH2'][g ] == 0.0 and mTEPES.dPar['pProductionFunctionHeat'][g ] == 0.0 and mTEPES.dPar['pProductionFunctionHydro'][g ] == 0.0])
|
|
532
532
|
mTEPES.es = Set(doc='ESS units' , initialize=[g for g in mTEPES.g if (mTEPES.dPar['pRatedMaxCharge'][g ] > 0.0 or mTEPES.dPar['pRatedMaxStorage'][g] > 0.0 or mTEPES.dPar['pProductionFunctionH2'][g ] > 0.0 or mTEPES.dPar['pProductionFunctionHeat'][g ] > 0.0) and mTEPES.dPar['pProductionFunctionHydro'][g ] == 0.0])
|
|
533
533
|
mTEPES.h = Set(doc='hydro units' , initialize=[g for g in mTEPES.g if mTEPES.dPar['pProductionFunctionH2'][g ] == 0.0 and mTEPES.dPar['pProductionFunctionHeat'][g ] == 0.0 and mTEPES.dPar['pProductionFunctionHydro'][g ] > 0.0])
|
|
@@ -613,7 +613,7 @@ def DataConfiguration(mTEPES):
|
|
|
613
613
|
#%% inverse index load level to stage
|
|
614
614
|
mTEPES.dPar['pStageToLevel'] = mTEPES.dPar['pLevelToStage'].reset_index().set_index(['Period','Scenario','Stage'])['LoadLevel']
|
|
615
615
|
#Filter only valid indices
|
|
616
|
-
mTEPES.dPar['pStageToLevel'] = mTEPES.dPar['pStageToLevel'].loc[mTEPES.dPar['pStageToLevel'].index.isin([(p,s,st) for
|
|
616
|
+
mTEPES.dPar['pStageToLevel'] = mTEPES.dPar['pStageToLevel'].loc[mTEPES.dPar['pStageToLevel'].index.isin([(p,s,st) for p,s in mTEPES.ps for st in mTEPES.st]) & mTEPES.dPar['pStageToLevel'].isin(mTEPES.n)]
|
|
617
617
|
#Reorder the elements
|
|
618
618
|
mTEPES.dPar['pStageToLevel'] = [(p,sc,st,n) for (p,sc,st),n in mTEPES.dPar['pStageToLevel'].items()]
|
|
619
619
|
mTEPES.s2n = Set(initialize=mTEPES.dPar['pStageToLevel'], doc='Load level to stage')
|
|
@@ -642,6 +642,7 @@ def DataConfiguration(mTEPES):
|
|
|
642
642
|
None: Sets are added directly to the mTEPES object.
|
|
643
643
|
'''
|
|
644
644
|
mTEPES.pg = Set(initialize = [(p, g ) for p, g in mTEPES.p *mTEPES.g if mTEPES.dPar['pElecGenPeriodIni'][g ] <= p and mTEPES.dPar['pElecGenPeriodFin'][g ] >= p])
|
|
645
|
+
mTEPES.ptr = Set(initialize = [(p, tr ) for p, tr in mTEPES.p *mTEPES.tr if (p,tr) in mTEPES.pg])
|
|
645
646
|
mTEPES.pgc = Set(initialize = [(p, gc ) for p, gc in mTEPES.p *mTEPES.gc if (p,gc) in mTEPES.pg])
|
|
646
647
|
mTEPES.pnr = Set(initialize = [(p, nr ) for p, nr in mTEPES.p *mTEPES.nr if (p,nr) in mTEPES.pg])
|
|
647
648
|
mTEPES.pch = Set(initialize = [(p, ch ) for p, ch in mTEPES.p *mTEPES.ch if (p,ch) in mTEPES.pg])
|
|
@@ -669,6 +670,7 @@ def DataConfiguration(mTEPES):
|
|
|
669
670
|
mTEPES.pseh = Set(initialize = [(p,sc, eh) for p,sc, eh in mTEPES.ps *mTEPES.eh if (p,eh) in mTEPES.peh ])
|
|
670
671
|
mTEPES.psn = Set(initialize = [(p,sc,n ) for p,sc,n in mTEPES.ps *mTEPES.n if mTEPES.dPar['pDuration'][p,sc,n]])
|
|
671
672
|
mTEPES.psng = Set(initialize = [(p,sc,n,g ) for p,sc,n,g in mTEPES.psn*mTEPES.g if (p,g ) in mTEPES.pg ])
|
|
673
|
+
mTEPES.psntr = Set(initialize = [(p,sc,n,tr) for p,sc,n,tr in mTEPES.psn*mTEPES.tr if (p,tr) in mTEPES.ptr ])
|
|
672
674
|
mTEPES.psngc = Set(initialize = [(p,sc,n,gc) for p,sc,n,gc in mTEPES.psn*mTEPES.gc if (p,gc) in mTEPES.pgc ])
|
|
673
675
|
mTEPES.psngb = Set(initialize = [(p,sc,n,gb) for p,sc,n,gb in mTEPES.psn*mTEPES.gb if (p,gb) in mTEPES.pgc ])
|
|
674
676
|
mTEPES.psnre = Set(initialize = [(p,sc,n,re) for p,sc,n,re in mTEPES.psn*mTEPES.re if (p,re) in mTEPES.pre ])
|
|
@@ -723,7 +725,8 @@ def DataConfiguration(mTEPES):
|
|
|
723
725
|
mTEPES.psnland = Set(initialize = [(p,sc,n,ni,nf,cc,nd) for p,sc,n,ni,nf,cc,nd in mTEPES.psnla*mTEPES.nd if (ni,nf,cc,nd) in mTEPES.dPar['pVariablePTDF'].columns])
|
|
724
726
|
|
|
725
727
|
# assigning a node to an area
|
|
726
|
-
mTEPES.ndar = Set(initialize = [(nd,ar) for
|
|
728
|
+
mTEPES.ndar = Set(initialize = [(nd,ar) for nd,zn,ar in mTEPES.ndzn*mTEPES.ar if (zn,ar) in mTEPES.znar])
|
|
729
|
+
mTEPES.arnd = Set(initialize = [(ar,nd) for nd, ar in mTEPES.ndar])
|
|
727
730
|
|
|
728
731
|
# assigning a line to an area. Both nodes are in the same area. Cross-area lines are not included
|
|
729
732
|
mTEPES.laar = Set(initialize = [(ni,nf,cc,ar) for ni,nf,cc,ar in mTEPES.la*mTEPES.ar if (ni,ar) in mTEPES.ndar and (nf,ar) in mTEPES.ndar])
|
|
@@ -820,9 +823,9 @@ def DataConfiguration(mTEPES):
|
|
|
820
823
|
|
|
821
824
|
mTEPES.n2g = Set(initialize=mTEPES.dPar['pNodeToGen'].index, doc='node to generator')
|
|
822
825
|
|
|
823
|
-
mTEPES.z2g = Set(doc='zone to generator', initialize=[(zn,g) for
|
|
824
|
-
mTEPES.a2g = Set(doc='area to generator', initialize=[(ar,g) for
|
|
825
|
-
mTEPES.r2g = Set(doc='region to generator', initialize=[(rg,g) for
|
|
826
|
+
mTEPES.z2g = Set(doc='zone to generator', initialize=[(zn,g) for nd,g,zn in mTEPES.n2g*mTEPES.zn if (nd,zn) in mTEPES.ndzn ])
|
|
827
|
+
mTEPES.a2g = Set(doc='area to generator', initialize=[(ar,g) for nd,g,zn,ar in mTEPES.n2g*mTEPES.znar if (nd,zn) in mTEPES.ndzn ])
|
|
828
|
+
mTEPES.r2g = Set(doc='region to generator', initialize=[(rg,g) for nd,g,zn,ar,rg in mTEPES.n2g*mTEPES.znar*mTEPES.rg if (nd,zn) in mTEPES.ndzn and [ar,rg] in mTEPES.arrg])
|
|
826
829
|
|
|
827
830
|
# mTEPES.z2g = Set(initialize = [(zn,g) for zn,g in mTEPES.zn*mTEPES.g if (zn,g) in pZone2Gen])
|
|
828
831
|
|
|
@@ -2201,7 +2204,7 @@ def SettingUpVariables(OptModel, mTEPES):
|
|
|
2201
2204
|
# activate only period, scenario, and load levels to formulate
|
|
2202
2205
|
mTEPES.del_component(mTEPES.st)
|
|
2203
2206
|
mTEPES.del_component(mTEPES.n )
|
|
2204
|
-
mTEPES.st = Set(doc='stages', initialize=[stt for stt in mTEPES.stt if st == stt and mTEPES.pStageWeight[stt] and sum(1 for
|
|
2207
|
+
mTEPES.st = Set(doc='stages', initialize=[stt for stt in mTEPES.stt if st == stt and mTEPES.pStageWeight[stt] and sum(1 for p,sc,st,nn in mTEPES.s2n)])
|
|
2205
2208
|
mTEPES.n = Set(doc='load levels', initialize=[nn for nn in mTEPES.nn if (p,sc,st,nn) in mTEPES.s2n ])
|
|
2206
2209
|
|
|
2207
2210
|
if mTEPES.n:
|
openTEPES/openTEPES_Main.py
CHANGED
|
@@ -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.12 - January 28, 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 28, 2026
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
5
|
import time
|
|
@@ -1183,7 +1183,7 @@ def GenerationOperationModelFormulationCommitment(OptModel, mTEPES, pIndLogConso
|
|
|
1183
1183
|
if nr not in mTEPES.GeneratorsInYearlyGroup[group]:
|
|
1184
1184
|
return Constraint.Skip
|
|
1185
1185
|
# Skip if there are one or fewer generators in the group
|
|
1186
|
-
if len(mTEPES.GeneratorsInYearlyGroup[group] & {nr for
|
|
1186
|
+
if len(mTEPES.GeneratorsInYearlyGroup[group] & {nr for p,nr in mTEPES.pnr}) <= 1:
|
|
1187
1187
|
return Constraint.Skip
|
|
1188
1188
|
return OptModel.vCommitment[p,sc,n,nr] <= OptModel.vMaxCommitmentYearly[p,sc,nr,group]
|
|
1189
1189
|
|
|
@@ -1203,7 +1203,7 @@ def GenerationOperationModelFormulationCommitment(OptModel, mTEPES, pIndLogConso
|
|
|
1203
1203
|
if mTEPES.pMaxPowerElec[p,sc,n,nr] == 0.0:
|
|
1204
1204
|
return Constraint.Skip
|
|
1205
1205
|
# Skip if there are one or less generators in the group
|
|
1206
|
-
if len(mTEPES.GeneratorsInYearlyGroup[group] & {nr for
|
|
1206
|
+
if len(mTEPES.GeneratorsInYearlyGroup[group] & {nr for p,nr in mTEPES.pnr}) <= 1:
|
|
1207
1207
|
return Constraint.Skip
|
|
1208
1208
|
return OptModel.vTotalOutput[p,sc,n,nr]/mTEPES.pMaxPowerElec[p,sc,n,nr] <= OptModel.vMaxCommitmentYearly[p,sc,nr,group]
|
|
1209
1209
|
setattr(OptModel, f'eMaxCommitGenYearly_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.ExclusiveGroupsYearly*mTEPES.nr, rule=eMaxCommitGenYearly, doc='maximum of all the capacity factors'))
|
|
@@ -1213,7 +1213,7 @@ def GenerationOperationModelFormulationCommitment(OptModel, mTEPES, pIndLogConso
|
|
|
1213
1213
|
|
|
1214
1214
|
def eExclusiveGensYearly(OptModel,group):
|
|
1215
1215
|
# Skip if there are one or fewer generators in the group
|
|
1216
|
-
if len(mTEPES.GeneratorsInYearlyGroup[group] & {nr for
|
|
1216
|
+
if len(mTEPES.GeneratorsInYearlyGroup[group] & {nr for p,nr in mTEPES.pnr}) <= 1:
|
|
1217
1217
|
return Constraint.Skip
|
|
1218
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
|
|
1219
1219
|
setattr(OptModel, f'eExclusiveGensYearly_{p}_{sc}_{st}', Constraint(mTEPES.ExclusiveGroupsYearly, rule=eExclusiveGensYearly, doc='mutually exclusive generators'))
|
|
@@ -1233,7 +1233,7 @@ def GenerationOperationModelFormulationCommitment(OptModel, mTEPES, pIndLogConso
|
|
|
1233
1233
|
if nr not in mTEPES.GeneratorsInHourlyGroup[group]:
|
|
1234
1234
|
return Constraint.Skip
|
|
1235
1235
|
# Skip if there are one or fewer generators in the group
|
|
1236
|
-
if len(mTEPES.GeneratorsInHourlyGroup[group] & {nr for
|
|
1236
|
+
if len(mTEPES.GeneratorsInHourlyGroup[group] & {nr for p,nr in mTEPES.pnr}) <= 1:
|
|
1237
1237
|
return Constraint.Skip
|
|
1238
1238
|
return OptModel.vCommitment[p,sc,n,nr] <= OptModel.vMaxCommitmentHourly[p,sc,n,nr,group]
|
|
1239
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.]'))
|
|
@@ -1252,7 +1252,7 @@ def GenerationOperationModelFormulationCommitment(OptModel, mTEPES, pIndLogConso
|
|
|
1252
1252
|
if mTEPES.pMaxPowerElec[p,sc,n,nr] == 0.0:
|
|
1253
1253
|
return Constraint.Skip
|
|
1254
1254
|
# Skip if there are one or less generators in the group
|
|
1255
|
-
if len(mTEPES.GeneratorsInHourlyGroup[group] & {nr for
|
|
1255
|
+
if len(mTEPES.GeneratorsInHourlyGroup[group] & {nr for p,nr in mTEPES.pnr}) <= 1:
|
|
1256
1256
|
return Constraint.Skip
|
|
1257
1257
|
return OptModel.vTotalOutput[p,sc,n,nr]/mTEPES.pMaxPowerElec[p,sc,n,nr] <= OptModel.vMaxCommitmentHourly[p,sc,n,nr,group]
|
|
1258
1258
|
|
|
@@ -1264,9 +1264,9 @@ def GenerationOperationModelFormulationCommitment(OptModel, mTEPES, pIndLogConso
|
|
|
1264
1264
|
def eExclusiveGensHourly(OptModel,n,group):
|
|
1265
1265
|
# Skip if there are one or fewer generators in the group
|
|
1266
1266
|
# This is written in a different way to the rest of the code to avoid variable shadowing due to comprehension
|
|
1267
|
-
if len(mTEPES.GeneratorsInHourlyGroup[group] & {gen for
|
|
1267
|
+
if len(mTEPES.GeneratorsInHourlyGroup[group] & {gen for period,gen in mTEPES.pnr if period == p}) <= 1:
|
|
1268
1268
|
return Constraint.Skip
|
|
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,
|
|
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
|
|
1270
1270
|
setattr(OptModel, f'eExclusiveGensHourly_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.ExclusiveGroupsHourly, rule=eExclusiveGensHourly, doc='mutually exclusive generators'))
|
|
1271
1271
|
|
|
1272
1272
|
if pIndLogConsole == 1:
|
|
@@ -1445,7 +1445,7 @@ def GenerationOperationModelFormulationRampMinTime(OptModel, mTEPES, pIndLogCons
|
|
|
1445
1445
|
return Constraint.Skip
|
|
1446
1446
|
else:
|
|
1447
1447
|
return Constraint.Skip
|
|
1448
|
-
setattr(OptModel, f'eMinUpTime_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.
|
|
1448
|
+
setattr(OptModel, f'eMinUpTime_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.tr, rule=eMinUpTime , doc='minimum up time [p.u.]'))
|
|
1449
1449
|
|
|
1450
1450
|
if pIndLogConsole == 1:
|
|
1451
1451
|
print('eMinUpTime ... ', len(getattr(OptModel, f'eMinUpTime_{p}_{sc}_{st}')), ' rows')
|
|
@@ -1458,7 +1458,7 @@ def GenerationOperationModelFormulationRampMinTime(OptModel, mTEPES, pIndLogCons
|
|
|
1458
1458
|
return Constraint.Skip
|
|
1459
1459
|
else:
|
|
1460
1460
|
return Constraint.Skip
|
|
1461
|
-
setattr(OptModel, f'eMinDownTime_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.
|
|
1461
|
+
setattr(OptModel, f'eMinDownTime_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.tr, rule=eMinDownTime, doc='minimum down time [p.u.]'))
|
|
1462
1462
|
|
|
1463
1463
|
if pIndLogConsole == 1:
|
|
1464
1464
|
print('eMinDownTime ... ', len(getattr(OptModel, f'eMinDownTime_{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 28, 2026
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
5
|
import time
|
|
@@ -1098,14 +1098,8 @@ def NetworkH2OperationResults(DirName, CaseName, OptModel, mTEPES):
|
|
|
1098
1098
|
if (gt,el) in mTEPES.t2g:
|
|
1099
1099
|
e2t[gt].append(el)
|
|
1100
1100
|
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
for ar,nd in mTEPES.ar*mTEPES.nd:
|
|
1104
|
-
if (nd,ar) in mTEPES.ndar:
|
|
1105
|
-
d2a[ar].append(nd)
|
|
1106
|
-
|
|
1107
|
-
sPSNARND = [(p,sc,n,ar,nd) for p,sc,n,ar,nd in mTEPES.psn*mTEPES.ar*mTEPES.nd if nd in d2a[ar] and sum(1 for el in e2n[nd]) + sum(1 for nf,cc in lout[nd]) + sum(1 for ni,cc in lin[nd])]
|
|
1108
|
-
sPSNARNDGT = [(p,sc,n,ar,nd,gt) for p,sc,n,ar,nd,gt in sPSNARND*mTEPES.gt if nd in d2a[ar] and sum(1 for el in e2t[gt] if (p,el) in mTEPES.pg) ]
|
|
1101
|
+
sPSNARND = [(p,sc,n,ar,nd) for p,sc,n,ar,nd in mTEPES.psn*mTEPES.arnd if sum(1 for el in e2n[nd]) + sum(1 for nf,cc in lout[nd]) + sum(1 for ni,cc in lin[nd])]
|
|
1102
|
+
sPSNARNDGT = [(p,sc,n,ar,nd,gt) for p,sc,n,ar,nd,gt in sPSNARND*mTEPES.gt if sum(1 for el in e2t[gt] if (p,el) in mTEPES.pg) ]
|
|
1109
1103
|
|
|
1110
1104
|
OutputResults2 = pd.Series(data=[ sum(OptModel.vESSTotalCharge[p,sc,n,el ]()*mTEPES.pLoadLevelDuration[p,sc,n]()/mTEPES.pProductionFunctionH2[el] for el in mTEPES.el if el in e2n[nd] and el in e2t[gt]) for p,sc,n,ar,nd,gt in sPSNARNDGT], index=pd.Index(sPSNARNDGT)).to_frame(name='Generation' ).reset_index().pivot_table(index=['level_0','level_1','level_2','level_3','level_4'], columns='level_5', values='Generation', aggfunc='sum')
|
|
1111
1105
|
OutputResults3 = pd.Series(data=[ OptModel.vH2NS [p,sc,n,nd ]() for p,sc,n,ar,nd in sPSNARND ], index=pd.Index(sPSNARND )).to_frame(name='HydrogenNotServed')
|
|
@@ -1305,14 +1299,8 @@ def NetworkHeatOperationResults(DirName, CaseName, OptModel, mTEPES):
|
|
|
1305
1299
|
if (gt,hp) in mTEPES.t2g:
|
|
1306
1300
|
h2t[gt].append(hp)
|
|
1307
1301
|
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
for ar,nd in mTEPES.ar*mTEPES.nd:
|
|
1311
|
-
if (nd,ar) in mTEPES.ndar:
|
|
1312
|
-
d2a[ar].append(nd)
|
|
1313
|
-
|
|
1314
|
-
sPSNARND = [(p,sc,n,ar,nd) for p,sc,n,ar,nd in mTEPES.psn*mTEPES.ar*mTEPES.nd if nd in d2a[ar] and sum(1 for ch in c2n[nd]) + sum(1 for hp in h2n[nd]) + sum(1 for nf,cc in lout[nd]) + sum(1 for ni,cc in lin[nd])]
|
|
1315
|
-
sPSNARNDGT = [(p,sc,n,ar,nd,gt) for p,sc,n,ar,nd,gt in sPSNARND*mTEPES.gt if nd in d2a[ar] and sum(1 for ch in c2t[gt] if (p,ch) in mTEPES.pg) + sum(1 for hp in h2t[gt] if (p,hp) in mTEPES.pg) ]
|
|
1302
|
+
sPSNARND = [(p,sc,n,ar,nd) for p,sc,n,ar,nd in mTEPES.psn*mTEPES.arnd if sum(1 for ch in c2n[nd]) + sum(1 for hp in h2n[nd]) + sum(1 for nf,cc in lout[nd]) + sum(1 for ni,cc in lin[nd])]
|
|
1303
|
+
sPSNARNDGT = [(p,sc,n,ar,nd,gt) for p,sc,n,ar,nd,gt in sPSNARND*mTEPES.gt if sum(1 for ch in c2t[gt] if (p,ch) in mTEPES.pg) + sum(1 for hp in h2t[gt] if (p,hp) in mTEPES.pg) ]
|
|
1316
1304
|
|
|
1317
1305
|
OutputResults2 = pd.Series(data=[ sum(OptModel.vESSTotalCharge [p,sc,n,hp ]()*mTEPES.pLoadLevelDuration[p,sc,n]()/mTEPES.pProductionFunctionHeat[hp] for hp in mTEPES.hp if hp in h2n[nd] and hp in h2t[gt]) for p,sc,n,ar,nd,gt in sPSNARNDGT], index=pd.Index(sPSNARNDGT)).to_frame(name='GenerationHeatPumps').reset_index().pivot_table(index=['level_0','level_1','level_2','level_3','level_4'], columns='level_5', values='GenerationHeatPumps', aggfunc='sum')
|
|
1318
1306
|
OutputResults3 = pd.Series(data=[ sum(OptModel.vTotalOutput [p,sc,n,ch ]()*mTEPES.pLoadLevelDuration[p,sc,n]()/mTEPES.pPower2HeatRatio [ch] for ch in mTEPES.ch if ch in c2n[nd] and ch in c2t[gt] and ch not in mTEPES.bo) for p,sc,n,ar,nd,gt in sPSNARNDGT], index=pd.Index(sPSNARNDGT)).to_frame(name='GenerationCHPs' ).reset_index().pivot_table(index=['level_0','level_1','level_2','level_3','level_4'], columns='level_5', values='GenerationCHPs' , aggfunc='sum')
|
|
@@ -1532,8 +1520,8 @@ def OperationSummaryResults(DirName, CaseName, OptModel, mTEPES):
|
|
|
1532
1520
|
g2t[gt].append(g)
|
|
1533
1521
|
|
|
1534
1522
|
# Ratio Fossil Fuel Generation/Total Generation [%]
|
|
1535
|
-
TotalGeneration = sum(OptModel.vTotalOutput[p,sc,n,g
|
|
1536
|
-
FossilFuelGeneration = sum(OptModel.vTotalOutput[p,sc,n,g
|
|
1523
|
+
TotalGeneration = sum(OptModel.vTotalOutput[p,sc,n,g]()*mTEPES.pLoadLevelDuration[p,sc,n]() for p,sc,n,g in mTEPES.psng )
|
|
1524
|
+
FossilFuelGeneration = sum(OptModel.vTotalOutput[p,sc,n,g]()*mTEPES.pLoadLevelDuration[p,sc,n]() for p,sc,n,g in mTEPES.psntr)
|
|
1537
1525
|
# Ratio Total Investments [%]
|
|
1538
1526
|
TotalInvestmentCost = sum(mTEPES.pDiscountedWeight[p] * OptModel.vTotalFCost [p ]() for p in mTEPES.p if len(mTEPES.gc) + len(mTEPES.gd) + len(mTEPES.lc))
|
|
1539
1527
|
GenInvestmentCost = sum(mTEPES.pDiscountedWeight[p] * mTEPES.pGenInvestCost[gc] * OptModel.vGenerationInvest[p,gc]() for p,gc in mTEPES.pgc)
|
|
@@ -1554,7 +1542,7 @@ def OperationSummaryResults(DirName, CaseName, OptModel, mTEPES):
|
|
|
1554
1542
|
NetInvCostVRESInsCap = 0.0
|
|
1555
1543
|
# Rate of return for VRE technologies
|
|
1556
1544
|
# warning division and multiplication
|
|
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.
|
|
1545
|
+
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.n2g if gc in g2n[nd] and (p,sc,n,gc) in mTEPES.psnre and sum(1 for g in g2n[nd]) + sum(1 for nf,cc in lout[nd]) + sum(1 for ni,cc in lin[nd]))
|
|
1558
1546
|
VREInvCostCapacity = sum(mTEPES.pDiscountedWeight[p]*mTEPES.pGenInvestCost[gc]*OptModel.vGenerationInvest[p,gc]() for p,gc in mTEPES.pgc if gc in mTEPES.re)
|
|
1559
1547
|
|
|
1560
1548
|
K1 = pd.Series(data={'Ratio Fossil Fuel Generation/Total Generation [%]' : FossilFuelGeneration / TotalGeneration *1e2}).to_frame(name='Value')
|
|
@@ -1665,13 +1653,13 @@ def OperationSummaryResults(DirName, CaseName, OptModel, mTEPES):
|
|
|
1665
1653
|
sPSNND = [(p,sc,n,nd) for p,sc,n,nd in mTEPES.psnnd if sum(1 for g in g2n[nd]) + sum(1 for nf,cc in lout[nd]) + sum(1 for ni,cc in lin[nd])]
|
|
1666
1654
|
OutputResults1 = pd.Series(data=[ ndzn[1][nd] for p,sc,n,nd in sPSNND], index=pd.Index(sPSNND)).to_frame(name='Zone' )
|
|
1667
1655
|
OutputResults2 = pd.Series(data=[ ndar[1][nd] for p,sc,n,nd in sPSNND], index=pd.Index(sPSNND)).to_frame(name='Area' )
|
|
1668
|
-
OutputResults3 = pd.Series(data=[ OptModel.vENS [p,sc,n,nd ]()*mTEPES.pLoadLevelDuration[p,sc,n]()
|
|
1669
|
-
OutputResults4 = pd.Series(data=[- mTEPES.pDemandElec [p,sc,n,nd ]
|
|
1670
|
-
OutputResults5 = pd.Series(data=[-sum(OptModel.vFlowElec [p,sc,n,nd,nf,cc]()
|
|
1671
|
-
OutputResults6 = pd.Series(data=[ sum(OptModel.vFlowElec [p,sc,n,ni,nd,cc]()
|
|
1656
|
+
OutputResults3 = pd.Series(data=[ OptModel.vENS [p,sc,n,nd ]() *mTEPES.pLoadLevelDuration[p,sc,n]() for p,sc,n,nd in sPSNND], index=pd.Index(sPSNND)).to_frame(name='ENS [GWh]' )
|
|
1657
|
+
OutputResults4 = pd.Series(data=[- mTEPES.pDemandElec [p,sc,n,nd ] *mTEPES.pLoadLevelDuration[p,sc,n]() for p,sc,n,nd in sPSNND], index=pd.Index(sPSNND)).to_frame(name='PowerDemand [GWh]' )
|
|
1658
|
+
OutputResults5 = pd.Series(data=[-sum(OptModel.vFlowElec [p,sc,n,nd,nf,cc]() for nf,cc in lout [nd] if (p,nd,nf,cc) in mTEPES.pla)*mTEPES.pLoadLevelDuration[p,sc,n]() for p,sc,n,nd in sPSNND], index=pd.Index(sPSNND)).to_frame(name='PowerFlowOut [GWh]' )
|
|
1659
|
+
OutputResults6 = pd.Series(data=[ sum(OptModel.vFlowElec [p,sc,n,ni,nd,cc]() for ni,cc in lin [nd] if (p,ni,nd,cc) in mTEPES.pla)*mTEPES.pLoadLevelDuration[p,sc,n]() for p,sc,n,nd in sPSNND], index=pd.Index(sPSNND)).to_frame(name='PowerFlowIn [GWh]' )
|
|
1672
1660
|
if mTEPES.ll:
|
|
1673
|
-
OutputResults7 = pd.Series(data=[-sum(OptModel.vLineLosses[p,sc,n,nd,nf,cc]()
|
|
1674
|
-
OutputResults8 = pd.Series(data=[-sum(OptModel.vLineLosses[p,sc,n,ni,nd,cc]()
|
|
1661
|
+
OutputResults7 = pd.Series(data=[-sum(OptModel.vLineLosses[p,sc,n,nd,nf,cc]() for nf,cc in loutl[nd] if (p,nd,nf,cc) in mTEPES.pll)*mTEPES.pLoadLevelDuration[p,sc,n]() for p,sc,n,nd in sPSNND], index=pd.Index(sPSNND)).to_frame(name='LineLossesOut [GWh]')
|
|
1662
|
+
OutputResults8 = pd.Series(data=[-sum(OptModel.vLineLosses[p,sc,n,ni,nd,cc]() for ni,cc in linl [nd] if (p,ni,nd,cc) in mTEPES.pll)*mTEPES.pLoadLevelDuration[p,sc,n]() for p,sc,n,nd in sPSNND], index=pd.Index(sPSNND)).to_frame(name='LineLossesIn [GWh]' )
|
|
1675
1663
|
|
|
1676
1664
|
OutputResults = pd.concat([OutputResults1, OutputResults2, OutputResults3, OutputResults4, OutputResults5, OutputResults6, OutputResults7, OutputResults8], axis=1)
|
|
1677
1665
|
else:
|
|
@@ -1738,8 +1726,8 @@ def FlexibilityResults(DirName, CaseName, OptModel, mTEPES):
|
|
|
1738
1726
|
OutputToFile *= 1e3
|
|
1739
1727
|
OutputToFile.to_frame(name='MW').reset_index().pivot_table(index=['level_0','level_1','level_2'], columns='level_3', values='MW', aggfunc='sum').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_FlexibilityPNS_{CaseName}.csv', sep=',')
|
|
1740
1728
|
|
|
1741
|
-
MeanFlow = pd.Series(data=[sum(OptModel.vFlowElec[p,sc,n,nd,nf,cc]() for nd,nf,cc,af in mTEPES.
|
|
1742
|
-
OutputToFile = pd.Series(data=[sum(OptModel.vFlowElec[p,sc,n,nd,nf,cc]() for nd,nf,cc,af in mTEPES.
|
|
1729
|
+
MeanFlow = pd.Series(data=[sum(OptModel.vFlowElec[p,sc,n,nd,nf,cc]() for nd,nf,cc,af in mTEPES.laar if nd in d2a[ar] and nf in d2a[af] and af != ar and (p,nd,nf,cc) in mTEPES.pla) for p,sc,n,ar in mTEPES.psnar], index=mTEPES.psnar).groupby(level=3).mean()
|
|
1730
|
+
OutputToFile = pd.Series(data=[sum(OptModel.vFlowElec[p,sc,n,nd,nf,cc]() for nd,nf,cc,af in mTEPES.laar if nd in d2a[ar] and nf in d2a[af] and af != ar and (p,nd,nf,cc) in mTEPES.pla) - MeanFlow[ar] for p,sc,n,ar in mTEPES.psnar], index=mTEPES.psnar)
|
|
1743
1731
|
OutputToFile *= 1e3
|
|
1744
1732
|
OutputToFile.to_frame(name='MW').reset_index().pivot_table(index=['level_0','level_1','level_2'], columns='level_3', values='MW', aggfunc='sum').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_FlexibilityNetwork_{CaseName}.csv', sep=',')
|
|
1745
1733
|
|
|
@@ -1998,7 +1986,7 @@ def MarginalResults(DirName, CaseName, OptModel, mTEPES, pIndPlotOutput):
|
|
|
1998
1986
|
|
|
1999
1987
|
#%% outputting the water values
|
|
2000
1988
|
if mTEPES.es:
|
|
2001
|
-
OutputResults = []
|
|
1989
|
+
#OutputResults = []
|
|
2002
1990
|
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])]
|
|
2003
1991
|
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))
|
|
2004
1992
|
if len(OutputToFile):
|
|
@@ -2176,12 +2164,6 @@ def EconomicResults(DirName, CaseName, OptModel, mTEPES, pIndAreaOutput, pIndPlo
|
|
|
2176
2164
|
for gt,g in mTEPES.t2g:
|
|
2177
2165
|
g2t[gt].append(g)
|
|
2178
2166
|
|
|
2179
|
-
# nodes to area (d2a)
|
|
2180
|
-
d2a = defaultdict(list)
|
|
2181
|
-
for ar,nd in mTEPES.ar*mTEPES.nd:
|
|
2182
|
-
if (nd,ar) in mTEPES.ndar:
|
|
2183
|
-
d2a[ar].append(nd)
|
|
2184
|
-
|
|
2185
2167
|
if sum(1 for ar in mTEPES.ar if sum(1 for g in g2a[ar])) > 1:
|
|
2186
2168
|
if pIndAreaOutput == 1:
|
|
2187
2169
|
for ar in mTEPES.ar:
|
|
@@ -2196,10 +2178,21 @@ def EconomicResults(DirName, CaseName, OptModel, mTEPES, pIndAreaOutput, pIndPlo
|
|
|
2196
2178
|
chart = PiePlots(p, sc, OutputToFile, 'Technology', '%')
|
|
2197
2179
|
chart.save(f'{_path}/oT_Plot_TechnologyGenerationEnergy_{CaseName}_{p}_{sc}_{ar}.html', embed_options={'renderer': 'svg'})
|
|
2198
2180
|
|
|
2199
|
-
sPSNARND = [(p,sc,n,ar,nd) for p,sc,n,ar,nd in mTEPES.psn*mTEPES.
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2181
|
+
sPSNARND = [(p,sc,n,ar,nd) for p,sc,n,ar,nd in mTEPES.psn*mTEPES.arnd if sum(1 for g in g2n[nd]) + sum(1 for nf,cc in lout[nd]) + sum(1 for ni,cc in lin[nd])]
|
|
2182
|
+
|
|
2183
|
+
# precompute valid technologies and resources per period to avoid recomputing for each tuple
|
|
2184
|
+
_valid_gt_per_p = {}
|
|
2185
|
+
_valid_rt_per_p = {}
|
|
2186
|
+
_valid_et_per_p = {}
|
|
2187
|
+
_periods = {p for p,_,_,_,_ in sPSNARND}
|
|
2188
|
+
for p in _periods:
|
|
2189
|
+
_valid_gt_per_p[p] = [gt for gt in mTEPES.gt if any((p,g ) in mTEPES.pg for g in g2t.get(gt,[]))]
|
|
2190
|
+
_valid_rt_per_p[p] = [rt for rt in mTEPES.rt if any((p,re) in mTEPES.pre for re in r2r.get(rt,[]))]
|
|
2191
|
+
_valid_et_per_p[p] = [et for et in mTEPES.et if any((p,eh) in mTEPES.peh for eh in e2e.get(et,[]))]
|
|
2192
|
+
|
|
2193
|
+
sPSNARNDGT = [(p,sc,n,ar,nd,gt) for p,sc,n,ar,nd in sPSNARND for gt in _valid_gt_per_p.get(p,[])]
|
|
2194
|
+
sPSNARNDRT = [(p,sc,n,ar,nd,rt) for p,sc,n,ar,nd in sPSNARND for rt in _valid_rt_per_p.get(p,[])]
|
|
2195
|
+
sPSNARNDET = [(p,sc,n,ar,nd,et) for p,sc,n,ar,nd in sPSNARND for et in _valid_et_per_p.get(p,[])]
|
|
2203
2196
|
|
|
2204
2197
|
if sum(1 for nr in mTEPES.nr if nr not in mTEPES.eh):
|
|
2205
2198
|
OutputResults01 = pd.Series(data=[ sum(OptModel.vTotalOutput [p,sc,n,nr ]()*mTEPES.pLoadLevelDuration[p,sc,n]() for nr in g2n[nd] if (p,nr) in mTEPES.pnr and nr in g2t[gt] and nr not in mTEPES.eh) for p,sc,n,ar,nd,gt in sPSNARNDGT], index=pd.Index(sPSNARNDGT)).to_frame(name='Generation' ).reset_index().pivot_table(index=['level_0','level_1','level_2','level_3','level_4'], columns='level_5', values='Generation' , aggfunc='sum')
|
|
@@ -2233,18 +2226,29 @@ def EconomicResults(DirName, CaseName, OptModel, mTEPES, pIndAreaOutput, pIndPlo
|
|
|
2233
2226
|
OutputResults.stack().reset_index().pivot_table(index=['level_0','level_1' ,'level_5'], columns='level_3', values=0, aggfunc='sum').rename_axis(['Period', 'Scenario' , 'Technology' ], axis=0).to_csv(f'{_path}/oT_Result_BalanceEnergyPerArea_{CaseName}.csv', sep=',')
|
|
2234
2227
|
|
|
2235
2228
|
#%% outputting the demand and the LSRMC of electricity
|
|
2236
|
-
sPSSTNARND = [(p,sc,st,n,ar,nd) for p,sc,st,n,ar,nd in mTEPES.s2n*mTEPES.
|
|
2229
|
+
sPSSTNARND = [(p,sc,st,n,ar,nd) for p,sc,st,n,ar,nd in mTEPES.s2n*mTEPES.arnd 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]
|
|
2237
2230
|
|
|
2238
2231
|
OutputResults = pd.Series(data=[mTEPES.pDuals["".join([f"eBalanceElec_{p}_{sc}_{st}('{n}', '{nd}')"])]/mTEPES.pPeriodProb[p,sc]()/mTEPES.pLoadLevelDuration[p,sc,n]() for p,sc,st,n,ar,nd in sPSSTNARND], index=pd.Index(sPSSTNARND))
|
|
2239
2232
|
OutputResults *= 1e3
|
|
2240
2233
|
OutputResults.index = [idx[:2] + idx[3:] for idx in OutputResults.index]
|
|
2241
2234
|
|
|
2242
|
-
|
|
2243
|
-
sPSNARNDG = [
|
|
2244
|
-
sPSNARNDNR = [
|
|
2245
|
-
sPSNARNDRE = [
|
|
2246
|
-
sPSNARNDEH = [
|
|
2235
|
+
# generate the sets for the different generator types
|
|
2236
|
+
sPSNARNDG = []
|
|
2237
|
+
sPSNARNDNR = []
|
|
2238
|
+
sPSNARNDRE = []
|
|
2239
|
+
sPSNARNDEH = []
|
|
2240
|
+
for p,sc,n,ar,nd in sPSNARND:
|
|
2241
|
+
for g in g2n.get(nd,[]):
|
|
2242
|
+
if (p,g) in mTEPES.pg:
|
|
2243
|
+
sPSNARNDG.append((p,sc,n,ar,nd,g))
|
|
2244
|
+
if (p,g) in mTEPES.pnr and g not in mTEPES.eh:
|
|
2245
|
+
sPSNARNDNR.append((p,sc,n,ar,nd,g))
|
|
2246
|
+
if (p,g) in mTEPES.pre:
|
|
2247
|
+
sPSNARNDRE.append((p,sc,n,ar,nd,g))
|
|
2248
|
+
if (p,g) in mTEPES.peh:
|
|
2249
|
+
sPSNARNDEH.append((p,sc,n,ar,nd,g))
|
|
2247
2250
|
|
|
2251
|
+
#%% outputting the generator power output
|
|
2248
2252
|
if sum(1 for nr in mTEPES.nr if nr not in mTEPES.eh):
|
|
2249
2253
|
OutputResults01 = pd.Series(data=[ OptModel.vTotalOutput [p,sc,n,nr ]()*mTEPES.pLoadLevelDuration[p,sc,n]() for p,sc,n,ar,nd,nr in sPSNARNDNR], index=pd.Index(sPSNARNDNR)).to_frame(name='Generation' ).reset_index().pivot_table(index=['level_0','level_1','level_2','level_3','level_4'], columns='level_5', values='Generation' , aggfunc='sum')
|
|
2250
2254
|
if mTEPES.re:
|
|
@@ -2396,9 +2400,9 @@ def EconomicResults(DirName, CaseName, OptModel, mTEPES, pIndAreaOutput, pIndPlo
|
|
|
2396
2400
|
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]()
|
|
2397
2401
|
OutputResults.to_csv(f'{_path}/oT_Result_CostSummary_{CaseName}_{ar}.csv', sep=',', index=False)
|
|
2398
2402
|
|
|
2399
|
-
sPSSTNG = [(p,sc,st,n, g) for p,sc,st,n, g in mTEPES.s2n*mTEPES.g
|
|
2400
|
-
|
|
2401
|
-
|
|
2403
|
+
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]
|
|
2404
|
+
sPSSTNNDG = [(p,sc,st,n,nd,g) for p,sc,st,n,nd,g in mTEPES.s2n*mTEPES.n2g if (p,sc,n,g) in mTEPES.psng]
|
|
2405
|
+
|
|
2402
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]() for p,sc,st,n,nd,g in sPSSTNNDG], index=pd.Index(sPSSTNNDG))
|
|
2403
2407
|
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()
|
|
2404
2408
|
MeanOutput *= 1e-3
|
|
@@ -2408,7 +2412,7 @@ def EconomicResults(DirName, CaseName, OptModel, mTEPES, pIndAreaOutput, pIndPlo
|
|
|
2408
2412
|
|
|
2409
2413
|
if mTEPES.eh:
|
|
2410
2414
|
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
|
|
2415
|
+
sPSSTNNDEH = [(p,sc,st,n,nd,eh) for p,sc,st,n,nd,eh in mTEPES.s2n*mTEPES.n2g if (p,sc,n,eh) in mTEPES.psneh]
|
|
2412
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]() for p,sc,st,n,nd,eh in sPSSTNNDEH], index=pd.Index(sPSSTNNDEH))
|
|
2413
2417
|
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()
|
|
2414
2418
|
MeanOutput *= 1e-3
|
|
@@ -2419,7 +2423,7 @@ def EconomicResults(DirName, CaseName, OptModel, mTEPES, pIndAreaOutput, pIndPlo
|
|
|
2419
2423
|
if mTEPES.gc:
|
|
2420
2424
|
GenRev = []
|
|
2421
2425
|
ChargeRev = []
|
|
2422
|
-
sPSSTNNDGC1 = [(p,sc,st,n,nd,gc) for p,sc,st,n,nd,gc in mTEPES.s2n*mTEPES.n2g if
|
|
2426
|
+
sPSSTNNDGC1 = [(p,sc,st,n,nd,gc) for p,sc,st,n,nd,gc in mTEPES.s2n*mTEPES.n2g if (p,sc,n,gc) in mTEPES.psngc]
|
|
2423
2427
|
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))
|
|
2424
2428
|
GenRev.append(OutputToGenRev)
|
|
2425
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 ot in mTEPES.ot if (p,sc,n,gc) in mTEPES.psngc and gc in o2e[ot]]):
|
|
@@ -2465,17 +2469,17 @@ def EconomicResults(DirName, CaseName, OptModel, mTEPES, pIndAreaOutput, pIndPlo
|
|
|
2465
2469
|
ResRev = pd.Series(data=[0.0 for gc in mTEPES.gc], index=mTEPES.gc, dtype='float64')
|
|
2466
2470
|
|
|
2467
2471
|
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)):
|
|
2468
|
-
if len([(p,sc,n,ar,nr) for p,sc, n,ar,nr in mTEPES.
|
|
2472
|
+
if len([(p,sc,n,ar,nr) for p,sc, n,ar,nr in mTEPES.psnar*mTEPES.nr if nr in g2a[ar] and mTEPES.pOperReserveUp[p,sc,n,ar] and (p,sc,n,nr) in mTEPES.psnnr]):
|
|
2469
2473
|
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]
|
|
2470
2474
|
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))
|
|
2471
2475
|
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=',')
|
|
2472
2476
|
|
|
2473
|
-
if len([(p,sc,n,ar,eh) for p,sc, n,ar,eh in mTEPES.
|
|
2477
|
+
if len([(p,sc,n,ar,eh) for p,sc, n,ar,eh in mTEPES.psnar*mTEPES.eh if eh in g2a[ar] and mTEPES.pOperReserveUp[p,sc,n,ar] and (p,sc,n,eh) in mTEPES.psnehc]):
|
|
2474
2478
|
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]
|
|
2475
2479
|
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))
|
|
2476
2480
|
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=',')
|
|
2477
2481
|
|
|
2478
|
-
if len([(p,sc,n,ar,ec) for p,sc, n,ar,ec in mTEPES.
|
|
2482
|
+
if len([(p,sc,n,ar,ec) for p,sc, n,ar,ec in mTEPES.psnar*mTEPES.gc if ec in g2a[ar] and mTEPES.pOperReserveUp[p,sc,n,ar] and (p,sc,n,ec) in mTEPES.psnec]):
|
|
2479
2483
|
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]
|
|
2480
2484
|
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')
|
|
2481
2485
|
if len(OutputResults):
|
|
@@ -2492,17 +2496,17 @@ def EconomicResults(DirName, CaseName, OptModel, mTEPES, pIndAreaOutput, pIndPlo
|
|
|
2492
2496
|
UpRev = pd.Series(data=[0.0 for gc in mTEPES.gc], index=mTEPES.gc, dtype='float64')
|
|
2493
2497
|
|
|
2494
2498
|
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 )):
|
|
2495
|
-
if len([(p,sc,n,ar,nr) for p,sc, n,ar,nr in mTEPES.
|
|
2499
|
+
if len([(p,sc,n,ar,nr) for p,sc, n,ar,nr in mTEPES.psnar*mTEPES.nr if nr in g2a[ar] and mTEPES.pOperReserveDw[p,sc,n,ar] and (p,sc,n,nr) in mTEPES.psnnr]):
|
|
2496
2500
|
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]
|
|
2497
2501
|
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))
|
|
2498
2502
|
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=',')
|
|
2499
2503
|
|
|
2500
|
-
if len([(p,sc,n,ar,eh) for p,sc, n,ar,eh in mTEPES.
|
|
2504
|
+
if len([(p,sc,n,ar,eh) for p,sc, n,ar,eh in mTEPES.psnar*mTEPES.eh if eh in g2a[ar] and mTEPES.pOperReserveDw[p,sc,n,ar] and (p,sc,n,eh) in mTEPES.psnehc]):
|
|
2501
2505
|
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]
|
|
2502
2506
|
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))
|
|
2503
2507
|
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=',')
|
|
2504
2508
|
|
|
2505
|
-
if len([(p,sc,n,ar,ec) for p,sc, n,ar,ec in mTEPES.
|
|
2509
|
+
if len([(p,sc,n,ar,ec) for p,sc, n,ar,ec in mTEPES.psnar*mTEPES.ec if ec in g2a[ar] and mTEPES.pOperReserveDw[p,sc,n,ar] and (p,sc,n,ec) in mTEPES.psnec]):
|
|
2506
2510
|
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]
|
|
2507
2511
|
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')
|
|
2508
2512
|
if len(OutputResults):
|
|
@@ -2518,17 +2522,17 @@ def EconomicResults(DirName, CaseName, OptModel, mTEPES, pIndAreaOutput, pIndPlo
|
|
|
2518
2522
|
DwRev = pd.Series(data=[0.0 for gc in mTEPES.gc], index=mTEPES.gc, dtype='float64')
|
|
2519
2523
|
|
|
2520
2524
|
if mTEPES.pIndRampReserves == 1 and sum(mTEPES.pRampReserveUp[:,:,:,:]):
|
|
2521
|
-
if len([(p,sc,n,nr) for p,sc, n,nr in mTEPES.
|
|
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.
|
|
2525
|
+
if len([(p,sc,n,nr) for p,sc, n,nr in mTEPES.psnnr if sum(mTEPES.pRampReserveUp[p,sc,n,ar] for ar in mTEPES.ar) and (p,sc,n,nr) in mTEPES.psnnr]):
|
|
2526
|
+
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.psnnr]
|
|
2523
2527
|
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))
|
|
2524
2528
|
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=',')
|
|
2525
2529
|
|
|
2526
|
-
# if len([(p,sc,n,eh) for p,sc, n,eh in mTEPES.
|
|
2530
|
+
# if len([(p,sc,n,eh) for p,sc, n,eh in mTEPES.psneh if sum(mTEPES.pRampReserveUp[p,sc,n,ar] for ar in mTEPES.ar) and (p,sc,n,eh) in mTEPES.psnehc]):
|
|
2527
2531
|
# 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]
|
|
2528
2532
|
# 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))
|
|
2529
2533
|
# 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=',')
|
|
2530
2534
|
|
|
2531
|
-
if len([(p,sc,n,ec) for p,sc, n,ec in mTEPES.
|
|
2535
|
+
if len([(p,sc,n,ec) for p,sc, n,ec in mTEPES.psngc if sum(mTEPES.pRampReserveUp[p,sc,n,ar] for ar in mTEPES.ar) and (p,sc,n,ec) in mTEPES.psnec]):
|
|
2532
2536
|
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]
|
|
2533
2537
|
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')
|
|
2534
2538
|
if len(OutputResults):
|
|
@@ -2545,17 +2549,17 @@ def EconomicResults(DirName, CaseName, OptModel, mTEPES, pIndAreaOutput, pIndPlo
|
|
|
2545
2549
|
RampUpRev = pd.Series(data=[0.0 for gc in mTEPES.gc], index=mTEPES.gc, dtype='float64')
|
|
2546
2550
|
|
|
2547
2551
|
if mTEPES.pIndRampReserves == 1 and sum(mTEPES.pRampReserveDw[:,:,:,:]):
|
|
2548
|
-
if len([(p,sc,n,nr) for p,sc, n,nr in mTEPES.
|
|
2552
|
+
if len([(p,sc,n,nr) for p,sc, n,nr in mTEPES.psnnr if sum(mTEPES.pRampReserveDw[p,sc,n,ar] for ar in mTEPES.ar) and (p,sc,n,nr) in mTEPES.psnnr]):
|
|
2549
2553
|
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]
|
|
2550
2554
|
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))
|
|
2551
2555
|
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=',')
|
|
2552
2556
|
|
|
2553
|
-
# if len([(p,sc,n,eh) for p,sc, n,eh in mTEPES.
|
|
2557
|
+
# if len([(p,sc,n,eh) for p,sc, n,eh in mTEPES.psneh if sum(mTEPES.pRampReserveDw[p,sc,n,ar] for ar in mTEPES.ar) and (p,sc,n,eh) in mTEPES.psnehc]):
|
|
2554
2558
|
# 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]
|
|
2555
2559
|
# 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))
|
|
2556
2560
|
# 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=',')
|
|
2557
2561
|
|
|
2558
|
-
if len([(p,sc,n,ec) for p,sc, n,ec in mTEPES.
|
|
2562
|
+
if len([(p,sc,n,ec) for p,sc, n,ec in mTEPES.psngc if sum(mTEPES.pRampReserveDw[p,sc,n,ar] for ar in mTEPES.ar) and (p,sc,n,ec) in mTEPES.psnec]):
|
|
2559
2563
|
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]
|
|
2560
2564
|
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')
|
|
2561
2565
|
if len(OutputResults):
|
|
@@ -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-9
|
|
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' ] = 'simplex'
|
|
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.12
|
|
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=hjQaRYxML6BvbNpldbSc57nvrmavmJ03HWED6UQG-Uo,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=eT3C6c6Hyd5Q92prg7g5M4E__c-_cGFVnNZCTcYMDOM,27463
|
|
4
|
+
openTEPES/openTEPES_InputData.py,sha256=W13SKTwreioE79ooqV6hxkfblvPhjXRodYkdXQzHsNw,246350
|
|
5
|
+
openTEPES/openTEPES_Main.py,sha256=U9tYggN2CnmTt55nj4HBrZudfaLPrJAKmBF7icMAt3c,40783
|
|
6
|
+
openTEPES/openTEPES_ModelFormulation.py,sha256=BZh419z5i3HnJZMDVm6pHZTAW8SHk-bO2C239nAm3_0,144043
|
|
7
|
+
openTEPES/openTEPES_OutputResults.py,sha256=Wf_Whz8PBU9FS7xJWyrvWN08WrVL1fisKxya6Y-2xYQ,240640
|
|
8
|
+
openTEPES/openTEPES_ProblemSolving.py,sha256=gORJdW46pSzphOfjIT-vSJ2kgkAEuPWh0exqm7ozx0Q,16766
|
|
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
|
|
@@ -26,7 +26,7 @@ openTEPES/9n/oT_Data_NodeLocation_9n.csv,sha256=eaz-9dcwWLoQUEp-oafd4jcetaQ_Grjg
|
|
|
26
26
|
openTEPES/9n/oT_Data_OperatingReserveDown_9n.csv,sha256=43rdY19DpT_A3K1Z0EPeMgFAocMK5DE6_PkiHRRjin8,383843
|
|
27
27
|
openTEPES/9n/oT_Data_OperatingReserveUp_9n.csv,sha256=43rdY19DpT_A3K1Z0EPeMgFAocMK5DE6_PkiHRRjin8,383843
|
|
28
28
|
openTEPES/9n/oT_Data_Option_9n.csv,sha256=2onSiuxVxB0WXX45pBWpfb6uoGY1o_FuAYKrp7w3cpQ,230
|
|
29
|
-
openTEPES/9n/oT_Data_Parameter_9n.csv,sha256=
|
|
29
|
+
openTEPES/9n/oT_Data_Parameter_9n.csv,sha256=jrkD4N7ztg0GaXcMQIkuV750Cqivy4wslAqQ8A64AnA,220
|
|
30
30
|
openTEPES/9n/oT_Data_Period_9n.csv,sha256=NFbJq1PV7fhKMp7ocoy_hy42mKuVabBdPqe9Pt2IVQ4,26
|
|
31
31
|
openTEPES/9n/oT_Data_RESEnergy_9n.csv,sha256=zOj39jlgP1Pj6oIWDY8Kr-ysvvKUhkap5zCZn9s68is,40
|
|
32
32
|
openTEPES/9n/oT_Data_ReserveMargin_9n.csv,sha256=WCIVw1Yr64PzAOBRta-7h4Ri8G0kLNvdu7700sQr6Yg,46
|
|
@@ -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.12.dist-info/entry_points.txt,sha256=gNNPrDaTsRuRJXI1FLNgqMX1CiJ45bEp1dEDH7ZB8Oc,49
|
|
388
|
+
opentepes-4.18.12.dist-info/licenses/LICENSE,sha256=4O7bphXVzRuYavtsWzpLGuM3E-fp3HTRna7F4yIfnS4,35184
|
|
389
|
+
opentepes-4.18.12.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
|
|
390
|
+
opentepes-4.18.12.dist-info/METADATA,sha256=ItvQkxzg9KXJybuHtpKQNDN4KPwi649vYKbR9QS3XEQ,19421
|
|
391
|
+
opentepes-4.18.12.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|