openTEPES 4.18.8__py3-none-any.whl → 4.18.10__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  """
2
- Open Generation, Storage, and Transmission Operation and Expansion Planning Model with RES and ESS (openTEPES) - January 15, 2026
2
+ Open Generation, Storage, and Transmission Operation and Expansion Planning Model with RES and ESS (openTEPES) - January 23, 2026
3
3
  """
4
4
 
5
5
  import time
@@ -181,7 +181,7 @@ def GenerationOperationModelFormulationObjFunct(OptModel, mTEPES, pIndLogConsole
181
181
  + mTEPES.pLoadLevelDuration[p,sc,n]() * sum(mTEPES.pEmissionRate[bo] * 1e-3 * OptModel.vTotalOutputHeat[p,sc,n,bo] for bo in mTEPES.bo if (ar,bo) in mTEPES.a2g and (p,bo) in mTEPES.pbo)) #1e-3 to change from tCO2/MWh to MtCO2/GWh
182
182
  else:
183
183
  return Constraint.Skip
184
- setattr(OptModel, f'eTotalEmissionArea_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.ar, rule=eTotalEmissionArea, doc='area total emission [MtCO2 eq]'))
184
+ setattr(OptModel, f'eTotalEmissionArea_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.ar, rule=eTotalEmissionArea, doc='area total emission [MtCO2 eq]'))
185
185
 
186
186
  def eTotalECostArea(OptModel,n,ar):
187
187
  if sum(mTEPES.pEmissionVarCost[p,sc,n,g] for g in mTEPES.g if (ar,g) in mTEPES.a2g and (p,g) in mTEPES.pg):
@@ -189,14 +189,14 @@ def GenerationOperationModelFormulationObjFunct(OptModel, mTEPES, pIndLogConsole
189
189
  + sum(mTEPES.pEmissionVarCost[p,sc,n,bo] * OptModel.vTotalOutputHeat[p,sc,n,bo] for bo in mTEPES.bo if (ar,bo) in mTEPES.a2g and (p,bo) in mTEPES.pbo)))
190
190
  else:
191
191
  return Constraint.Skip
192
- setattr(OptModel, f'eTotalECostArea_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.ar, rule=eTotalECostArea, doc='area emission cost [MEUR]'))
192
+ setattr(OptModel, f'eTotalECostArea_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.ar, rule=eTotalECostArea, doc='area emission cost [MEUR]'))
193
193
 
194
194
  def eTotalRESEnergyArea(OptModel,n,ar):
195
195
  if mTEPES.pRESEnergy[p,ar] and st == mTEPES.Last_st:
196
196
  return OptModel.vTotalRESEnergyArea[p,sc,n,ar] == mTEPES.pLoadLevelDuration[p,sc,n]() * sum(OptModel.vTotalOutput[p,sc,n,re] for re in mTEPES.re if (ar,re) in mTEPES.a2g and (p,re) in mTEPES.pre)
197
197
  else:
198
198
  return Constraint.Skip
199
- setattr(OptModel, f'eTotalRESEnergyArea_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.ar, rule=eTotalRESEnergyArea, doc='area RES energy [GWh]'))
199
+ setattr(OptModel, f'eTotalRESEnergyArea_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.ar, rule=eTotalRESEnergyArea, doc='area RES energy [GWh]'))
200
200
 
201
201
  def eTotalNCost(OptModel,n):
202
202
  return OptModel.vTotalNCost[p,sc,n] == mTEPES.pLoadLevelDuration[p,sc,n]() * pEpsilon * sum(OptModel.vLineLosses[p,sc,n,ni,nf,cc] for ni,nf,cc in mTEPES.ll if (p,ni,nf,cc) in mTEPES.pll)
@@ -232,7 +232,7 @@ def GenerationOperationModelFormulationInvestment(OptModel, mTEPES, pIndLogConso
232
232
  return OptModel.vCommitment[p,sc,n,gc] == OptModel.vGenerationInvest[p,gc]
233
233
  else:
234
234
  return Constraint.Skip
235
- setattr(OptModel, f'eInstallGenComm_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.gc, rule=eInstallGenComm, doc='commitment if installed unit [p.u.]'))
235
+ setattr(OptModel, f'eInstallGenComm_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.gc, rule=eInstallGenComm, doc='commitment if installed unit [p.u.]'))
236
236
 
237
237
  if pIndLogConsole == 1:
238
238
  print('eInstallGenComm ... ', len(getattr(OptModel, f'eInstallGenComm_{p}_{sc}_{st}')), ' rows')
@@ -245,7 +245,7 @@ def GenerationOperationModelFormulationInvestment(OptModel, mTEPES, pIndLogConso
245
245
  return Constraint.Skip
246
246
  else:
247
247
  return Constraint.Skip
248
- setattr(OptModel, f'eInstallESSComm_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.ec, rule=eInstallESSComm, doc='commitment if ESS unit [p.u.]'))
248
+ setattr(OptModel, f'eInstallESSComm_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.ec, rule=eInstallESSComm, doc='commitment if ESS unit [p.u.]'))
249
249
 
250
250
  if pIndLogConsole == 1:
251
251
  print('eInstallESSComm ... ', len(getattr(OptModel, f'eInstallESSComm_{p}_{sc}_{st}')), ' rows')
@@ -258,7 +258,7 @@ def GenerationOperationModelFormulationInvestment(OptModel, mTEPES, pIndLogConso
258
258
  return Constraint.Skip
259
259
  else:
260
260
  return Constraint.Skip
261
- setattr(OptModel, f'eInstallGenCap_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.gc, rule=eInstallGenCap, doc='output if installed gen unit [p.u.]'))
261
+ setattr(OptModel, f'eInstallGenCap_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.gc, rule=eInstallGenCap, doc='output if installed gen unit [p.u.]'))
262
262
 
263
263
  if pIndLogConsole == 1:
264
264
  print('eInstallGenCap ... ', len(getattr(OptModel, f'eInstallGenCap_{p}_{sc}_{st}')), ' rows')
@@ -271,7 +271,7 @@ def GenerationOperationModelFormulationInvestment(OptModel, mTEPES, pIndLogConso
271
271
  return Constraint.Skip
272
272
  else:
273
273
  return Constraint.Skip
274
- setattr(OptModel, f'eInstallFHUCap_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.bc, rule=eInstallFHUCap, doc='heat production if installed fuel heating unit [p.u.]'))
274
+ setattr(OptModel, f'eInstallFHUCap_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.bc, rule=eInstallFHUCap, doc='heat production if installed fuel heating unit [p.u.]'))
275
275
 
276
276
  if pIndLogConsole == 1:
277
277
  print('eInstallFHUCap ... ', len(getattr(OptModel, f'eInstallFHUCap_{p}_{sc}_{st}')), ' rows')
@@ -284,7 +284,7 @@ def GenerationOperationModelFormulationInvestment(OptModel, mTEPES, pIndLogConso
284
284
  return Constraint.Skip
285
285
  else:
286
286
  return Constraint.Skip
287
- setattr(OptModel, f'eInstallConESS_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.ec, rule=eInstallConESS, doc='consumption if installed ESS unit [p.u.]'))
287
+ setattr(OptModel, f'eInstallConESS_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.ec, rule=eInstallConESS, doc='consumption if installed ESS unit [p.u.]'))
288
288
 
289
289
  if pIndLogConsole == 1:
290
290
  print('eInstallConESS ... ', len(getattr(OptModel, f'eInstallConESS_{p}_{sc}_{st}')), ' rows')
@@ -297,7 +297,7 @@ def GenerationOperationModelFormulationInvestment(OptModel, mTEPES, pIndLogConso
297
297
  return Constraint.Skip
298
298
  else:
299
299
  return Constraint.Skip
300
- setattr(OptModel, f'eUninstallGenComm_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.gd, rule=eUninstallGenComm, doc='commitment if uninstalled unit [p.u.]'))
300
+ setattr(OptModel, f'eUninstallGenComm_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.gd, rule=eUninstallGenComm, doc='commitment if uninstalled unit [p.u.]'))
301
301
 
302
302
  if pIndLogConsole == 1:
303
303
  print('eUninstallGenComm ... ', len(getattr(OptModel, f'eUninstallGenComm_{p}_{sc}_{st}')), ' rows')
@@ -310,7 +310,7 @@ def GenerationOperationModelFormulationInvestment(OptModel, mTEPES, pIndLogConso
310
310
  return Constraint.Skip
311
311
  else:
312
312
  return Constraint.Skip
313
- setattr(OptModel, f'eUninstallGenCap_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.gd, rule=eUninstallGenCap, doc='output if uninstalled gen unit [p.u.]'))
313
+ setattr(OptModel, f'eUninstallGenCap_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.gd, rule=eUninstallGenCap, doc='output if uninstalled gen unit [p.u.]'))
314
314
 
315
315
  if pIndLogConsole == 1:
316
316
  print('eUninstallGenCap ... ', len(getattr(OptModel, f'eUninstallGenCap_{p}_{sc}_{st}')), ' rows')
@@ -414,7 +414,7 @@ def GenerationOperationModelFormulationDemand(OptModel, mTEPES, pIndLogConsole,
414
414
  return sum(OptModel.vCommitment[p,sc,n,nr] * mTEPES.pInertia[nr] for nr in mTEPES.nr if (ar,nr) in mTEPES.a2g) >= mTEPES.pSystemInertia[p,sc,n,ar]
415
415
  else:
416
416
  return Constraint.Skip
417
- setattr(OptModel, f'eSystemInertia_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.ar, rule=eSystemInertia, doc='system inertia [s]'))
417
+ setattr(OptModel, f'eSystemInertia_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.ar, rule=eSystemInertia, doc='system inertia [s]'))
418
418
 
419
419
  if pIndLogConsole == 1:
420
420
  print('eSystemInertia ... ', len(getattr(OptModel, f'eSystemInertia_{p}_{sc}_{st}')), ' rows')
@@ -429,7 +429,7 @@ def GenerationOperationModelFormulationDemand(OptModel, mTEPES, pIndLogConsole,
429
429
  return Constraint.Skip
430
430
  return sum(OptModel.vReserveUp [p,sc,n,nr] for nr in n2a[ar] if mTEPES.pIndOperReserveGen[nr] == 0 and (p,nr) in mTEPES.pnr) + sum(OptModel.vESSReserveUp [p,sc,n,eh] for eh in e2a[ar] if mTEPES.pIndOperReserveCon[eh] == 0 and (p,eh) in mTEPES.peh) == mTEPES.pOperReserveUp[p,sc,n,ar]
431
431
 
432
- setattr(OptModel, f'eOperReserveUp_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.ar, rule=eOperReserveUp, doc='up operating reserve [GW]'))
432
+ setattr(OptModel, f'eOperReserveUp_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.ar, rule=eOperReserveUp, doc='up operating reserve [GW]'))
433
433
 
434
434
  if pIndLogConsole == 1:
435
435
  print('eOperReserveUp ... ', len(getattr(OptModel, f'eOperReserveUp_{p}_{sc}_{st}')), ' rows')
@@ -444,7 +444,7 @@ def GenerationOperationModelFormulationDemand(OptModel, mTEPES, pIndLogConsole,
444
444
  return Constraint.Skip
445
445
  return sum(OptModel.vReserveDown[p,sc,n,nr] for nr in n2a[ar] if mTEPES.pIndOperReserveGen[nr] == 0 and (p,nr) in mTEPES.pnr) + sum(OptModel.vESSReserveDown[p,sc,n,eh] for eh in e2a[ar] if mTEPES.pIndOperReserveCon[eh] == 0 and (p,eh) in mTEPES.peh) == mTEPES.pOperReserveDw[p,sc,n,ar]
446
446
 
447
- setattr(OptModel, f'eOperReserveDw_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.ar, rule=eOperReserveDw, doc='down operating reserve [GW]'))
447
+ setattr(OptModel, f'eOperReserveDw_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.ar, rule=eOperReserveDw, doc='down operating reserve [GW]'))
448
448
 
449
449
  if pIndLogConsole == 1:
450
450
  print('eOperReserveDw ... ', len(getattr(OptModel, f'eOperReserveDw_{p}_{sc}_{st}')), ' rows')
@@ -462,7 +462,7 @@ def GenerationOperationModelFormulationDemand(OptModel, mTEPES, pIndLogConsole,
462
462
 
463
463
  return OptModel.vReserveDown[p,sc,n,nr] >= OptModel.vReserveUp[p,sc,n,nr] * mTEPES.pMinRatioDwUp
464
464
 
465
- setattr(OptModel, f'eReserveMinRatioDwUp_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.nr, rule=eReserveMinRatioDwUp, doc='minimum ratio down to up operating reserve [GW]'))
465
+ setattr(OptModel, f'eReserveMinRatioDwUp_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.nr, rule=eReserveMinRatioDwUp, doc='minimum ratio down to up operating reserve [GW]'))
466
466
 
467
467
  if pIndLogConsole == 1:
468
468
  print('eReserveMinRatioDwUp ... ', len(getattr(OptModel, f'eReserveMinRatioDwUp_{p}_{sc}_{st}')), ' rows')
@@ -480,7 +480,7 @@ def GenerationOperationModelFormulationDemand(OptModel, mTEPES, pIndLogConsole,
480
480
 
481
481
  return OptModel.vReserveDown[p,sc,n,nr] <= OptModel.vReserveUp[p,sc,n,nr] * mTEPES.pMaxRatioDwUp
482
482
 
483
- setattr(OptModel, f'eReserveMaxRatioDwUp_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.nr, rule=eReserveMaxRatioDwUp, doc='maximum ratio down to up operating reserve [GW]'))
483
+ setattr(OptModel, f'eReserveMaxRatioDwUp_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.nr, rule=eReserveMaxRatioDwUp, doc='maximum ratio down to up operating reserve [GW]'))
484
484
 
485
485
  if pIndLogConsole == 1:
486
486
  print('eReserveMaxRatioDwUp ... ', len(getattr(OptModel, f'eReserveMaxRatioDwUp_{p}_{sc}_{st}')), ' rows')
@@ -497,7 +497,7 @@ def GenerationOperationModelFormulationDemand(OptModel, mTEPES, pIndLogConsole,
497
497
  return Constraint.Skip
498
498
 
499
499
  return OptModel.vESSReserveDown[p,sc,n,eh] >= OptModel.vESSReserveUp[p,sc,n,eh] * mTEPES.pMinRatioDwUp
500
- setattr(OptModel, f'eRsrvMinRatioDwUpESS_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.eh, rule=eRsrvMinRatioDwUpESS, doc='minimum ratio down to up operating reserve [GW]'))
500
+ setattr(OptModel, f'eRsrvMinRatioDwUpESS_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.eh, rule=eRsrvMinRatioDwUpESS, doc='minimum ratio down to up operating reserve [GW]'))
501
501
 
502
502
  if pIndLogConsole == 1:
503
503
  print('eRsrvMinRatioDwUpESS ... ', len(getattr(OptModel, f'eRsrvMinRatioDwUpESS_{p}_{sc}_{st}')), ' rows')
@@ -515,7 +515,7 @@ def GenerationOperationModelFormulationDemand(OptModel, mTEPES, pIndLogConsole,
515
515
 
516
516
  return OptModel.vESSReserveDown[p,sc,n,eh] <= OptModel.vESSReserveUp[p,sc,n,eh] * mTEPES.pMaxRatioDwUp
517
517
 
518
- setattr(OptModel, f'eRsrvMaxRatioDwUpESS_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.eh, rule=eRsrvMaxRatioDwUpESS, doc='maximum ratio down to up operating reserve [GW]'))
518
+ setattr(OptModel, f'eRsrvMaxRatioDwUpESS_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.eh, rule=eRsrvMaxRatioDwUpESS, doc='maximum ratio down to up operating reserve [GW]'))
519
519
 
520
520
  if pIndLogConsole == 1:
521
521
  print('eRsrvMaxRatioDwUpESS ... ', len(getattr(OptModel, f'eRsrvMaxRatioDwUpESS_{p}_{sc}_{st}')), ' rows')
@@ -587,7 +587,7 @@ def GenerationOperationModelFormulationDemand(OptModel, mTEPES, pIndLogConsole,
587
587
  sum(OptModel.vLineLosses[p,sc,n,ni,nd,cc] for ni,cc in linl [nd] if (p,ni,nd,cc) in mTEPES.pll) + sum(OptModel.vFlowElec[p,sc,n,ni,nd,cc] for ni,cc in lin [nd] if (p,ni,nd,cc) in mTEPES.pla)) == mTEPES.pDemandElec[p,sc,n,nd]
588
588
  else:
589
589
  return Constraint.Skip
590
- setattr(OptModel, f'eBalanceElec_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.nd, rule=eBalanceElec, doc='electric load generation balance [GW]'))
590
+ setattr(OptModel, f'eBalanceElec_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.nd, rule=eBalanceElec, doc='electric load generation balance [GW]'))
591
591
 
592
592
  if pIndLogConsole == 1:
593
593
  print('eBalanceElec ... ', len(getattr(OptModel, f'eBalanceElec_{p}_{sc}_{st}')), ' rows')
@@ -694,7 +694,7 @@ def GenerationOperationModelFormulationStorage(OptModel, mTEPES, pIndLogConsole,
694
694
  return mTEPES.pDuration[p,sc,n]()*mTEPES.pEfficiency[eh]*OptModel.vESSTotalCharge[p,sc,n,eh] <= sum(mTEPES.pDuration[p,sc,n2]()*OptModel.vTotalOutput[p,sc,n2,eh] for n2 in list(mTEPES.n2)[mTEPES.n.ord(n):mTEPES.n.ord(n)+mTEPES.pShiftTime[eh]])
695
695
  else:
696
696
  return Constraint.Skip
697
- setattr(OptModel, f'eMaxShiftTime_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.eh, rule=eMaxShiftTime, doc='Maximum shift time [GWh]'))
697
+ setattr(OptModel, f'eMaxShiftTime_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.eh, rule=eMaxShiftTime, doc='Maximum shift time [GWh]'))
698
698
 
699
699
  if pIndLogConsole == 1:
700
700
  print('eMaxShiftTime ... ', len(getattr(OptModel, f'eMaxShiftTime_{p}_{sc}_{st}')), ' rows')
@@ -713,7 +713,7 @@ def GenerationOperationModelFormulationStorage(OptModel, mTEPES, pIndLogConsole,
713
713
  # Hydro case equation
714
714
  else:
715
715
  return (OptModel.vCharge2ndBlock[p,sc,n,eh] + OptModel.vESSReserveDown[p,sc,n,eh]) / mTEPES.pMaxCharge2ndBlock[p,sc,n,eh] <= OptModel.vCommitmentCons[p,sc,n,eh]
716
- setattr(OptModel, f'eMaxCharge_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.eh, rule=eMaxCharge, doc='max charge of an ESS [p.u.]'))
716
+ setattr(OptModel, f'eMaxCharge_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.eh, rule=eMaxCharge, doc='max charge of an ESS [p.u.]'))
717
717
 
718
718
  if pIndLogConsole == 1:
719
719
  print('eMaxCharge ... ', len(getattr(OptModel, f'eMaxCharge_{p}_{sc}_{st}')), ' rows')
@@ -732,7 +732,7 @@ def GenerationOperationModelFormulationStorage(OptModel, mTEPES, pIndLogConsole,
732
732
  if not mTEPES.pMaxCharge2ndBlock[p,sc,n,eh]:
733
733
  return Constraint.Skip
734
734
  return OptModel.vCharge2ndBlock[p,sc,n,eh] - OptModel.vESSReserveUp[p,sc,n,eh] >= 0.0
735
- setattr(OptModel, f'eMinCharge_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.eh, rule=eMinCharge, doc='min charge of an ESS [p.u.]'))
735
+ setattr(OptModel, f'eMinCharge_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.eh, rule=eMinCharge, doc='min charge of an ESS [p.u.]'))
736
736
 
737
737
  if pIndLogConsole == 1:
738
738
  print('eMinCharge ... ', len(getattr(OptModel, f'eMinCharge_{p}_{sc}_{st}')), ' rows')
@@ -742,7 +742,7 @@ def GenerationOperationModelFormulationStorage(OptModel, mTEPES, pIndLogConsole,
742
742
  # return OptModel.vTotalOutput[p,sc,n,eh] / mTEPES.pMaxPowerElec[p,sc,n,eh] + OptModel.vCharge2ndBlock[p,sc,n,eh] / mTEPES.pMaxCharge[p,sc,n,eh] <= 1
743
743
  # else:
744
744
  # return Constraint.Skip
745
- # OptModel.eChargeDischarge = Constraint(mTEPES.n, mTEPES.eh, rule=eChargeDischarge, doc='incompatibility between charge and discharge [p.u.]')
745
+ # OptModel.eChargeDischarge = Constraint(mTEPES.n*mTEPES.eh, rule=eChargeDischarge, doc='incompatibility between charge and discharge [p.u.]')
746
746
 
747
747
  # Generators with consumption capability cannot be consuming and generating simultaneously
748
748
  def eChargeDischarge(OptModel,n,eh):
@@ -760,7 +760,7 @@ def GenerationOperationModelFormulationStorage(OptModel, mTEPES, pIndLogConsole,
760
760
  # Hydro Generator
761
761
  else:
762
762
  return OptModel.vCommitment[p,sc,n,eh] + OptModel.vCommitmentCons[p,sc,n,eh] <= 1.0
763
- setattr(OptModel, f'eChargeDischarge_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.eh, rule=eChargeDischarge, doc='incompatibility between charge and discharge [p.u.]'))
763
+ setattr(OptModel, f'eChargeDischarge_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.eh, rule=eChargeDischarge, doc='incompatibility between charge and discharge [p.u.]'))
764
764
 
765
765
  if pIndLogConsole == 1:
766
766
  print('eChargeDischarge ... ', len(getattr(OptModel, f'eChargeDischarge_{p}_{sc}_{st}')), ' rows')
@@ -787,7 +787,7 @@ def GenerationOperationModelFormulationStorage(OptModel, mTEPES, pIndLogConsole,
787
787
  return OptModel.vESSTotalCharge[p,sc,n,eh] == OptModel.vCharge2ndBlock[p,sc,n,eh] + mTEPES.pDwReserveActivation * OptModel.vESSReserveDown[p,sc,n,eh] - mTEPES.pUpReserveActivation * OptModel.vESSReserveUp[p,sc,n,eh]
788
788
  else:
789
789
  return OptModel.vESSTotalCharge[p,sc,n,eh] / mTEPES.pMinCharge[p,sc,n,eh] == OptModel.vCommitmentCons[p,sc,n,eh] + (OptModel.vCharge2ndBlock[p,sc,n,eh] + mTEPES.pDwReserveActivation * OptModel.vESSReserveDown[p,sc,n,eh] - mTEPES.pUpReserveActivation * OptModel.vESSReserveUp[p,sc,n,eh]) / mTEPES.pMinCharge[p,sc,n,eh]
790
- setattr(OptModel, f'eESSTotalCharge_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.eh, rule=eESSTotalCharge, doc='total charge of an ESS unit [GW]'))
790
+ setattr(OptModel, f'eESSTotalCharge_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.eh, rule=eESSTotalCharge, doc='total charge of an ESS unit [GW]'))
791
791
 
792
792
  if pIndLogConsole == 1:
793
793
  print('eESSTotalCharge ... ', len(getattr(OptModel, f'eESSTotalCharge_{p}_{sc}_{st}')), ' rows')
@@ -800,7 +800,7 @@ def GenerationOperationModelFormulationStorage(OptModel, mTEPES, pIndLogConsole,
800
800
  return Constraint.Skip
801
801
  else:
802
802
  return Constraint.Skip
803
- setattr(OptModel, f'eChargeOutflows_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.eh, rule=eChargeOutflows, doc='incompatibility between charge and outflows use [p.u.]'))
803
+ setattr(OptModel, f'eChargeOutflows_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.eh, rule=eChargeOutflows, doc='incompatibility between charge and outflows use [p.u.]'))
804
804
 
805
805
  if pIndLogConsole == 1:
806
806
  print('eChargeOutflows ... ', len(getattr(OptModel, f'eChargeOutflows_{p}_{sc}_{st}')), ' rows')
@@ -1063,47 +1063,75 @@ def GenerationOperationModelFormulationCommitment(OptModel, mTEPES, pIndLogConso
1063
1063
  a2n[nr].append(ar)
1064
1064
 
1065
1065
  def eMaxOutput2ndBlock(OptModel,n,nr):
1066
- if (p,nr) in mTEPES.pnr and (nr not in mTEPES.es or (nr in mTEPES.es and (mTEPES.pTotalMaxCharge[nr] or mTEPES.pTotalEnergyInflows[nr]))) and sum(mTEPES.pOperReserveUp[p,sc,n,ar] for ar in a2n[nr]):
1067
- if mTEPES.pIndRampReserves == 0 or sum(mTEPES.pRampReserveUp[p,sc,n,ar] for ar in mTEPES.ar) == 0.0:
1068
- if mTEPES.pMaxPower2ndBlock[p,sc,n,nr] and mTEPES.pIndOperReserveGen[nr] != 1 and n != mTEPES.n.last():
1069
- return (OptModel.vOutput2ndBlock[p,sc,n,nr] + OptModel.vReserveUp [p,sc,n,nr] ) / mTEPES.pMaxPower2ndBlock[p,sc,n,nr] <= OptModel.vCommitment[p,sc,n,nr] - OptModel.vStartUp[p,sc,n,nr] - OptModel.vShutDown[p,sc,mTEPES.n.next(n),nr]
1070
- elif mTEPES.pMaxPower2ndBlock[p,sc,n,nr] and mTEPES.pIndOperReserveGen[nr] != 1 and n == mTEPES.n.last():
1071
- return (OptModel.vOutput2ndBlock[p,sc,n,nr] + OptModel.vReserveUp [p,sc,n,nr] ) / mTEPES.pMaxPower2ndBlock[p,sc,n,nr] <= OptModel.vCommitment[p,sc,n,nr] - OptModel.vStartUp[p,sc,n,nr]
1066
+ if mTEPES.pMaxPower2ndBlock[p,sc,n,nr] == 0.0:
1067
+ return Constraint.Skip
1068
+ if (p,nr) in mTEPES.pnr and (nr not in mTEPES.es or (nr in mTEPES.es and (mTEPES.pTotalMaxCharge[nr] or mTEPES.pTotalEnergyInflows[nr]))):
1069
+ if sum(mTEPES.pOperReserveUp[p,sc,n,ar] for ar in a2n[nr]):
1070
+ if mTEPES.pIndRampReserves == 0 or sum(mTEPES.pRampReserveUp[p,sc,n,ar] for ar in mTEPES.ar) == 0.0:
1071
+ if mTEPES.pIndOperReserveGen[nr] != 1 and n != mTEPES.n.last():
1072
+ return (OptModel.vOutput2ndBlock[p,sc,n,nr] + OptModel.vReserveUp [p,sc,n,nr] ) / mTEPES.pMaxPower2ndBlock[p,sc,n,nr] <= OptModel.vCommitment[p,sc,n,nr] - OptModel.vStartUp[p,sc,n,nr] - OptModel.vShutDown[p,sc,mTEPES.n.next(n),nr]
1073
+ elif mTEPES.pIndOperReserveGen[nr] != 1 and n == mTEPES.n.last():
1074
+ return (OptModel.vOutput2ndBlock[p,sc,n,nr] + OptModel.vReserveUp [p,sc,n,nr] ) / mTEPES.pMaxPower2ndBlock[p,sc,n,nr] <= OptModel.vCommitment[p,sc,n,nr] - OptModel.vStartUp[p,sc,n,nr]
1075
+ else:
1076
+ return Constraint.Skip
1077
+ elif mTEPES.pIndRampReserves == 1 and sum(mTEPES.pRampReserveUp[p,sc,n,ar] for ar in mTEPES.ar) > 0.0:
1078
+ if mTEPES.pIndOperReserveGen[nr] != 1 and n != mTEPES.n.last():
1079
+ return (OptModel.vOutput2ndBlock[p,sc,n,nr] + OptModel.vReserveUp [p,sc,n,nr] + OptModel.vRampReserveUp [p,sc,n,nr]) / mTEPES.pMaxPower2ndBlock[p,sc,n,nr] <= OptModel.vCommitment[p,sc,n,nr] - OptModel.vStartUp[p,sc,n,nr] - OptModel.vShutDown[p,sc,mTEPES.n.next(n),nr]
1080
+ elif mTEPES.pIndOperReserveGen[nr] != 1 and n == mTEPES.n.last():
1081
+ return (OptModel.vOutput2ndBlock[p,sc,n,nr] + OptModel.vReserveUp [p,sc,n,nr] + OptModel.vRampReserveUp [p,sc,n,nr]) / mTEPES.pMaxPower2ndBlock[p,sc,n,nr] <= OptModel.vCommitment[p,sc,n,nr] - OptModel.vStartUp[p,sc,n,nr]
1082
+ else:
1083
+ return Constraint.Skip
1072
1084
  else:
1073
1085
  return Constraint.Skip
1074
- elif mTEPES.pIndRampReserves == 1 and sum(mTEPES.pRampReserveUp[p,sc,n,ar] for ar in mTEPES.ar) > 0.0:
1075
- if mTEPES.pMaxPower2ndBlock[p,sc,n,nr] and mTEPES.pIndOperReserveGen[nr] != 1 and n != mTEPES.n.last():
1076
- return (OptModel.vOutput2ndBlock[p,sc,n,nr] + OptModel.vReserveUp [p,sc,n,nr] + OptModel.vRampReserveUp [p,sc,n,nr]) / mTEPES.pMaxPower2ndBlock[p,sc,n,nr] <= OptModel.vCommitment[p,sc,n,nr] - OptModel.vStartUp[p,sc,n,nr] - OptModel.vShutDown[p,sc,mTEPES.n.next(n),nr]
1077
- elif mTEPES.pMaxPower2ndBlock[p,sc,n,nr] and mTEPES.pIndOperReserveGen[nr] != 1 and n == mTEPES.n.last():
1078
- return (OptModel.vOutput2ndBlock[p,sc,n,nr] + OptModel.vReserveUp [p,sc,n,nr] + OptModel.vRampReserveUp [p,sc,n,nr]) / mTEPES.pMaxPower2ndBlock[p,sc,n,nr] <= OptModel.vCommitment[p,sc,n,nr] - OptModel.vStartUp[p,sc,n,nr]
1086
+ if sum(mTEPES.pOperReserveUp[p,sc,n,ar] for ar in a2n[nr]) == 0.0:
1087
+ if mTEPES.pIndRampReserves == 0 or sum(mTEPES.pRampReserveUp[p,sc,n,ar] for ar in mTEPES.ar) == 0.0:
1088
+ if n != mTEPES.n.last():
1089
+ return (OptModel.vOutput2ndBlock[p,sc,n,nr] ) / mTEPES.pMaxPower2ndBlock[p,sc,n,nr] <= OptModel.vCommitment[p,sc,n,nr] - OptModel.vStartUp[p,sc,n,nr] - OptModel.vShutDown[p,sc,mTEPES.n.next(n),nr]
1090
+ elif n == mTEPES.n.last():
1091
+ return (OptModel.vOutput2ndBlock[p,sc,n,nr] ) / mTEPES.pMaxPower2ndBlock[p,sc,n,nr] <= OptModel.vCommitment[p,sc,n,nr] - OptModel.vStartUp[p,sc,n,nr]
1092
+ else:
1093
+ return Constraint.Skip
1094
+ elif mTEPES.pIndRampReserves == 1 and sum(mTEPES.pRampReserveUp[p,sc,n,ar] for ar in mTEPES.ar) > 0.0:
1095
+ if n != mTEPES.n.last():
1096
+ return (OptModel.vOutput2ndBlock[p,sc,n,nr] + OptModel.vRampReserveUp [p,sc,n,nr]) / mTEPES.pMaxPower2ndBlock[p,sc,n,nr] <= OptModel.vCommitment[p,sc,n,nr] - OptModel.vStartUp[p,sc,n,nr] - OptModel.vShutDown[p,sc,mTEPES.n.next(n),nr]
1097
+ elif n == mTEPES.n.last():
1098
+ return (OptModel.vOutput2ndBlock[p,sc,n,nr] + OptModel.vRampReserveUp [p,sc,n,nr]) / mTEPES.pMaxPower2ndBlock[p,sc,n,nr] <= OptModel.vCommitment[p,sc,n,nr] - OptModel.vStartUp[p,sc,n,nr]
1099
+ else:
1100
+ return Constraint.Skip
1079
1101
  else:
1080
1102
  return Constraint.Skip
1081
- else:
1082
- return Constraint.Skip
1083
1103
  else:
1084
1104
  return Constraint.Skip
1085
- setattr(OptModel, f'eMaxOutput2ndBlock_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.nr, rule=eMaxOutput2ndBlock, doc='max output of the second block of a committed unit [p.u.]'))
1105
+ setattr(OptModel, f'eMaxOutput2ndBlock_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.nr, rule=eMaxOutput2ndBlock, doc='max output of the second block of a committed unit [p.u.]'))
1086
1106
 
1087
1107
  if pIndLogConsole == 1:
1088
1108
  print('eMaxOutput2ndBlock ... ', len(getattr(OptModel, f'eMaxOutput2ndBlock_{p}_{sc}_{st}')), ' rows')
1089
1109
 
1090
1110
  def eMinOutput2ndBlock(OptModel,n,nr):
1091
- if (p,nr) in mTEPES.pnr and (nr not in mTEPES.es or (nr in mTEPES.es and (mTEPES.pTotalMaxCharge[nr] or mTEPES.pTotalEnergyInflows[nr]))) and sum(mTEPES.pOperReserveDw[p,sc,n,ar] for ar in a2n[nr]):
1092
- if mTEPES.pMaxPower2ndBlock[p,sc,n,nr] and mTEPES.pIndOperReserveGen[nr] != 1 and (mTEPES.pIndRampReserves == 0 or sum(mTEPES.pRampReserveDw[p,sc,n,ar] for ar in mTEPES.ar) == 0.0):
1093
- return OptModel.vOutput2ndBlock[p,sc,n,nr] - OptModel.vReserveDown[p,sc,n,nr] >= 0.0
1094
- if mTEPES.pMaxPower2ndBlock[p,sc,n,nr] and mTEPES.pIndOperReserveGen[nr] != 1 and mTEPES.pIndRampReserves == 1 and sum(mTEPES.pRampReserveDw[p,sc,n,ar] for ar in mTEPES.ar) > 0.0:
1095
- return OptModel.vOutput2ndBlock[p,sc,n,nr] - OptModel.vReserveDown[p,sc,n,nr] - OptModel.vRampReserveDw[p,sc,n,nr] >= 0.0
1096
- else:
1097
- return Constraint.Skip
1111
+ if mTEPES.pMaxPower2ndBlock[p,sc,n,nr] == 0.0:
1112
+ return Constraint.Skip
1113
+ if (p,nr) in mTEPES.pnr and (nr not in mTEPES.es or (nr in mTEPES.es and (mTEPES.pTotalMaxCharge[nr] or mTEPES.pTotalEnergyInflows[nr]))):
1114
+ if sum(mTEPES.pOperReserveDw[p,sc,n,ar] for ar in a2n[nr]):
1115
+ if mTEPES.pIndOperReserveGen[nr] != 1 and (mTEPES.pIndRampReserves == 0 or sum(mTEPES.pRampReserveDw[p,sc,n,ar] for ar in mTEPES.ar) == 0.0):
1116
+ return OptModel.vOutput2ndBlock[p,sc,n,nr] - OptModel.vReserveDown[p,sc,n,nr] >= 0.0
1117
+ elif mTEPES.pIndOperReserveGen[nr] != 1 and mTEPES.pIndRampReserves == 1 and sum(mTEPES.pRampReserveDw[p,sc,n,ar] for ar in mTEPES.ar) > 0.0:
1118
+ return OptModel.vOutput2ndBlock[p,sc,n,nr] - OptModel.vReserveDown[p,sc,n,nr] - OptModel.vRampReserveDw[p,sc,n,nr] >= 0.0
1119
+ else:
1120
+ return Constraint.Skip
1121
+ if sum(mTEPES.pOperReserveDw[p,sc,n,ar] for ar in a2n[nr]) == 0.0:
1122
+ if mTEPES.pIndRampReserves == 1 and sum(mTEPES.pRampReserveDw[p,sc,n,ar] for ar in mTEPES.ar) > 0.0:
1123
+ return OptModel.vOutput2ndBlock[p,sc,n,nr] - OptModel.vRampReserveDw[p,sc,n,nr] >= 0.0
1124
+ else:
1125
+ return Constraint.Skip
1098
1126
  else:
1099
1127
  return Constraint.Skip
1100
- setattr(OptModel, f'eMinOutput2ndBlock_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.nr, rule=eMinOutput2ndBlock, doc='min output of the second block of a committed unit [p.u.]'))
1128
+ setattr(OptModel, f'eMinOutput2ndBlock_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.nr, rule=eMinOutput2ndBlock, doc='min output of the second block of a committed unit [p.u.]'))
1101
1129
 
1102
1130
  if pIndLogConsole == 1:
1103
1131
  print('eMinOutput2ndBlock ... ', len(getattr(OptModel, f'eMinOutput2ndBlock_{p}_{sc}_{st}')), ' rows')
1104
1132
 
1105
1133
  def eTotalOutput(OptModel,n,nr):
1106
- if (p,nr) in mTEPES.pnr and (nr not in mTEPES.es or (nr in mTEPES.es and (mTEPES.pTotalMaxCharge[nr] or mTEPES.pTotalEnergyInflows[nr]))):
1134
+ if (p,nr) in mTEPES.pnr and (mTEPES.pMustRun[nr] == 0 or mTEPES.pMaxPower2ndBlock[p,sc,n,nr] or nr in mTEPES.gc) and (nr not in mTEPES.es or (nr in mTEPES.es and (mTEPES.pTotalMaxCharge[nr] or mTEPES.pTotalEnergyInflows[nr]))):
1107
1135
  if mTEPES.pMaxPowerElec[p,sc,n,nr]:
1108
1136
  if mTEPES.pMinPowerElec[p,sc,n,nr] == 0.0:
1109
1137
  return OptModel.vTotalOutput[p,sc,n,nr] == OptModel.vOutput2ndBlock[p,sc,n,nr] + mTEPES.pUpReserveActivation * OptModel.vReserveUp[p,sc,n,nr] - mTEPES.pDwReserveActivation * OptModel.vReserveDown[p,sc,n,nr]
@@ -1113,7 +1141,7 @@ def GenerationOperationModelFormulationCommitment(OptModel, mTEPES, pIndLogConso
1113
1141
  return Constraint.Skip
1114
1142
  else:
1115
1143
  return Constraint.Skip
1116
- setattr(OptModel, f'eTotalOutput_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.nr, rule=eTotalOutput, doc='total output of a unit [GW]'))
1144
+ setattr(OptModel, f'eTotalOutput_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.nr, rule=eTotalOutput, doc='total output of a unit [GW]'))
1117
1145
 
1118
1146
  if pIndLogConsole == 1:
1119
1147
  print('eTotalOutput ... ', len(getattr(OptModel, f'eTotalOutput_{p}_{sc}_{st}')), ' rows')
@@ -1129,7 +1157,7 @@ def GenerationOperationModelFormulationCommitment(OptModel, mTEPES, pIndLogConso
1129
1157
  return Constraint.Skip
1130
1158
  else:
1131
1159
  return Constraint.Skip
1132
- setattr(OptModel, f'eUCStrShut_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.nr, rule=eUCStrShut, doc='relation among commitment startup and shutdown [p.u.]'))
1160
+ setattr(OptModel, f'eUCStrShut_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.nr, rule=eUCStrShut, doc='relation among commitment startup and shutdown [p.u.]'))
1133
1161
 
1134
1162
  if pIndLogConsole == 1:
1135
1163
  print('eUCStrShut ... ', len(getattr(OptModel, f'eUCStrShut_{p}_{sc}_{st}')), ' rows')
@@ -1159,7 +1187,7 @@ def GenerationOperationModelFormulationCommitment(OptModel, mTEPES, pIndLogConso
1159
1187
  return Constraint.Skip
1160
1188
  return OptModel.vCommitment[p,sc,n,nr] <= OptModel.vMaxCommitmentYearly[p,sc,nr,group]
1161
1189
 
1162
- setattr(OptModel, f'eMaxCommitmentYearly_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.ExclusiveGroupsYearly, mTEPES.nr, rule=eMaxCommitmentYearly, doc='maximum of all the commitments [p.u.]'))
1190
+ setattr(OptModel, f'eMaxCommitmentYearly_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.ExclusiveGroupsYearly*mTEPES.nr, rule=eMaxCommitmentYearly, doc='maximum of all the commitments [p.u.]'))
1163
1191
 
1164
1192
  if pIndLogConsole == 1:
1165
1193
  print('eMaxCommitmentYearly ... ', len(getattr(OptModel, f'eMaxCommitmentYearly_{p}_{sc}_{st}')), ' rows')
@@ -1178,14 +1206,13 @@ def GenerationOperationModelFormulationCommitment(OptModel, mTEPES, pIndLogConso
1178
1206
  if len(mTEPES.GeneratorsInYearlyGroup[group] & {nr for (p, nr) in mTEPES.pnr}) <= 1:
1179
1207
  return Constraint.Skip
1180
1208
  return OptModel.vTotalOutput[p,sc,n,nr]/mTEPES.pMaxPowerElec[p,sc,n,nr] <= OptModel.vMaxCommitmentYearly[p,sc,nr,group]
1181
-
1182
- setattr(OptModel, f'eMaxCommitGenYearly_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.ExclusiveGroupsYearly,mTEPES.nr, rule=eMaxCommitGenYearly, doc='maximum of all the capacity factors'))
1209
+ setattr(OptModel, f'eMaxCommitGenYearly_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.ExclusiveGroupsYearly*mTEPES.nr, rule=eMaxCommitGenYearly, doc='maximum of all the capacity factors'))
1183
1210
 
1184
1211
  if pIndLogConsole == 1:
1185
1212
  print('eMaxCommitGenYearly ... ', len(getattr(OptModel, f'eMaxCommitGenYearly_{p}_{sc}_{st}')), ' rows')
1186
1213
 
1187
1214
  def eExclusiveGensYearly(OptModel,group):
1188
- # Skip if there are one or less generators in the group
1215
+ # Skip if there are one or fewer generators in the group
1189
1216
  if len(mTEPES.GeneratorsInYearlyGroup[group] & {nr for (p,nr) in mTEPES.pnr}) <= 1:
1190
1217
  return Constraint.Skip
1191
1218
  return sum(OptModel.vMaxCommitmentYearly[p,sc,nr,group] + (OptModel.vCommitmentCons[p,sc,nr] if nr in mTEPES.h else 0) for nr in mTEPES.GeneratorsInYearlyGroup[group] if (p,nr) in mTEPES.pnr ) <= 1
@@ -1209,8 +1236,7 @@ def GenerationOperationModelFormulationCommitment(OptModel, mTEPES, pIndLogConso
1209
1236
  if len(mTEPES.GeneratorsInHourlyGroup[group] & {nr for (p,nr) in mTEPES.pnr}) <= 1:
1210
1237
  return Constraint.Skip
1211
1238
  return OptModel.vCommitment[p,sc,n,nr] <= OptModel.vMaxCommitmentHourly[p,sc,n,nr,group]
1212
-
1213
- setattr(OptModel, f'eMaxCommitmentHourly_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.ExclusiveGroupsHourly, mTEPES.nr, rule=eMaxCommitmentHourly, doc='maximum of all the commitments [p.u.]'))
1239
+ setattr(OptModel, f'eMaxCommitmentHourly_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.ExclusiveGroupsHourly*mTEPES.nr, rule=eMaxCommitmentHourly, doc='maximum of all the commitments [p.u.]'))
1214
1240
 
1215
1241
  if pIndLogConsole == 1:
1216
1242
  print('eMaxCommitmentHourly ... ', len(getattr(OptModel, f'eMaxCommitmentHourly_{p}_{sc}_{st}')), ' rows')
@@ -1230,7 +1256,7 @@ def GenerationOperationModelFormulationCommitment(OptModel, mTEPES, pIndLogConso
1230
1256
  return Constraint.Skip
1231
1257
  return OptModel.vTotalOutput[p,sc,n,nr]/mTEPES.pMaxPowerElec[p,sc,n,nr] <= OptModel.vMaxCommitmentHourly[p,sc,n,nr,group]
1232
1258
 
1233
- setattr(OptModel, f'eMaxCommitGenHourly_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.ExclusiveGroupsHourly,mTEPES.nr, rule=eMaxCommitGenHourly, doc='maximum of all the capacity factors'))
1259
+ setattr(OptModel, f'eMaxCommitGenHourly_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.ExclusiveGroupsHourly*mTEPES.nr, rule=eMaxCommitGenHourly, doc='maximum of all the capacity factors'))
1234
1260
 
1235
1261
  if pIndLogConsole == 1:
1236
1262
  print('eMaxCommitGenHourly ... ', len(getattr(OptModel, f'eMaxCommitGenHourly_{p}_{sc}_{st}')), ' rows')
@@ -1241,8 +1267,7 @@ def GenerationOperationModelFormulationCommitment(OptModel, mTEPES, pIndLogConso
1241
1267
  if len(mTEPES.GeneratorsInHourlyGroup[group] & {gen for (period, gen) in mTEPES.pnr if period == p}) <= 1:
1242
1268
  return Constraint.Skip
1243
1269
  return sum(OptModel.vMaxCommitmentHourly[p,sc,n,nr,group] + (OptModel.vCommitmentCons[p,sc,n,nr] if nr in mTEPES.h else 0) for nr in mTEPES.GeneratorsInHourlyGroup[group] if (p, nr) in mTEPES.pnr ) <= 1
1244
-
1245
- setattr(OptModel, f'eExclusiveGensHourly_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.ExclusiveGroupsHourly, rule=eExclusiveGensHourly, doc='mutually exclusive generators'))
1270
+ setattr(OptModel, f'eExclusiveGensHourly_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.ExclusiveGroupsHourly, rule=eExclusiveGensHourly, doc='mutually exclusive generators'))
1246
1271
 
1247
1272
  if pIndLogConsole == 1:
1248
1273
  print('eExclusiveGensHourly ... ', len(getattr(OptModel, f'eExclusiveGensHourly_{p}_{sc}_{st}')), ' rows')
@@ -1289,7 +1314,7 @@ def GenerationOperationModelFormulationRampMinTime(OptModel, mTEPES, pIndLogCons
1289
1314
  return Constraint.Skip
1290
1315
  else:
1291
1316
  return Constraint.Skip
1292
- setattr(OptModel, f'eRampUp_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.nr, rule=eRampUp, doc='maximum ramp up [p.u.]'))
1317
+ setattr(OptModel, f'eRampUp_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.nr, rule=eRampUp, doc='maximum ramp up [p.u.]'))
1293
1318
 
1294
1319
  if pIndLogConsole == 1:
1295
1320
  print('eRampUp ... ', len(getattr(OptModel, f'eRampUp_{p}_{sc}_{st}')), ' rows')
@@ -1305,7 +1330,7 @@ def GenerationOperationModelFormulationRampMinTime(OptModel, mTEPES, pIndLogCons
1305
1330
  return Constraint.Skip
1306
1331
  else:
1307
1332
  return Constraint.Skip
1308
- setattr(OptModel, f'eRampDw_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.nr, rule=eRampDw, doc='maximum ramp down [p.u.]'))
1333
+ setattr(OptModel, f'eRampDw_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.nr, rule=eRampDw, doc='maximum ramp down [p.u.]'))
1309
1334
 
1310
1335
  if pIndLogConsole == 1:
1311
1336
  print('eRampDw ... ', len(getattr(OptModel, f'eRampDw_{p}_{sc}_{st}')), ' rows')
@@ -1321,7 +1346,7 @@ def GenerationOperationModelFormulationRampMinTime(OptModel, mTEPES, pIndLogCons
1321
1346
  return Constraint.Skip
1322
1347
  else:
1323
1348
  return Constraint.Skip
1324
- setattr(OptModel, f'eRampUpChr_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.eh, rule=eRampUpCharge, doc='maximum ramp up charge [p.u.]'))
1349
+ setattr(OptModel, f'eRampUpChr_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.eh, rule=eRampUpCharge, doc='maximum ramp up charge [p.u.]'))
1325
1350
 
1326
1351
  if pIndLogConsole == 1:
1327
1352
  print('eRampUpChr ... ', len(getattr(OptModel, f'eRampUpChr_{p}_{sc}_{st}')), ' rows')
@@ -1337,7 +1362,7 @@ def GenerationOperationModelFormulationRampMinTime(OptModel, mTEPES, pIndLogCons
1337
1362
  return Constraint.Skip
1338
1363
  else:
1339
1364
  return Constraint.Skip
1340
- setattr(OptModel, f'eRampDwChr_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.eh, rule=eRampDwCharge, doc='maximum ramp down charge [p.u.]'))
1365
+ setattr(OptModel, f'eRampDwChr_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.eh, rule=eRampDwCharge, doc='maximum ramp down charge [p.u.]'))
1341
1366
 
1342
1367
  if pIndLogConsole == 1:
1343
1368
  print('eRampDwChr ... ', len(getattr(OptModel, f'eRampDwChr_{p}_{sc}_{st}')), ' rows')
@@ -1376,7 +1401,7 @@ def GenerationOperationModelFormulationRampMinTime(OptModel, mTEPES, pIndLogCons
1376
1401
  return (- OptModel.vOutput2ndBlock[p,sc,mTEPES.n.prev(n),nr] + OptModel.vOutput2ndBlock[p,sc,n,nr]) / mTEPES.pDuration[p,sc,n]() / mTEPES.pMaxPower2ndBlock[p,sc,n,nr] <= OptModel.vRampUpState[p,sc,n,nr] - pEpsilon * OptModel.vRampDwState[p,sc,n,nr]
1377
1402
  else:
1378
1403
  return Constraint.Skip
1379
- setattr(OptModel, f'eRampUpState_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.nr, rule=eRampUpState, doc='ramp up state [p.u.]'))
1404
+ setattr(OptModel, f'eRampUpState_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.nr, rule=eRampUpState, doc='ramp up state [p.u.]'))
1380
1405
 
1381
1406
  if pIndLogConsole == 1:
1382
1407
  print('eRampUpState ... ', len(getattr(OptModel, f'eRampUpState_{p}_{sc}_{st}')), ' rows')
@@ -1407,7 +1432,7 @@ def GenerationOperationModelFormulationRampMinTime(OptModel, mTEPES, pIndLogCons
1407
1432
  return (OptModel.vOutput2ndBlock[p,sc,mTEPES.n.prev(n),nr] - OptModel.vOutput2ndBlock[p,sc,n,nr]) / mTEPES.pDuration[p,sc,n]() / mTEPES.pMaxPower2ndBlock[p,sc,n,nr] <= OptModel.vRampDwState[p,sc,n,nr] - pEpsilon * OptModel.vRampUpState[p,sc,n,nr]
1408
1433
  else:
1409
1434
  return Constraint.Skip
1410
- setattr(OptModel, f'eRampDwState_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.nr, rule=eRampDwState, doc='maximum ramp down [p.u.]'))
1435
+ setattr(OptModel, f'eRampDwState_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.nr, rule=eRampDwState, doc='maximum ramp down [p.u.]'))
1411
1436
 
1412
1437
  if pIndLogConsole == 1:
1413
1438
  print('eRampDwState ... ', len(getattr(OptModel, f'eRampDwState_{p}_{sc}_{st}')), ' rows')
@@ -1420,7 +1445,7 @@ def GenerationOperationModelFormulationRampMinTime(OptModel, mTEPES, pIndLogCons
1420
1445
  return Constraint.Skip
1421
1446
  else:
1422
1447
  return Constraint.Skip
1423
- setattr(OptModel, f'eMinUpTime_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.t, rule=eMinUpTime , doc='minimum up time [p.u.]'))
1448
+ setattr(OptModel, f'eMinUpTime_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.t, rule=eMinUpTime , doc='minimum up time [p.u.]'))
1424
1449
 
1425
1450
  if pIndLogConsole == 1:
1426
1451
  print('eMinUpTime ... ', len(getattr(OptModel, f'eMinUpTime_{p}_{sc}_{st}')), ' rows')
@@ -1433,7 +1458,7 @@ def GenerationOperationModelFormulationRampMinTime(OptModel, mTEPES, pIndLogCons
1433
1458
  return Constraint.Skip
1434
1459
  else:
1435
1460
  return Constraint.Skip
1436
- setattr(OptModel, f'eMinDownTime_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.t, rule=eMinDownTime, doc='minimum down time [p.u.]'))
1461
+ setattr(OptModel, f'eMinDownTime_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.t, rule=eMinDownTime, doc='minimum down time [p.u.]'))
1437
1462
 
1438
1463
  if pIndLogConsole == 1:
1439
1464
  print('eMinDownTime ... ', len(getattr(OptModel, f'eMinDownTime_{p}_{sc}_{st}')), ' rows')
@@ -1444,7 +1469,7 @@ def GenerationOperationModelFormulationRampMinTime(OptModel, mTEPES, pIndLogCons
1444
1469
  return OptModel.vRampUpState[p,sc,n,nr] + sum(OptModel.vRampDwState[p,sc,n2,nr] for n2 in list(mTEPES.n2)[mTEPES.n.ord(n)-mTEPES.pStableTime[nr]-1:mTEPES.n.ord(n)-1]) <= 1
1445
1470
  else:
1446
1471
  return Constraint.Skip
1447
- setattr(OptModel, f'eMinStableTime_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.nr, rule=eMinStableTime, doc='minimum stable time [p.u.]'))
1472
+ setattr(OptModel, f'eMinStableTime_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.nr, rule=eMinStableTime, doc='minimum stable time [p.u.]'))
1448
1473
  else:
1449
1474
  MinStableTimeLoadLevels = []
1450
1475
  if sum(mTEPES.pStableTime[nr] for nr in mTEPES.nr):
@@ -1480,7 +1505,7 @@ def NetworkSwitchingModelFormulation(OptModel, mTEPES, pIndLogConsole, p, sc, st
1480
1505
  return OptModel.vLineCommit[p,sc,n,ni,nf,cc] == OptModel.vNetworkInvest[p,ni,nf,cc]
1481
1506
  else:
1482
1507
  return Constraint.Skip
1483
- setattr(OptModel, f'eLineStateCand_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.lc, rule=eLineStateCand, doc='logical relation between investment and operation in candidates'))
1508
+ setattr(OptModel, f'eLineStateCand_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.lc, rule=eLineStateCand, doc='logical relation between investment and operation in candidates'))
1484
1509
 
1485
1510
  if pIndLogConsole == 1:
1486
1511
  print('eLineStateCand ... ', len(getattr(OptModel, f'eLineStateCand_{p}_{sc}_{st}')), ' rows')
@@ -1496,7 +1521,7 @@ def NetworkSwitchingModelFormulation(OptModel, mTEPES, pIndLogConsole, p, sc, st
1496
1521
  return Constraint.Skip
1497
1522
  else:
1498
1523
  return Constraint.Skip
1499
- setattr(OptModel, f'eSWOnOff_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.la, rule=eSWOnOff, doc='relation among switching decision activate and deactivate state'))
1524
+ setattr(OptModel, f'eSWOnOff_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.la, rule=eSWOnOff, doc='relation among switching decision activate and deactivate state'))
1500
1525
 
1501
1526
  if pIndLogConsole == 1:
1502
1527
  print('eSWOnOff ... ', len(getattr(OptModel, f'eSWOnOff_{p}_{sc}_{st}')), ' rows')
@@ -1509,7 +1534,7 @@ def NetworkSwitchingModelFormulation(OptModel, mTEPES, pIndLogConsole, p, sc, st
1509
1534
  return Constraint.Skip
1510
1535
  else:
1511
1536
  return Constraint.Skip
1512
- setattr(OptModel, f'eMinSwOnState_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.la, rule=eMinSwOnState, doc='minimum switch on state [h]'))
1537
+ setattr(OptModel, f'eMinSwOnState_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.la, rule=eMinSwOnState, doc='minimum switch on state [h]'))
1513
1538
 
1514
1539
  if pIndLogConsole == 1:
1515
1540
  print('eMinSwOnState ... ', len(getattr(OptModel, f'eMinSwOnState_{p}_{sc}_{st}')), ' rows')
@@ -1522,7 +1547,7 @@ def NetworkSwitchingModelFormulation(OptModel, mTEPES, pIndLogConsole, p, sc, st
1522
1547
  return Constraint.Skip
1523
1548
  else:
1524
1549
  return Constraint.Skip
1525
- setattr(OptModel, f'eMinSwOffState_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.la, rule=eMinSwOffState, doc='minimum switch off state [h]'))
1550
+ setattr(OptModel, f'eMinSwOffState_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.la, rule=eMinSwOffState, doc='minimum switch off state [h]'))
1526
1551
 
1527
1552
  if pIndLogConsole == 1:
1528
1553
  print('eMinSwOffState ... ', len(getattr(OptModel, f'eMinSwOffState_{p}_{sc}_{st}')), ' rows')
@@ -1543,7 +1568,7 @@ def NetworkOperationModelFormulation(OptModel, mTEPES, pIndLogConsole, p, sc, st
1543
1568
  return OptModel.vFlowElec[p,sc,n,ni,nf,cc] / mTEPES.pMaxNTCMax[p,sc,n,ni,nf,cc] >= - OptModel.vLineCommit[p,sc,n,ni,nf,cc]
1544
1569
  else:
1545
1570
  return Constraint.Skip
1546
- setattr(OptModel, f'eNetCapacity1_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.la, rule=eNetCapacity1, doc='maximum flow by existing network capacity [p.u.]'))
1571
+ setattr(OptModel, f'eNetCapacity1_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.la, rule=eNetCapacity1, doc='maximum flow by existing network capacity [p.u.]'))
1547
1572
 
1548
1573
  if pIndLogConsole == 1:
1549
1574
  print('eNetCapacity1 ... ', len(getattr(OptModel, f'eNetCapacity1_{p}_{sc}_{st}')), ' rows')
@@ -1553,7 +1578,7 @@ def NetworkOperationModelFormulation(OptModel, mTEPES, pIndLogConsole, p, sc, st
1553
1578
  return OptModel.vFlowElec[p,sc,n,ni,nf,cc] / mTEPES.pMaxNTCMax[p,sc,n,ni,nf,cc] <= OptModel.vLineCommit[p,sc,n,ni,nf,cc]
1554
1579
  else:
1555
1580
  return Constraint.Skip
1556
- setattr(OptModel, f'eNetCapacity2_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.la, rule=eNetCapacity2, doc='maximum flow by existing network capacity [p.u.]'))
1581
+ setattr(OptModel, f'eNetCapacity2_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.la, rule=eNetCapacity2, doc='maximum flow by existing network capacity [p.u.]'))
1557
1582
 
1558
1583
  if pIndLogConsole == 1:
1559
1584
  print('eNetCapacity2 ... ', len(getattr(OptModel, f'eNetCapacity2_{p}_{sc}_{st}')), ' rows')
@@ -1566,7 +1591,7 @@ def NetworkOperationModelFormulation(OptModel, mTEPES, pIndLogConsole, p, sc, st
1566
1591
  return OptModel.vFlowElec[p,sc,n,ni,nf,cc] / mTEPES.pBigMFlowBck[ni,nf,cc]() - (OptModel.vTheta[p,sc,n,ni] - OptModel.vTheta[p,sc,n,nf]) / mTEPES.pLineX[ni,nf,cc] / mTEPES.pBigMFlowBck[ni,nf,cc]() * mTEPES.pSBase == 0
1567
1592
  else:
1568
1593
  return Constraint.Skip
1569
- setattr(OptModel, f'eKirchhoff2ndLaw1_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.laa, rule=eKirchhoff2ndLaw1, doc='flow for each AC candidate line [rad]'))
1594
+ setattr(OptModel, f'eKirchhoff2ndLaw1_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.laa, rule=eKirchhoff2ndLaw1, doc='flow for each AC candidate line [rad]'))
1570
1595
 
1571
1596
  if pIndLogConsole == 1:
1572
1597
  print('eKirchhoff2ndLaw1 ... ', len(getattr(OptModel, f'eKirchhoff2ndLaw1_{p}_{sc}_{st}')), ' rows')
@@ -1576,7 +1601,7 @@ def NetworkOperationModelFormulation(OptModel, mTEPES, pIndLogConsole, p, sc, st
1576
1601
  return OptModel.vFlowElec[p,sc,n,ni,nf,cc] / mTEPES.pBigMFlowFrw[ni,nf,cc]() - (OptModel.vTheta[p,sc,n,ni] - OptModel.vTheta[p,sc,n,nf]) / mTEPES.pLineX[ni,nf,cc] / mTEPES.pBigMFlowFrw[ni,nf,cc]() * mTEPES.pSBase <= 1 - OptModel.vLineCommit[p,sc,n,ni,nf,cc]
1577
1602
  else:
1578
1603
  return Constraint.Skip
1579
- setattr(OptModel, f'eKirchhoff2ndLaw2_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.lca, rule=eKirchhoff2ndLaw2, doc='flow for each AC candidate line [rad]'))
1604
+ setattr(OptModel, f'eKirchhoff2ndLaw2_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.lca, rule=eKirchhoff2ndLaw2, doc='flow for each AC candidate line [rad]'))
1580
1605
 
1581
1606
  if pIndLogConsole == 1:
1582
1607
  print('eKirchhoff2ndLaw2 ... ', len(getattr(OptModel, f'eKirchhoff2ndLaw2_{p}_{sc}_{st}')), ' rows')
@@ -1586,7 +1611,7 @@ def NetworkOperationModelFormulation(OptModel, mTEPES, pIndLogConsole, p, sc, st
1586
1611
  return OptModel.vLineLosses[p,sc,n,ni,nf,cc] >= - 0.5 * mTEPES.pLineLossFactor[ni,nf,cc] * OptModel.vFlowElec[p,sc,n,ni,nf,cc]
1587
1612
  else:
1588
1613
  return Constraint.Skip
1589
- setattr(OptModel, f'eLineLosses1_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.ll, rule=eLineLosses1, doc='ohmic losses for all the lines [GW]'))
1614
+ setattr(OptModel, f'eLineLosses1_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.ll, rule=eLineLosses1, doc='ohmic losses for all the lines [GW]'))
1590
1615
 
1591
1616
  if pIndLogConsole == 1:
1592
1617
  print('eLineLosses1 ... ', len(getattr(OptModel, f'eLineLosses1_{p}_{sc}_{st}')), ' rows')
@@ -1596,7 +1621,7 @@ def NetworkOperationModelFormulation(OptModel, mTEPES, pIndLogConsole, p, sc, st
1596
1621
  return OptModel.vLineLosses[p,sc,n,ni,nf,cc] >= 0.5 * mTEPES.pLineLossFactor[ni,nf,cc] * OptModel.vFlowElec[p,sc,n,ni,nf,cc]
1597
1622
  else:
1598
1623
  return Constraint.Skip
1599
- setattr(OptModel, f'eLineLosses2_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.ll, rule=eLineLosses2, doc='ohmic losses for all the lines [GW]'))
1624
+ setattr(OptModel, f'eLineLosses2_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.ll, rule=eLineLosses2, doc='ohmic losses for all the lines [GW]'))
1600
1625
 
1601
1626
  if pIndLogConsole == 1:
1602
1627
  print('eLineLosses2 ... ', len(getattr(OptModel, f'eLineLosses2_{p}_{sc}_{st}')), ' rows')
@@ -1616,7 +1641,7 @@ def NetworkOperationModelFormulation(OptModel, mTEPES, pIndLogConsole, p, sc, st
1616
1641
  return (OptModel.vNetPosition[p,sc,n,nd] == sum(OptModel.vTotalOutput[p,sc,n,g] for g in g2n[nd] if (p,g) in mTEPES.pg) - sum(OptModel.vESSTotalCharge[p,sc,n,eh] for eh in e2n[nd] if (p,eh) in mTEPES.peh) + OptModel.vENS[p,sc,n,nd] - mTEPES.pDemandElec[p,sc,n,nd])
1617
1642
  else:
1618
1643
  return Constraint.Skip
1619
- setattr(OptModel, f'eNetPosition_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.nd, rule=eNetPosition, doc='net position [GW]'))
1644
+ setattr(OptModel, f'eNetPosition_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.nd, rule=eNetPosition, doc='net position [GW]'))
1620
1645
 
1621
1646
  def eFlowBasedCalcu1(OptModel,n,ni,nf,cc):
1622
1647
  if mTEPES.pIndBinSingleNode() == 0 and mTEPES.pElecNetPeriodIni[ni,nf,cc] <= p and mTEPES.pElecNetPeriodFin[ni,nf,cc] >= p and mTEPES.pIndPTDF == 1 and mTEPES.pIndBinLinePTDF[ni,nf,cc] == 1:
@@ -1626,7 +1651,7 @@ def NetworkOperationModelFormulation(OptModel, mTEPES, pIndLogConsole, p, sc, st
1626
1651
  return OptModel.vFlowElec[p,sc,n,ni,nf,cc] - sum(mTEPES.pPTDF[p,sc,n,ni,nf,cc,nd] * OptModel.vNetPosition[p,sc,n,nd] for nd in mTEPES.nd if (p,sc,n,ni,nf,cc,nd) in mTEPES.psnland) == 0
1627
1652
  else:
1628
1653
  return Constraint.Skip
1629
- setattr(OptModel, f'eFlowBasedCalcu1_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.la, rule=eFlowBasedCalcu1, doc='flow based calculation [p.u.]'))
1654
+ setattr(OptModel, f'eFlowBasedCalcu1_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.la, rule=eFlowBasedCalcu1, doc='flow based calculation [p.u.]'))
1630
1655
 
1631
1656
  if pIndLogConsole == 1:
1632
1657
  print('eFlowBasedCalcu1 ... ', len(getattr(OptModel, f'eFlowBasedCalcu1_{p}_{sc}_{st}')), ' rows')
@@ -1636,7 +1661,7 @@ def NetworkOperationModelFormulation(OptModel, mTEPES, pIndLogConsole, p, sc, st
1636
1661
  return OptModel.vFlowElec[p,sc,n,ni,nf,cc] - sum(mTEPES.pPTDF[p,sc,n,ni,nf,cc,nd] * OptModel.vNetPosition[p,sc,n,nd] for nd in mTEPES.nd if (p,sc,n,ni,nf,cc,nd) in mTEPES.psnland) <= 1 - OptModel.vLineCommit[p,sc,n,ni,nf,cc]
1637
1662
  else:
1638
1663
  return Constraint.Skip
1639
- setattr(OptModel, f'eFlowBasedCalcu2_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.lca, rule=eFlowBasedCalcu2, doc='flow based calculation [p.u.]'))
1664
+ setattr(OptModel, f'eFlowBasedCalcu2_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.lca, rule=eFlowBasedCalcu2, doc='flow based calculation [p.u.]'))
1640
1665
 
1641
1666
  if pIndLogConsole == 1:
1642
1667
  print('eFlowBasedCalcu2 ... ', len(getattr(OptModel, f'eFlowBasedCalcu2_{p}_{sc}_{st}')), ' rows')
@@ -1646,7 +1671,7 @@ def NetworkOperationModelFormulation(OptModel, mTEPES, pIndLogConsole, p, sc, st
1646
1671
  # return OptModel.vFlowElec[p,sc,n,ni,nf,cc] <= mTEPES.pVariableTTCFrw[p,sc,n,ni,nf,cc]
1647
1672
  # else:
1648
1673
  # return Constraint.Skip
1649
- # setattr(OptModel, f'eSecurityMargingTTCFrw_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.lca, rule=eSecurityMargingTTCFrw, doc='security margin TTC for flow based calculation [p.u.]'))
1674
+ # setattr(OptModel, f'eSecurityMargingTTCFrw_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.lca, rule=eSecurityMargingTTCFrw, doc='security margin TTC for flow based calculation [p.u.]'))
1650
1675
  #
1651
1676
  # if pIndLogConsole == 1:
1652
1677
  # print('eSecurityMargingTTCFrw... ', len(getattr(OptModel, f'eSecurityMargingTTCFrw_{p}_{sc}_{st}')), ' rows')
@@ -1656,7 +1681,7 @@ def NetworkOperationModelFormulation(OptModel, mTEPES, pIndLogConsole, p, sc, st
1656
1681
  # return OptModel.vFlowElec[p,sc,n,ni,nf,cc] >= - mTEPES.pVariableTTCBck[p,sc,n,ni,nf,cc]
1657
1682
  # else:
1658
1683
  # return Constraint.Skip
1659
- # setattr(OptModel, f'eSecurityMargingTTCBck_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.lca, rule=eSecurityMargingTTCBck, doc='security margin TTC for flow based calculation [p.u.]'))
1684
+ # setattr(OptModel, f'eSecurityMargingTTCBck_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.lca, rule=eSecurityMargingTTCBck, doc='security margin TTC for flow based calculation [p.u.]'))
1660
1685
  #
1661
1686
  # if pIndLogConsole == 1:
1662
1687
  # print('eSecurityMargingTTCBck... ', len(getattr(OptModel, f'eSecurityMargingTTCBck_{p}_{sc}_{st}')), ' rows')
@@ -1757,7 +1782,7 @@ def CycleConstraints(OptModel, mTEPES, pIndLogConsole, p, sc, st):
1757
1782
  sum(OptModel.vFlowElec[p,sc,n,ni,nf,cc] * mTEPES.pLineX[ni,nf,cc] / mTEPES.pSBase for nf,ni in list(zip(mTEPES.ncd[cyc], mTEPES.ncd[cyc][1:] + mTEPES.ncd[cyc][:1])) for cc in mTEPES.cc if (ni,nf,cc) in mTEPES.uctc) ) / mTEPES.pBigMTheta[cyc,nii,nff,cc] <= 1 - OptModel.vLineCommit[p,sc,n,nii,nff,cc]
1758
1783
  else:
1759
1784
  return Constraint.Skip
1760
- setattr(OptModel, f'eCycleKirchhoff2ndLawCnd1_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.lcac, rule=eCycleKirchhoff2ndLawCnd1, doc='cycle flow for with some AC candidate lines [rad]'))
1785
+ setattr(OptModel, f'eCycleKirchhoff2ndLawCnd1_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.lcac, rule=eCycleKirchhoff2ndLawCnd1, doc='cycle flow for with some AC candidate lines [rad]'))
1761
1786
 
1762
1787
  if pIndLogConsole == 1:
1763
1788
  print('eCycleKirchhoff2ndLC1 ... ', len(getattr(OptModel, f'eCycleKirchhoff2ndLawCnd1_{p}_{sc}_{st}')), ' rows')
@@ -1768,7 +1793,7 @@ def CycleConstraints(OptModel, mTEPES, pIndLogConsole, p, sc, st):
1768
1793
  sum(OptModel.vFlowElec[p,sc,n,ni,nf,cc] * mTEPES.pLineX[ni,nf,cc] / mTEPES.pSBase for nf,ni in list(zip(mTEPES.ncd[cyc], mTEPES.ncd[cyc][1:] + mTEPES.ncd[cyc][:1])) for cc in mTEPES.cc if (ni,nf,cc) in mTEPES.uctc) ) / mTEPES.pBigMTheta[cyc,nii,nff,cc] >= - 1 + OptModel.vLineCommit[p,sc,n,nii,nff,cc]
1769
1794
  else:
1770
1795
  return Constraint.Skip
1771
- setattr(OptModel, f'eCycleKirchhoff2ndLawCnd2_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.lcac, rule=eCycleKirchhoff2ndLawCnd2, doc='cycle flow for with some AC candidate lines [rad]'))
1796
+ setattr(OptModel, f'eCycleKirchhoff2ndLawCnd2_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.lcac, rule=eCycleKirchhoff2ndLawCnd2, doc='cycle flow for with some AC candidate lines [rad]'))
1772
1797
 
1773
1798
  if pIndLogConsole == 1:
1774
1799
  print('eCycleKirchhoff2ndLC2 ... ', len(getattr(OptModel, f'eCycleKirchhoff2ndLawCnd2_{p}_{sc}_{st}')), ' rows')
@@ -1778,7 +1803,7 @@ def CycleConstraints(OptModel, mTEPES, pIndLogConsole, p, sc, st):
1778
1803
  return (OptModel.vFlowElec[p,sc,n,ni,nf,cc] - OptModel.vFlowElec[p,sc,n,ni,nf,c2] * mTEPES.pLineX[ni,nf,c2] / mTEPES.pLineX[ni,nf,cc]) / max(mTEPES.pMaxNTCBck[p,sc,n,ni,nf,cc],mTEPES.pMaxNTCFrw[p,sc,n,ni,nf,cc]) <= 1 - OptModel.vLineCommit[p,sc,n,ni,nf,c2]
1779
1804
  else:
1780
1805
  return Constraint.Skip
1781
- setattr(OptModel, f'eFlowParallelCandidate1_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.pct, mTEPES.cc, mTEPES.c2, rule=eFlowParallelCandidate1, doc='unitary flow for each AC candidate parallel circuit [p.u.]'))
1806
+ setattr(OptModel, f'eFlowParallelCandidate1_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.pct, mTEPES.cc, mTEPES.c2, rule=eFlowParallelCandidate1, doc='unitary flow for each AC candidate parallel circuit [p.u.]'))
1782
1807
 
1783
1808
  if pIndLogConsole == 1:
1784
1809
  print('eFlowParallelCnddate1 ... ', len(getattr(OptModel, f'eFlowParallelCandidate1_{p}_{sc}_{st}')), ' rows')
@@ -1788,7 +1813,7 @@ def CycleConstraints(OptModel, mTEPES, pIndLogConsole, p, sc, st):
1788
1813
  return (OptModel.vFlowElec[p,sc,n,ni,nf,cc] - OptModel.vFlowElec[p,sc,n,ni,nf,c2] * mTEPES.pLineX[ni,nf,c2] / mTEPES.pLineX[ni,nf,cc]) / max(mTEPES.pMaxNTCBck[p,sc,n,ni,nf,cc],mTEPES.pMaxNTCFrw[p,sc,n,ni,nf,cc]) >= - 1 + OptModel.vLineCommit[p,sc,n,ni,nf,c2]
1789
1814
  else:
1790
1815
  return Constraint.Skip
1791
- setattr(OptModel, f'eFlowParallelCandidate2_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.pct, mTEPES.cc, mTEPES.c2, rule=eFlowParallelCandidate2, doc='unitary flow for each AC candidate parallel circuit [p.u.]'))
1816
+ setattr(OptModel, f'eFlowParallelCandidate2_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.pct, mTEPES.cc, mTEPES.c2, rule=eFlowParallelCandidate2, doc='unitary flow for each AC candidate parallel circuit [p.u.]'))
1792
1817
 
1793
1818
  if pIndLogConsole == 1:
1794
1819
  print('eFlowParallelCnddate2 ... ', len(getattr(OptModel, f'eFlowParallelCandidate2_{p}_{sc}_{st}')), ' rows')
@@ -1829,7 +1854,7 @@ def NetworkH2OperationModelFormulation(OptModel, mTEPES, pIndLogConsole, p, sc,
1829
1854
  sum(OptModel.vFlowH2[p,sc,n,nd,nf,cc] for nf,cc in lout[nd] if (p,nd,nf,cc) in mTEPES.ppa) + sum(OptModel.vFlowH2[p,sc,n,ni,nd,cc] for ni,cc in lin[nd] if (p,ni,nd,cc) in mTEPES.ppa)) == mTEPES.pDemandH2[p,sc,n,nd]*mTEPES.pDuration[p,sc,n]()
1830
1855
  else:
1831
1856
  return Constraint.Skip
1832
- setattr(OptModel, f'eBalanceH2_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.nd, rule=eBalanceH2, doc='H2 load generation balance [tH2]'))
1857
+ setattr(OptModel, f'eBalanceH2_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.nd, rule=eBalanceH2, doc='H2 load generation balance [tH2]'))
1833
1858
 
1834
1859
  if pIndLogConsole == 1:
1835
1860
  print('eBalanceH2 ... ', len(getattr(OptModel, f'eBalanceH2_{p}_{sc}_{st}')), ' rows')
@@ -1865,7 +1890,7 @@ def NetworkHeatOperationModelFormulation(OptModel, mTEPES, pIndLogConsole, p, sc
1865
1890
  return OptModel.vTotalOutputHeat[p,sc,n,chp] == OptModel.vESSTotalCharge[p,sc,n,chp] / mTEPES.pProductionFunctionHeat[chp]
1866
1891
  else:
1867
1892
  return Constraint.Skip
1868
- setattr(OptModel, f'eEnergy2Heat_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.chp, rule=eEnergy2Heat, doc='Energy to heat conversion [GW]'))
1893
+ setattr(OptModel, f'eEnergy2Heat_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.chp, rule=eEnergy2Heat, doc='Energy to heat conversion [GW]'))
1869
1894
 
1870
1895
  if pIndLogConsole == 1:
1871
1896
  print('eEnergy2Heat ... ', len(getattr(OptModel, f'eEnergy2Heat_{p}_{sc}_{st}')), ' rows')
@@ -1876,7 +1901,7 @@ def NetworkHeatOperationModelFormulation(OptModel, mTEPES, pIndLogConsole, p, sc
1876
1901
  sum(OptModel.vFlowHeat[p,sc,n,nd,nf,cc] for nf,cc in lout[nd] if (p,nd,nf,cc) in mTEPES.pha) + sum(OptModel.vFlowHeat[p,sc,n,ni,nd,cc] for ni,cc in lin[nd] if (p,ni,nd,cc) in mTEPES.pha)) == mTEPES.pDemandHeat[p,sc,n,nd]
1877
1902
  else:
1878
1903
  return Constraint.Skip
1879
- setattr(OptModel, f'eBalanceHeat_{p}_{sc}_{st}', Constraint(mTEPES.n, mTEPES.nd, rule=eBalanceHeat, doc='Heat load generation balance [GW]'))
1904
+ setattr(OptModel, f'eBalanceHeat_{p}_{sc}_{st}', Constraint(mTEPES.n*mTEPES.nd, rule=eBalanceHeat, doc='Heat load generation balance [GW]'))
1880
1905
 
1881
1906
  if pIndLogConsole == 1:
1882
1907
  print('eBalanceHeat ... ', len(getattr(OptModel, f'eBalanceHeat_{p}_{sc}_{st}')), ' rows')