openTEPES 4.18.4__py3-none-any.whl → 4.18.6__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 (75) 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/oT_Data_VariableMinGeneration_RTS-GMLC.csv +1 -1
  49. openTEPES/RTS-GMLC_6y/oT_Data_VariableFuelCost_RTS-GMLC_6y.csv +1 -1
  50. openTEPES/RTS-GMLC_6y/oT_Dict_AreaToRegion_RTS-GMLC_6y.csv +4 -4
  51. openTEPES/RTS-GMLC_6y/oT_Dict_Area_RTS-GMLC_6y.csv +4 -4
  52. openTEPES/RTS-GMLC_6y/oT_Dict_Circuit_RTS-GMLC_6y.csv +5 -5
  53. openTEPES/RTS-GMLC_6y/oT_Dict_Line_RTS-GMLC_6y.csv +3 -3
  54. openTEPES/RTS-GMLC_6y/oT_Dict_NodeToZone_RTS-GMLC_6y.csv +74 -74
  55. openTEPES/RTS-GMLC_6y/oT_Dict_Region_RTS-GMLC_6y.csv +2 -2
  56. openTEPES/RTS-GMLC_6y/oT_Dict_Scenario_RTS-GMLC_6y.csv +2 -2
  57. openTEPES/RTS-GMLC_6y/oT_Dict_Storage_RTS-GMLC_6y.csv +3 -3
  58. openTEPES/RTS-GMLC_6y/oT_Dict_Technology_RTS-GMLC_6y.csv +10 -10
  59. openTEPES/RTS-GMLC_6y/oT_Dict_ZoneToArea_RTS-GMLC_6y.csv +22 -22
  60. openTEPES/RTS-GMLC_6y/oT_Dict_Zone_RTS-GMLC_6y.csv +22 -22
  61. openTEPES/__init__.py +1 -1
  62. openTEPES/openTEPES.py +26 -17
  63. openTEPES/openTEPES_InputData.py +1335 -1188
  64. openTEPES/openTEPES_Main.py +3 -3
  65. openTEPES/openTEPES_ModelFormulation.py +413 -156
  66. openTEPES/openTEPES_OutputResults.py +263 -206
  67. openTEPES/openTEPES_ProblemSolving.py +35 -28
  68. openTEPES/sSEP/oT_Data_DemandHydrogen_sSEP.csv +8736 -8736
  69. openTEPES/sSEP/oT_Data_Generation_sSEP.csv +1 -1
  70. openTEPES/sSEP/oT_Data_HydroOutflows_sSEP.csv +1 -1
  71. {opentepes-4.18.4.dist-info → opentepes-4.18.6.dist-info}/METADATA +65 -46
  72. {opentepes-4.18.4.dist-info → opentepes-4.18.6.dist-info}/RECORD +75 -28
  73. {opentepes-4.18.4.dist-info → opentepes-4.18.6.dist-info}/WHEEL +1 -1
  74. {opentepes-4.18.4.dist-info → opentepes-4.18.6.dist-info}/entry_points.txt +0 -0
  75. {opentepes-4.18.4.dist-info → opentepes-4.18.6.dist-info/licenses}/LICENSE +0 -0
@@ -1,5 +1,5 @@
1
1
  """
2
- Open Generation, Storage, and Transmission Operation and Expansion Planning Model with RES and ESS (openTEPES) - April 03, 2025
2
+ Open Generation, Storage, and Transmission Operation and Expansion Planning Model with RES and ESS (openTEPES) - July 16, 2025
3
3
  """
4
4
 
5
5
  import time
@@ -20,28 +20,30 @@ def ProblemSolving(DirName, CaseName, SolverName, OptModel, mTEPES, pIndLogConso
20
20
  #%% solving the problem
21
21
  Solver = SolverFactory(SolverName) # select solver
22
22
  if SolverName == 'gurobi':
23
- FileName = _path+f'/openTEPES_gurobi_{CaseName}_{p}_{sc}_{st}.log'
23
+ FileName = f'{_path}/openTEPES_gurobi_{CaseName}_{p}_{sc}_{st}.log'
24
24
  if os.path.exists(FileName):
25
25
  os.remove(FileName)
26
- Solver.options['LogFile' ] = _path+f'/openTEPES_gurobi_{CaseName}_{p}_{sc}_{st}.log'
26
+ Solver.options['LogFile' ] = f'{_path}/openTEPES_gurobi_{CaseName}_{p}_{sc}_{st}.log'
27
+ # Solver.options['OutputFlag' ] = 0 # suppress log file
27
28
  # Solver.options['SolutionTarget'] = 1 # optimal solution with or without basic solutions
28
29
  Solver.options['Method' ] = 2 # barrier method
29
30
  Solver.options['Crossover' ] = -1
30
31
  # Solver.options['MIPFocus' ] = 3
32
+ # Solver.options['Seed' ] = 104729
31
33
  # Solver.options['Presolve' ] = 2
32
34
  # Solver.options['RINS' ] = 100
33
35
  # Solver.options['BarConvTol' ] = 1e-9
34
36
  # Solver.options['BarQCPConvTol' ] = 0.025
35
- # Solver.options['IISFile' ] = _path+f'/openTEPES_gurobi_'+CaseName+'.ilp' # should be uncommented to show results of IIS
37
+ # Solver.options['IISFile' ] = f'{_path}/openTEPES_gurobi_'+CaseName+'.ilp' # should be uncommented to show results of IIS
36
38
  Solver.options['MIPGap' ] = 0.01
37
39
  Solver.options['Threads' ] = int((psutil.cpu_count(logical=True) + psutil.cpu_count(logical=False))/2)
38
40
  Solver.options['TimeLimit' ] = 36000
39
41
  Solver.options['IterationLimit' ] = 36000000
40
42
  if SolverName == 'cplex':
41
- FileName = _path+f'/openTEPES_cplex_{CaseName}_{p}_{sc}_{st}.log'
43
+ FileName = f'{_path}/openTEPES_cplex_{CaseName}_{p}_{sc}_{st}.log'
42
44
  if os.path.exists(FileName):
43
45
  os.remove(FileName)
44
- # Solver.options['LogFile' ] = _path+f'/openTEPES_cplex_{CaseName}_{p}_{sc}_{st}.log'
46
+ # Solver.options['LogFile' ] = f'{_path}/openTEPES_cplex_{CaseName}_{p}_{sc}_{st}.log'
45
47
  Solver.options['LPMethod' ] = 4 # barrier method
46
48
  # Solver.options['BarCrossAlg' ] = 0
47
49
  # Solver.options['NumericalEmphasis'] = 1
@@ -52,10 +54,10 @@ def ProblemSolving(DirName, CaseName, SolverName, OptModel, mTEPES, pIndLogConso
52
54
  Solver.options['TimeLimit' ] = 36000
53
55
  # Solver.options['ItLim' ] = 36000000
54
56
  if SolverName == 'appsi_highs':
55
- FileName = _path+f'/openTEPES_highs_{CaseName}_{p}_{sc}_{st}.log'
57
+ FileName = f'{_path}/openTEPES_highs_{CaseName}_{p}_{sc}_{st}.log'
56
58
  if os.path.exists(FileName):
57
59
  os.remove(FileName)
58
- Solver.options['log_file' ] = _path+f'/openTEPES_highs_{CaseName}_{p}_{sc}_{st}.log'
60
+ Solver.options['log_file' ] = f'{_path}/openTEPES_highs_{CaseName}_{p}_{sc}_{st}.log'
59
61
  Solver.options['solver' ] = 'choose'
60
62
  Solver.options['simplex_strategy' ] = 3
61
63
  Solver.options['run_crossover' ] = 'on'
@@ -65,31 +67,33 @@ def ProblemSolving(DirName, CaseName, SolverName, OptModel, mTEPES, pIndLogConso
65
67
  Solver.options['time_limit' ] = 36000
66
68
  Solver.options['simplex_iteration_limit'] = 36000000
67
69
  if SolverName == 'gams' or SolverName == 'GAMS':
70
+ FileName = f'{_path}/openTEPES_gams_{CaseName}_{p}_{sc}_{st}.log'
68
71
  solver_options = {
69
- 'file COPT / cplex.opt / ; put COPT putclose "LPMethod 4" / "EpGap 0.01" / ; GAMS_MODEL.OptFile = 1 ;'
72
+ 'file COPT / cplex.opt / ; put COPT putclose "LPMethod 4" / "EpGap 0.01" / ; GAMS_MODEL.OptFile = 1 ; '
70
73
  'option SysOut = off ;',
71
74
  'option LP = cplex ; option MIP = cplex ;',
72
75
  'option ResLim = 36000 ; option IterLim = 36000000 ;',
73
76
  'option Threads = '+str(int((psutil.cpu_count(logical=True) + psutil.cpu_count(logical=False))/2))+' ;'
74
77
  }
75
78
 
76
- idx = 0
79
+ nUnfixedVars = 0
77
80
  for var in OptModel.component_data_objects(pyo.Var, active=True, descend_into=True):
78
- if not var.is_continuous():
79
- idx += 1
80
- if idx == 0:
81
+ if not var.is_continuous() and not var.is_fixed() and var.value != None:
82
+ nUnfixedVars += 1
83
+
84
+ if nUnfixedVars == 0:
81
85
  OptModel.dual = Suffix(direction=Suffix.IMPORT_EXPORT)
82
86
  OptModel.rc = Suffix(direction=Suffix.IMPORT_EXPORT)
83
87
 
84
- if SolverName == 'gams':
85
- SolverResults = Solver.solve(OptModel, tee=True, report_timing=True, symbolic_solver_labels=False, add_options=solver_options)
88
+ if SolverName == 'gams' or SolverName == 'GAMS':
89
+ SolverResults = Solver.solve(OptModel, tee=True, report_timing=True, symbolic_solver_labels=False, add_options=solver_options, logfile=FileName)
86
90
  else:
87
91
  SolverResults = Solver.solve(OptModel, tee=True, report_timing=True)
88
92
 
89
93
  print('Termination condition: ', SolverResults.solver.termination_condition)
90
94
  if SolverResults.solver.termination_condition == TerminationCondition.infeasible or SolverResults.solver.termination_condition == TerminationCondition.maxTimeLimit or SolverResults.solver.termination_condition == TerminationCondition.infeasible.maxIterations:
91
95
  log_infeasible_constraints(OptModel, log_expression=True, log_variables=True)
92
- logging.basicConfig(filename=_path+f'/openTEPES_infeasibilities_{CaseName}_{p}_{sc}_{st}.log', level=logging.INFO)
96
+ logging.basicConfig(filename=f'{_path}/openTEPES_infeasibilities_{CaseName}_{p}_{sc}_{st}.log', level=logging.INFO)
93
97
  raise ValueError('Problem infeasible')
94
98
  SolverResults.write() # summary of the solver results
95
99
 
@@ -98,17 +102,17 @@ def ProblemSolving(DirName, CaseName, SolverName, OptModel, mTEPES, pIndLogConso
98
102
  # binary operation decisions are fixed to their optimal values
99
103
  # if NoRepetition == 1, all variables are fixed
100
104
  # if NoRepetition == 0, only the variables of the current period and scenario are fixed
101
- idx = 0
105
+ nUnfixedVars = 0
102
106
  if mTEPES.NoRepetition == 1:
103
107
  for var in OptModel.component_data_objects(pyo.Var, active=True, descend_into=True):
104
- if not var.is_continuous() and not var.is_fixed():
108
+ if not var.is_continuous() and not var.is_fixed() and var.value != None:
105
109
  var.fixed = True # fix the current value
106
- idx += 1
110
+ nUnfixedVars += 1
107
111
  else:
108
112
  for var in OptModel.component_data_objects(pyo.Var, active=True, descend_into=True):
109
- if not var.is_continuous() and not var.is_fixed() and var.index()[0] == p and var.index()[1] == sc:
113
+ if not var.is_continuous() and not var.is_fixed() and var.value != None and var.index()[0] == p and var.index()[1] == sc:
110
114
  var.fixed = True # fix the current value
111
- idx += 1
115
+ nUnfixedVars += 1
112
116
 
113
117
  # continuous investment decisions are fixed to their optimal values
114
118
  for eb in mTEPES.eb:
@@ -133,7 +137,7 @@ def ProblemSolving(DirName, CaseName, SolverName, OptModel, mTEPES, pIndLogConso
133
137
  if (p,ni,nf,cc) in mTEPES.phc:
134
138
  OptModel.vHeatPipeInvest[p,ni,nf,cc].fix(OptModel.vHeatPipeInvest [p,ni,nf,cc]())
135
139
 
136
- if idx > 0:
140
+ if nUnfixedVars > 0:
137
141
  OptModel.dual = Suffix(direction=Suffix.IMPORT_EXPORT)
138
142
  OptModel.rc = Suffix(direction=Suffix.IMPORT_EXPORT)
139
143
  SolverResults = Solver.solve(OptModel, tee=True, report_timing=True)
@@ -170,16 +174,16 @@ def ProblemSolving(DirName, CaseName, SolverName, OptModel, mTEPES, pIndLogConso
170
174
  print (' Total generation investment cost [MEUR] ', sum(mTEPES.pDiscountedWeight[pp] * mTEPES.pGenInvestCost [eb ] * OptModel.vGenerationInvest [pp,eb ]() for eb in mTEPES.eb if (pp,eb) in mTEPES.peb) +
171
175
  sum(mTEPES.pDiscountedWeight[pp] * mTEPES.pGenInvestCost [bc ] * OptModel.vGenerationInvestHeat[pp,bc ]() for bc in mTEPES.bc if (pp,bc) in mTEPES.pbc))
172
176
  print (' Total generation retirement cost [MEUR] ', sum(mTEPES.pDiscountedWeight[pp] * mTEPES.pGenRetireCost [gd ] * OptModel.vGenerationRetire [pp,gd ]() for gd in mTEPES.gd if (pp,gd) in mTEPES.pgd))
173
- if mTEPES.pIndHydroTopology == 1 and len(mTEPES.rn):
177
+ if mTEPES.pIndHydroTopology == 1 and mTEPES.rn:
174
178
  print(' Total reservoir investment cost [MEUR] ', sum(mTEPES.pDiscountedWeight[pp] * mTEPES.pRsrInvestCost [rc ] * OptModel.vReservoirInvest [pp,rc ]() for rc in mTEPES.rn if (pp,rc) in mTEPES.prc))
175
179
  else:
176
180
  print(' Total reservoir investment cost [MEUR] ', 0.0)
177
181
  print (' Total network investment cost [MEUR] ', sum(mTEPES.pDiscountedWeight[pp] * mTEPES.pNetFixedCost [ni,nf,cc] * OptModel.vNetworkInvest [pp,ni,nf,cc]() for ni,nf,cc in mTEPES.lc if (pp,ni,nf,cc) in mTEPES.plc))
178
- if mTEPES.pIndHydrogen == 1 and len(mTEPES.pc):
182
+ if mTEPES.pIndHydrogen == 1 and mTEPES.pc:
179
183
  print(' Total H2 pipe investment cost [MEUR] ', sum(mTEPES.pDiscountedWeight[pp] * mTEPES.pH2PipeFixedCost [ni,nf,cc] * OptModel.vH2PipeInvest [pp,ni,nf,cc]() for ni,nf,cc in mTEPES.pc if (pp,ni,nf,cc) in mTEPES.ppc))
180
184
  else:
181
185
  print(' Total H2 pipe investment cost [MEUR] ', 0.0)
182
- if mTEPES.pIndHeat == 1 and len(mTEPES.hc):
186
+ if mTEPES.pIndHeat == 1 and mTEPES.hc:
183
187
  print(' Total heat pipe investment cost [MEUR] ', sum(mTEPES.pDiscountedWeight[pp] * mTEPES.pHeatPipeFixedCost[ni,nf,cc] * OptModel.vHeatPipeInvest [pp,ni,nf,cc]() for ni,nf,cc in mTEPES.hc if (pp,ni,nf,cc) in mTEPES.phc))
184
188
  else:
185
189
  print(' Total heat pipe investment cost [MEUR] ', 0.0)
@@ -192,16 +196,16 @@ def ProblemSolving(DirName, CaseName, SolverName, OptModel, mTEPES, pIndLogConso
192
196
  print (' Total generation investment cost [MEUR] ', sum(mTEPES.pDiscountedWeight[p] * mTEPES.pGenInvestCost [eb ] * OptModel.vGenerationInvest [p,eb ]() for eb in mTEPES.eb if (p,eb) in mTEPES.peb) +
193
197
  sum(mTEPES.pDiscountedWeight[p] * mTEPES.pGenInvestCost [bc ] * OptModel.vGenerationInvestHeat[p,bc ]() for bc in mTEPES.bc if (p,bc) in mTEPES.pbc))
194
198
  print (' Total generation retirement cost [MEUR] ', sum(mTEPES.pDiscountedWeight[p] * mTEPES.pGenRetireCost [gd ] * OptModel.vGenerationRetire [p,gd ]() for gd in mTEPES.gd if (p,gd) in mTEPES.pgd))
195
- if mTEPES.pIndHydroTopology == 1 and len(mTEPES.rn):
199
+ if mTEPES.pIndHydroTopology == 1 and mTEPES.rn:
196
200
  print (' Total reservoir investment cost [MEUR] ', sum(mTEPES.pDiscountedWeight[p] * mTEPES.pRsrInvestCost [rc ] * OptModel.vReservoirInvest [p,rc ]() for rc in mTEPES.rn if (p,rc) in mTEPES.prc))
197
201
  else:
198
202
  print (' Total reservoir investment cost [MEUR] ', 0.0)
199
203
  print (' Total network investment cost [MEUR] ', sum(mTEPES.pDiscountedWeight[p] * mTEPES.pNetFixedCost [ni,nf,cc] * OptModel.vNetworkInvest [p,ni,nf,cc ]() for ni,nf,cc in mTEPES.lc if (p,ni,nf,cc) in mTEPES.plc))
200
- if mTEPES.pIndHydrogen == 1 and len(mTEPES.pc):
204
+ if mTEPES.pIndHydrogen == 1 and mTEPES.pc:
201
205
  print (' Total H2 pipe investment cost [MEUR] ', sum(mTEPES.pDiscountedWeight[p] * mTEPES.pH2PipeFixedCost [ni,nf,cc] * OptModel.vH2PipeInvest [p,ni,nf,cc ]() for ni,nf,cc in mTEPES.pc if (p,ni,nf,cc) in mTEPES.ppc))
202
206
  else:
203
207
  print (' Total H2 pipe investment cost [MEUR] ', 0.0)
204
- if mTEPES.pIndHeat == 1 and len(mTEPES.hc):
208
+ if mTEPES.pIndHeat == 1 and mTEPES.hc:
205
209
  print (' Total heat pipe investment cost [MEUR] ', sum(mTEPES.pDiscountedWeight[p] * mTEPES.pHeatPipeFixedCost[ni,nf,cc] * OptModel.vHeatPipeInvest [p,ni,nf,cc ]() for ni,nf,cc in mTEPES.hc if (p,ni,nf,cc) in mTEPES.phc))
206
210
  else:
207
211
  print (' Total heat pipe investment cost [MEUR] ', 0.0)
@@ -209,3 +213,6 @@ def ProblemSolving(DirName, CaseName, SolverName, OptModel, mTEPES, pIndLogConso
209
213
  print (' Total consumption operation cost [MEUR] ', sum(mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb [p,sc ]() * OptModel.vTotalCCost [p,sc,n ]() for n in mTEPES.n ))
210
214
  print (' Total emission cost [MEUR] ', sum(mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb [p,sc ]() * OptModel.vTotalECost [p,sc,n ]() for n in mTEPES.n ))
211
215
  print (' Total reliability cost [MEUR] ', sum(mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb [p,sc ]() * OptModel.vTotalRCost [p,sc,n ]() for n in mTEPES.n ))
216
+
217
+ # Adding SolverResults to mTEPES
218
+ mTEPES.SolverResults = SolverResults