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.
Files changed (70) hide show
  1. openTEPES/9n_PTDF/oT_Data_Demand_9n_PTDF.csv +8737 -0
  2. openTEPES/9n_PTDF/oT_Data_Duration_9n_PTDF.csv +8737 -0
  3. openTEPES/9n_PTDF/oT_Data_Emission_9n_PTDF.csv +2 -0
  4. openTEPES/9n_PTDF/oT_Data_EnergyInflows_9n_PTDF.csv +8737 -0
  5. openTEPES/9n_PTDF/oT_Data_EnergyOutflows_9n_PTDF.csv +8737 -0
  6. openTEPES/9n_PTDF/oT_Data_Generation_9n_PTDF.csv +17 -0
  7. openTEPES/9n_PTDF/oT_Data_Inertia_9n_PTDF.csv +8737 -0
  8. openTEPES/9n_PTDF/oT_Data_Network_9n_PTDF.csv +14 -0
  9. openTEPES/9n_PTDF/oT_Data_NodeLocation_9n_PTDF.csv +10 -0
  10. openTEPES/9n_PTDF/oT_Data_OperatingReserveDown_9n_PTDF.csv +8737 -0
  11. openTEPES/9n_PTDF/oT_Data_OperatingReserveUp_9n_PTDF.csv +8737 -0
  12. openTEPES/9n_PTDF/oT_Data_Option_9n_PTDF.csv +2 -0
  13. openTEPES/9n_PTDF/oT_Data_Parameter_9n_PTDF.csv +2 -0
  14. openTEPES/9n_PTDF/oT_Data_Period_9n_PTDF.csv +2 -0
  15. openTEPES/9n_PTDF/oT_Data_RESEnergy_9n_PTDF.csv +2 -0
  16. openTEPES/9n_PTDF/oT_Data_ReserveMargin_9n_PTDF.csv +2 -0
  17. openTEPES/9n_PTDF/oT_Data_Scenario_9n_PTDF.csv +2 -0
  18. openTEPES/9n_PTDF/oT_Data_Stage_9n_PTDF.csv +2 -0
  19. openTEPES/9n_PTDF/oT_Data_VariableEmissionCost_9n_PTDF.csv +8737 -0
  20. openTEPES/9n_PTDF/oT_Data_VariableFuelCost_9n_PTDF.csv +8737 -0
  21. openTEPES/9n_PTDF/oT_Data_VariableMaxConsumption_9n_PTDF.csv +8737 -0
  22. openTEPES/9n_PTDF/oT_Data_VariableMaxEnergy_9n_PTDF.csv +8737 -0
  23. openTEPES/9n_PTDF/oT_Data_VariableMaxGeneration_9n_PTDF.csv +8737 -0
  24. openTEPES/9n_PTDF/oT_Data_VariableMaxStorage_9n_PTDF.csv +8737 -0
  25. openTEPES/9n_PTDF/oT_Data_VariableMinConsumption_9n_PTDF.csv +8737 -0
  26. openTEPES/9n_PTDF/oT_Data_VariableMinEnergy_9n_PTDF.csv +8737 -0
  27. openTEPES/9n_PTDF/oT_Data_VariableMinGeneration_9n_PTDF.csv +8737 -0
  28. openTEPES/9n_PTDF/oT_Data_VariableMinStorage_9n_PTDF.csv +8737 -0
  29. openTEPES/9n_PTDF/oT_Data_VariablePTDF_9n_PTDF.csv +8740 -0
  30. openTEPES/9n_PTDF/oT_Data_VariableTTCBck_9n_PTDF.csv +8739 -0
  31. openTEPES/9n_PTDF/oT_Data_VariableTTCFrw_9n_PTDF.csv +8739 -0
  32. openTEPES/9n_PTDF/oT_Dict_AreaToRegion_9n_PTDF.csv +2 -0
  33. openTEPES/9n_PTDF/oT_Dict_Area_9n_PTDF.csv +2 -0
  34. openTEPES/9n_PTDF/oT_Dict_Circuit_9n_PTDF.csv +3 -0
  35. openTEPES/9n_PTDF/oT_Dict_Generation_9n_PTDF.csv +17 -0
  36. openTEPES/9n_PTDF/oT_Dict_Line_9n_PTDF.csv +3 -0
  37. openTEPES/9n_PTDF/oT_Dict_LoadLevel_9n_PTDF.csv +8737 -0
  38. openTEPES/9n_PTDF/oT_Dict_NodeToZone_9n_PTDF.csv +10 -0
  39. openTEPES/9n_PTDF/oT_Dict_Node_9n_PTDF.csv +10 -0
  40. openTEPES/9n_PTDF/oT_Dict_Period_9n_PTDF.csv +2 -0
  41. openTEPES/9n_PTDF/oT_Dict_Region_9n_PTDF.csv +31 -0
  42. openTEPES/9n_PTDF/oT_Dict_Scenario_9n_PTDF.csv +2 -0
  43. openTEPES/9n_PTDF/oT_Dict_Stage_9n_PTDF.csv +2 -0
  44. openTEPES/9n_PTDF/oT_Dict_Storage_9n_PTDF.csv +3 -0
  45. openTEPES/9n_PTDF/oT_Dict_Technology_9n_PTDF.csv +7 -0
  46. openTEPES/9n_PTDF/oT_Dict_ZoneToArea_9n_PTDF.csv +10 -0
  47. openTEPES/9n_PTDF/oT_Dict_Zone_9n_PTDF.csv +10 -0
  48. openTEPES/RTS-GMLC_6y/oT_Dict_AreaToRegion_RTS-GMLC_6y.csv +4 -4
  49. openTEPES/RTS-GMLC_6y/oT_Dict_Area_RTS-GMLC_6y.csv +4 -4
  50. openTEPES/RTS-GMLC_6y/oT_Dict_Circuit_RTS-GMLC_6y.csv +5 -5
  51. openTEPES/RTS-GMLC_6y/oT_Dict_Line_RTS-GMLC_6y.csv +3 -3
  52. openTEPES/RTS-GMLC_6y/oT_Dict_NodeToZone_RTS-GMLC_6y.csv +74 -74
  53. openTEPES/RTS-GMLC_6y/oT_Dict_Region_RTS-GMLC_6y.csv +2 -2
  54. openTEPES/RTS-GMLC_6y/oT_Dict_Scenario_RTS-GMLC_6y.csv +2 -2
  55. openTEPES/RTS-GMLC_6y/oT_Dict_Storage_RTS-GMLC_6y.csv +3 -3
  56. openTEPES/RTS-GMLC_6y/oT_Dict_Technology_RTS-GMLC_6y.csv +10 -10
  57. openTEPES/RTS-GMLC_6y/oT_Dict_ZoneToArea_RTS-GMLC_6y.csv +22 -22
  58. openTEPES/RTS-GMLC_6y/oT_Dict_Zone_RTS-GMLC_6y.csv +22 -22
  59. openTEPES/__init__.py +1 -1
  60. openTEPES/openTEPES.py +137 -65
  61. openTEPES/openTEPES_InputData.py +419 -234
  62. openTEPES/openTEPES_Main.py +2 -2
  63. openTEPES/openTEPES_ModelFormulation.py +469 -180
  64. openTEPES/openTEPES_OutputResults.py +305 -223
  65. openTEPES/openTEPES_ProblemSolving.py +68 -56
  66. {opentepes-4.18.3.dist-info → openTEPES-4.18.5.dist-info}/METADATA +17 -18
  67. {opentepes-4.18.3.dist-info → openTEPES-4.18.5.dist-info}/RECORD +70 -23
  68. {opentepes-4.18.3.dist-info → openTEPES-4.18.5.dist-info}/WHEEL +1 -1
  69. {opentepes-4.18.3.dist-info → openTEPES-4.18.5.dist-info}/LICENSE +0 -0
  70. {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) - March 18, 2025
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.3 - March 18, 2025')
43
- print( 'Open Generation, Storage, and Transmission Operation and Expansion Planning Model with RES and ESS (openTEPES) - Version 4.18.3 - March 18, 2025', file=open(f'{_path}/openTEPES_version_{CaseName}.log','w'))
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 len(mTEPES.st):
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
- if ( (len(mTEPES.gc) == 0 or mTEPES.pIndBinGenInvest() == 2) # No generator investments
144
- and (len(mTEPES.gd) == 0 or mTEPES.pIndBinGenRetire() == 2) # No generator retirements
145
- and (len(mTEPES.lc) == 0 or mTEPES.pIndBinNetElecInvest() == 2) # No line investments
146
- and (max([mTEPES.pRESEnergy[p,ar] for ar in mTEPES.ar]) == 0) # No minimum RES requirements
147
- and (min([mTEPES.pEmission [p,ar] for ar in mTEPES.ar]) == math.inf or sum(mTEPES.pEmissionRate[nr] for nr in mTEPES.nr) == 0)): # No emission limit
148
-
149
- if pIndLogConsole == 1:
150
- StartTime = time.time()
151
- mTEPES.write(f'{_path}/openTEPES_{CaseName}_{p}_{sc}_{st}.lp', io_options={'symbolic_solver_labels': True})
152
- WritingLPFileTime = time.time() - StartTime
153
- StartTime = time.time()
154
- print('Writing LP file ... ', round(WritingLPFileTime), 's')
155
-
156
- # there are no expansion decisions, or they are ignored (it is an operation planning model)
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 investment decisions (it is an expansion and operation planning model)
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 amount of output results
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 len(mTEPES.ch) and mTEPES.pIndHeat == 1:
365
+ if mTEPES.ch and mTEPES.pIndHeat == 1:
294
366
  GenerationOperationHeatResults(DirName, CaseName, mTEPES, mTEPES, pIndTechnologyOutput, pIndAreaOutput, pIndPlotOutput)
295
- if pIndESSOperationResults == 1 and len(mTEPES.es):
367
+ if pIndESSOperationResults == 1 and mTEPES.es:
296
368
  ESSOperationResults (DirName, CaseName, mTEPES, mTEPES, pIndTechnologyOutput, pIndAreaOutput, pIndPlotOutput)
297
- if pIndReservoirOperationResults == 1 and len(mTEPES.rs) and mTEPES.pIndHydroTopology == 1:
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 len(mTEPES.pa) and mTEPES.pIndHydrogen == 1:
371
+ if pIndNetworkH2OperationResults == 1 and mTEPES.pa and mTEPES.pIndHydrogen == 1:
300
372
  NetworkH2OperationResults (DirName, CaseName, mTEPES, mTEPES)
301
- if pIndNetworkHeatOperationResults == 1 and len(mTEPES.ha) and mTEPES.pIndHeat == 1:
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)