openTEPES 4.18.3__py3-none-any.whl → 4.18.5__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_PTDF/oT_Data_Demand_9n_PTDF.csv +8737 -0
- openTEPES/9n_PTDF/oT_Data_Duration_9n_PTDF.csv +8737 -0
- openTEPES/9n_PTDF/oT_Data_Emission_9n_PTDF.csv +2 -0
- openTEPES/9n_PTDF/oT_Data_EnergyInflows_9n_PTDF.csv +8737 -0
- openTEPES/9n_PTDF/oT_Data_EnergyOutflows_9n_PTDF.csv +8737 -0
- openTEPES/9n_PTDF/oT_Data_Generation_9n_PTDF.csv +17 -0
- openTEPES/9n_PTDF/oT_Data_Inertia_9n_PTDF.csv +8737 -0
- openTEPES/9n_PTDF/oT_Data_Network_9n_PTDF.csv +14 -0
- openTEPES/9n_PTDF/oT_Data_NodeLocation_9n_PTDF.csv +10 -0
- openTEPES/9n_PTDF/oT_Data_OperatingReserveDown_9n_PTDF.csv +8737 -0
- openTEPES/9n_PTDF/oT_Data_OperatingReserveUp_9n_PTDF.csv +8737 -0
- openTEPES/9n_PTDF/oT_Data_Option_9n_PTDF.csv +2 -0
- openTEPES/9n_PTDF/oT_Data_Parameter_9n_PTDF.csv +2 -0
- openTEPES/9n_PTDF/oT_Data_Period_9n_PTDF.csv +2 -0
- openTEPES/9n_PTDF/oT_Data_RESEnergy_9n_PTDF.csv +2 -0
- openTEPES/9n_PTDF/oT_Data_ReserveMargin_9n_PTDF.csv +2 -0
- openTEPES/9n_PTDF/oT_Data_Scenario_9n_PTDF.csv +2 -0
- openTEPES/9n_PTDF/oT_Data_Stage_9n_PTDF.csv +2 -0
- openTEPES/9n_PTDF/oT_Data_VariableEmissionCost_9n_PTDF.csv +8737 -0
- openTEPES/9n_PTDF/oT_Data_VariableFuelCost_9n_PTDF.csv +8737 -0
- openTEPES/9n_PTDF/oT_Data_VariableMaxConsumption_9n_PTDF.csv +8737 -0
- openTEPES/9n_PTDF/oT_Data_VariableMaxEnergy_9n_PTDF.csv +8737 -0
- openTEPES/9n_PTDF/oT_Data_VariableMaxGeneration_9n_PTDF.csv +8737 -0
- openTEPES/9n_PTDF/oT_Data_VariableMaxStorage_9n_PTDF.csv +8737 -0
- openTEPES/9n_PTDF/oT_Data_VariableMinConsumption_9n_PTDF.csv +8737 -0
- openTEPES/9n_PTDF/oT_Data_VariableMinEnergy_9n_PTDF.csv +8737 -0
- openTEPES/9n_PTDF/oT_Data_VariableMinGeneration_9n_PTDF.csv +8737 -0
- openTEPES/9n_PTDF/oT_Data_VariableMinStorage_9n_PTDF.csv +8737 -0
- openTEPES/9n_PTDF/oT_Data_VariablePTDF_9n_PTDF.csv +8740 -0
- openTEPES/9n_PTDF/oT_Data_VariableTTCBck_9n_PTDF.csv +8739 -0
- openTEPES/9n_PTDF/oT_Data_VariableTTCFrw_9n_PTDF.csv +8739 -0
- openTEPES/9n_PTDF/oT_Dict_AreaToRegion_9n_PTDF.csv +2 -0
- openTEPES/9n_PTDF/oT_Dict_Area_9n_PTDF.csv +2 -0
- openTEPES/9n_PTDF/oT_Dict_Circuit_9n_PTDF.csv +3 -0
- openTEPES/9n_PTDF/oT_Dict_Generation_9n_PTDF.csv +17 -0
- openTEPES/9n_PTDF/oT_Dict_Line_9n_PTDF.csv +3 -0
- openTEPES/9n_PTDF/oT_Dict_LoadLevel_9n_PTDF.csv +8737 -0
- openTEPES/9n_PTDF/oT_Dict_NodeToZone_9n_PTDF.csv +10 -0
- openTEPES/9n_PTDF/oT_Dict_Node_9n_PTDF.csv +10 -0
- openTEPES/9n_PTDF/oT_Dict_Period_9n_PTDF.csv +2 -0
- openTEPES/9n_PTDF/oT_Dict_Region_9n_PTDF.csv +31 -0
- openTEPES/9n_PTDF/oT_Dict_Scenario_9n_PTDF.csv +2 -0
- openTEPES/9n_PTDF/oT_Dict_Stage_9n_PTDF.csv +2 -0
- openTEPES/9n_PTDF/oT_Dict_Storage_9n_PTDF.csv +3 -0
- openTEPES/9n_PTDF/oT_Dict_Technology_9n_PTDF.csv +7 -0
- openTEPES/9n_PTDF/oT_Dict_ZoneToArea_9n_PTDF.csv +10 -0
- openTEPES/9n_PTDF/oT_Dict_Zone_9n_PTDF.csv +10 -0
- openTEPES/RTS-GMLC_6y/oT_Dict_AreaToRegion_RTS-GMLC_6y.csv +4 -4
- openTEPES/RTS-GMLC_6y/oT_Dict_Area_RTS-GMLC_6y.csv +4 -4
- openTEPES/RTS-GMLC_6y/oT_Dict_Circuit_RTS-GMLC_6y.csv +5 -5
- openTEPES/RTS-GMLC_6y/oT_Dict_Line_RTS-GMLC_6y.csv +3 -3
- openTEPES/RTS-GMLC_6y/oT_Dict_NodeToZone_RTS-GMLC_6y.csv +74 -74
- openTEPES/RTS-GMLC_6y/oT_Dict_Region_RTS-GMLC_6y.csv +2 -2
- openTEPES/RTS-GMLC_6y/oT_Dict_Scenario_RTS-GMLC_6y.csv +2 -2
- openTEPES/RTS-GMLC_6y/oT_Dict_Storage_RTS-GMLC_6y.csv +3 -3
- openTEPES/RTS-GMLC_6y/oT_Dict_Technology_RTS-GMLC_6y.csv +10 -10
- openTEPES/RTS-GMLC_6y/oT_Dict_ZoneToArea_RTS-GMLC_6y.csv +22 -22
- openTEPES/RTS-GMLC_6y/oT_Dict_Zone_RTS-GMLC_6y.csv +22 -22
- openTEPES/__init__.py +1 -1
- openTEPES/openTEPES.py +137 -65
- openTEPES/openTEPES_InputData.py +419 -234
- openTEPES/openTEPES_Main.py +2 -2
- openTEPES/openTEPES_ModelFormulation.py +469 -180
- openTEPES/openTEPES_OutputResults.py +305 -223
- openTEPES/openTEPES_ProblemSolving.py +68 -56
- {opentepes-4.18.3.dist-info → openTEPES-4.18.5.dist-info}/METADATA +17 -18
- {opentepes-4.18.3.dist-info → openTEPES-4.18.5.dist-info}/RECORD +70 -23
- {opentepes-4.18.3.dist-info → openTEPES-4.18.5.dist-info}/WHEEL +1 -1
- {opentepes-4.18.3.dist-info → openTEPES-4.18.5.dist-info}/LICENSE +0 -0
- {opentepes-4.18.3.dist-info → openTEPES-4.18.5.dist-info}/entry_points.txt +0 -0
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) -
|
|
2
|
+
Open Generation, Storage, and Transmission Operation and Expansion Planning Model with RES and ESS (openTEPES) - June 20, 2025
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
5
|
# import dill as pickle
|
|
@@ -39,8 +39,8 @@ def openTEPES_run(DirName, CaseName, SolverName, pIndOutputResults, pIndLogConso
|
|
|
39
39
|
idxDict['y' ] = 1
|
|
40
40
|
|
|
41
41
|
#%% model declaration
|
|
42
|
-
mTEPES = ConcreteModel('Open Generation, Storage, and Transmission Operation and Expansion Planning Model with RES and ESS (openTEPES) - Version 4.18.
|
|
43
|
-
print( 'Open Generation, Storage, and Transmission Operation and Expansion Planning Model with RES and ESS (openTEPES) - Version 4.18.
|
|
42
|
+
mTEPES = ConcreteModel('Open Generation, Storage, and Transmission Operation and Expansion Planning Model with RES and ESS (openTEPES) - Version 4.18.5 - June 23, 2025')
|
|
43
|
+
print( 'Open Generation, Storage, and Transmission Operation and Expansion Planning Model with RES and ESS (openTEPES) - Version 4.18.5 - June 23, 2025', file=open(f'{_path}/openTEPES_version_{CaseName}.log','w'))
|
|
44
44
|
|
|
45
45
|
pIndOutputResults = [j for i,j in idxDict.items() if i == pIndOutputResults][0]
|
|
46
46
|
pIndLogConsole = [j for i,j in idxDict.items() if i == pIndLogConsole ][0]
|
|
@@ -69,14 +69,15 @@ def openTEPES_run(DirName, CaseName, SolverName, pIndOutputResults, pIndLogConso
|
|
|
69
69
|
# initialize parameter for dual variables
|
|
70
70
|
mTEPES.pDuals = {}
|
|
71
71
|
|
|
72
|
-
# control for not repeating the stages in case of several ones
|
|
73
|
-
mTEPES.NoRepetition = 0
|
|
74
|
-
|
|
75
72
|
# initialize the set of load levels up to the current stage
|
|
76
73
|
mTEPES.na = Set(initialize=[])
|
|
77
74
|
|
|
78
75
|
# iterative model formulation for each stage of a year
|
|
79
76
|
for p,sc,st in mTEPES.ps*mTEPES.stt:
|
|
77
|
+
|
|
78
|
+
# control for not repeating the stages in case of several ones
|
|
79
|
+
mTEPES.NoRepetition = 0
|
|
80
|
+
|
|
80
81
|
# activate only load levels to formulate
|
|
81
82
|
mTEPES.del_component(mTEPES.st)
|
|
82
83
|
mTEPES.del_component(mTEPES.n )
|
|
@@ -99,12 +100,12 @@ def openTEPES_run(DirName, CaseName, SolverName, pIndOutputResults, pIndLogConso
|
|
|
99
100
|
if sum(1 for rs,h in mTEPES.r2p):
|
|
100
101
|
mTEPES.npc = [(n,h ) for n,h in mTEPES.n*mTEPES.h if sum(1 for rs in mTEPES.rs if (rs,h) in mTEPES.r2p) and mTEPES.n.ord(n) % sum(mTEPES.pReservoirTimeStep[rs] for rs in mTEPES.rs if (rs,h) in mTEPES.r2p) == 0]
|
|
101
102
|
else:
|
|
102
|
-
mTEPES.npc
|
|
103
|
+
mTEPES.npc = []
|
|
103
104
|
mTEPES.nrsc = [(n,rs) for n,rs in mTEPES.n*mTEPES.rs if mTEPES.n.ord(n) % mTEPES.pReservoirTimeStep[rs] == 0]
|
|
104
105
|
mTEPES.nrcc = [(n,rs) for n,rs in mTEPES.n*mTEPES.rn if mTEPES.n.ord(n) % mTEPES.pReservoirTimeStep[rs] == 0]
|
|
105
106
|
mTEPES.nrso = [(n,rs) for n,rs in mTEPES.n*mTEPES.rs if mTEPES.n.ord(n) % mTEPES.pWaterOutTimeStep [rs] == 0]
|
|
106
107
|
|
|
107
|
-
if
|
|
108
|
+
if mTEPES.st:
|
|
108
109
|
|
|
109
110
|
# load levels up to the current stage for emission and RES energy constraints
|
|
110
111
|
# if (p != mTEPES.p.first() or sc != mTEPES.sc.first()) and st == mTEPES.First_st:
|
|
@@ -140,57 +141,22 @@ def openTEPES_run(DirName, CaseName, SolverName, pIndOutputResults, pIndLogConso
|
|
|
140
141
|
NetworkCycles ( mTEPES, pIndLogConsole )
|
|
141
142
|
CycleConstraints (mTEPES, mTEPES, pIndLogConsole, p, sc, st)
|
|
142
143
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
if
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
mTEPES.pScenProb[p,sc] = 1.0
|
|
158
|
-
ProblemSolving(DirName, CaseName, SolverName, mTEPES, mTEPES, pIndLogConsole, p, sc, st)
|
|
159
|
-
mTEPES.pScenProb[p,sc] = 0.0
|
|
160
|
-
# deactivate the constraints of the previous period and scenario
|
|
161
|
-
for c in mTEPES.component_objects(pyo.Constraint, active=True):
|
|
162
|
-
if c.name.find(str(p)) != -1 and c.name.find(str(sc)) != -1:
|
|
163
|
-
c.deactivate()
|
|
164
|
-
else:
|
|
165
|
-
if (p,sc) == mTEPES.ps.last() and st == mTEPES.Last_st and mTEPES.NoRepetition == 0:
|
|
166
|
-
mTEPES.NoRepetition = 1
|
|
167
|
-
|
|
168
|
-
mTEPES.del_component(mTEPES.st)
|
|
169
|
-
mTEPES.del_component(mTEPES.n )
|
|
170
|
-
mTEPES.del_component(mTEPES.n2)
|
|
171
|
-
mTEPES.st = Set(doc='stages', initialize=[stt for stt in mTEPES.stt if mTEPES.pStageWeight[stt] and sum(1 for p,sc,stt,nn in mTEPES.s2n)])
|
|
172
|
-
mTEPES.n = Set(doc='load levels', initialize=[nn for nn in mTEPES.nn if sum(1 for p,sc,st in mTEPES.ps*mTEPES.st if (p,sc,st, nn) in mTEPES.s2n)])
|
|
173
|
-
mTEPES.n2 = Set(doc='load levels', initialize=[nn for nn in mTEPES.nn if sum(1 for p,sc,st in mTEPES.ps*mTEPES.st if (p,sc,st, nn) in mTEPES.s2n)])
|
|
174
|
-
|
|
175
|
-
# load levels multiple of cycles for each ESS/generator
|
|
176
|
-
mTEPES.nesc = [(n,es) for n,es in mTEPES.n*mTEPES.es if mTEPES.n.ord(n) % mTEPES.pStorageTimeStep [es] == 0]
|
|
177
|
-
mTEPES.necc = [(n,ec) for n,ec in mTEPES.n*mTEPES.ec if mTEPES.n.ord(n) % mTEPES.pStorageTimeStep [ec] == 0]
|
|
178
|
-
mTEPES.neso = [(n,es) for n,es in mTEPES.n*mTEPES.es if mTEPES.n.ord(n) % mTEPES.pOutflowsTimeStep[es] == 0]
|
|
179
|
-
mTEPES.ngen = [(n,g ) for n,g in mTEPES.n*mTEPES.g if mTEPES.n.ord(n) % mTEPES.pEnergyTimeStep [g ] == 0]
|
|
180
|
-
if mTEPES.pIndHydroTopology == 1:
|
|
181
|
-
mTEPES.nhc = [(n,h ) for n,h in mTEPES.n*mTEPES.h if mTEPES.n.ord(n) % sum(mTEPES.pReservoirTimeStep[rs] for rs in mTEPES.rs if (rs,h) in mTEPES.r2h) == 0]
|
|
182
|
-
if sum(1 for h,rs in mTEPES.p2r):
|
|
183
|
-
mTEPES.np2c = [(n,h ) for n,h in mTEPES.n*mTEPES.h if sum(1 for rs in mTEPES.rs if (h,rs) in mTEPES.p2r) and mTEPES.n.ord(n) % sum(mTEPES.pReservoirTimeStep[rs] for rs in mTEPES.rs if (h,rs) in mTEPES.p2r) == 0]
|
|
184
|
-
else:
|
|
185
|
-
mTEPES.np2c = []
|
|
186
|
-
if sum(1 for rs,h in mTEPES.r2p):
|
|
187
|
-
mTEPES.npc = [(n,h ) for n,h in mTEPES.n*mTEPES.h if sum(1 for rs in mTEPES.rs if (rs,h) in mTEPES.r2p) and mTEPES.n.ord(n) % sum(mTEPES.pReservoirTimeStep[rs] for rs in mTEPES.rs if (rs,h) in mTEPES.r2p) == 0]
|
|
188
|
-
else:
|
|
189
|
-
mTEPES.npc = []
|
|
190
|
-
mTEPES.nrsc = [(n,rs) for n,rs in mTEPES.n*mTEPES.rs if mTEPES.n.ord(n) % mTEPES.pReservoirTimeStep[rs] == 0]
|
|
191
|
-
mTEPES.nrcc = [(n,rs) for n,rs in mTEPES.n*mTEPES.rn if mTEPES.n.ord(n) % mTEPES.pReservoirTimeStep[rs] == 0]
|
|
192
|
-
mTEPES.nrso = [(n,rs) for n,rs in mTEPES.n*mTEPES.rs if mTEPES.n.ord(n) % mTEPES.pWaterOutTimeStep [rs] == 0]
|
|
144
|
+
# No generator investments and no generator retirements, and no line investments
|
|
145
|
+
if ( sum(1 for pp,eb in mTEPES.peb if pp <= p) == 0 or mTEPES.pIndBinGenInvest() == 2
|
|
146
|
+
and sum(1 for pp,gd in mTEPES.pgd if pp <= p) == 0 or mTEPES.pIndBinGenRetire() == 2
|
|
147
|
+
and sum(1 for pp,rc in mTEPES.prc if pp <= p) == 0 or mTEPES.pIndBinRsrInvest() == 2
|
|
148
|
+
and sum(1 for pp,lc in mTEPES.plc if pp <= p) == 0 or mTEPES.pIndBinNetElecInvest() == 2
|
|
149
|
+
and sum(1 for pp,pc in mTEPES.ppc if pp <= p) == 0 or mTEPES.pIndBinNetH2Invest() == 2
|
|
150
|
+
and sum(1 for pp,hc in mTEPES.phc if pp <= p) == 0 or mTEPES.pIndBinNetHeatInvest() == 2):
|
|
151
|
+
|
|
152
|
+
# No minimum RES requirements and no emission limit
|
|
153
|
+
if (max([mTEPES.pRESEnergy[p,ar] for ar in mTEPES.ar]) == 0
|
|
154
|
+
and (min([mTEPES.pEmission [p,ar] for ar in mTEPES.ar]) == math.inf or sum(mTEPES.pEmissionRate[nr] for nr in mTEPES.nr) == 0)):
|
|
155
|
+
|
|
156
|
+
if (p,sc) == mTEPES.ps.last() and st == mTEPES.Last_st and mTEPES.NoRepetition == 0:
|
|
157
|
+
mTEPES.NoRepetition = 1
|
|
193
158
|
|
|
159
|
+
# Writing LP file
|
|
194
160
|
if pIndLogConsole == 1:
|
|
195
161
|
StartTime = time.time()
|
|
196
162
|
mTEPES.write(f'{_path}/openTEPES_{CaseName}_{p}_{sc}_{st}.lp', io_options={'symbolic_solver_labels': True})
|
|
@@ -198,8 +164,114 @@ def openTEPES_run(DirName, CaseName, SolverName, pIndOutputResults, pIndLogConso
|
|
|
198
164
|
StartTime = time.time()
|
|
199
165
|
print('Writing LP file ... ', round(WritingLPFileTime), 's')
|
|
200
166
|
|
|
201
|
-
# there are
|
|
167
|
+
# there are no expansion decisions, or they are ignored (it is an operation model), or there are no system emission nor minimum RES constraints
|
|
168
|
+
mTEPES.pScenProb[p,sc] = 1.0
|
|
202
169
|
ProblemSolving(DirName, CaseName, SolverName, mTEPES, mTEPES, pIndLogConsole, p, sc, st)
|
|
170
|
+
mTEPES.pScenProb[p,sc] = 0.0
|
|
171
|
+
|
|
172
|
+
# deactivate the constraints of the previous period and scenario
|
|
173
|
+
for c in mTEPES.component_objects(pyo.Constraint, active=True):
|
|
174
|
+
if c.name.find(str(p)) != -1 and c.name.find(str(sc)) != -1:
|
|
175
|
+
c.deactivate()
|
|
176
|
+
|
|
177
|
+
# Minimum RES requirements or emission limit
|
|
178
|
+
elif (max([mTEPES.pRESEnergy[p,ar] for ar in mTEPES.ar]) > 0
|
|
179
|
+
or (min([mTEPES.pEmission [p,ar] for ar in mTEPES.ar]) < math.inf and sum(mTEPES.pEmissionRate[nr] for nr in mTEPES.nr) > 0)):
|
|
180
|
+
|
|
181
|
+
if st == mTEPES.Last_st and mTEPES.NoRepetition == 0:
|
|
182
|
+
|
|
183
|
+
if (p,sc) == mTEPES.ps.last():
|
|
184
|
+
mTEPES.NoRepetition = 1
|
|
185
|
+
|
|
186
|
+
mTEPES.del_component(mTEPES.st)
|
|
187
|
+
mTEPES.del_component(mTEPES.n )
|
|
188
|
+
mTEPES.del_component(mTEPES.n2)
|
|
189
|
+
mTEPES.st = Set(doc='stages', initialize=[stt for stt in mTEPES.stt if mTEPES.pStageWeight[stt] and sum(1 for p,sc,stt,nn in mTEPES.s2n)])
|
|
190
|
+
mTEPES.n = Set(doc='load levels', initialize=[nn for nn in mTEPES.nn if sum(1 for p,sc,st in mTEPES.ps*mTEPES.st if (p,sc,st, nn) in mTEPES.s2n)])
|
|
191
|
+
mTEPES.n2 = Set(doc='load levels', initialize=[nn for nn in mTEPES.nn if sum(1 for p,sc,st in mTEPES.ps*mTEPES.st if (p,sc,st, nn) in mTEPES.s2n)])
|
|
192
|
+
|
|
193
|
+
# load levels multiple of cycles for each ESS/generator
|
|
194
|
+
mTEPES.nesc = [(n,es) for n,es in mTEPES.n*mTEPES.es if mTEPES.n.ord(n) % mTEPES.pStorageTimeStep [es] == 0]
|
|
195
|
+
mTEPES.necc = [(n,ec) for n,ec in mTEPES.n*mTEPES.ec if mTEPES.n.ord(n) % mTEPES.pStorageTimeStep [ec] == 0]
|
|
196
|
+
mTEPES.neso = [(n,es) for n,es in mTEPES.n*mTEPES.es if mTEPES.n.ord(n) % mTEPES.pOutflowsTimeStep[es] == 0]
|
|
197
|
+
mTEPES.ngen = [(n,g ) for n,g in mTEPES.n*mTEPES.g if mTEPES.n.ord(n) % mTEPES.pEnergyTimeStep [g ] == 0]
|
|
198
|
+
if mTEPES.pIndHydroTopology == 1:
|
|
199
|
+
mTEPES.nhc = [(n,h ) for n,h in mTEPES.n*mTEPES.h if mTEPES.n.ord(n) % sum(mTEPES.pReservoirTimeStep[rs] for rs in mTEPES.rs if (rs,h) in mTEPES.r2h) == 0]
|
|
200
|
+
if sum(1 for h,rs in mTEPES.p2r):
|
|
201
|
+
mTEPES.np2c = [(n,h ) for n,h in mTEPES.n*mTEPES.h if sum(1 for rs in mTEPES.rs if (h,rs) in mTEPES.p2r) and mTEPES.n.ord(n) % sum(mTEPES.pReservoirTimeStep[rs] for rs in mTEPES.rs if (h,rs) in mTEPES.p2r) == 0]
|
|
202
|
+
else:
|
|
203
|
+
mTEPES.np2c = []
|
|
204
|
+
if sum(1 for rs,h in mTEPES.r2p):
|
|
205
|
+
mTEPES.npc = [(n,h ) for n,h in mTEPES.n*mTEPES.h if sum(1 for rs in mTEPES.rs if (rs,h) in mTEPES.r2p) and mTEPES.n.ord(n) % sum(mTEPES.pReservoirTimeStep[rs] for rs in mTEPES.rs if (rs,h) in mTEPES.r2p) == 0]
|
|
206
|
+
else:
|
|
207
|
+
mTEPES.npc = []
|
|
208
|
+
mTEPES.nrsc = [(n,rs) for n,rs in mTEPES.n*mTEPES.rs if mTEPES.n.ord(n) % mTEPES.pReservoirTimeStep[rs] == 0]
|
|
209
|
+
mTEPES.nrcc = [(n,rs) for n,rs in mTEPES.n*mTEPES.rn if mTEPES.n.ord(n) % mTEPES.pReservoirTimeStep[rs] == 0]
|
|
210
|
+
mTEPES.nrso = [(n,rs) for n,rs in mTEPES.n*mTEPES.rs if mTEPES.n.ord(n) % mTEPES.pWaterOutTimeStep [rs] == 0]
|
|
211
|
+
|
|
212
|
+
# Writing an LP file
|
|
213
|
+
if pIndLogConsole == 1:
|
|
214
|
+
StartTime = time.time()
|
|
215
|
+
mTEPES.write(f'{_path}/openTEPES_{CaseName}_{p}_{sc}_{st}.lp', io_options={'symbolic_solver_labels': True})
|
|
216
|
+
WritingLPFileTime = time.time() - StartTime
|
|
217
|
+
StartTime = time.time()
|
|
218
|
+
print('Writing LP file ... ', round(WritingLPFileTime), 's')
|
|
219
|
+
|
|
220
|
+
# there are investment decisions (it is an expansion and operation model), or there are system emission constraints
|
|
221
|
+
ProblemSolving(DirName, CaseName, SolverName, mTEPES, mTEPES, pIndLogConsole, p, sc, st)
|
|
222
|
+
|
|
223
|
+
# deactivate the constraints of the previous period and scenario
|
|
224
|
+
for c in mTEPES.component_objects(pyo.Constraint, active=True):
|
|
225
|
+
if c.name.find(str(p)) != -1 and c.name.find(str(sc)) != -1:
|
|
226
|
+
c.deactivate()
|
|
227
|
+
|
|
228
|
+
# generator investments or generator retirements, or line investments
|
|
229
|
+
elif ( sum(1 for pp,eb in mTEPES.peb if pp <= p) > 0 and mTEPES.pIndBinGenInvest() < 2
|
|
230
|
+
or sum(1 for pp,gd in mTEPES.pgd if pp <= p) > 0 and mTEPES.pIndBinGenRetire() < 2
|
|
231
|
+
or sum(1 for pp,rc in mTEPES.prc if pp <= p) > 0 and mTEPES.pIndBinRsrInvest() < 2
|
|
232
|
+
or sum(1 for pp,lc in mTEPES.plc if pp <= p) > 0 and mTEPES.pIndBinNetElecInvest() < 2
|
|
233
|
+
or sum(1 for pp,pc in mTEPES.ppc if pp <= p) > 0 and mTEPES.pIndBinNetH2Invest() < 2
|
|
234
|
+
or sum(1 for pp,hc in mTEPES.phc if pp <= p) > 0 and mTEPES.pIndBinNetHeatInvest() < 2):
|
|
235
|
+
|
|
236
|
+
if (p,sc) == mTEPES.ps.last() and st == mTEPES.Last_st and mTEPES.NoRepetition == 0:
|
|
237
|
+
mTEPES.NoRepetition = 1
|
|
238
|
+
|
|
239
|
+
mTEPES.del_component(mTEPES.st)
|
|
240
|
+
mTEPES.del_component(mTEPES.n )
|
|
241
|
+
mTEPES.del_component(mTEPES.n2)
|
|
242
|
+
mTEPES.st = Set(doc='stages', initialize=[stt for stt in mTEPES.stt if mTEPES.pStageWeight[stt] and sum(1 for p,sc,stt,nn in mTEPES.s2n)])
|
|
243
|
+
mTEPES.n = Set(doc='load levels', initialize=[nn for nn in mTEPES.nn if sum(1 for p,sc,st in mTEPES.ps*mTEPES.st if (p,sc,st, nn) in mTEPES.s2n)])
|
|
244
|
+
mTEPES.n2 = Set(doc='load levels', initialize=[nn for nn in mTEPES.nn if sum(1 for p,sc,st in mTEPES.ps*mTEPES.st if (p,sc,st, nn) in mTEPES.s2n)])
|
|
245
|
+
|
|
246
|
+
# load levels multiple of cycles for each ESS/generator
|
|
247
|
+
mTEPES.nesc = [(n,es) for n,es in mTEPES.n*mTEPES.es if mTEPES.n.ord(n) % mTEPES.pStorageTimeStep [es] == 0]
|
|
248
|
+
mTEPES.necc = [(n,ec) for n,ec in mTEPES.n*mTEPES.ec if mTEPES.n.ord(n) % mTEPES.pStorageTimeStep [ec] == 0]
|
|
249
|
+
mTEPES.neso = [(n,es) for n,es in mTEPES.n*mTEPES.es if mTEPES.n.ord(n) % mTEPES.pOutflowsTimeStep[es] == 0]
|
|
250
|
+
mTEPES.ngen = [(n,g ) for n,g in mTEPES.n*mTEPES.g if mTEPES.n.ord(n) % mTEPES.pEnergyTimeStep [g ] == 0]
|
|
251
|
+
if mTEPES.pIndHydroTopology == 1:
|
|
252
|
+
mTEPES.nhc = [(n,h ) for n,h in mTEPES.n*mTEPES.h if mTEPES.n.ord(n) % sum(mTEPES.pReservoirTimeStep[rs] for rs in mTEPES.rs if (rs,h) in mTEPES.r2h) == 0]
|
|
253
|
+
if sum(1 for h,rs in mTEPES.p2r):
|
|
254
|
+
mTEPES.np2c = [(n,h ) for n,h in mTEPES.n*mTEPES.h if sum(1 for rs in mTEPES.rs if (h,rs) in mTEPES.p2r) and mTEPES.n.ord(n) % sum(mTEPES.pReservoirTimeStep[rs] for rs in mTEPES.rs if (h,rs) in mTEPES.p2r) == 0]
|
|
255
|
+
else:
|
|
256
|
+
mTEPES.np2c = []
|
|
257
|
+
if sum(1 for rs,h in mTEPES.r2p):
|
|
258
|
+
mTEPES.npc = [(n,h ) for n,h in mTEPES.n*mTEPES.h if sum(1 for rs in mTEPES.rs if (rs,h) in mTEPES.r2p) and mTEPES.n.ord(n) % sum(mTEPES.pReservoirTimeStep[rs] for rs in mTEPES.rs if (rs,h) in mTEPES.r2p) == 0]
|
|
259
|
+
else:
|
|
260
|
+
mTEPES.npc = []
|
|
261
|
+
mTEPES.nrsc = [(n,rs) for n,rs in mTEPES.n*mTEPES.rs if mTEPES.n.ord(n) % mTEPES.pReservoirTimeStep[rs] == 0]
|
|
262
|
+
mTEPES.nrcc = [(n,rs) for n,rs in mTEPES.n*mTEPES.rn if mTEPES.n.ord(n) % mTEPES.pReservoirTimeStep[rs] == 0]
|
|
263
|
+
mTEPES.nrso = [(n,rs) for n,rs in mTEPES.n*mTEPES.rs if mTEPES.n.ord(n) % mTEPES.pWaterOutTimeStep [rs] == 0]
|
|
264
|
+
|
|
265
|
+
# Writing an LP file
|
|
266
|
+
if pIndLogConsole == 1:
|
|
267
|
+
StartTime = time.time()
|
|
268
|
+
mTEPES.write(f'{_path}/openTEPES_{CaseName}_{p}_{sc}_{st}.lp', io_options={'symbolic_solver_labels': True})
|
|
269
|
+
WritingLPFileTime = time.time() - StartTime
|
|
270
|
+
StartTime = time.time()
|
|
271
|
+
print('Writing LP file ... ', round(WritingLPFileTime), 's')
|
|
272
|
+
|
|
273
|
+
# there are investment decisions (it is an expansion and operation model), or there are system emission constraints
|
|
274
|
+
ProblemSolving(DirName, CaseName, SolverName, mTEPES, mTEPES, pIndLogConsole, p, sc, st)
|
|
203
275
|
|
|
204
276
|
mTEPES.del_component(mTEPES.st)
|
|
205
277
|
mTEPES.del_component(mTEPES.n )
|
|
@@ -248,7 +320,7 @@ def openTEPES_run(DirName, CaseName, SolverName, pIndOutputResults, pIndLogConso
|
|
|
248
320
|
# output plot results
|
|
249
321
|
pIndPlotOutput = 1
|
|
250
322
|
|
|
251
|
-
# indicators to control the
|
|
323
|
+
# indicators to control the number of output results
|
|
252
324
|
if pIndOutputResults == 1:
|
|
253
325
|
pIndDumpRawResults = 0
|
|
254
326
|
pIndInvestmentResults = 1
|
|
@@ -290,15 +362,15 @@ def openTEPES_run(DirName, CaseName, SolverName, pIndOutputResults, pIndLogConso
|
|
|
290
362
|
InvestmentResults (DirName, CaseName, mTEPES, mTEPES, pIndTechnologyOutput, pIndPlotOutput)
|
|
291
363
|
if pIndGenerationOperationResults == 1:
|
|
292
364
|
GenerationOperationResults (DirName, CaseName, mTEPES, mTEPES, pIndTechnologyOutput, pIndAreaOutput, pIndPlotOutput)
|
|
293
|
-
if
|
|
365
|
+
if mTEPES.ch and mTEPES.pIndHeat == 1:
|
|
294
366
|
GenerationOperationHeatResults(DirName, CaseName, mTEPES, mTEPES, pIndTechnologyOutput, pIndAreaOutput, pIndPlotOutput)
|
|
295
|
-
if pIndESSOperationResults == 1 and
|
|
367
|
+
if pIndESSOperationResults == 1 and mTEPES.es:
|
|
296
368
|
ESSOperationResults (DirName, CaseName, mTEPES, mTEPES, pIndTechnologyOutput, pIndAreaOutput, pIndPlotOutput)
|
|
297
|
-
if pIndReservoirOperationResults == 1 and
|
|
369
|
+
if pIndReservoirOperationResults == 1 and mTEPES.rs and mTEPES.pIndHydroTopology == 1:
|
|
298
370
|
ReservoirOperationResults (DirName, CaseName, mTEPES, mTEPES, pIndTechnologyOutput, pIndPlotOutput)
|
|
299
|
-
if pIndNetworkH2OperationResults == 1 and
|
|
371
|
+
if pIndNetworkH2OperationResults == 1 and mTEPES.pa and mTEPES.pIndHydrogen == 1:
|
|
300
372
|
NetworkH2OperationResults (DirName, CaseName, mTEPES, mTEPES)
|
|
301
|
-
if pIndNetworkHeatOperationResults == 1 and
|
|
373
|
+
if pIndNetworkHeatOperationResults == 1 and mTEPES.ha and mTEPES.pIndHeat == 1:
|
|
302
374
|
NetworkHeatOperationResults (DirName, CaseName, mTEPES, mTEPES)
|
|
303
375
|
if pIndFlexibilityResults == 1:
|
|
304
376
|
FlexibilityResults (DirName, CaseName, mTEPES, mTEPES)
|