openTEPES 4.18.7__py3-none-any.whl → 4.18.8__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- openTEPES/__init__.py +1 -1
- openTEPES/openTEPES.py +3 -4
- openTEPES/openTEPES_InputData.py +209 -109
- openTEPES/openTEPES_Main.py +17 -7
- openTEPES/openTEPES_ModelFormulation.py +101 -60
- openTEPES/openTEPES_OutputResults.py +280 -140
- openTEPES/openTEPES_ProblemSolving.py +30 -29
- openTEPES/sSEP/oT_Data_RampReserveDown_sSEP.csv +8737 -0
- openTEPES/sSEP/oT_Data_RampReserveUp_sSEP.csv +8737 -0
- {opentepes-4.18.7.dist-info → opentepes-4.18.8.dist-info}/METADATA +6 -5
- {opentepes-4.18.7.dist-info → opentepes-4.18.8.dist-info}/RECORD +14 -12
- {opentepes-4.18.7.dist-info → opentepes-4.18.8.dist-info}/WHEEL +0 -0
- {opentepes-4.18.7.dist-info → opentepes-4.18.8.dist-info}/entry_points.txt +0 -0
- {opentepes-4.18.7.dist-info → opentepes-4.18.8.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
"""
|
|
2
|
-
Open Generation, Storage, and Transmission Operation and Expansion Planning Model with RES and ESS (openTEPES) -
|
|
2
|
+
Open Generation, Storage, and Transmission Operation and Expansion Planning Model with RES and ESS (openTEPES) - January 15, 2026
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
5
|
import time
|
|
6
6
|
import datetime
|
|
7
7
|
import os
|
|
8
|
-
# import ast
|
|
9
8
|
import math
|
|
10
9
|
import csv
|
|
11
10
|
import pandas as pd
|
|
@@ -16,8 +15,11 @@ import plotly.graph_objs as go
|
|
|
16
15
|
from collections import defaultdict
|
|
17
16
|
from colour import Color
|
|
18
17
|
|
|
18
|
+
# from line_profiler import profile
|
|
19
|
+
|
|
19
20
|
|
|
20
21
|
# Definition of Pie plots
|
|
22
|
+
# @profile
|
|
21
23
|
def PiePlots(period, scenario, df, Category, Value):
|
|
22
24
|
df = df.reset_index()
|
|
23
25
|
df = df.loc[(df['level_0'] == period) & (df['level_1'] == scenario)]
|
|
@@ -43,6 +45,7 @@ def PiePlots(period, scenario, df, Category, Value):
|
|
|
43
45
|
|
|
44
46
|
|
|
45
47
|
# Definition of Area plots
|
|
48
|
+
# @profile
|
|
46
49
|
def AreaPlots(period, scenario, df, Category, X, Y, OperationType):
|
|
47
50
|
Results = df.loc[period,scenario,:,:]
|
|
48
51
|
Results = Results.reset_index().rename(columns={'level_0': X, 'level_1': Category, 0: Y})
|
|
@@ -71,6 +74,7 @@ def AreaPlots(period, scenario, df, Category, X, Y, OperationType):
|
|
|
71
74
|
|
|
72
75
|
|
|
73
76
|
# Definition of Line plots
|
|
77
|
+
# @profile
|
|
74
78
|
def LinePlots(period, scenario, df, Category, X, Y, OperationType):
|
|
75
79
|
Results = df.loc[period,scenario,:,:].rename_axis(['level_0', 'level_1'], axis=0)
|
|
76
80
|
Results.columns = [0]
|
|
@@ -100,6 +104,7 @@ def LinePlots(period, scenario, df, Category, X, Y, OperationType):
|
|
|
100
104
|
|
|
101
105
|
|
|
102
106
|
# write parameters, variables, and duals
|
|
107
|
+
# @profile
|
|
103
108
|
def OutputResultsParVarCon(DirName, CaseName, OptModel, mTEPES):
|
|
104
109
|
# print('Writing pars, vars, and duals results ... ', end='')
|
|
105
110
|
# DirName = os.path.dirname(DirName)
|
|
@@ -178,6 +183,7 @@ def OutputResultsParVarCon(DirName, CaseName, OptModel, mTEPES):
|
|
|
178
183
|
print('Writing pars, vars, and duals results ... ', round(WritingResultsTime), 's')
|
|
179
184
|
|
|
180
185
|
|
|
186
|
+
# @profile
|
|
181
187
|
def InvestmentResults(DirName, CaseName, OptModel, mTEPES, pIndTechnologyOutput, pIndPlotOutput):
|
|
182
188
|
#%% outputting the investment decisions
|
|
183
189
|
_path = os.path.join(DirName, CaseName)
|
|
@@ -201,26 +207,28 @@ def InvestmentResults(DirName, CaseName, OptModel, mTEPES, pIndTechnologyOutput,
|
|
|
201
207
|
|
|
202
208
|
# Saving generation investments
|
|
203
209
|
OutputToFile = pd.Series(data=[OptModel.vGenerationInvest[p,eb]() for p,eb in mTEPES.peb], index=mTEPES.peb)
|
|
204
|
-
OutputToFile = OutputToFile.fillna(0).to_frame(name='InvestmentDecision').reset_index().rename(columns={'level_0': 'Period', 'level_1': '
|
|
210
|
+
OutputToFile = OutputToFile.fillna(0).to_frame(name='InvestmentDecision').reset_index().rename(columns={'level_0': 'Period', 'level_1': 'Generator'})
|
|
205
211
|
if pIndTechnologyOutput == 0 or pIndTechnologyOutput == 2:
|
|
206
|
-
OutputToFile.pivot_table(index=['Period'], columns=['
|
|
207
|
-
OutputToFile = OutputToFile.set_index(['Period', '
|
|
212
|
+
OutputToFile.pivot_table(index=['Period'], columns=['Generator'], values='InvestmentDecision').rename_axis(['Period'], axis=0).to_csv(f'{_path}/oT_Result_GenerationInvestmentPerUnit_{CaseName}.csv', index=True, sep=',')
|
|
213
|
+
OutputToFile = OutputToFile.set_index(['Period', 'Generator'])
|
|
214
|
+
|
|
208
215
|
OutputToFile = pd.Series(data=[OptModel.vGenerationInvest[p,eb]()*max(mTEPES.pRatedMaxPowerElec[eb],mTEPES.pRatedMaxCharge[eb]) for p,eb in mTEPES.peb], index=mTEPES.peb)
|
|
209
216
|
OutputToFile *= 1e3
|
|
210
|
-
OutputToFile = OutputToFile.fillna(0).to_frame(name='MW'
|
|
217
|
+
OutputToFile = OutputToFile.fillna(0).to_frame(name='MW').reset_index().rename(columns={'level_0': 'Period', 'level_1': 'Generator'})
|
|
211
218
|
if pIndTechnologyOutput == 0 or pIndTechnologyOutput == 2:
|
|
212
|
-
OutputToFile.pivot_table(index=['Period'], columns=['
|
|
213
|
-
|
|
219
|
+
OutputToFile.pivot_table(index=['Period'], columns=['Generator'], values='MW').rename_axis(['Period'], axis=0).to_csv(f'{_path}/oT_Result_GenerationInvestment_{CaseName}.csv', index=True, sep=',')
|
|
220
|
+
OutputToFile.pivot_table(index=['Period', 'Generator'], values='MW').rename_axis(['Period', 'Generator'], axis=0).rename(columns={'MW': 'Power [MW]'}, inplace=False).to_csv(f'{_path}/oT_Result_MarketResultsGenerationInvestment_{CaseName}.csv', index=True, sep=',')
|
|
221
|
+
OutputToFile = OutputToFile.set_index(['Period', 'Generator'])
|
|
214
222
|
|
|
215
223
|
if sum(1 for ar in mTEPES.ar if sum(1 for g in g2a[ar])) > 1:
|
|
216
224
|
if pIndPlotOutput == 1:
|
|
217
225
|
sPAREB = [(p,ar,eb) for p,ar,eb in mTEPES.par*mTEPES.eb if (p,eb) in mTEPES.peb and eb in g2a[ar]]
|
|
218
226
|
GenInvestToArea = pd.Series(data=[OutputToFile['MW'][p,eb] for p,ar,eb in sPAREB], index=pd.Index(sPAREB)).to_frame(name='MW')
|
|
219
|
-
GenInvestToArea.index.names = ['Period', 'Area', '
|
|
220
|
-
chart = alt.Chart(GenInvestToArea.reset_index()).mark_bar().encode(x='
|
|
227
|
+
GenInvestToArea.index.names = ['Period', 'Area', 'Generator']
|
|
228
|
+
chart = alt.Chart(GenInvestToArea.reset_index()).mark_bar().encode(x='Generator:O', y='sum(MW):Q', color='Area:N', column='Period:N').properties(width=600, height=400)
|
|
221
229
|
chart.save(f'{_path}/oT_Plot_GenerationInvestmentPerArea_{CaseName}.html', embed_options={'renderer':'svg'})
|
|
222
|
-
TechInvestToArea = pd.Series(data=[sum(OutputToFile['MW'][p,eb] for eb in mTEPES.eb if (p,eb) in mTEPES.peb and eb in
|
|
223
|
-
TechInvestToArea.index.names = ['Period', 'Area', 'Technology'
|
|
230
|
+
TechInvestToArea = pd.Series(data=[sum(OutputToFile['MW'][p,eb] for eb in mTEPES.eb if (p,eb) in mTEPES.peb and eb in g2t[gt] and eb in g2a[ar]) for p,ar,gt in mTEPES.par*mTEPES.gt], index=mTEPES.par*mTEPES.gt).to_frame(name='MW')
|
|
231
|
+
TechInvestToArea.index.names = ['Period', 'Area', 'Technology']
|
|
224
232
|
chart = alt.Chart(TechInvestToArea.reset_index()).mark_bar().encode(x='Technology:O', y='sum(MW):Q', color='Area:N', column='Period:N').properties(width=600, height=400)
|
|
225
233
|
chart.save(f'{_path}/oT_Plot_TechnologyInvestmentPerArea_{CaseName}.html', embed_options={'renderer':'svg'})
|
|
226
234
|
|
|
@@ -230,11 +238,14 @@ def InvestmentResults(DirName, CaseName, OptModel, mTEPES, pIndTechnologyOutput,
|
|
|
230
238
|
OutputResults1 = OutputResults1.to_frame(name='Technology')
|
|
231
239
|
OutputResults2 = OutputToFile
|
|
232
240
|
OutputResults = pd.concat([OutputResults1, OutputResults2], axis=1)
|
|
233
|
-
OutputResults.index.names = ['Period', '
|
|
241
|
+
OutputResults.index.names = ['Period', 'Generator']
|
|
234
242
|
OutputResults = OutputResults.reset_index().groupby(['Period', 'Technology']).sum(numeric_only=True)
|
|
235
243
|
OutputResults['MW'] = round(OutputResults['MW'], 2)
|
|
236
244
|
OutputResults.reset_index().pivot_table(index=['Period'], columns=['Technology'], values='MW').rename_axis(['Period'], axis=0).to_csv(f'{_path}/oT_Result_TechnologyInvestment_{CaseName}.csv', index=True, sep=',')
|
|
237
245
|
|
|
246
|
+
MarketResultsInv = pd.DataFrame()
|
|
247
|
+
MarketResultsInv = pd.concat([MarketResultsInv, OutputResults], axis=1)
|
|
248
|
+
|
|
238
249
|
if pIndPlotOutput == 1:
|
|
239
250
|
chart = alt.Chart(OutputResults.reset_index()).mark_bar().encode(x='Technology:O', y='sum(MW):Q', color='Technology:N', column='Period:N').properties(width=600, height=400)
|
|
240
251
|
chart.save(f'{_path}/oT_Plot_TechnologyInvestment_{CaseName}.html', embed_options={'renderer':'svg'})
|
|
@@ -242,18 +253,30 @@ def InvestmentResults(DirName, CaseName, OptModel, mTEPES, pIndTechnologyOutput,
|
|
|
242
253
|
# Saving and plotting generation investment cost
|
|
243
254
|
OutputResults0 = OutputResults
|
|
244
255
|
OutputToFile = pd.Series(data=[mTEPES.pDiscountedWeight[p] * mTEPES.pGenInvestCost[eb] * OptModel.vGenerationInvest[p,eb]() for p,eb in mTEPES.peb], index=mTEPES.peb)
|
|
245
|
-
OutputToFile = OutputToFile.fillna(0).to_frame(name='MEUR').reset_index().rename(columns={'level_0': 'Period', 'level_1': '
|
|
256
|
+
OutputToFile = OutputToFile.fillna(0).to_frame(name='MEUR').reset_index().rename(columns={'level_0': 'Period', 'level_1': 'Generator'}).set_index(['Period', 'Generator'])
|
|
246
257
|
|
|
247
258
|
OutputResults1 = pd.Series(data=[gt for p,eb,gt in mTEPES.peb*mTEPES.gt if eb in g2t[gt]], index=mTEPES.peb)
|
|
248
259
|
OutputResults1 = OutputResults1.to_frame(name='Technology')
|
|
249
260
|
OutputResults2 = OutputToFile
|
|
250
261
|
OutputResults = pd.concat([OutputResults1, OutputResults2], axis=1)
|
|
251
|
-
OutputResults.index.names = ['Period', '
|
|
262
|
+
OutputResults.index.names = ['Period', 'Generator']
|
|
252
263
|
OutputResults = OutputResults.reset_index().groupby(['Period', 'Technology']).sum(numeric_only=True)
|
|
253
264
|
OutputResults['MEUR'] = round(OutputResults['MEUR'], 2)
|
|
254
265
|
|
|
255
266
|
OutputResults.reset_index().pivot_table(index=['Period'], columns=['Technology'], values='MEUR').rename_axis(['Period'], axis=0).to_csv(f'{_path}/oT_Result_TechnologyInvestmentCost_{CaseName}.csv', index=True, sep=',')
|
|
256
267
|
|
|
268
|
+
MarketResultsInv = pd.concat([MarketResultsInv, OutputResults], axis=1)
|
|
269
|
+
|
|
270
|
+
GenTechInvestCost = pd.Series(data=[sum(mTEPES.pDiscountedWeight[p] * mTEPES.pGenInvestCost[eb] * OptModel.vGenerationInvest[p,eb]() for eb in mTEPES.eb if eb in g2t[gt] ) for p,gt in mTEPES.p*mTEPES.gt], index=mTEPES.p*mTEPES.gt)
|
|
271
|
+
GenTechInvestCost *= 1e3
|
|
272
|
+
GenTechInjection = pd.Series(data=[sum(mTEPES.pDiscountedWeight[p] * mTEPES.pLoadLevelDuration[p,sc,n]() * OptModel.vTotalOutput[p,sc,n,eb]() for sc,n,eb in mTEPES.sc*mTEPES.n*mTEPES.eb if eb in g2t[gt] and (p,sc,n) in mTEPES.psn) for p,gt in mTEPES.p*mTEPES.gt], index=mTEPES.p*mTEPES.gt)
|
|
273
|
+
GenTechInjection.name = 'Generation'
|
|
274
|
+
MarketResultsInv = pd.concat([MarketResultsInv, GenTechInjection], axis=1)
|
|
275
|
+
LCOE = GenTechInvestCost.div(GenTechInjection)
|
|
276
|
+
LCOE.name = 'LCOE'
|
|
277
|
+
MarketResultsInv = pd.concat([MarketResultsInv, LCOE], axis=1)
|
|
278
|
+
MarketResultsInv.stack().reset_index().pivot_table(index=['level_0','level_1'], columns='level_2', values=0, aggfunc='sum').rename_axis(['Period', 'Technology'], axis=0).rename(columns={'MW': 'Power [MW]', 'MEUR': 'Cost [MEUR]', 'Generation': 'Generation [GWh]', 'LCOE': 'LCOE [EUR/MWh]'}, inplace=False).to_csv(f'{_path}/oT_Result_MarketResultsTechnologyInvestment_{CaseName}.csv', sep=',')
|
|
279
|
+
|
|
257
280
|
if pIndPlotOutput == 1:
|
|
258
281
|
chart = alt.Chart(OutputResults.reset_index()).mark_bar().encode(x='Technology:O', y='sum(MEUR):Q', color='Technology:N', column='Period:N').properties(width=600, height=400)
|
|
259
282
|
chart.save(f'{_path}/oT_Plot_TechnologyInvestmentCost_{CaseName}.html', embed_options={'renderer':'svg'})
|
|
@@ -276,23 +299,23 @@ def InvestmentResults(DirName, CaseName, OptModel, mTEPES, pIndTechnologyOutput,
|
|
|
276
299
|
|
|
277
300
|
if pIndTechnologyOutput == 0 or pIndTechnologyOutput == 2:
|
|
278
301
|
# Saving generation retirement
|
|
279
|
-
OutputToFile = pd.Series(data=[OptModel.vGenerationRetire[p,gd]()
|
|
280
|
-
OutputToFile = OutputToFile.fillna(0).to_frame(name='RetirementDecision').reset_index().rename(columns={'level_0': 'Period', 'level_1': '
|
|
281
|
-
OutputToFile.pivot_table(index=['Period'], columns=['
|
|
302
|
+
OutputToFile = pd.Series(data=[OptModel.vGenerationRetire[p,gd]() for p,gd in mTEPES.pgd], index=mTEPES.pgd)
|
|
303
|
+
OutputToFile = OutputToFile.fillna(0).to_frame(name='RetirementDecision').reset_index().rename(columns={'level_0': 'Period', 'level_1': 'Generator'})
|
|
304
|
+
OutputToFile.pivot_table(index=['Period'], columns=['Generator'], values='RetirementDecision').rename_axis(['Period'], axis=0).to_csv(f'{_path}/oT_Result_GenerationRetirementPerUnit_{CaseName}.csv', index=True, sep=',')
|
|
282
305
|
OutputToFile = pd.Series(data=[OptModel.vGenerationRetire[p,gd]()*max(mTEPES.pRatedMaxPowerElec[gd],mTEPES.pRatedMaxCharge[gd]) for p,gd in mTEPES.pgd], index=mTEPES.pgd)
|
|
283
306
|
OutputToFile *= 1e3
|
|
284
|
-
OutputToFile = OutputToFile.fillna(0).to_frame(name='MW' ).reset_index().rename(columns={'level_0': 'Period', 'level_1': '
|
|
285
|
-
OutputToFile.pivot_table(index=['Period'], columns=['
|
|
286
|
-
OutputToFile = OutputToFile.set_index(['Period', '
|
|
307
|
+
OutputToFile = OutputToFile.fillna(0).to_frame(name='MW' ).reset_index().rename(columns={'level_0': 'Period', 'level_1': 'Generator'})
|
|
308
|
+
OutputToFile.pivot_table(index=['Period'], columns=['Generator'], values='MW').rename_axis(['Period'], axis=0).to_csv(f'{_path}/oT_Result_GenerationRetirement_{CaseName}.csv', index=True, sep=',')
|
|
309
|
+
OutputToFile = OutputToFile.set_index(['Period', 'Generator'])
|
|
287
310
|
|
|
288
311
|
if sum(1 for ar in mTEPES.ar if sum(1 for g in g2a[ar])) > 1:
|
|
289
312
|
if pIndPlotOutput == 1:
|
|
290
313
|
sPARGD = [(p,ar,gd) for p,ar,gd in mTEPES.par*mTEPES.gd if (p,gd) in mTEPES.pgd and gd in g2a[ar]]
|
|
291
314
|
GenRetireToArea = pd.Series(data=[OutputToFile['MW'][p,gd] for p,ar,gd in sPARGD], index=pd.Index(sPARGD)).to_frame(name='MW')
|
|
292
|
-
GenRetireToArea.index.names = ['Period', 'Area', '
|
|
293
|
-
chart = alt.Chart(GenRetireToArea.reset_index()).mark_bar().encode(x='
|
|
315
|
+
GenRetireToArea.index.names = ['Period', 'Area', 'Generator']
|
|
316
|
+
chart = alt.Chart(GenRetireToArea.reset_index()).mark_bar().encode(x='Generator:O', y='sum(MW):Q', color='Area:N', column='Period:N').properties(width=600, height=400)
|
|
294
317
|
chart.save(f'{_path}/oT_Plot_GenerationRetirementPerArea_{CaseName}.html', embed_options={'renderer':'svg'})
|
|
295
|
-
TechRetireToArea = pd.Series(data=[sum(OutputToFile['MW'][p,gd] for gd in mTEPES.gd if gd in
|
|
318
|
+
TechRetireToArea = pd.Series(data=[sum(OutputToFile['MW'][p,gd] for gd in mTEPES.gd if (p,gd) in mTEPES.pgd and gd in g2t[gt] and gd in g2a[ar]) for p,ar,gt in mTEPES.par*mTEPES.gt], index=mTEPES.par*mTEPES.gt).to_frame(name='MW')
|
|
296
319
|
TechRetireToArea.index.names = ['Period', 'Area', 'Technology' ]
|
|
297
320
|
chart = alt.Chart(TechRetireToArea.reset_index()).mark_bar().encode(x='Technology:O', y='sum(MW):Q', color='Area:N', column='Period:N').properties(width=600, height=400)
|
|
298
321
|
chart.save(f'{_path}/oT_Plot_TechnologyRetirementPerArea_{CaseName}.html', embed_options={'renderer':'svg'})
|
|
@@ -303,7 +326,7 @@ def InvestmentResults(DirName, CaseName, OptModel, mTEPES, pIndTechnologyOutput,
|
|
|
303
326
|
OutputResults1 = OutputResults1.to_frame(name='Technology')
|
|
304
327
|
OutputResults2 = OutputToFile
|
|
305
328
|
OutputResults = pd.concat([OutputResults1, OutputResults2], axis=1)
|
|
306
|
-
OutputResults.index.names = ['Period', '
|
|
329
|
+
OutputResults.index.names = ['Period', 'Generator']
|
|
307
330
|
OutputResults = OutputResults.reset_index().groupby(['Period', 'Technology']).sum(numeric_only=True)
|
|
308
331
|
OutputResults['MW'] = round(OutputResults['MW'], 2)
|
|
309
332
|
OutputResults.reset_index().pivot_table(index=['Period'], columns=['Technology'], values='MW').rename_axis([None], axis=0).to_csv(f'{_path}/oT_Result_TechnologyRetirement_{CaseName}.csv', sep=',', index=False)
|
|
@@ -356,6 +379,7 @@ def InvestmentResults(DirName, CaseName, OptModel, mTEPES, pIndTechnologyOutput,
|
|
|
356
379
|
print('Writing investment results ... ', round(WritingResultsTime), 's')
|
|
357
380
|
|
|
358
381
|
|
|
382
|
+
# @profile
|
|
359
383
|
def GenerationOperationResults(DirName, CaseName, OptModel, mTEPES, pIndTechnologyOutput, pIndAreaOutput, pIndPlotOutput):
|
|
360
384
|
#%% outputting the generation operation
|
|
361
385
|
_path = os.path.join(DirName, CaseName)
|
|
@@ -405,7 +429,7 @@ def GenerationOperationResults(DirName, CaseName, OptModel, mTEPES, pIndTechnolo
|
|
|
405
429
|
OutputToFile = OutputToFile.fillna(0.0)
|
|
406
430
|
OutputToFile *= 1e3
|
|
407
431
|
if pIndTechnologyOutput == 0 or pIndTechnologyOutput == 2:
|
|
408
|
-
OutputToFile.to_frame(name='MW').reset_index().pivot_table(index=['level_0','level_1','level_2'], columns='level_3', values='MW').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/
|
|
432
|
+
OutputToFile.to_frame(name='MW').reset_index().pivot_table(index=['level_0','level_1','level_2'], columns='level_3', values='MW').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_GenerationOperatingReserveUp_{CaseName}.csv', sep=',')
|
|
409
433
|
|
|
410
434
|
if pIndTechnologyOutput == 1 or pIndTechnologyOutput == 2:
|
|
411
435
|
OutputToFile = pd.Series(data=[sum(OutputToFile[p,sc,n,nr] for nr in n2n[nt] if (p,nr) in mTEPES.pnr) for p,sc,n,nt in mTEPES.psnnt], index=mTEPES.psnnt)
|
|
@@ -428,7 +452,7 @@ def GenerationOperationResults(DirName, CaseName, OptModel, mTEPES, pIndTechnolo
|
|
|
428
452
|
OutputToFile = OutputToFile.fillna(0.0)
|
|
429
453
|
OutputToFile *= 1e3
|
|
430
454
|
if pIndTechnologyOutput == 0 or pIndTechnologyOutput == 2:
|
|
431
|
-
OutputToFile.to_frame(name='MW').reset_index().pivot_table(index=['level_0','level_1','level_2'], columns='level_3', values='MW').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/
|
|
455
|
+
OutputToFile.to_frame(name='MW').reset_index().pivot_table(index=['level_0','level_1','level_2'], columns='level_3', values='MW').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_GenerationOperatingReserveDown_{CaseName}.csv', sep=',')
|
|
432
456
|
|
|
433
457
|
if pIndTechnologyOutput == 1 or pIndTechnologyOutput == 2:
|
|
434
458
|
OutputToFile = pd.Series(data=[sum(OutputToFile[p,sc,n,nr] for nr in n2n[nt] if (p,nr) in mTEPES.pnr) for p,sc,n,nt in mTEPES.psnnt], index=mTEPES.psnnt)
|
|
@@ -445,6 +469,26 @@ def GenerationOperationResults(DirName, CaseName, OptModel, mTEPES, pIndTechnolo
|
|
|
445
469
|
OutputToFile = pd.Series(data=[sum(OutputToFile[p,sc,n,eh] for eh in e2e[et] if (p,eh) in mTEPES.peh and mTEPES.pRatedMaxCharge[eh]) for p,sc,n,et in mTEPES.psnet], index=mTEPES.psnet)
|
|
446
470
|
OutputToFile.to_frame(name='MW').reset_index().pivot_table(index=['level_0','level_1','level_2'], columns='level_3', values='MW').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_TechnologyOperatingReserveDownESS_{CaseName}.csv', sep=',')
|
|
447
471
|
|
|
472
|
+
if mTEPES.pIndRampReserves == 1 and sum(mTEPES.pRampReserveUp[:,:,:,:]) and mTEPES.nr:
|
|
473
|
+
OutputToFile = pd.Series(data=[OptModel.vRampReserveUp[p,sc,n,nr]() for p,sc,n,nr in mTEPES.psnnr], index=mTEPES.psnnr)
|
|
474
|
+
OutputToFile = OutputToFile.fillna(0.0)
|
|
475
|
+
OutputToFile *= 1e3
|
|
476
|
+
if pIndTechnologyOutput == 0 or pIndTechnologyOutput == 2:
|
|
477
|
+
OutputToFile.to_frame(name='MW').reset_index().pivot_table(index=['level_0','level_1','level_2'], columns='level_3', values='MW').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_GenerationRampReserveUp_{CaseName}.csv', sep=',')
|
|
478
|
+
if pIndTechnologyOutput == 1 or pIndTechnologyOutput == 2:
|
|
479
|
+
OutputToFile = pd.Series(data=[sum(OutputToFile[p,sc,n,nr] for nr in n2n[nt] if (p,nr) in mTEPES.pnr) for p,sc,n,nt in mTEPES.psnnt], index=mTEPES.psnnt)
|
|
480
|
+
OutputToFile.to_frame(name='MW').reset_index().pivot_table(index=['level_0','level_1','level_2'], columns='level_3', values='MW').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_TechnologyRampReserveUp_{CaseName}.csv', sep=',')
|
|
481
|
+
|
|
482
|
+
if mTEPES.pIndRampReserves == 1 and sum(mTEPES.pRampReserveDw[:,:,:,:]) and mTEPES.nr:
|
|
483
|
+
OutputToFile = pd.Series(data=[OptModel.vRampReserveDw[p,sc,n,nr]() for p,sc,n,nr in mTEPES.psnnr], index=mTEPES.psnnr)
|
|
484
|
+
OutputToFile = OutputToFile.fillna(0.0)
|
|
485
|
+
OutputToFile *= 1e3
|
|
486
|
+
if pIndTechnologyOutput == 0 or pIndTechnologyOutput == 2:
|
|
487
|
+
OutputToFile.to_frame(name='MW').reset_index().pivot_table(index=['level_0','level_1','level_2'], columns='level_3', values='MW').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_GenerationRampReserveDown_{CaseName}.csv', sep=',')
|
|
488
|
+
if pIndTechnologyOutput == 1 or pIndTechnologyOutput == 2:
|
|
489
|
+
OutputToFile = pd.Series(data=[sum(OutputToFile[p,sc,n,nr] for nr in n2n[nt] if (p,nr) in mTEPES.pnr) for p,sc,n,nt in mTEPES.psnnt], index=mTEPES.psnnt)
|
|
490
|
+
OutputToFile.to_frame(name='MW').reset_index().pivot_table(index=['level_0','level_1','level_2'], columns='level_3', values='MW').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_TechnologyRampReserveDown_{CaseName}.csv', sep=',')
|
|
491
|
+
|
|
448
492
|
OutputToFile = pd.Series(data=[OptModel.vTotalOutput[p,sc,n,g]() for p,sc,n,g in mTEPES.psng], index=mTEPES.psng)
|
|
449
493
|
OutputToFile *= 1e3
|
|
450
494
|
OutputToFile.to_frame(name='MW').reset_index().pivot_table(index=['level_0','level_1','level_2'], columns='level_3', values='MW').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_Generation_{CaseName}.csv', sep=',')
|
|
@@ -484,8 +528,8 @@ def GenerationOperationResults(DirName, CaseName, OptModel, mTEPES, pIndTechnolo
|
|
|
484
528
|
(OptModel.vTotalOutput[p,sc,n,re].ub - OptModel.vTotalOutput[p,sc,n,re]())*mTEPES.pLoadLevelDuration[p,sc,n]() for p,sc,n,re in mTEPES.psnre], index=mTEPES.psnre)
|
|
485
529
|
OutputToFile2 = pd.Series(data=[(OptModel.vTotalOutput[p,sc,n,re].ub*OptModel.vGenerationInvest[p,re]() )*mTEPES.pLoadLevelDuration[p,sc,n]() if re in mTEPES.gc else
|
|
486
530
|
(OptModel.vTotalOutput[p,sc,n,re].ub )*mTEPES.pLoadLevelDuration[p,sc,n]() for p,sc,n,re in mTEPES.psnre], index=mTEPES.psnre)
|
|
487
|
-
OutputToFile1 = OutputToFile1.to_frame(name='GWh').reset_index().pivot_table(index=['level_0','level_1','level_3'], values='GWh', aggfunc='sum').rename_axis(['Period', 'Scenario', '
|
|
488
|
-
OutputToFile2 = OutputToFile2.to_frame(name='GWh').reset_index().pivot_table(index=['level_0','level_1','level_3'], values='GWh', aggfunc='sum').rename_axis(['Period', 'Scenario', '
|
|
531
|
+
OutputToFile1 = OutputToFile1.to_frame(name='GWh').reset_index().pivot_table(index=['level_0','level_1','level_3'], values='GWh', aggfunc='sum').rename_axis(['Period', 'Scenario', 'Generator'], axis=0).rename_axis([None], axis=1)
|
|
532
|
+
OutputToFile2 = OutputToFile2.to_frame(name='GWh').reset_index().pivot_table(index=['level_0','level_1','level_3'], values='GWh', aggfunc='sum').rename_axis(['Period', 'Scenario', 'Generator'], axis=0).rename_axis([None], axis=1)
|
|
489
533
|
if pIndTechnologyOutput == 0 or pIndTechnologyOutput == 2:
|
|
490
534
|
OutputToFile = OutputToFile1.div(OutputToFile2)*1e2
|
|
491
535
|
OutputToFile = OutputToFile.fillna(0.0)
|
|
@@ -534,10 +578,10 @@ def GenerationOperationResults(DirName, CaseName, OptModel, mTEPES, pIndTechnolo
|
|
|
534
578
|
if pIndAreaOutput == 1:
|
|
535
579
|
for ar in mTEPES.ar:
|
|
536
580
|
if sum(1 for g in g2a[ar]):
|
|
537
|
-
sPSNGT = [(p,sc,n,gt) for p,sc,n,gt in mTEPES.psngt if sum(1 for g in g2a[ar]
|
|
581
|
+
sPSNGT = [(p,sc,n,gt) for p,sc,n,gt in mTEPES.psngt if sum(1 for g in g2t[gt] if g in g2a[ar] and (p,g) in mTEPES.pg)]
|
|
538
582
|
if sPSNGT:
|
|
539
583
|
if sum(OutputToFile[:,:,:,:]):
|
|
540
|
-
OutputResults = pd.Series(data=[sum(OutputToFile[p,sc,n,g] for g in g2a[ar]
|
|
584
|
+
OutputResults = pd.Series(data=[sum(OutputToFile[p,sc,n,g] for g in g2t[gt] if g in g2a[ar] and (p,g) in mTEPES.pg) for p,sc,n,gt in sPSNGT], index=pd.Index(sPSNGT))
|
|
541
585
|
OutputResults.to_frame(name='MtCO2').reset_index().pivot_table(index=['level_0','level_1','level_2'], columns='level_3', values='MtCO2', aggfunc='sum').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_TechnologyEmission_{CaseName}_{ar}.csv', sep=',')
|
|
542
586
|
|
|
543
587
|
if sum(OutputToFile[:,:,:,:]):
|
|
@@ -573,9 +617,9 @@ def GenerationOperationResults(DirName, CaseName, OptModel, mTEPES, pIndTechnolo
|
|
|
573
617
|
if pIndAreaOutput == 1:
|
|
574
618
|
for ar in mTEPES.ar:
|
|
575
619
|
if sum(1 for g in g2a[ar]):
|
|
576
|
-
sPSNGT = [(p,sc,n,gt) for p,sc,n,gt in mTEPES.psngt if sum(1 for g in g2a[ar]
|
|
620
|
+
sPSNGT = [(p,sc,n,gt) for p,sc,n,gt in mTEPES.psngt if sum(1 for g in g2t[gt] if g in g2a[ar] and (p,g) in mTEPES.pg)]
|
|
577
621
|
if sPSNGT:
|
|
578
|
-
OutputToFile = pd.Series(data=[sum(OptModel.vTotalOutput[p,sc,n,g]()*mTEPES.pLoadLevelDuration[p,sc,n]() for g in g2a[ar]
|
|
622
|
+
OutputToFile = pd.Series(data=[sum(OptModel.vTotalOutput[p,sc,n,g]()*mTEPES.pLoadLevelDuration[p,sc,n]() for g in g2t[gt] if g in g2a[ar] and (p,g) in mTEPES.pg) for p,sc,n,gt in sPSNGT], index=pd.Index(sPSNGT))
|
|
579
623
|
OutputToFile.to_frame(name='GWh').reset_index().pivot_table(index=['level_0','level_1','level_2'], columns='level_3', values='GWh', aggfunc='sum').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_TechnologyGenerationEnergy_{CaseName}_{ar}.csv', sep=',')
|
|
580
624
|
|
|
581
625
|
if pIndPlotOutput == 1:
|
|
@@ -588,6 +632,7 @@ def GenerationOperationResults(DirName, CaseName, OptModel, mTEPES, pIndTechnolo
|
|
|
588
632
|
print('Writing generation operation results ... ', round(WritingResultsTime), 's')
|
|
589
633
|
|
|
590
634
|
|
|
635
|
+
# @profile
|
|
591
636
|
def GenerationOperationHeatResults(DirName, CaseName, OptModel, mTEPES, pIndTechnologyOutput, pIndAreaOutput, pIndPlotOutput):
|
|
592
637
|
#%% outputting the generation operation
|
|
593
638
|
_path = os.path.join(DirName, CaseName)
|
|
@@ -650,10 +695,10 @@ def GenerationOperationHeatResults(DirName, CaseName, OptModel, mTEPES, pIndTech
|
|
|
650
695
|
if sum(1 for ar in mTEPES.ar if sum(1 for chp in g2a[ar])) > 1:
|
|
651
696
|
if pIndAreaOutput == 1:
|
|
652
697
|
for ar in mTEPES.ar:
|
|
653
|
-
if sum(1 for chp in
|
|
654
|
-
sPSNGT = [(p,sc,n,gt) for p,sc,n,gt in mTEPES.psngt if sum(1 for chp in g2a[ar]
|
|
698
|
+
if sum(1 for chp in g2t[gt] if chp in g2a[ar]):
|
|
699
|
+
sPSNGT = [(p,sc,n,gt) for p,sc,n,gt in mTEPES.psngt if sum(1 for chp in g2t[gt] if chp in g2a[ar] and (p,chp) in mTEPES.pchp)]
|
|
655
700
|
if sPSNGT:
|
|
656
|
-
OutputToFile = pd.Series(data=[sum(OptModel.vTotalOutputHeat[p,sc,n,chp]()*mTEPES.pLoadLevelDuration[p,sc,n]() for chp in g2a[ar] if (p,chp) in mTEPES.pchp
|
|
701
|
+
OutputToFile = pd.Series(data=[sum(OptModel.vTotalOutputHeat[p,sc,n,chp]()*mTEPES.pLoadLevelDuration[p,sc,n]() for chp in g2a[ar] if chp in g2t[gt] and (p,chp) in mTEPES.pchp) for p,sc,n,gt in sPSNGT], index=pd.Index(sPSNGT))
|
|
657
702
|
OutputToFile.to_frame(name='GWh').reset_index().pivot_table(index=['level_0','level_1','level_2'], columns='level_3', values='GWh', aggfunc='sum').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_TechnologyGenerationEnergyHeat_{CaseName}_{ar}.csv', sep=',')
|
|
658
703
|
|
|
659
704
|
if pIndPlotOutput == 1:
|
|
@@ -666,6 +711,7 @@ def GenerationOperationHeatResults(DirName, CaseName, OptModel, mTEPES, pIndTech
|
|
|
666
711
|
print('Writing heat operation results ... ', round(WritingResultsTime), 's')
|
|
667
712
|
|
|
668
713
|
|
|
714
|
+
# @profile
|
|
669
715
|
def ESSOperationResults(DirName, CaseName, OptModel, mTEPES, pIndTechnologyOutput, pIndAreaOutput, pIndPlotOutput):
|
|
670
716
|
# %% outputting the ESS operation
|
|
671
717
|
_path = os.path.join(DirName, CaseName)
|
|
@@ -786,8 +832,8 @@ def ESSOperationResults(DirName, CaseName, OptModel, mTEPES, pIndTechnologyOutpu
|
|
|
786
832
|
(OptModel.vTotalOutput[p,sc,n,es].ub - OptModel.vTotalOutput[p,sc,n,es]())*mTEPES.pLoadLevelDuration[p,sc,n]() for p,sc,n,es in mTEPES.psnes], index=mTEPES.psnes)
|
|
787
833
|
OutputToFile2 = pd.Series(data=[(OptModel.vTotalOutput[p,sc,n,es].ub*OptModel.vGenerationInvest[p,es]() )*mTEPES.pLoadLevelDuration[p,sc,n]() if es in mTEPES.ec else
|
|
788
834
|
(OptModel.vTotalOutput[p,sc,n,es].ub )*mTEPES.pLoadLevelDuration[p,sc,n]() for p,sc,n,es in mTEPES.psnes], index=mTEPES.psnes)
|
|
789
|
-
OutputToFile1 = OutputToFile1.to_frame(name='GWh').reset_index().pivot_table(index=['level_0','level_1','level_3'], values='GWh', aggfunc='sum').rename_axis(['Period', 'Scenario', '
|
|
790
|
-
OutputToFile2 = OutputToFile2.to_frame(name='GWh').reset_index().pivot_table(index=['level_0','level_1','level_3'], values='GWh', aggfunc='sum').rename_axis(['Period', 'Scenario', '
|
|
835
|
+
OutputToFile1 = OutputToFile1.to_frame(name='GWh').reset_index().pivot_table(index=['level_0','level_1','level_3'], values='GWh', aggfunc='sum').rename_axis(['Period', 'Scenario', 'Generator'], axis=0).rename_axis([None], axis=1)
|
|
836
|
+
OutputToFile2 = OutputToFile2.to_frame(name='GWh').reset_index().pivot_table(index=['level_0','level_1','level_3'], values='GWh', aggfunc='sum').rename_axis(['Period', 'Scenario', 'Generator'], axis=0).rename_axis([None], axis=1)
|
|
791
837
|
|
|
792
838
|
if pIndTechnologyOutput == 0 or pIndTechnologyOutput == 2:
|
|
793
839
|
OutputToFile = OutputToFile1.div(OutputToFile2)*1e2
|
|
@@ -807,6 +853,7 @@ def ESSOperationResults(DirName, CaseName, OptModel, mTEPES, pIndTechnologyOutpu
|
|
|
807
853
|
print('Writing ESS operation results ... ', round(WritingResultsTime), 's')
|
|
808
854
|
|
|
809
855
|
|
|
856
|
+
# @profile
|
|
810
857
|
def ReservoirOperationResults(DirName, CaseName, OptModel, mTEPES, pIndTechnologyOutput, pIndPlotOutput):
|
|
811
858
|
# %% outputting the reservoir operation
|
|
812
859
|
_path = os.path.join(DirName, CaseName)
|
|
@@ -814,9 +861,9 @@ def ReservoirOperationResults(DirName, CaseName, OptModel, mTEPES, pIndTechnolog
|
|
|
814
861
|
|
|
815
862
|
# technology to hydro units (o2h)
|
|
816
863
|
o2h = defaultdict(list)
|
|
817
|
-
for ht,h
|
|
818
|
-
if (ht,h
|
|
819
|
-
o2h[ht].append(h
|
|
864
|
+
for ht,h in mTEPES.ht*mTEPES.h:
|
|
865
|
+
if (ht,h) in mTEPES.t2g:
|
|
866
|
+
o2h[ht].append(h)
|
|
820
867
|
|
|
821
868
|
# tolerance to avoid division by 0
|
|
822
869
|
pEpsilon = 1e-6
|
|
@@ -848,7 +895,7 @@ def ReservoirOperationResults(DirName, CaseName, OptModel, mTEPES, pIndTechnolog
|
|
|
848
895
|
if len(OutputToFile) and pIndPlotOutput == 1:
|
|
849
896
|
WaterValue = OutputToFile.to_frame(name='WaterValue').reset_index().pivot_table(index=['level_0','level_1','level_3','level_4'], values='WaterValue').rename_axis(['level_0','level_1','level_2','level_3'], axis=0).loc[:,:,:,:]
|
|
850
897
|
for p,sc in mTEPES.ps:
|
|
851
|
-
chart = LinePlots(p, sc, WaterValue, '
|
|
898
|
+
chart = LinePlots(p, sc, WaterValue, 'Generator', 'LoadLevel', 'EUR/dam3', 'average')
|
|
852
899
|
chart.save(f'{_path}/oT_Plot_MarginalWaterValue_{CaseName}_{p}_{sc}.html', embed_options={'renderer': 'svg'})
|
|
853
900
|
|
|
854
901
|
WritingResultsTime = time.time() - StartTime
|
|
@@ -856,6 +903,7 @@ def ReservoirOperationResults(DirName, CaseName, OptModel, mTEPES, pIndTechnolog
|
|
|
856
903
|
print('Writing reservoir operation results ... ', round(WritingResultsTime), 's')
|
|
857
904
|
|
|
858
905
|
|
|
906
|
+
# @profile
|
|
859
907
|
def NetworkH2OperationResults(DirName, CaseName, OptModel, mTEPES):
|
|
860
908
|
# %% outputting the hydrogen pipeline network operation
|
|
861
909
|
_path = os.path.join(DirName, CaseName)
|
|
@@ -881,8 +929,14 @@ def NetworkH2OperationResults(DirName, CaseName, OptModel, mTEPES):
|
|
|
881
929
|
if (gt,el) in mTEPES.t2g:
|
|
882
930
|
e2t[gt].append(el)
|
|
883
931
|
|
|
884
|
-
|
|
885
|
-
|
|
932
|
+
# nodes to area (d2a)
|
|
933
|
+
d2a = defaultdict(list)
|
|
934
|
+
for ar,nd in mTEPES.ar*mTEPES.nd:
|
|
935
|
+
if (nd,ar) in mTEPES.ndar:
|
|
936
|
+
d2a[ar].append(nd)
|
|
937
|
+
|
|
938
|
+
sPSNARND = [(p,sc,n,ar,nd) for p,sc,n,ar,nd in mTEPES.psn*mTEPES.ar*mTEPES.nd if nd in d2a[ar] and sum(1 for el in e2n[nd]) + sum(1 for nf,cc in lout[nd]) + sum(1 for ni,cc in lin[nd])]
|
|
939
|
+
sPSNARNDGT = [(p,sc,n,ar,nd,gt) for p,sc,n,ar,nd,gt in sPSNARND*mTEPES.gt if nd in d2a[ar] and sum(1 for el in e2t[gt] if (p,el) in mTEPES.pg) ]
|
|
886
940
|
|
|
887
941
|
OutputResults2 = pd.Series(data=[ sum(OptModel.vESSTotalCharge[p,sc,n,el ]()*mTEPES.pLoadLevelDuration[p,sc,n]()/mTEPES.pProductionFunctionH2[el] for el in mTEPES.el if el in e2n[nd] and el in e2t[gt]) for p,sc,n,ar,nd,gt in sPSNARNDGT], index=pd.Index(sPSNARNDGT)).to_frame(name='Generation' ).reset_index().pivot_table(index=['level_0','level_1','level_2','level_3','level_4'], columns='level_5', values='Generation', aggfunc='sum')
|
|
888
942
|
OutputResults3 = pd.Series(data=[ OptModel.vH2NS [p,sc,n,nd ]() for p,sc,n,ar,nd in sPSNARND ], index=pd.Index(sPSNARND )).to_frame(name='HydrogenNotServed')
|
|
@@ -1044,6 +1098,7 @@ def NetworkH2OperationResults(DirName, CaseName, OptModel, mTEPES):
|
|
|
1044
1098
|
print('Writing hydrogen operation results ... ', round(WritingResultsTime), 's')
|
|
1045
1099
|
|
|
1046
1100
|
|
|
1101
|
+
# @profile
|
|
1047
1102
|
def NetworkHeatOperationResults(DirName, CaseName, OptModel, mTEPES):
|
|
1048
1103
|
# %% outputting the heat pipe network operation
|
|
1049
1104
|
_path = os.path.join(DirName, CaseName)
|
|
@@ -1081,8 +1136,14 @@ def NetworkHeatOperationResults(DirName, CaseName, OptModel, mTEPES):
|
|
|
1081
1136
|
if (gt,hp) in mTEPES.t2g:
|
|
1082
1137
|
h2t[gt].append(hp)
|
|
1083
1138
|
|
|
1084
|
-
|
|
1085
|
-
|
|
1139
|
+
# nodes to area (d2a)
|
|
1140
|
+
d2a = defaultdict(list)
|
|
1141
|
+
for ar,nd in mTEPES.ar*mTEPES.nd:
|
|
1142
|
+
if (nd,ar) in mTEPES.ndar:
|
|
1143
|
+
d2a[ar].append(nd)
|
|
1144
|
+
|
|
1145
|
+
sPSNARND = [(p,sc,n,ar,nd) for p,sc,n,ar,nd in mTEPES.psn*mTEPES.ar*mTEPES.nd if nd in d2a[ar] and sum(1 for ch in c2n[nd]) + sum(1 for hp in h2n[nd]) + sum(1 for nf,cc in lout[nd]) + sum(1 for ni,cc in lin[nd])]
|
|
1146
|
+
sPSNARNDGT = [(p,sc,n,ar,nd,gt) for p,sc,n,ar,nd,gt in sPSNARND*mTEPES.gt if nd in d2a[ar] and sum(1 for ch in c2t[gt] if (p,ch) in mTEPES.pg) + sum(1 for hp in h2t[gt] if (p,hp) in mTEPES.pg) ]
|
|
1086
1147
|
|
|
1087
1148
|
OutputResults2 = pd.Series(data=[ sum(OptModel.vESSTotalCharge [p,sc,n,hp ]()*mTEPES.pLoadLevelDuration[p,sc,n]()/mTEPES.pProductionFunctionHeat[hp] for hp in mTEPES.hp if hp in h2n[nd] and hp in h2t[gt]) for p,sc,n,ar,nd,gt in sPSNARNDGT], index=pd.Index(sPSNARNDGT)).to_frame(name='GenerationHeatPumps').reset_index().pivot_table(index=['level_0','level_1','level_2','level_3','level_4'], columns='level_5', values='GenerationHeatPumps', aggfunc='sum')
|
|
1088
1149
|
OutputResults3 = pd.Series(data=[ sum(OptModel.vTotalOutput [p,sc,n,ch ]()*mTEPES.pLoadLevelDuration[p,sc,n]()/mTEPES.pPower2HeatRatio [ch] for ch in mTEPES.ch if ch in c2n[nd] and ch in c2t[gt] and ch not in mTEPES.bo) for p,sc,n,ar,nd,gt in sPSNARNDGT], index=pd.Index(sPSNARNDGT)).to_frame(name='GenerationCHPs' ).reset_index().pivot_table(index=['level_0','level_1','level_2','level_3','level_4'], columns='level_5', values='GenerationCHPs' , aggfunc='sum')
|
|
@@ -1272,6 +1333,7 @@ def NetworkHeatOperationResults(DirName, CaseName, OptModel, mTEPES):
|
|
|
1272
1333
|
print('Writing heat netwk operation results ... ', round(WritingResultsTime), 's')
|
|
1273
1334
|
|
|
1274
1335
|
|
|
1336
|
+
# @profile
|
|
1275
1337
|
def OperationSummaryResults(DirName, CaseName, OptModel, mTEPES):
|
|
1276
1338
|
#%% outputting the generation operation
|
|
1277
1339
|
_path = os.path.join(DirName, CaseName)
|
|
@@ -1365,71 +1427,69 @@ def OperationSummaryResults(DirName, CaseName, OptModel, mTEPES):
|
|
|
1365
1427
|
|
|
1366
1428
|
# LCOE per technology
|
|
1367
1429
|
if mTEPES.gc:
|
|
1368
|
-
GenTechInvestCost = pd.Series(data=[sum(mTEPES.pDiscountedWeight[p] * mTEPES.pGenInvestCost[gc]
|
|
1369
|
-
GenTechInjection = pd.Series(data=[sum(
|
|
1430
|
+
GenTechInvestCost = pd.Series(data=[sum(mTEPES.pDiscountedWeight[p] * mTEPES.pGenInvestCost[gc] * OptModel.vGenerationInvest[p,gc]() for p, gc in mTEPES.pgc if gc in g2t[gt]) for gt in mTEPES.gt], index=mTEPES.gt)
|
|
1431
|
+
GenTechInjection = pd.Series(data=[sum(mTEPES.pDiscountedWeight[p] * mTEPES.pLoadLevelDuration[p,sc,n]() * OptModel.vTotalOutput[p,sc,n,gc]() for p,sc,n,gc in mTEPES.psngc if gc in g2t[gt]) for gt in mTEPES.gt], index=mTEPES.gt)
|
|
1370
1432
|
GenTechInvestCost *= 1e3
|
|
1371
|
-
LCOE = GenTechInvestCost.div(GenTechInjection).to_frame(name='EUR/MWh')
|
|
1372
|
-
LCOE.rename_axis(['Technology'], axis=0).to_csv(f'{_path}/oT_Result_TechnologyLCOE_{CaseName}.csv', index=True, sep=',')
|
|
1433
|
+
LCOE = GenTechInvestCost.div(GenTechInjection).to_frame(name='EUR/MWh').rename_axis(['Technology'], axis=0).to_csv(f'{_path}/oT_Result_TechnologyLCOE_{CaseName}.csv', index=True, sep=',')
|
|
1373
1434
|
|
|
1374
|
-
#
|
|
1435
|
+
# LCOH per technology
|
|
1375
1436
|
if mTEPES.gb:
|
|
1376
|
-
GenTechInvestCost = pd.Series(data=[sum(mTEPES.pDiscountedWeight[p] * mTEPES.pGenInvestCost[gb]
|
|
1377
|
-
GenTechInjection = pd.Series(data=[sum(
|
|
1437
|
+
GenTechInvestCost = pd.Series(data=[sum(mTEPES.pDiscountedWeight[p] * mTEPES.pGenInvestCost[gb] * OptModel.vGenerationInvest[p,gb]() for p, gb in mTEPES.pgb if gb in g2t[gt]) for gt in mTEPES.gt], index=mTEPES.gt)
|
|
1438
|
+
GenTechInjection = pd.Series(data=[sum(mTEPES.pDiscountedWeight[p] * mTEPES.pLoadLevelDuration[p,sc,n]() * OptModel.vTotalOutputHeat[p,sc,n,gb]() for p,sc,n,gb in mTEPES.psngb if gb in g2t[gt]) for gt in mTEPES.gt], index=mTEPES.gt)
|
|
1378
1439
|
GenTechInvestCost *= 1e3
|
|
1379
|
-
LCOH = GenTechInvestCost.div(GenTechInjection).to_frame(name='EUR/MWh')
|
|
1380
|
-
LCOH.rename_axis(['Technology'], axis=0).to_csv(f'{_path}/oT_Result_TechnologyLCOH_{CaseName}.csv', index=True, sep=',')
|
|
1440
|
+
LCOH = GenTechInvestCost.div(GenTechInjection).to_frame(name='EUR/MWh').rename_axis(['Technology'], axis=0).to_csv(f'{_path}/oT_Result_TechnologyLCOH_{CaseName}.csv', index=True, sep=',')
|
|
1381
1441
|
|
|
1382
1442
|
WritingResultsTime = time.time() - StartTime
|
|
1383
1443
|
StartTime = time.time()
|
|
1384
1444
|
print('Writing KPI summary results ... ', round(WritingResultsTime), 's')
|
|
1385
|
-
|
|
1386
|
-
StartTime = time.time()
|
|
1387
|
-
t2g = pd.DataFrame(mTEPES.t2g).set_index(1)
|
|
1388
|
-
n2g = pd.DataFrame(mTEPES.n2g).set_index(1)
|
|
1389
|
-
z2g = pd.DataFrame(mTEPES.z2g).set_index(1)
|
|
1390
|
-
a2g = pd.DataFrame(mTEPES.a2g).set_index(1)
|
|
1391
|
-
r2g = pd.DataFrame(mTEPES.r2g).set_index(1)
|
|
1392
|
-
OutputToFile01 = pd.Series(data=[t2g[0][g] for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='Technology' )
|
|
1393
|
-
OutputToFile02 = pd.Series(data=[n2g[0][g] for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='Node' )
|
|
1394
|
-
OutputToFile03 = pd.Series(data=[z2g[0][g] for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='Zone' )
|
|
1395
|
-
OutputToFile04 = pd.Series(data=[a2g[0][g] for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='Area' )
|
|
1396
|
-
OutputToFile05 = pd.Series(data=[r2g[0][g] for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='Region' )
|
|
1397
|
-
OutputToFile06 = pd.Series(data=[mTEPES.pLoadLevelDuration[p,sc,n ]() for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='LoadLevelDuration [h]' )
|
|
1398
|
-
OutputToFile07 = pd.Series(data=[OptModel.vCommitment [p,sc,n,g]() if g in mTEPES.nr else 0 for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='Commitment {0,1}' )
|
|
1399
|
-
OutputToFile08 = pd.Series(data=[OptModel.vStartUp [p,sc,n,g]() if g in mTEPES.nr else 0 for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='StartUp {0,1}' )
|
|
1400
|
-
OutputToFile09 = pd.Series(data=[OptModel.vShutDown [p,sc,n,g]() if g in mTEPES.nr else 0 for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='ShutDown {0,1}' )
|
|
1401
|
-
OutputToFile10 = pd.Series(data=[OptModel.vTotalOutput [p,sc,n,g].ub for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='MaxPower [MW]' )
|
|
1402
|
-
OutputToFile11 = pd.Series(data=[OptModel.vTotalOutput [p,sc,n,g].lb for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='MinPower [MW]' )
|
|
1403
|
-
OutputToFile12 = pd.Series(data=[OptModel.vTotalOutput [p,sc,n,g]()*mTEPES.pLoadLevelDuration[p,sc,n]() for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='EnergyProduction [GWh]' )
|
|
1404
|
-
OutputToFile13 = pd.Series(data=[OptModel.vESSTotalCharge [p,sc,n,g]()*mTEPES.pLoadLevelDuration[p,sc,n]() if g in mTEPES.es else 0.0 for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='EnergyConsumption [GWh]')
|
|
1405
|
-
OutputToFile14 = pd.Series(data=[OptModel.vEnergyOutflows [p,sc,n,g]()*mTEPES.pLoadLevelDuration[p,sc,n]() if g in mTEPES.es else 0.0 for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='Outflows [GWh]' )
|
|
1406
|
-
OutputToFile15 = pd.Series(data=[OptModel.vESSInventory [p,sc,n,g]() if g in mTEPES.es else 0.0 for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='Inventory [GWh]' )
|
|
1407
|
-
OutputToFile16 = pd.Series(data=[OptModel.vESSSpillage [p,sc,n,g]() if g in mTEPES.es else 0.0 for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='Spillage [GWh]' )
|
|
1408
|
-
OutputToFile17 = pd.Series(data=[(OptModel.vTotalOutput [p,sc,n,g].ub-OptModel.vTotalOutput[p,sc,n,g]())*mTEPES.pLoadLevelDuration[p,sc,n]() if g in mTEPES.re else 0.0 for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='Curtailment [GWh]' )
|
|
1409
|
-
OutputToFile18 = pd.Series(data=[OptModel.vReserveUp [p,sc,n,g]() if g in mTEPES.nr else 0.0 for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='ReserveUpGen [MW]' )
|
|
1410
|
-
OutputToFile19 = pd.Series(data=[OptModel.vReserveDown [p,sc,n,g]() if g in mTEPES.nr else 0.0 for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='ReserveDownGen [MW]' )
|
|
1411
|
-
OutputToFile20 = pd.Series(data=[OptModel.vESSReserveUp [p,sc,n,g]() if g in mTEPES.es else 0.0 for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='ReserveUpCons [MW]' )
|
|
1412
|
-
OutputToFile21 = pd.Series(data=[OptModel.vESSReserveDown [p,sc,n,g]() if g in mTEPES.es else 0.0 for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='ReserveDownCons [MW]' )
|
|
1413
|
-
OutputToFile22 = pd.Series(data=[OptModel.vTotalOutput [p,sc,n,g]()*mTEPES.pLoadLevelDuration[p,sc,n]()*mTEPES.pEmissionRate[g] if g not in mTEPES.bo
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
OutputToFile10 *= 1e3
|
|
1417
|
-
OutputToFile11 *= 1e3
|
|
1418
|
-
OutputToFile18 *= 1e3
|
|
1419
|
-
OutputToFile19 *= 1e3
|
|
1420
|
-
OutputToFile20 *= 1e3
|
|
1421
|
-
OutputToFile21 *= 1e3
|
|
1422
|
-
OutputToFile22 *= 1e-3
|
|
1423
|
-
|
|
1424
|
-
OutputResults = pd.concat([OutputToFile01, OutputToFile02, OutputToFile03, OutputToFile04, OutputToFile05, OutputToFile06, OutputToFile07, OutputToFile08, OutputToFile09, OutputToFile10,
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
# OutputResults.rename_axis(['Period', 'Scenario', 'LoadLevel', 'Generator'], axis=0).to_csv (f'{_path}/oT_Result_SummaryGeneration_{CaseName}.csv', sep=',')
|
|
1428
|
-
# OutputResults.rename_axis(['Period', 'Scenario', 'LoadLevel', 'Generator'], axis=0).to_parquet(f'{_path}/oT_Result_SummaryGeneration_{CaseName}.parquet', engine='pyarrow')
|
|
1429
|
-
|
|
1430
|
-
WritingResultsTime = time.time() - StartTime
|
|
1431
|
-
StartTime = time.time()
|
|
1432
|
-
print('Writing generation summary results ... ', round(WritingResultsTime), 's')
|
|
1445
|
+
#
|
|
1446
|
+
# StartTime = time.time()
|
|
1447
|
+
# t2g = pd.DataFrame(mTEPES.t2g).set_index(1)
|
|
1448
|
+
# n2g = pd.DataFrame(mTEPES.n2g).set_index(1)
|
|
1449
|
+
# z2g = pd.DataFrame(mTEPES.z2g).set_index(1)
|
|
1450
|
+
# a2g = pd.DataFrame(mTEPES.a2g).set_index(1)
|
|
1451
|
+
# r2g = pd.DataFrame(mTEPES.r2g).set_index(1)
|
|
1452
|
+
# OutputToFile01 = pd.Series(data=[t2g[0][g] for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='Technology' )
|
|
1453
|
+
# OutputToFile02 = pd.Series(data=[n2g[0][g] for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='Node' )
|
|
1454
|
+
# OutputToFile03 = pd.Series(data=[z2g[0][g] for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='Zone' )
|
|
1455
|
+
# OutputToFile04 = pd.Series(data=[a2g[0][g] for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='Area' )
|
|
1456
|
+
# OutputToFile05 = pd.Series(data=[r2g[0][g] for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='Region' )
|
|
1457
|
+
# OutputToFile06 = pd.Series(data=[mTEPES.pLoadLevelDuration[p,sc,n ]() for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='LoadLevelDuration [h]' )
|
|
1458
|
+
# OutputToFile07 = pd.Series(data=[OptModel.vCommitment [p,sc,n,g]() if g in mTEPES.nr else 0 for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='Commitment {0,1}' )
|
|
1459
|
+
# OutputToFile08 = pd.Series(data=[OptModel.vStartUp [p,sc,n,g]() if g in mTEPES.nr else 0 for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='StartUp {0,1}' )
|
|
1460
|
+
# OutputToFile09 = pd.Series(data=[OptModel.vShutDown [p,sc,n,g]() if g in mTEPES.nr else 0 for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='ShutDown {0,1}' )
|
|
1461
|
+
# OutputToFile10 = pd.Series(data=[OptModel.vTotalOutput [p,sc,n,g].ub for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='MaxPower [MW]' )
|
|
1462
|
+
# OutputToFile11 = pd.Series(data=[OptModel.vTotalOutput [p,sc,n,g].lb for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='MinPower [MW]' )
|
|
1463
|
+
# OutputToFile12 = pd.Series(data=[OptModel.vTotalOutput [p,sc,n,g]()*mTEPES.pLoadLevelDuration[p,sc,n]() for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='EnergyProduction [GWh]' )
|
|
1464
|
+
# OutputToFile13 = pd.Series(data=[OptModel.vESSTotalCharge [p,sc,n,g]()*mTEPES.pLoadLevelDuration[p,sc,n]() if g in mTEPES.es else 0.0 for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='EnergyConsumption [GWh]')
|
|
1465
|
+
# OutputToFile14 = pd.Series(data=[OptModel.vEnergyOutflows [p,sc,n,g]()*mTEPES.pLoadLevelDuration[p,sc,n]() if g in mTEPES.es else 0.0 for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='Outflows [GWh]' )
|
|
1466
|
+
# OutputToFile15 = pd.Series(data=[OptModel.vESSInventory [p,sc,n,g]() if g in mTEPES.es else 0.0 for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='Inventory [GWh]' )
|
|
1467
|
+
# OutputToFile16 = pd.Series(data=[OptModel.vESSSpillage [p,sc,n,g]() if g in mTEPES.es else 0.0 for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='Spillage [GWh]' )
|
|
1468
|
+
# OutputToFile17 = pd.Series(data=[(OptModel.vTotalOutput [p,sc,n,g].ub-OptModel.vTotalOutput[p,sc,n,g]())*mTEPES.pLoadLevelDuration[p,sc,n]() if g in mTEPES.re else 0.0 for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='Curtailment [GWh]' )
|
|
1469
|
+
# OutputToFile18 = pd.Series(data=[OptModel.vReserveUp [p,sc,n,g]() if g in mTEPES.nr else 0.0 for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='ReserveUpGen [MW]' )
|
|
1470
|
+
# OutputToFile19 = pd.Series(data=[OptModel.vReserveDown [p,sc,n,g]() if g in mTEPES.nr else 0.0 for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='ReserveDownGen [MW]' )
|
|
1471
|
+
# OutputToFile20 = pd.Series(data=[OptModel.vESSReserveUp [p,sc,n,g]() if g in mTEPES.es else 0.0 for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='ReserveUpCons [MW]' )
|
|
1472
|
+
# OutputToFile21 = pd.Series(data=[OptModel.vESSReserveDown [p,sc,n,g]() if g in mTEPES.es else 0.0 for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='ReserveDownCons [MW]' )
|
|
1473
|
+
# OutputToFile22 = pd.Series(data=[OptModel.vTotalOutput [p,sc,n,g]()*mTEPES.pLoadLevelDuration[p,sc,n]()*mTEPES.pEmissionRate[g] if g not in mTEPES.bo
|
|
1474
|
+
# else OptModel.vTotalOutputHeat [p,sc,n,g]()*mTEPES.pLoadLevelDuration[p,sc,n]()*mTEPES.pEmissionRate[g] for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='Emissions [MtCO2]' )
|
|
1475
|
+
#
|
|
1476
|
+
# OutputToFile10 *= 1e3
|
|
1477
|
+
# OutputToFile11 *= 1e3
|
|
1478
|
+
# OutputToFile18 *= 1e3
|
|
1479
|
+
# OutputToFile19 *= 1e3
|
|
1480
|
+
# OutputToFile20 *= 1e3
|
|
1481
|
+
# OutputToFile21 *= 1e3
|
|
1482
|
+
# OutputToFile22 *= 1e-3
|
|
1483
|
+
#
|
|
1484
|
+
# OutputResults = pd.concat([OutputToFile01, OutputToFile02, OutputToFile03, OutputToFile04, OutputToFile05, OutputToFile06, OutputToFile07, OutputToFile08, OutputToFile09, OutputToFile10,
|
|
1485
|
+
# OutputToFile11, OutputToFile12, OutputToFile13, OutputToFile14, OutputToFile15, OutputToFile16, OutputToFile17, OutputToFile18, OutputToFile19, OutputToFile20,
|
|
1486
|
+
# OutputToFile21, OutputToFile22], axis=1)
|
|
1487
|
+
# # OutputResults.rename_axis(['Period', 'Scenario', 'LoadLevel', 'Generator'], axis=0).to_csv (f'{_path}/oT_Result_SummaryGeneration_{CaseName}.csv', sep=',')
|
|
1488
|
+
# # OutputResults.rename_axis(['Period', 'Scenario', 'LoadLevel', 'Generator'], axis=0).to_parquet(f'{_path}/oT_Result_SummaryGeneration_{CaseName}.parquet', engine='pyarrow')
|
|
1489
|
+
#
|
|
1490
|
+
# WritingResultsTime = time.time() - StartTime
|
|
1491
|
+
# StartTime = time.time()
|
|
1492
|
+
# print('Writing generation summary results ... ', round(WritingResultsTime), 's')
|
|
1433
1493
|
|
|
1434
1494
|
ndzn = pd.DataFrame(mTEPES.ndzn).set_index(0)
|
|
1435
1495
|
ndar = pd.DataFrame(mTEPES.ndar).set_index(0)
|
|
@@ -1455,6 +1515,7 @@ def OperationSummaryResults(DirName, CaseName, OptModel, mTEPES):
|
|
|
1455
1515
|
print('Writing elect network summary results ... ', round(WritingResultsTime), 's')
|
|
1456
1516
|
|
|
1457
1517
|
|
|
1518
|
+
# @profile
|
|
1458
1519
|
def FlexibilityResults(DirName, CaseName, OptModel, mTEPES):
|
|
1459
1520
|
# %% outputting the flexibility
|
|
1460
1521
|
_path = os.path.join(DirName, CaseName)
|
|
@@ -1518,6 +1579,7 @@ def FlexibilityResults(DirName, CaseName, OptModel, mTEPES):
|
|
|
1518
1579
|
print('Writing flexibility results ... ', round(WritingResultsTime), 's')
|
|
1519
1580
|
|
|
1520
1581
|
|
|
1582
|
+
# @profile
|
|
1521
1583
|
def NetworkOperationResults(DirName, CaseName, OptModel, mTEPES):
|
|
1522
1584
|
# %% outputting the electric network operation
|
|
1523
1585
|
_path = os.path.join(DirName, CaseName)
|
|
@@ -1590,6 +1652,7 @@ def NetworkOperationResults(DirName, CaseName, OptModel, mTEPES):
|
|
|
1590
1652
|
print('Writing elect netwk operation results ... ', round(WritingResultsTime), 's')
|
|
1591
1653
|
|
|
1592
1654
|
|
|
1655
|
+
# @profile
|
|
1593
1656
|
def MarginalResults(DirName, CaseName, OptModel, mTEPES, pIndPlotOutput):
|
|
1594
1657
|
# %% outputting marginal results
|
|
1595
1658
|
_path = os.path.join(DirName, CaseName)
|
|
@@ -1637,14 +1700,14 @@ def MarginalResults(DirName, CaseName, OptModel, mTEPES, pIndPlotOutput):
|
|
|
1637
1700
|
# tolerance to consider 0 a number
|
|
1638
1701
|
pEpsilon = 1e-6
|
|
1639
1702
|
|
|
1640
|
-
#%% outputting the incremental variable cost of each
|
|
1703
|
+
#%% outputting the incremental variable cost of each Generator (neither ESS nor boilers) with power surplus
|
|
1641
1704
|
sPSNARG = [(p,sc,n,ar,g) for p,sc,n,ar,g in mTEPES.psn*mTEPES.a2g if g not in mTEPES.eh and g not in mTEPES.bo and (p,g) in mTEPES.pg]
|
|
1642
1705
|
OutputToFile = pd.Series(data=[(mTEPES.pLinearVarCost[p,sc,n,g]+mTEPES.pEmissionVarCost[p,sc,n,g]) if OptModel.vTotalOutput[p,sc,n,g].ub - OptModel.vTotalOutput[p,sc,n,g]() > pEpsilon else math.inf for p,sc,n,ar,g in sPSNARG], index=pd.Index(sPSNARG))
|
|
1643
1706
|
OutputToFile *= 1e3
|
|
1644
1707
|
|
|
1645
1708
|
OutputToFile = OutputToFile.to_frame(name='EUR/MWh').reset_index().pivot_table(index=['level_0','level_1','level_2','level_3'], columns='level_4', values='EUR/MWh')
|
|
1646
1709
|
OutputToFile.rename_axis(['Period', 'Scenario', 'LoadLevel', 'Area'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_MarginalIncrementalVariableCost_{CaseName}.csv', sep=',')
|
|
1647
|
-
IncrementalGens = pd.Series('N/A', index=mTEPES.psnar).to_frame(name='
|
|
1710
|
+
IncrementalGens = pd.Series('N/A', index=mTEPES.psnar).to_frame(name='Generator')
|
|
1648
1711
|
for p,sc,n,ar in mTEPES.psnar:
|
|
1649
1712
|
if all(g not in mTEPES.eh and g not in mTEPES.bo and (p, g) in mTEPES.pg and (ar, g) in mTEPES.a2g for g in mTEPES.g):
|
|
1650
1713
|
if len(OutputToFile.loc[(p,sc,n,ar)]) > 1:
|
|
@@ -1716,7 +1779,7 @@ def MarginalResults(DirName, CaseName, OptModel, mTEPES, pIndPlotOutput):
|
|
|
1716
1779
|
if mTEPES.gc:
|
|
1717
1780
|
sPSSTAR = [(p,sc,st,ar) for p,sc,st,ar in mTEPES.ps*mTEPES.st*mTEPES.ar if mTEPES.pReserveMargin[p,ar] and st == mTEPES.Last_st and sum(1 for g in mTEPES.g if g in g2a[ar]) and (p,sc,n) in mTEPES.psn and sum(mTEPES.pRatedMaxPowerElec[g] * mTEPES.pAvailability[g]() / (1.0-mTEPES.pEFOR[g]) for g in mTEPES.g if g in g2a[ar] and g not in (mTEPES.gc or mTEPES.gd)) <= mTEPES.pDemandElecPeak[p,ar] * mTEPES.pReserveMargin[p,ar]]
|
|
1718
1781
|
if sPSSTAR:
|
|
1719
|
-
OutputResults = pd.Series(data=[mTEPES.pDuals[
|
|
1782
|
+
OutputResults = pd.Series(data=[mTEPES.pDuals[''.join([f'eAdequacyReserveMarginElec_{p}_{sc}_{st}{ar}'])] for p,sc,st,ar in sPSSTAR], index=pd.Index(sPSSTAR))
|
|
1720
1783
|
OutputResults.to_frame(name='RM').reset_index().pivot_table(index=['level_0','level_1'], columns='level_3', values='RM').rename_axis(['Period', 'Scenario'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_MarginalReserveMargin_{CaseName}.csv', sep=',')
|
|
1721
1784
|
|
|
1722
1785
|
if mTEPES.pIndHeat == 1:
|
|
@@ -1724,17 +1787,17 @@ def MarginalResults(DirName, CaseName, OptModel, mTEPES, pIndPlotOutput):
|
|
|
1724
1787
|
if mTEPES.gc:
|
|
1725
1788
|
sPSSTAR = [(p,sc,st,ar) for p,sc,st,ar in mTEPES.ps*mTEPES.st*mTEPES.ar if mTEPES.pReserveMarginHeat[p,ar] and st == mTEPES.Last_st and sum(1 for g in mTEPES.g if g in g2a[ar]) and (p,sc,n) in mTEPES.psn and sum(mTEPES.pRatedMaxPowerHeat[g] * mTEPES.pAvailability[g]() / (1.0-mTEPES.pEFOR[g]) for g in mTEPES.g if g in g2a[ar] and g not in (mTEPES.gc or mTEPES.gd)) <= mTEPES.pDemandHeatPeak[p,ar] * mTEPES.pReserveMarginHeat[p,ar]]
|
|
1726
1789
|
if sPSSTAR:
|
|
1727
|
-
OutputResults = pd.Series(data=[mTEPES.pDuals[
|
|
1790
|
+
OutputResults = pd.Series(data=[mTEPES.pDuals[''.join([f'eAdequacyReserveMarginHeat_{p}_{sc}_{st}{ar}'])] for p,sc,st,ar in sPSSTAR], index=pd.Index(sPSSTAR))
|
|
1728
1791
|
OutputResults.to_frame(name='RM').reset_index().pivot_table(index=['level_0','level_1'], columns='level_3', values='RM').rename_axis(['Period', 'Scenario'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_MarginalReserveMarginHeat_{CaseName}.csv', sep=',')
|
|
1729
1792
|
|
|
1730
1793
|
sPSSTAR = [(p,sc,st,ar) for p,sc,st,ar in mTEPES.ps*mTEPES.st*mTEPES.ar if mTEPES.pEmission[p,ar] < math.inf and st == mTEPES.Last_st and (p,sc,n) in mTEPES.psn and sum(mTEPES.pEmissionVarCost[p,sc,na,g] for na,g in mTEPES.na*mTEPES.g if (ar,g) in mTEPES.a2g and (p,g) in mTEPES.pg)]
|
|
1731
1794
|
if sPSSTAR:
|
|
1732
|
-
OutputResults = pd.Series(data=[mTEPES.pDuals[
|
|
1795
|
+
OutputResults = pd.Series(data=[mTEPES.pDuals[''.join([f'eMaxSystemEmission_{p}_{sc}_{st}{ar}'])] for p,sc,st,ar in sPSSTAR], index=pd.Index(sPSSTAR))
|
|
1733
1796
|
OutputResults.to_frame(name='EM').reset_index().pivot_table(index=['level_0','level_1'], columns='level_3', values='EM').rename_axis(['Period', 'Scenario'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_MarginalEmission_{CaseName}.csv', sep=',')
|
|
1734
1797
|
|
|
1735
1798
|
sPSSTAR = [(p,sc,st,ar) for p,sc,st,ar in mTEPES.ps*mTEPES.st*mTEPES.ar if mTEPES.pRESEnergy[p,ar] and st == mTEPES.Last_st and (p,sc,n) in mTEPES.psn]
|
|
1736
1799
|
if sPSSTAR:
|
|
1737
|
-
OutputResults = pd.Series(data=[mTEPES.pDuals[
|
|
1800
|
+
OutputResults = pd.Series(data=[mTEPES.pDuals[''.join([f'eMinSystemRESEnergy_{p}_{sc}_{st}{ar}'])] for p,sc,st,ar in sPSSTAR], index=pd.Index(sPSSTAR))
|
|
1738
1801
|
OutputResults *= 1e-3*sum(mTEPES.pLoadLevelDuration[p,sc,na]() for na in mTEPES.na)
|
|
1739
1802
|
OutputResults.to_frame(name='RES').reset_index().pivot_table(index=['level_0','level_1'], columns='level_3', values='RES').rename_axis(['Period', 'Scenario'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_MarginalRESEnergy_{CaseName}.csv', sep=',')
|
|
1740
1803
|
|
|
@@ -1775,7 +1838,7 @@ def MarginalResults(DirName, CaseName, OptModel, mTEPES, pIndPlotOutput):
|
|
|
1775
1838
|
if len(OutputToFile) and pIndPlotOutput == 1:
|
|
1776
1839
|
WaterValue = OutputToFile.to_frame(name='WaterValue').reset_index().pivot_table(index=['level_0','level_1','level_3','level_4'], values='WaterValue').rename_axis(['level_0','level_1','level_2','level_3'], axis=0).loc[:,:,:,:]
|
|
1777
1840
|
for p,sc in mTEPES.ps:
|
|
1778
|
-
chart = LinePlots(p, sc, WaterValue, '
|
|
1841
|
+
chart = LinePlots(p, sc, WaterValue, 'Generator', 'LoadLevel', 'EUR/MWh', 'average')
|
|
1779
1842
|
chart.save(f'{_path}/oT_Plot_MarginalEnergyValue_{CaseName}_{p}_{sc}.html', embed_options={'renderer': 'svg'})
|
|
1780
1843
|
|
|
1781
1844
|
# #%% Reduced cost for NetworkInvestment
|
|
@@ -1798,6 +1861,7 @@ def MarginalResults(DirName, CaseName, OptModel, mTEPES, pIndPlotOutput):
|
|
|
1798
1861
|
print('Writing marginal information results ... ', round(WritingResultsTime), 's')
|
|
1799
1862
|
|
|
1800
1863
|
|
|
1864
|
+
# @profile
|
|
1801
1865
|
def ReliabilityResults(DirName, CaseName, OptModel, mTEPES):
|
|
1802
1866
|
# %% outputting the reliability indexes
|
|
1803
1867
|
_path = os.path.join(DirName, CaseName)
|
|
@@ -1827,7 +1891,7 @@ def ReliabilityResults(DirName, CaseName, OptModel, mTEPES):
|
|
|
1827
1891
|
OutputToFile2 = pd.Series(data=[ mTEPES.pDemandElec [p,sc,n,nd] for p,sc,n,nd in mTEPES.psnnd], index=mTEPES.psnnd)
|
|
1828
1892
|
OutputToFile = OutputToFile2 - OutputToFile1
|
|
1829
1893
|
OutputToFile *= 1e3
|
|
1830
|
-
OutputToFile = OutputToFile.to_frame(name='MW'
|
|
1894
|
+
OutputToFile = OutputToFile.to_frame(name='MW')
|
|
1831
1895
|
OutputToFile.reset_index().pivot_table(index=['level_0','level_1','level_2'], columns='level_3', values='MW', aggfunc='sum').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_NetDemandNetwork_{CaseName}.csv', sep=',')
|
|
1832
1896
|
OutputToFile.reset_index().pivot_table(index=['level_0','level_1','level_2'], values='MW', aggfunc='sum').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_NetDemand_{CaseName}.csv', sep=',')
|
|
1833
1897
|
|
|
@@ -1839,7 +1903,7 @@ def ReliabilityResults(DirName, CaseName, OptModel, mTEPES):
|
|
|
1839
1903
|
OutputToFile2[p,sc] = pDemandElec.loc [(p,sc)].reset_index().pivot_table(index=['level_0'], values=0, aggfunc='sum')[0].max()
|
|
1840
1904
|
ReserveMargin1 = OutputToFile1 - OutputToFile2
|
|
1841
1905
|
ReserveMargin2 = (OutputToFile1 - OutputToFile2)/OutputToFile2
|
|
1842
|
-
ReserveMargin1.to_frame(name='MW' ).rename_axis(['Period', 'Scenario'], axis=0).to_csv(f'{_path}/oT_Result_ReserveMargin_{CaseName}.csv',
|
|
1906
|
+
ReserveMargin1.to_frame(name='MW' ).rename_axis(['Period', 'Scenario'], axis=0).to_csv(f'{_path}/oT_Result_ReserveMargin_{CaseName}.csv', sep=',')
|
|
1843
1907
|
ReserveMargin2.to_frame(name='p.u.').rename_axis(['Period', 'Scenario'], axis=0).to_csv(f'{_path}/oT_Result_ReserveMarginPerUnit_{CaseName}.csv', sep=',')
|
|
1844
1908
|
|
|
1845
1909
|
# Determination of the index: Largest Unit
|
|
@@ -1853,6 +1917,8 @@ def ReliabilityResults(DirName, CaseName, OptModel, mTEPES):
|
|
|
1853
1917
|
WritingResultsTime = time.time() - StartTime
|
|
1854
1918
|
print('Writing reliability indexes ... ', round(WritingResultsTime), 's')
|
|
1855
1919
|
|
|
1920
|
+
|
|
1921
|
+
# @profile
|
|
1856
1922
|
def CostSummaryResults(DirName, CaseName, OptModel, mTEPES):
|
|
1857
1923
|
# %% outputting the system costs and revenues
|
|
1858
1924
|
_path = os.path.join(DirName, CaseName)
|
|
@@ -1883,6 +1949,7 @@ def CostSummaryResults(DirName, CaseName, OptModel, mTEPES):
|
|
|
1883
1949
|
print('Writing cost summary results ... ', round(WritingResultsTime), 's')
|
|
1884
1950
|
|
|
1885
1951
|
|
|
1952
|
+
# @profile
|
|
1886
1953
|
def EconomicResults(DirName, CaseName, OptModel, mTEPES, pIndAreaOutput, pIndPlotOutput):
|
|
1887
1954
|
# %% outputting the system costs and revenues
|
|
1888
1955
|
_path = os.path.join(DirName, CaseName)
|
|
@@ -1950,9 +2017,9 @@ def EconomicResults(DirName, CaseName, OptModel, mTEPES, pIndAreaOutput, pIndPlo
|
|
|
1950
2017
|
if pIndAreaOutput == 1:
|
|
1951
2018
|
for ar in mTEPES.ar:
|
|
1952
2019
|
if sum(1 for g in g2a[ar]):
|
|
1953
|
-
sPSNGT = [(p,sc,n,gt) for p,sc,n,gt in mTEPES.psngt if sum(1 for g in g2a[ar]
|
|
2020
|
+
sPSNGT = [(p,sc,n,gt) for p,sc,n,gt in mTEPES.psngt if sum(1 for g in g2t[gt] if g in g2a[ar] and (p,g) in mTEPES.pg)]
|
|
1954
2021
|
if sPSNGT:
|
|
1955
|
-
OutputToFile = pd.Series(data=[sum(OptModel.vTotalOutput[p,sc,n,g]()*mTEPES.pLoadLevelDuration[p,sc,n]() for g in g2a[ar]
|
|
2022
|
+
OutputToFile = pd.Series(data=[sum(OptModel.vTotalOutput[p,sc,n,g]()*mTEPES.pLoadLevelDuration[p,sc,n]() for g in g2t[gt] if g in g2a[ar] and (p,g) in mTEPES.pg) for p,sc,n,gt in sPSNGT], index=pd.Index(sPSNGT))
|
|
1956
2023
|
OutputToFile.to_frame(name='GWh').reset_index().pivot_table(index=['level_0','level_1','level_2'], columns='level_3', values='GWh', aggfunc='sum').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_TechnologyGenerationEnergy_{CaseName}_{ar}.csv', sep=',')
|
|
1957
2024
|
|
|
1958
2025
|
if pIndPlotOutput == 1:
|
|
@@ -1960,10 +2027,10 @@ def EconomicResults(DirName, CaseName, OptModel, mTEPES, pIndAreaOutput, pIndPlo
|
|
|
1960
2027
|
chart = PiePlots(p, sc, OutputToFile, 'Technology', '%')
|
|
1961
2028
|
chart.save(f'{_path}/oT_Plot_TechnologyGenerationEnergy_{CaseName}_{p}_{sc}_{ar}.html', embed_options={'renderer': 'svg'})
|
|
1962
2029
|
|
|
1963
|
-
sPSNARND = [(p,sc,n,ar,nd) for p,sc,n,ar,nd in mTEPES.
|
|
1964
|
-
sPSNARNDGT = [(p,sc,n,ar,nd,gt) for p,sc,n,ar,nd,gt in sPSNARND*mTEPES.gt
|
|
1965
|
-
sPSNARNDRT = [(p,sc,n,ar,nd,rt) for p,sc,n,ar,nd,rt in sPSNARND*mTEPES.rt
|
|
1966
|
-
sPSNARNDET = [(p,sc,n,ar,nd,et) for p,sc,n,ar,nd,et in sPSNARND*mTEPES.et
|
|
2030
|
+
sPSNARND = [(p,sc,n,ar,nd) for p,sc,n,ar,nd in mTEPES.psn*mTEPES.ar*mTEPES.nd if nd in d2a[ar] and sum(1 for g in g2n[nd]) + sum(1 for nf,cc in lout[nd]) + sum(1 for ni,cc in lin[nd])]
|
|
2031
|
+
sPSNARNDGT = [(p,sc,n,ar,nd,gt) for p,sc,n,ar,nd,gt in sPSNARND*mTEPES.gt if sum(1 for g in g2t[gt] if (p,g ) in mTEPES.pg )]
|
|
2032
|
+
sPSNARNDRT = [(p,sc,n,ar,nd,rt) for p,sc,n,ar,nd,rt in sPSNARND*mTEPES.rt if sum(1 for re in r2r[rt] if (p,re) in mTEPES.pre)]
|
|
2033
|
+
sPSNARNDET = [(p,sc,n,ar,nd,et) for p,sc,n,ar,nd,et in sPSNARND*mTEPES.et if sum(1 for eh in e2e[et] if (p,eh) in mTEPES.peh)]
|
|
1967
2034
|
|
|
1968
2035
|
if sum(1 for nr in mTEPES.nr if nr not in mTEPES.eh):
|
|
1969
2036
|
OutputResults01 = pd.Series(data=[ sum(OptModel.vTotalOutput [p,sc,n,nr ]()*mTEPES.pLoadLevelDuration[p,sc,n]() for nr in g2n[nd] if (p,nr) in mTEPES.pnr and nr in g2t[gt] and nr not in mTEPES.eh) for p,sc,n,ar,nd,gt in sPSNARNDGT], index=pd.Index(sPSNARNDGT)).to_frame(name='Generation' ).reset_index().pivot_table(index=['level_0','level_1','level_2','level_3','level_4'], columns='level_5', values='Generation' , aggfunc='sum')
|
|
@@ -1997,16 +2064,17 @@ def EconomicResults(DirName, CaseName, OptModel, mTEPES, pIndAreaOutput, pIndPlo
|
|
|
1997
2064
|
OutputResults.stack().reset_index().pivot_table(index=['level_0','level_1' ,'level_5'], columns='level_3', values=0, aggfunc='sum').rename_axis(['Period', 'Scenario' , 'Technology' ], axis=0).to_csv(f'{_path}/oT_Result_BalanceEnergyPerArea_{CaseName}.csv', sep=',')
|
|
1998
2065
|
|
|
1999
2066
|
#%% outputting the demand and the LSRMC of electricity
|
|
2000
|
-
|
|
2067
|
+
sPSSTNARND = [(p,sc,st,n,ar,nd) for p,sc,st,n,ar,nd in mTEPES.s2n*mTEPES.ar*mTEPES.nd if nd in d2a[ar] and sum(1 for g in g2n[nd]) + sum(1 for nf,cc in lout[nd]) + sum(1 for ni,cc in lin[nd]) and (p,sc,n) in mTEPES.psn]
|
|
2001
2068
|
|
|
2002
|
-
OutputResults = pd.Series(data=[mTEPES.pDuals["".join([f"eBalanceElec_{p}_{sc}_{st}('{n}', '{nd}')"])]/mTEPES.pPeriodProb[p,sc]()/mTEPES.pLoadLevelDuration[p,sc,n]() for p,sc,st,n,ar,nd in
|
|
2069
|
+
OutputResults = pd.Series(data=[mTEPES.pDuals["".join([f"eBalanceElec_{p}_{sc}_{st}('{n}', '{nd}')"])]/mTEPES.pPeriodProb[p,sc]()/mTEPES.pLoadLevelDuration[p,sc,n]() for p,sc,st,n,ar,nd in sPSSTNARND], index=pd.Index(sPSSTNARND))
|
|
2003
2070
|
OutputResults *= 1e3
|
|
2004
2071
|
OutputResults.index = [idx[:2] + idx[3:] for idx in OutputResults.index]
|
|
2005
2072
|
|
|
2006
2073
|
#%% outputting the generator power output
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2074
|
+
sPSNARNDG = [(p,sc,n,ar,nd,g ) for p,sc,n,ar,nd,g in sPSNARND*mTEPES.g if g in g2n[nd] and (p,g ) in mTEPES.pg ]
|
|
2075
|
+
sPSNARNDNR = [(p,sc,n,ar,nd,nr) for p,sc,n,ar,nd,nr in sPSNARND*mTEPES.nr if nr in g2n[nd] and (p,nr) in mTEPES.pnr and nr not in mTEPES.eh]
|
|
2076
|
+
sPSNARNDRE = [(p,sc,n,ar,nd,re) for p,sc,n,ar,nd,re in sPSNARND*mTEPES.re if re in g2n[nd] and (p,re) in mTEPES.pre ]
|
|
2077
|
+
sPSNARNDEH = [(p,sc,n,ar,nd,eh) for p,sc,n,ar,nd,eh in sPSNARND*mTEPES.eh if eh in g2n[nd] and (p,eh) in mTEPES.peh ]
|
|
2010
2078
|
|
|
2011
2079
|
if sum(1 for nr in mTEPES.nr if nr not in mTEPES.eh):
|
|
2012
2080
|
OutputResults01 = pd.Series(data=[ OptModel.vTotalOutput [p,sc,n,nr ]()*mTEPES.pLoadLevelDuration[p,sc,n]() for p,sc,n,ar,nd,nr in sPSNARNDNR], index=pd.Index(sPSNARNDNR)).to_frame(name='Generation' ).reset_index().pivot_table(index=['level_0','level_1','level_2','level_3','level_4'], columns='level_5', values='Generation' , aggfunc='sum')
|
|
@@ -2022,32 +2090,38 @@ def EconomicResults(DirName, CaseName, OptModel, mTEPES, pIndAreaOutput, pIndPlo
|
|
|
2022
2090
|
OutputResults09 = pd.Series(data=[-sum(OptModel.vLineLosses [p,sc,n,nd,nf,cc]()*mTEPES.pLoadLevelDuration[p,sc,n]() for nf,cc in loutl[nd] if (p,nd,nf,cc) in mTEPES.pla) for p,sc,n,ar,nd in sPSNARND ], index=pd.Index(sPSNARND )).to_frame(name='LineLossesOut' )
|
|
2023
2091
|
OutputResults10 = pd.Series(data=[-sum(OptModel.vLineLosses [p,sc,n,ni,nd,cc]()*mTEPES.pLoadLevelDuration[p,sc,n]() for ni,cc in linl [nd] if (p,ni,nd,cc) in mTEPES.pla) for p,sc,n,ar,nd in sPSNARND ], index=pd.Index(sPSNARND )).to_frame(name='LineLossesIn' )
|
|
2024
2092
|
|
|
2025
|
-
MarketResultsDem
|
|
2093
|
+
MarketResultsDem = pd.DataFrame()
|
|
2026
2094
|
if mTEPES.eh:
|
|
2027
2095
|
MarketResultsDem = pd.concat([MarketResultsDem, OutputResults04],axis=1)
|
|
2028
|
-
|
|
2029
2096
|
MarketResultsDem = pd.concat([MarketResultsDem, OutputResults06],axis=1)
|
|
2030
|
-
|
|
2031
2097
|
if mTEPES.ll:
|
|
2032
2098
|
MarketResultsDem = pd.concat([MarketResultsDem, OutputResults09, OutputResults10], axis=1)
|
|
2033
2099
|
|
|
2100
|
+
MarketResultsDem *= -1e3
|
|
2101
|
+
MarketResultsDem = pd.concat([MarketResultsDem.sum(axis=1), OutputResults], axis=1)
|
|
2102
|
+
MarketResultsDem.stack().reset_index().pivot_table(index=['level_0','level_1','level_2','level_3','level_4'], columns='level_5', values=0, aggfunc='sum').rename_axis(['Period', 'Scenario', 'LoadLevel', 'Area', 'Node'], axis=0).rename(columns={0: 'Demand [MWh]', 1: 'LSRMC [EUR/MWh]'}, inplace=False).to_csv(f'{_path}/oT_Result_MarketResultsDemand_{CaseName}.csv', sep=',')
|
|
2103
|
+
|
|
2034
2104
|
MarketResultsGen = pd.DataFrame()
|
|
2035
2105
|
# Check if there are non-RES generators
|
|
2036
2106
|
if sum(1 for nr in mTEPES.nr if nr not in mTEPES.eh):
|
|
2037
|
-
MarketResultsGen = pd.concat([MarketResultsGen,OutputResults01], axis=1)
|
|
2038
|
-
|
|
2107
|
+
MarketResultsGen = pd.concat([MarketResultsGen, OutputResults01], axis=1)
|
|
2039
2108
|
if mTEPES.re:
|
|
2040
2109
|
MarketResultsGen = pd.concat([MarketResultsGen, OutputResults02], axis=1)
|
|
2041
|
-
|
|
2042
2110
|
if mTEPES.eh:
|
|
2043
2111
|
MarketResultsGen = pd.concat([MarketResultsGen, OutputResults03], axis=1)
|
|
2044
2112
|
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2113
|
+
OutputResults11 = pd.Series(data=[(OptModel.vTotalOutput[p,sc,n,g].ub*OptModel.vGenerationInvest[p,g]() - OptModel.vTotalOutput[p,sc,n,g]())*mTEPES.pLoadLevelDuration[p,sc,n]() if g in mTEPES.re and g in mTEPES.gc else
|
|
2114
|
+
(OptModel.vTotalOutput[p,sc,n,g].ub - OptModel.vTotalOutput[p,sc,n,g]())*mTEPES.pLoadLevelDuration[p,sc,n]() if g in mTEPES.re and g not in mTEPES.gc else
|
|
2115
|
+
OptModel.vESSSpillage[p,sc,n,g]() if g in mTEPES.es else 0.0 for p,sc,n,ar,nd,g in sPSNARNDG], index=pd.Index(sPSNARNDG))
|
|
2116
|
+
OutputResults12 = pd.Series(data=[ OptModel.vTotalOutput [p,sc,n,g]()*mTEPES.pLoadLevelDuration[p,sc,n]()*mTEPES.pEmissionRate[g]/1e3 if g not in mTEPES.bo else
|
|
2117
|
+
OptModel.vTotalOutputHeat[p,sc,n,g]()*mTEPES.pLoadLevelDuration[p,sc,n]()*mTEPES.pEmissionRate[g]/1e3 for p,sc,n,ar,nd,g in sPSNARNDG], index=pd.Index(sPSNARNDG))
|
|
2118
|
+
|
|
2119
|
+
OutputResults11.index = [idx[:6] for idx in OutputResults11.index]
|
|
2120
|
+
OutputResults12.index = [idx[:6] for idx in OutputResults12.index]
|
|
2048
2121
|
|
|
2049
2122
|
MarketResultsGen *= 1e3
|
|
2050
|
-
MarketResultsGen.
|
|
2123
|
+
MarketResultsGen = pd.concat([MarketResultsGen.stack(), OutputResults11, OutputResults12], axis=1)
|
|
2124
|
+
MarketResultsGen.reset_index().pivot_table(index=['level_0','level_1','level_2','level_3','level_4','level_5']).rename_axis(['Period', 'Scenario', 'LoadLevel', 'Area', 'Node', 'Generator'], axis=0).rename(columns={0: 'Generation [MWh]', 1: 'Curtailment [MWh]', 2: 'Emissions [MtCO2]'}, inplace=False).to_csv(f'{_path}/oT_Result_MarketResultsGeneration_{CaseName}.csv', sep=',')
|
|
2051
2125
|
|
|
2052
2126
|
# df=OutputResults.stack().rename_axis(['Period', 'Scenario', 'LoadLevel', 'Area', 'Node', 'Technology'], axis=0).reset_index()
|
|
2053
2127
|
# df['AreaFin'] = df['Area']
|
|
@@ -2153,14 +2227,25 @@ def EconomicResults(DirName, CaseName, OptModel, mTEPES, pIndAreaOutput, pIndPlo
|
|
|
2153
2227
|
OutputResults.loc[(OutputResults['Period'] == p) & (OutputResults['Scenario'] == sc), 'MEUR/year'] = OutputResults.loc[(OutputResults['Period'] == p) & (OutputResults['Scenario'] == sc), 'MEUR'] / mTEPES.pDiscountedWeight[p] / mTEPES.pScenProb[p,sc]()
|
|
2154
2228
|
OutputResults.to_csv(f'{_path}/oT_Result_CostSummary_{CaseName}_{ar}.csv', sep=',', index=False)
|
|
2155
2229
|
|
|
2156
|
-
|
|
2230
|
+
sPSSTNG = [(p,sc,st,n, g) for p,sc,st,n, g in mTEPES.s2n*mTEPES.g if (p,sc,n) in mTEPES.psn]
|
|
2231
|
+
sPSSTNND = [(p,sc,st,n,nd ) for p,sc,st,n,nd in mTEPES.s2n*mTEPES.nd if sum(1 for g in g2n[nd]) + sum(1 for nf,cc in lout[nd]) + sum(1 for ni,cc in lin[nd]) and (p,sc,n) in mTEPES.psn]
|
|
2232
|
+
sPSSTNNDG = [(p,sc,st,n,nd,g) for p,sc,st,n,nd,g in sPSSTNND*mTEPES.g if (nd,g) in mTEPES.n2g and (p,g) in mTEPES.pg]
|
|
2157
2233
|
OutputResults = pd.Series(data=[ mTEPES.pDuals["".join([f"eBalanceElec_{p}_{sc}_{st}('{n}', '{nd}')"])]/mTEPES.pPeriodProb[p,sc]()/mTEPES.pLoadLevelDuration[p,sc,n]()*OptModel.vTotalOutput [p,sc,n,g]() for p,sc,st,n,nd,g in sPSSTNNDG], index=pd.Index(sPSSTNNDG))
|
|
2234
|
+
MeanOutput = pd.Series(data=[ OptModel.vTotalOutput [p,sc,n,g]() for p,sc,st,n, g in sPSSTNG ], index=pd.Index(sPSSTNG )).groupby(level=4).mean()
|
|
2235
|
+
MeanOutput *= 1e-3
|
|
2158
2236
|
OutputResults.to_frame(name='MEUR').reset_index().pivot_table(index=['level_0','level_1','level_3'], columns='level_5', values='MEUR').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_RevenueEnergyGeneration_{CaseName}.csv', sep=',')
|
|
2237
|
+
OutputResults = pd.Series(data=[ mTEPES.pDuals["".join([f"eBalanceElec_{p}_{sc}_{st}('{n}', '{nd}')"])]/mTEPES.pPeriodProb[p,sc]()/mTEPES.pLoadLevelDuration[p,sc,n]()*OptModel.vTotalOutput [p,sc,n,g]()/MeanOutput[g] for p,sc,st,n,nd,g in sPSSTNNDG], index=pd.Index(sPSSTNNDG))
|
|
2238
|
+
OutputResults.to_frame(name='EUR/MWh').reset_index().pivot_table(index=['level_0','level_1','level_3'], columns='level_5', values='EUR/MWh').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_GenerationCapturedSRMC_{CaseName}.csv', sep=',')
|
|
2159
2239
|
|
|
2160
2240
|
if mTEPES.eh:
|
|
2161
|
-
|
|
2162
|
-
|
|
2241
|
+
sPSSTNES = [(p,sc,st,n, eh) for p,sc,st,n, eh in mTEPES.s2n*mTEPES.eh if (p,sc,n) in mTEPES.psn]
|
|
2242
|
+
sPSSTNNDEH = [(p,sc,st,n,nd,eh) for p,sc,st,n,nd,eh in sPSSTNND*mTEPES.eh if (nd,eh) in mTEPES.n2g and (p,eh) in mTEPES.peh]
|
|
2243
|
+
OutputResults = pd.Series(data=[-mTEPES.pDuals["".join([f"eBalanceElec_{p}_{sc}_{st}('{n}', '{nd}')"])]/mTEPES.pPeriodProb[p,sc]()/mTEPES.pLoadLevelDuration[p,sc,n]()*OptModel.vESSTotalCharge[p,sc,n,eh]() for p,sc,st,n,nd,eh in sPSSTNNDEH], index=pd.Index(sPSSTNNDEH))
|
|
2244
|
+
MeanOutput = pd.Series(data=[ OptModel.vESSTotalCharge[p,sc,n,eh]() for p,sc,st,n, eh in sPSSTNES ], index=pd.Index(sPSSTNES )).groupby(level=4).mean()
|
|
2245
|
+
MeanOutput *= 1e-3
|
|
2163
2246
|
OutputResults.to_frame(name='MEUR').reset_index().pivot_table(index=['level_0','level_1','level_3'], columns='level_5', values='MEUR').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_RevenueEnergyConsumption_{CaseName}.csv', sep=',')
|
|
2247
|
+
OutputResults = pd.Series(data=[-mTEPES.pDuals["".join([f"eBalanceElec_{p}_{sc}_{st}('{n}', '{nd}')"])]/mTEPES.pPeriodProb[p,sc]()/mTEPES.pLoadLevelDuration[p,sc,n]()*OptModel.vESSTotalCharge[p,sc,n,eh]()/MeanOutput[eh] for p,sc,st,n,nd,eh in sPSSTNNDEH], index=pd.Index(sPSSTNNDEH))
|
|
2248
|
+
OutputResults.to_frame(name='EUR/MWh').reset_index().pivot_table(index=['level_0','level_1','level_3'], columns='level_5', values='EUR/MWh').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_ConsumptionCapturedSRMC_{CaseName}.csv', sep=',')
|
|
2164
2249
|
|
|
2165
2250
|
if mTEPES.gc:
|
|
2166
2251
|
GenRev = []
|
|
@@ -2200,7 +2285,7 @@ def EconomicResults(DirName, CaseName, OptModel, mTEPES, pIndAreaOutput, pIndPlo
|
|
|
2200
2285
|
if sum(mTEPES.pReserveMargin[:,:]):
|
|
2201
2286
|
if mTEPES.gc:
|
|
2202
2287
|
sPSSTARGC = [(p,sc,st,ar,gc) for p,sc,st,ar,gc in mTEPES.ps*mTEPES.st*mTEPES.ar*mTEPES.gc if gc in g2a[ar] and mTEPES.pReserveMargin[p,ar] and st == mTEPES.Last_st and sum(1 for gc in mTEPES.gc if gc in g2a[ar]) and sum(mTEPES.pRatedMaxPowerElec[g] * mTEPES.pAvailability[g]() / (1.0-mTEPES.pEFOR[g]) for g in mTEPES.g if g in g2a[ar] and g not in (mTEPES.gc or mTEPES.gd)) <= mTEPES.pDemandElecPeak[p,ar] * mTEPES.pReserveMargin[p,ar]]
|
|
2203
|
-
OutputToResRev = pd.Series(data=[mTEPES.pDuals[
|
|
2288
|
+
OutputToResRev = pd.Series(data=[mTEPES.pDuals[''.join([f'eAdequacyReserveMarginElec_{p}_{sc}_{st}{ar}'])]*mTEPES.pRatedMaxPowerElec[gc]*mTEPES.pAvailability[gc]() for p,sc,st,ar,gc in sPSSTARGC], index=pd.Index(sPSSTARGC))
|
|
2204
2289
|
ResRev = pd.Series(data=[0.0 for gc in mTEPES.gc], index=mTEPES.gc, dtype='float64')
|
|
2205
2290
|
if sPSSTARGC:
|
|
2206
2291
|
OutputToResRev /= 1e3
|
|
@@ -2210,7 +2295,7 @@ def EconomicResults(DirName, CaseName, OptModel, mTEPES, pIndAreaOutput, pIndPlo
|
|
|
2210
2295
|
else:
|
|
2211
2296
|
ResRev = pd.Series(data=[0.0 for gc in mTEPES.gc], index=mTEPES.gc, dtype='float64')
|
|
2212
2297
|
|
|
2213
|
-
if sum(mTEPES.pOperReserveUp[:,:,:,:]) and sum(1 for ar,nr in mTEPES.ar*mTEPES.nr if nr in g2a[ar] and (mTEPES.pIndOperReserveGen[nr] == 0 or mTEPES.pIndOperReserveCon[nr] == 0)
|
|
2298
|
+
if sum(mTEPES.pOperReserveUp[:,:,:,:]) and sum(1 for ar,nr in mTEPES.ar*mTEPES.nr if nr in g2a[ar] and (mTEPES.pIndOperReserveGen[nr] == 0 or mTEPES.pIndOperReserveCon[nr] == 0)) + sum(1 for ar,es in mTEPES.ar*mTEPES.es if es in g2a[ar] and (mTEPES.pIndOperReserveGen[nr] == 0 or mTEPES.pIndOperReserveCon[nr] == 0)):
|
|
2214
2299
|
if len([(p,sc,n,ar,nr) for p,sc,n,ar,nr in mTEPES.psn*mTEPES.ar*mTEPES.nr if nr in g2a[ar] and mTEPES.pOperReserveUp[p,sc,n,ar] and (p,sc,n,nr) in mTEPES.psnnr]):
|
|
2215
2300
|
sPSSTNARNR = [(p,sc,st,n,ar,nr) for p,sc,st,n,ar,nr in mTEPES.s2n*mTEPES.ar*mTEPES.nr if nr in g2a[ar] and mTEPES.pOperReserveUp[p,sc,n,ar] and (p,sc,n,nr) in mTEPES.psnnr]
|
|
2216
2301
|
OutputResults = pd.Series(data=[mTEPES.pDuals["".join([f"eOperReserveUp_{p}_{sc}_{st}('{n}', '{ar}')"])]/mTEPES.pPeriodProb[p,sc]()*OptModel.vReserveUp [p,sc,n,nr]() for p,sc,st,n,ar,nr in sPSSTNARNR], index=pd.Index(sPSSTNARNR))
|
|
@@ -2263,6 +2348,60 @@ def EconomicResults(DirName, CaseName, OptModel, mTEPES, pIndAreaOutput, pIndPlo
|
|
|
2263
2348
|
else:
|
|
2264
2349
|
DwRev = pd.Series(data=[0.0 for gc in mTEPES.gc], index=mTEPES.gc, dtype='float64')
|
|
2265
2350
|
|
|
2351
|
+
if mTEPES.pIndRampReserves == 1 and sum(mTEPES.pRampReserveUp[:,:,:,:]):
|
|
2352
|
+
if len([(p,sc,n,nr) for p,sc,n,nr in mTEPES.psn*mTEPES.nr if sum(mTEPES.pRampReserveUp[p,sc,n,ar] for ar in mTEPES.ar) and (p,sc,n,nr) in mTEPES.psnnr]):
|
|
2353
|
+
sPSSTNNR = [(p,sc,st,n,nr) for p,sc,st,n,nr in mTEPES.s2n*mTEPES.nr if sum(mTEPES.pRampReserveUp[p,sc,n,ar] for ar in mTEPES.ar) and (p,sc,n,nr) in mTEPES.psnnr]
|
|
2354
|
+
OutputResults = pd.Series(data=[mTEPES.pDuals["".join([f"eSystemRampUp_{p}_{sc}_{st}{n}"])]/mTEPES.pPeriodProb[p,sc]()*OptModel.vRampReserveUp[p,sc,n,nr]() for p,sc,st,n,nr in sPSSTNNR], index=pd.Index(sPSSTNNR))
|
|
2355
|
+
OutputResults.to_frame(name='MEUR').reset_index().pivot_table(index=['level_0','level_1','level_3'], columns='level_4', values='MEUR').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_RevenueRampReserveUp_{CaseName}.csv', sep=',')
|
|
2356
|
+
|
|
2357
|
+
# if len([(p,sc,n,eh) for p,sc,n,eh in mTEPES.psn*mTEPES.eh if sum(mTEPES.pRampReserveUp[p,sc,n,ar] for ar in mTEPES.ar) and (p,sc,n,eh) in mTEPES.psnehc]):
|
|
2358
|
+
# sPSSTNES = [(p,sc,st,n,eh) for p,sc,st,n,eh in mTEPES.s2n*mTEPES.eh if sum(mTEPES.pRampReserveUp[p,sc,n,ar] for ar in mTEPES.ar) and (p,sc,n,eh) in mTEPES.psnehc]
|
|
2359
|
+
# OutputResults = pd.Series(data=[mTEPES.pDuals["".join([f"eSystemRampUp_{p}_{sc}_{st}{n}"])]/mTEPES.pPeriodProb[p,sc]()*OptModel.vRampReserveUp[p,sc,n,eh]() for p,sc,st,n,eh in sPSSTNES], index=pd.Index(sPSSTNES))
|
|
2360
|
+
# OutputResults.to_frame(name='MEUR').reset_index().pivot_table(index=['level_0','level_1','level_3'], columns='level_4', values='MEUR').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_RevenueRampReserveUpESS_{CaseName}.csv', sep=',')
|
|
2361
|
+
|
|
2362
|
+
if len([(p,sc,n,ec) for p,sc,n,ec in mTEPES.psn*mTEPES.gc if sum(mTEPES.pRampReserveUp[p,sc,n,ar] for ar in mTEPES.ar) and (p,sc,n,ec) in mTEPES.psnec]):
|
|
2363
|
+
sPSSTNEC = [(p,sc,st,n,ec) for p,sc,st,n,ec in mTEPES.s2n*mTEPES.ec if sum(mTEPES.pRampReserveUp[p,sc,n,ar] for ar in mTEPES.ar) and (p,sc,n,ec) in mTEPES.psnec]
|
|
2364
|
+
OutputResults = pd.Series(data=[mTEPES.pDuals["".join([f"eSystemRampUp_{p}_{sc}_{st}{n}"])]/mTEPES.pPeriodProb[p,sc]()*OptModel.vRampReserveUp[p,sc,n,ec]() for p,sc,st,n,ec in sPSSTNEC], index=pd.Index(sPSSTNEC), dtype='float64')
|
|
2365
|
+
if len(OutputResults):
|
|
2366
|
+
OutputToUpRev = OutputResults.to_frame('MEUR').reset_index().pivot_table(index=['level_0','level_1','level_3'], columns='level_4', values='MEUR').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).sum(axis=0)
|
|
2367
|
+
else:
|
|
2368
|
+
OutputToUpRev = pd.Series(data=[0.0 for gc in mTEPES.gc], index=mTEPES.gc, dtype='float64')
|
|
2369
|
+
RampUpRev = pd.Series(data=[0.0 for gc in mTEPES.gc], index=mTEPES.gc, dtype='float64')
|
|
2370
|
+
|
|
2371
|
+
for g in OutputToUpRev.index:
|
|
2372
|
+
RampUpRev[g] = OutputToUpRev[g]
|
|
2373
|
+
else:
|
|
2374
|
+
RampUpRev = pd.Series(data=[0.0 for gc in mTEPES.gc], index=mTEPES.gc, dtype='float64')
|
|
2375
|
+
else:
|
|
2376
|
+
RampUpRev = pd.Series(data=[0.0 for gc in mTEPES.gc], index=mTEPES.gc, dtype='float64')
|
|
2377
|
+
|
|
2378
|
+
if mTEPES.pIndRampReserves == 1 and sum(mTEPES.pRampReserveDw[:,:,:,:]):
|
|
2379
|
+
if len([(p,sc,n,nr) for p,sc,n,nr in mTEPES.psn*mTEPES.nr if sum(mTEPES.pRampReserveDw[p,sc,n,ar] for ar in mTEPES.ar) and (p,sc,n,nr) in mTEPES.psnnr]):
|
|
2380
|
+
sPSSTNNR = [(p,sc,st,n,nr) for p,sc,st,n,nr in mTEPES.s2n*mTEPES.nr if sum(mTEPES.pRampReserveDw[p,sc,n,ar] for ar in mTEPES.ar) and (p,sc,n,nr) in mTEPES.psnnr]
|
|
2381
|
+
OutputResults = pd.Series(data=[mTEPES.pDuals["".join([f"eSystemRampDw_{p}_{sc}_{st}{n}"])]/mTEPES.pPeriodProb[p,sc]()*OptModel.vRampReserveDw[p,sc,n,nr]() for p,sc,st,n,nr in sPSSTNNR], index=pd.Index(sPSSTNNR))
|
|
2382
|
+
OutputResults.to_frame(name='MEUR').reset_index().pivot_table(index=['level_0','level_1','level_3'], columns='level_4', values='MEUR').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_RevenueRampReserveDw_{CaseName}.csv', sep=',')
|
|
2383
|
+
|
|
2384
|
+
# if len([(p,sc,n,eh) for p,sc,n,eh in mTEPES.psn*mTEPES.eh if sum(mTEPES.pRampReserveDw[p,sc,n,ar] for ar in mTEPES.ar) and (p,sc,n,eh) in mTEPES.psnehc]):
|
|
2385
|
+
# sPSSTNES = [(p,sc,st,n,eh) for p,sc,st,n,eh in mTEPES.s2n*mTEPES.eh if sum(mTEPES.pRampReserveDw[p,sc,n,ar] for ar in mTEPES.ar) and (p,sc,n,eh) in mTEPES.psnehc]
|
|
2386
|
+
# OutputResults = pd.Series(data=[mTEPES.pDuals["".join([f"eSystemRampDw_{p}_{sc}_{st}{n}"])]/mTEPES.pPeriodProb[p,sc]()*OptModel.vRampReserveDw[p,sc,n,eh]() for p,sc,st,n,eh in sPSSTNES], index=pd.Index(sPSSTNES))
|
|
2387
|
+
# OutputResults.to_frame(name='MEUR').reset_index().pivot_table(index=['level_0','level_1','level_3'], columns='level_4', values='MEUR').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_RevenueRampReserveDwESS_{CaseName}.csv', sep=',')
|
|
2388
|
+
|
|
2389
|
+
if len([(p,sc,n,ec) for p,sc,n,ec in mTEPES.psn*mTEPES.gc if sum(mTEPES.pRampReserveDw[p,sc,n,ar] for ar in mTEPES.ar) and (p,sc,n,ec) in mTEPES.psnec]):
|
|
2390
|
+
sPSSTNEC = [(p,sc,st,n,ec) for p,sc,st,n,ec in mTEPES.s2n*mTEPES.ec if sum(mTEPES.pRampReserveDw[p,sc,n,ar] for ar in mTEPES.ar) and (p,sc,n,ec) in mTEPES.psnec]
|
|
2391
|
+
OutputResults = pd.Series(data=[mTEPES.pDuals["".join([f"eSystemRampDw_{p}_{sc}_{st}{n}"])]/mTEPES.pPeriodProb[p,sc]()*OptModel.vRampReserveUp[p,sc,n,ec]() for p,sc,st,n,ec in sPSSTNEC], index=pd.Index(sPSSTNEC), dtype='float64')
|
|
2392
|
+
if len(OutputResults):
|
|
2393
|
+
OutputToDwRev = OutputResults.to_frame('MEUR').reset_index().pivot_table(index=['level_0','level_1','level_3'], columns='level_4', values='MEUR').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).sum(axis=0)
|
|
2394
|
+
else:
|
|
2395
|
+
OutputToDwRev = pd.Series(data=[0.0 for gc in mTEPES.gc], index=mTEPES.gc, dtype='float64')
|
|
2396
|
+
RampDwRev = pd.Series(data=[0.0 for gc in mTEPES.gc], index=mTEPES.gc, dtype='float64')
|
|
2397
|
+
|
|
2398
|
+
for g in OutputToUpRev.index:
|
|
2399
|
+
RampDwRev[g] = OutputToDwRev[g]
|
|
2400
|
+
else:
|
|
2401
|
+
RampDwRev = pd.Series(data=[0.0 for gc in mTEPES.gc], index=mTEPES.gc, dtype='float64')
|
|
2402
|
+
else:
|
|
2403
|
+
RampDwRev = pd.Series(data=[0.0 for gc in mTEPES.gc], index=mTEPES.gc, dtype='float64')
|
|
2404
|
+
|
|
2266
2405
|
if mTEPES.gc:
|
|
2267
2406
|
GenCost = pd.Series(data=[sum(mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelDuration[p,sc,n]() * mTEPES.pLinearVarCost [p,sc,n,gc] * OptModel.vTotalOutput [p,sc,n,gc]() +
|
|
2268
2407
|
mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelDuration[p,sc,n]() * mTEPES.pConstantVarCost[p,sc,n,gc] * OptModel.vCommitment [p,sc,n,gc]() +
|
|
@@ -2282,14 +2421,15 @@ def EconomicResults(DirName, CaseName, OptModel, mTEPES, pIndAreaOutput, pIndPlo
|
|
|
2282
2421
|
OpCCost[gc] = 0.0 if gc not in OpCCost.index else OpCCost[gc]
|
|
2283
2422
|
|
|
2284
2423
|
InvCost = pd.Series(data=[sum(mTEPES.pDiscountedWeight[p] * mTEPES.pGenInvestCost[gc] * OptModel.vGenerationInvest[p,gc]() for p in mTEPES.p if (p,gc) in mTEPES.pgc) for gc in mTEPES.gc], index=mTEPES.gc, dtype='float64')
|
|
2285
|
-
Balance = pd.Series(data=[GenRev[gc]+ChargeRev[gc]+UpRev[gc]+DwRev[gc]+ResRev[gc]-GenCost[gc]-EmsCost[gc]-OpGCost[gc]-CnsCost[gc]-OpCCost[gc]-InvCost[gc] for gc in mTEPES.gc], index=mTEPES.gc, dtype='float64')
|
|
2286
|
-
CostRecovery = pd.concat([GenRev,ChargeRev,UpRev,DwRev,ResRev,-GenCost,-EmsCost,-OpGCost,-CnsCost,-OpCCost,-InvCost,Balance], axis=1, keys=['Revenue generation [MEUR]', 'Revenue consumption [MEUR]', 'Revenue operating reserve up [MEUR]', 'Revenue operating reserve down [MEUR]', 'Revenue reserve margin [MEUR]', 'Cost operation generation [MEUR]', 'Cost emission [MEUR]', 'Cost operating reserves generation [MEUR]', 'Cost operation consumption [MEUR]', 'Cost operating reserves consumption [MEUR]', 'Cost investment [MEUR]', ' Total [MEUR]'])
|
|
2424
|
+
Balance = pd.Series(data=[GenRev[gc]+ChargeRev[gc]+UpRev[gc]+DwRev[gc]+RampUpRev[gc]+RampDwRev[gc]+ResRev[gc]-GenCost[gc]-EmsCost[gc]-OpGCost[gc]-CnsCost[gc]-OpCCost[gc]-InvCost[gc] for gc in mTEPES.gc], index=mTEPES.gc, dtype='float64')
|
|
2425
|
+
CostRecovery = pd.concat([GenRev,ChargeRev,UpRev,DwRev,RampUpRev,RampDwRev,ResRev,-GenCost,-EmsCost,-OpGCost,-CnsCost,-OpCCost,-InvCost,Balance], axis=1, keys=['Revenue generation [MEUR]', 'Revenue consumption [MEUR]', 'Revenue operating reserve up [MEUR]', 'Revenue operating reserve down [MEUR]' 'Revenue ramp reserve up [MEUR]', 'Revenue ramp reserve down [MEUR]', 'Revenue reserve margin [MEUR]', 'Cost operation generation [MEUR]', 'Cost emission [MEUR]', 'Cost operating reserves generation [MEUR]', 'Cost operation consumption [MEUR]', 'Cost operating reserves consumption [MEUR]', 'Cost investment [MEUR]', ' Total [MEUR]'])
|
|
2287
2426
|
CostRecovery.stack().to_frame(name='MEUR').reset_index().pivot_table(values='MEUR', index=['level_1'], columns=['level_0']).rename_axis([None], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_CostRecovery_{CaseName}.csv', sep=',')
|
|
2288
2427
|
|
|
2289
2428
|
WritingResultsTime = time.time() - StartTime
|
|
2290
2429
|
print('Writing economic results ... ', round(WritingResultsTime), 's')
|
|
2291
2430
|
|
|
2292
2431
|
|
|
2432
|
+
# @profile
|
|
2293
2433
|
def NetworkMapResults(DirName, CaseName, OptModel, mTEPES):
|
|
2294
2434
|
# %% plotting the network in a map
|
|
2295
2435
|
_path = os.path.join(DirName, CaseName)
|