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.
- openTEPES/9n_PTDF/oT_Data_Demand_9n_PTDF.csv +8737 -0
- openTEPES/9n_PTDF/oT_Data_Duration_9n_PTDF.csv +8737 -0
- openTEPES/9n_PTDF/oT_Data_Emission_9n_PTDF.csv +2 -0
- openTEPES/9n_PTDF/oT_Data_EnergyInflows_9n_PTDF.csv +8737 -0
- openTEPES/9n_PTDF/oT_Data_EnergyOutflows_9n_PTDF.csv +8737 -0
- openTEPES/9n_PTDF/oT_Data_Generation_9n_PTDF.csv +17 -0
- openTEPES/9n_PTDF/oT_Data_Inertia_9n_PTDF.csv +8737 -0
- openTEPES/9n_PTDF/oT_Data_Network_9n_PTDF.csv +14 -0
- openTEPES/9n_PTDF/oT_Data_NodeLocation_9n_PTDF.csv +10 -0
- openTEPES/9n_PTDF/oT_Data_OperatingReserveDown_9n_PTDF.csv +8737 -0
- openTEPES/9n_PTDF/oT_Data_OperatingReserveUp_9n_PTDF.csv +8737 -0
- openTEPES/9n_PTDF/oT_Data_Option_9n_PTDF.csv +2 -0
- openTEPES/9n_PTDF/oT_Data_Parameter_9n_PTDF.csv +2 -0
- openTEPES/9n_PTDF/oT_Data_Period_9n_PTDF.csv +2 -0
- openTEPES/9n_PTDF/oT_Data_RESEnergy_9n_PTDF.csv +2 -0
- openTEPES/9n_PTDF/oT_Data_ReserveMargin_9n_PTDF.csv +2 -0
- openTEPES/9n_PTDF/oT_Data_Scenario_9n_PTDF.csv +2 -0
- openTEPES/9n_PTDF/oT_Data_Stage_9n_PTDF.csv +2 -0
- openTEPES/9n_PTDF/oT_Data_VariableEmissionCost_9n_PTDF.csv +8737 -0
- openTEPES/9n_PTDF/oT_Data_VariableFuelCost_9n_PTDF.csv +8737 -0
- openTEPES/9n_PTDF/oT_Data_VariableMaxConsumption_9n_PTDF.csv +8737 -0
- openTEPES/9n_PTDF/oT_Data_VariableMaxEnergy_9n_PTDF.csv +8737 -0
- openTEPES/9n_PTDF/oT_Data_VariableMaxGeneration_9n_PTDF.csv +8737 -0
- openTEPES/9n_PTDF/oT_Data_VariableMaxStorage_9n_PTDF.csv +8737 -0
- openTEPES/9n_PTDF/oT_Data_VariableMinConsumption_9n_PTDF.csv +8737 -0
- openTEPES/9n_PTDF/oT_Data_VariableMinEnergy_9n_PTDF.csv +8737 -0
- openTEPES/9n_PTDF/oT_Data_VariableMinGeneration_9n_PTDF.csv +8737 -0
- openTEPES/9n_PTDF/oT_Data_VariableMinStorage_9n_PTDF.csv +8737 -0
- openTEPES/9n_PTDF/oT_Data_VariablePTDF_9n_PTDF.csv +8740 -0
- openTEPES/9n_PTDF/oT_Data_VariableTTCBck_9n_PTDF.csv +8739 -0
- openTEPES/9n_PTDF/oT_Data_VariableTTCFrw_9n_PTDF.csv +8739 -0
- openTEPES/9n_PTDF/oT_Dict_AreaToRegion_9n_PTDF.csv +2 -0
- openTEPES/9n_PTDF/oT_Dict_Area_9n_PTDF.csv +2 -0
- openTEPES/9n_PTDF/oT_Dict_Circuit_9n_PTDF.csv +3 -0
- openTEPES/9n_PTDF/oT_Dict_Generation_9n_PTDF.csv +17 -0
- openTEPES/9n_PTDF/oT_Dict_Line_9n_PTDF.csv +3 -0
- openTEPES/9n_PTDF/oT_Dict_LoadLevel_9n_PTDF.csv +8737 -0
- openTEPES/9n_PTDF/oT_Dict_NodeToZone_9n_PTDF.csv +10 -0
- openTEPES/9n_PTDF/oT_Dict_Node_9n_PTDF.csv +10 -0
- openTEPES/9n_PTDF/oT_Dict_Period_9n_PTDF.csv +2 -0
- openTEPES/9n_PTDF/oT_Dict_Region_9n_PTDF.csv +31 -0
- openTEPES/9n_PTDF/oT_Dict_Scenario_9n_PTDF.csv +2 -0
- openTEPES/9n_PTDF/oT_Dict_Stage_9n_PTDF.csv +2 -0
- openTEPES/9n_PTDF/oT_Dict_Storage_9n_PTDF.csv +3 -0
- openTEPES/9n_PTDF/oT_Dict_Technology_9n_PTDF.csv +7 -0
- openTEPES/9n_PTDF/oT_Dict_ZoneToArea_9n_PTDF.csv +10 -0
- openTEPES/9n_PTDF/oT_Dict_Zone_9n_PTDF.csv +10 -0
- openTEPES/RTS-GMLC/oT_Data_VariableMinGeneration_RTS-GMLC.csv +1 -1
- openTEPES/RTS-GMLC_6y/oT_Data_VariableFuelCost_RTS-GMLC_6y.csv +1 -1
- openTEPES/RTS-GMLC_6y/oT_Dict_AreaToRegion_RTS-GMLC_6y.csv +4 -4
- openTEPES/RTS-GMLC_6y/oT_Dict_Area_RTS-GMLC_6y.csv +4 -4
- openTEPES/RTS-GMLC_6y/oT_Dict_Circuit_RTS-GMLC_6y.csv +5 -5
- openTEPES/RTS-GMLC_6y/oT_Dict_Line_RTS-GMLC_6y.csv +3 -3
- openTEPES/RTS-GMLC_6y/oT_Dict_NodeToZone_RTS-GMLC_6y.csv +74 -74
- openTEPES/RTS-GMLC_6y/oT_Dict_Region_RTS-GMLC_6y.csv +2 -2
- openTEPES/RTS-GMLC_6y/oT_Dict_Scenario_RTS-GMLC_6y.csv +2 -2
- openTEPES/RTS-GMLC_6y/oT_Dict_Storage_RTS-GMLC_6y.csv +3 -3
- openTEPES/RTS-GMLC_6y/oT_Dict_Technology_RTS-GMLC_6y.csv +10 -10
- openTEPES/RTS-GMLC_6y/oT_Dict_ZoneToArea_RTS-GMLC_6y.csv +22 -22
- openTEPES/RTS-GMLC_6y/oT_Dict_Zone_RTS-GMLC_6y.csv +22 -22
- openTEPES/__init__.py +1 -1
- openTEPES/openTEPES.py +26 -17
- openTEPES/openTEPES_InputData.py +1335 -1188
- openTEPES/openTEPES_Main.py +3 -3
- openTEPES/openTEPES_ModelFormulation.py +413 -156
- openTEPES/openTEPES_OutputResults.py +263 -206
- openTEPES/openTEPES_ProblemSolving.py +35 -28
- openTEPES/sSEP/oT_Data_DemandHydrogen_sSEP.csv +8736 -8736
- openTEPES/sSEP/oT_Data_Generation_sSEP.csv +1 -1
- openTEPES/sSEP/oT_Data_HydroOutflows_sSEP.csv +1 -1
- {opentepes-4.18.4.dist-info → opentepes-4.18.6.dist-info}/METADATA +65 -46
- {opentepes-4.18.4.dist-info → opentepes-4.18.6.dist-info}/RECORD +75 -28
- {opentepes-4.18.4.dist-info → opentepes-4.18.6.dist-info}/WHEEL +1 -1
- {opentepes-4.18.4.dist-info → opentepes-4.18.6.dist-info}/entry_points.txt +0 -0
- {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) -
|
|
2
|
+
Open Generation, Storage, and Transmission Operation and Expansion Planning Model with RES and ESS (openTEPES) - September 17, 2025
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
5
|
import time
|
|
@@ -8,7 +8,6 @@ import os
|
|
|
8
8
|
import ast
|
|
9
9
|
import math
|
|
10
10
|
import csv
|
|
11
|
-
import numpy as np
|
|
12
11
|
import pandas as pd
|
|
13
12
|
import pyomo.environ as pyo
|
|
14
13
|
import altair as alt
|
|
@@ -16,7 +15,6 @@ import plotly.io as pio
|
|
|
16
15
|
import plotly.graph_objs as go
|
|
17
16
|
from collections import defaultdict
|
|
18
17
|
from colour import Color
|
|
19
|
-
from pyomo.environ import Suffix
|
|
20
18
|
|
|
21
19
|
|
|
22
20
|
# Definition of Pie plots
|
|
@@ -103,7 +101,7 @@ def LinePlots(period, scenario, df, Category, X, Y, OperationType):
|
|
|
103
101
|
return plot
|
|
104
102
|
|
|
105
103
|
|
|
106
|
-
# write parameters, variables, and duals
|
|
104
|
+
# write parameters, variables, and duals
|
|
107
105
|
def OutputResultsParVarCon(DirName, CaseName, OptModel, mTEPES):
|
|
108
106
|
# print('Writing pars, vars, and duals results ... ', end='')
|
|
109
107
|
# DirName = os.path.dirname(DirName)
|
|
@@ -114,7 +112,7 @@ def OutputResultsParVarCon(DirName, CaseName, OptModel, mTEPES):
|
|
|
114
112
|
# dump_folder = f'{_path}/CaseDumpFolder_{CaseName}_{DateName}/'
|
|
115
113
|
# with open(dump_folder+f'/oT_Case_{CaseName}.pkl','rb') as f:
|
|
116
114
|
# OptModel = pickle.load(f)
|
|
117
|
-
# output parameters, variables, and constraints
|
|
115
|
+
# output parameters, variables, and constraints
|
|
118
116
|
|
|
119
117
|
# dump_folder = f'{_path}/CaseDumpFolder_{CaseName}_'+str(datetime.datetime.now().strftime('%Y%m%d'))+f'/'
|
|
120
118
|
dump_folder = os.path.join(DirName, CaseName, f'CaseDumpFolder_{CaseName}_'+str(datetime.datetime.now().strftime('%Y%m%d')))
|
|
@@ -192,7 +190,7 @@ def InvestmentResults(DirName, CaseName, OptModel, mTEPES, pIndTechnologyOutput,
|
|
|
192
190
|
for gt,g in mTEPES.t2g:
|
|
193
191
|
g2t[gt].append(g)
|
|
194
192
|
|
|
195
|
-
if
|
|
193
|
+
if mTEPES.eb:
|
|
196
194
|
|
|
197
195
|
# generators to area (g2a)
|
|
198
196
|
g2a = defaultdict(list)
|
|
@@ -243,7 +241,7 @@ def InvestmentResults(DirName, CaseName, OptModel, mTEPES, pIndTechnologyOutput,
|
|
|
243
241
|
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)
|
|
244
242
|
chart.save(f'{_path}/oT_Plot_TechnologyInvestment_{CaseName}.html', embed_options={'renderer':'svg'})
|
|
245
243
|
|
|
246
|
-
# Saving and plotting generation investment cost
|
|
244
|
+
# Saving and plotting generation investment cost
|
|
247
245
|
OutputResults0 = OutputResults
|
|
248
246
|
OutputToFile = pd.Series(data=[mTEPES.pDiscountedWeight[p] * mTEPES.pGenInvestCost[eb] * OptModel.vGenerationInvest[p,eb]() for p,eb in mTEPES.peb], index=mTEPES.peb)
|
|
249
247
|
OutputToFile = OutputToFile.fillna(0).to_frame(name='MEUR').reset_index().rename(columns={'level_0': 'Period', 'level_1': 'Generating unit'}).set_index(['Period', 'Generating unit'])
|
|
@@ -270,7 +268,7 @@ def InvestmentResults(DirName, CaseName, OptModel, mTEPES, pIndTechnologyOutput,
|
|
|
270
268
|
chart = alt.Chart(OutputResults.reset_index().rename(columns={'level_0': 'Period', 'level_1': 'Technology'})).mark_bar().encode(x='Technology:O', y='sum(MEUR/MW):Q', color='Technology:N', column='Period:N').properties(width=600, height=400)
|
|
271
269
|
chart.save(f'{_path}/oT_Plot_TechnologyInvestmentCostPerMW_{CaseName}.html', embed_options={'renderer':'svg'})
|
|
272
270
|
|
|
273
|
-
if
|
|
271
|
+
if mTEPES.gd:
|
|
274
272
|
|
|
275
273
|
# generators to area (g2a)
|
|
276
274
|
g2a = defaultdict(list)
|
|
@@ -279,7 +277,7 @@ def InvestmentResults(DirName, CaseName, OptModel, mTEPES, pIndTechnologyOutput,
|
|
|
279
277
|
g2a[ar].append(gd)
|
|
280
278
|
|
|
281
279
|
if pIndTechnologyOutput == 0 or pIndTechnologyOutput == 2:
|
|
282
|
-
# Saving generation retirement
|
|
280
|
+
# Saving generation retirement
|
|
283
281
|
OutputToFile = pd.Series(data=[OptModel.vGenerationRetire[p,gd]() for p,gd in mTEPES.pgd], index=mTEPES.pgd)
|
|
284
282
|
OutputToFile = OutputToFile.fillna(0).to_frame(name='RetirementDecision').reset_index().rename(columns={'level_0': 'Period', 'level_1': 'Generating unit'})
|
|
285
283
|
OutputToFile.pivot_table(index=['Period'], columns=['Generating unit'], values='RetirementDecision').rename_axis(['Period'], axis=0).to_csv(f'{_path}/oT_Result_GenerationRetirementPerUnit_{CaseName}.csv', index=True, sep=',')
|
|
@@ -316,7 +314,7 @@ def InvestmentResults(DirName, CaseName, OptModel, mTEPES, pIndTechnologyOutput,
|
|
|
316
314
|
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)
|
|
317
315
|
chart.save(f'{_path}/oT_Plot_TechnologyRetirement_{CaseName}.html', embed_options={'renderer':'svg'})
|
|
318
316
|
|
|
319
|
-
if
|
|
317
|
+
if mTEPES.lc:
|
|
320
318
|
|
|
321
319
|
# Saving investment decisions
|
|
322
320
|
OutputToFile = pd.Series(data=[OptModel.vNetworkInvest[p,ni,nf,cc]() for p,ni,nf,cc in mTEPES.plc], index=mTEPES.plc)
|
|
@@ -394,7 +392,7 @@ def GenerationOperationResults(DirName, CaseName, OptModel, mTEPES, pIndTechnolo
|
|
|
394
392
|
for gt,g in mTEPES.t2g:
|
|
395
393
|
g2t[gt].append(g)
|
|
396
394
|
|
|
397
|
-
if
|
|
395
|
+
if mTEPES.nr:
|
|
398
396
|
if pIndTechnologyOutput == 0 or pIndTechnologyOutput == 2:
|
|
399
397
|
OutputToFile = pd.Series(data=[OptModel.vCommitment[p,sc,n,nr]() for p,sc,n,nr in mTEPES.psnnr], index=mTEPES.psnnr)
|
|
400
398
|
OutputToFile.to_frame(name='p.u.').reset_index().pivot_table(index=['level_0','level_1','level_2'], columns='level_3', values='p.u.').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_GenerationCommitment_{CaseName}.csv', sep=',')
|
|
@@ -404,7 +402,7 @@ def GenerationOperationResults(DirName, CaseName, OptModel, mTEPES, pIndTechnolo
|
|
|
404
402
|
OutputToFile.to_frame(name='p.u.').reset_index().pivot_table(index=['level_0','level_1','level_2'], columns='level_3', values='p.u.').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_GenerationShutDown_{CaseName}.csv', sep=',')
|
|
405
403
|
|
|
406
404
|
if sum(mTEPES.pOperReserveUp[:,:,:,:]):
|
|
407
|
-
if
|
|
405
|
+
if mTEPES.nr:
|
|
408
406
|
OutputToFile = pd.Series(data=[OptModel.vReserveUp [p,sc,n,nr]() for p,sc,n,nr in mTEPES.psnnr], index=mTEPES.psnnr)
|
|
409
407
|
OutputToFile = OutputToFile.fillna(0.0)
|
|
410
408
|
OutputToFile *= 1e3
|
|
@@ -415,7 +413,7 @@ def GenerationOperationResults(DirName, CaseName, OptModel, mTEPES, pIndTechnolo
|
|
|
415
413
|
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)
|
|
416
414
|
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_TechnologyOperatingReserveUp_{CaseName}.csv', sep=',')
|
|
417
415
|
|
|
418
|
-
if
|
|
416
|
+
if mTEPES.eh:
|
|
419
417
|
OutputToFile = pd.Series(data=[OptModel.vESSReserveUp [p,sc,n,eh]() for p,sc,n,eh in mTEPES.psnehc], index=mTEPES.psnehc)
|
|
420
418
|
OutputToFile = OutputToFile.fillna(0.0)
|
|
421
419
|
OutputToFile *= 1e3
|
|
@@ -423,11 +421,11 @@ def GenerationOperationResults(DirName, CaseName, OptModel, mTEPES, pIndTechnolo
|
|
|
423
421
|
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_ConsumptionReserveUp_{CaseName}.csv', sep=',')
|
|
424
422
|
|
|
425
423
|
if pIndTechnologyOutput == 1 or pIndTechnologyOutput == 2:
|
|
426
|
-
OutputToFile = pd.Series(data=[sum(OutputToFile[p,sc,n,eh] for eh in e2e[et] if (p,eh) in mTEPES.peh) for p,sc,n,et in mTEPES.psnet], index=mTEPES.psnet)
|
|
424
|
+
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)
|
|
427
425
|
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_TechnologyOperatingReserveUpESS_{CaseName}.csv', sep=',')
|
|
428
426
|
|
|
429
427
|
if sum(mTEPES.pOperReserveDw[:,:,:,:]):
|
|
430
|
-
if
|
|
428
|
+
if mTEPES.nr:
|
|
431
429
|
OutputToFile = pd.Series(data=[OptModel.vReserveDown [p,sc,n,nr]() for p,sc,n,nr in mTEPES.psnnr], index=mTEPES.psnnr)
|
|
432
430
|
OutputToFile = OutputToFile.fillna(0.0)
|
|
433
431
|
OutputToFile *= 1e3
|
|
@@ -438,7 +436,7 @@ def GenerationOperationResults(DirName, CaseName, OptModel, mTEPES, pIndTechnolo
|
|
|
438
436
|
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)
|
|
439
437
|
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_TechnologyOperatingReserveDown_{CaseName}.csv', sep=',')
|
|
440
438
|
|
|
441
|
-
if
|
|
439
|
+
if mTEPES.psnehc:
|
|
442
440
|
OutputToFile = pd.Series(data=[OptModel.vESSReserveDown[p,sc,n,eh]() for p,sc,n,eh in mTEPES.psnehc], index=mTEPES.psnehc)
|
|
443
441
|
OutputToFile = OutputToFile.fillna(0.0)
|
|
444
442
|
OutputToFile *= 1e3
|
|
@@ -463,26 +461,27 @@ def GenerationOperationResults(DirName, CaseName, OptModel, mTEPES, pIndTechnolo
|
|
|
463
461
|
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_GenerationSurplus_{CaseName}.csv', sep=',')
|
|
464
462
|
|
|
465
463
|
OutputResults = []
|
|
466
|
-
sPSSTNNR = [(p,sc,st,n,nr) for p,sc,st,n,nr in mTEPES.s2n*mTEPES.nr if mTEPES.pRampUp[nr] and mTEPES.pIndBinGenRamps() == 1 and mTEPES.pRampUp[nr] < mTEPES.pMaxPower2ndBlock[p,sc,n,nr] and (p,sc,n,nr) in mTEPES.psnnr and (nr not in mTEPES.es or (nr in mTEPES.es and (mTEPES.pTotalMaxCharge[nr] or mTEPES.pTotalEnergyInflows[nr])))]
|
|
467
|
-
OutputToFile = pd.Series(data=[(getattr(OptModel, f'eRampUp_{p}_{sc}_{st}')[n,nr].
|
|
464
|
+
sPSSTNNR = [(p,sc,st,n,nr) for p,sc,st,n,nr in mTEPES.s2n*mTEPES.nr if mTEPES.pRampUp[nr] and mTEPES.pIndBinGenRamps() == 1 and mTEPES.pRampUp[nr] < mTEPES.pMaxPower2ndBlock[p,sc,n,nr] and OptModel.vCommitment[p,sc,n,nr]() - OptModel.vStartUp[p,sc,n,nr]() and (p,sc,n,nr) in mTEPES.psnnr and (nr not in mTEPES.es or (nr in mTEPES.es and (mTEPES.pTotalMaxCharge[nr] or mTEPES.pTotalEnergyInflows[nr])))]
|
|
465
|
+
OutputToFile = pd.Series(data=[(getattr(OptModel, f'eRampUp_{p}_{sc}_{st}')[n,nr].slack())*mTEPES.pDuration[p,sc,n]()*mTEPES.pRampUp[nr]*(OptModel.vCommitment[p,sc,n,nr]() - OptModel.vStartUp[p,sc,n,nr]()) for p,sc,st,n,nr in sPSSTNNR], index=pd.Index(sPSSTNNR), dtype='float64')
|
|
468
466
|
OutputToFile *= 1e3
|
|
469
467
|
if len(OutputToFile):
|
|
470
468
|
OutputToFile.to_frame(name='MW/h').reset_index().pivot_table(index=['level_0','level_1','level_3'], columns='level_4', values='MW/h', aggfunc='sum').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_GenerationRampUpSurplus_{CaseName}.csv', sep=',')
|
|
471
469
|
|
|
472
470
|
OutputResults = []
|
|
473
|
-
sPSSTNNR = [(p,sc,st,n,nr) for p,sc,st,n,nr in mTEPES.s2n*mTEPES.nr if mTEPES.pRampDw[nr] and mTEPES.pIndBinGenRamps() == 1 and mTEPES.pRampDw[nr] < mTEPES.pMaxPower2ndBlock[p,sc,n,nr] and n == mTEPES.n.first() and (p,sc,n,nr) in mTEPES.psnnr and (nr not in mTEPES.es or (nr in mTEPES.es and (mTEPES.pTotalMaxCharge[nr] or mTEPES.pTotalEnergyInflows[nr])))]
|
|
474
|
-
OutputToFile = pd.Series(data=[(getattr(OptModel, f'eRampDw_{p}_{sc}_{st}')[n,nr].
|
|
471
|
+
sPSSTNNR = [(p,sc,st,n,nr) for p,sc,st,n,nr in mTEPES.s2n*mTEPES.nr if mTEPES.pRampDw[nr] and mTEPES.pIndBinGenRamps() == 1 and mTEPES.pRampDw[nr] < mTEPES.pMaxPower2ndBlock[p,sc,n,nr] and n == mTEPES.n.first() and mTEPES.pInitialUC[p,sc,n,nr]() - OptModel.vShutDown[p,sc,n,nr]() and (p,sc,n,nr) in mTEPES.psnnr and (nr not in mTEPES.es or (nr in mTEPES.es and (mTEPES.pTotalMaxCharge[nr] or mTEPES.pTotalEnergyInflows[nr])))]
|
|
472
|
+
OutputToFile = pd.Series(data=[min((getattr(OptModel, f'eRampDw_{p}_{sc}_{st}')[n,nr].slack())*mTEPES.pDuration[p,sc,n]()*mTEPES.pRampDw[nr]*(mTEPES.pInitialUC[p,sc,n,nr]() - OptModel.vShutDown[p,sc,n,nr]()), OptModel.vOutput2ndBlock[p,sc,n,nr]()) for p,sc,st,n,nr in sPSSTNNR], index=pd.Index(sPSSTNNR), dtype='float64')
|
|
475
473
|
OutputToFile *= 1e3
|
|
476
474
|
OutputResults.append(OutputToFile)
|
|
477
|
-
sPSSTNNR = [(p,sc,st,n,nr) for p,sc,st,n,nr in mTEPES.s2n*mTEPES.nr if mTEPES.pRampDw[nr] and mTEPES.pIndBinGenRamps() == 1 and mTEPES.pRampDw[nr] < mTEPES.pMaxPower2ndBlock[p,sc,n,nr] and n != mTEPES.n.first() and (p,sc,n,nr) in mTEPES.psnnr and (nr not in mTEPES.es or (nr in mTEPES.es and (mTEPES.pTotalMaxCharge[nr] or mTEPES.pTotalEnergyInflows[nr])))]
|
|
478
|
-
OutputToFile = pd.Series(data=[(getattr(OptModel, f'eRampDw_{p}_{sc}_{st}')[n,nr].
|
|
475
|
+
sPSSTNNR = [(p,sc,st,n,nr) for p,sc,st,n,nr in mTEPES.s2n*mTEPES.nr if mTEPES.pRampDw[nr] and mTEPES.pIndBinGenRamps() == 1 and mTEPES.pRampDw[nr] < mTEPES.pMaxPower2ndBlock[p,sc,n,nr] and n != mTEPES.n.first() and OptModel.vCommitment[p,sc,mTEPES.n.prev(n),nr]() - OptModel.vShutDown[p,sc,n,nr]() and (p,sc,n,nr) in mTEPES.psnnr and (nr not in mTEPES.es or (nr in mTEPES.es and (mTEPES.pTotalMaxCharge[nr] or mTEPES.pTotalEnergyInflows[nr])))]
|
|
476
|
+
OutputToFile = pd.Series(data=[min((getattr(OptModel, f'eRampDw_{p}_{sc}_{st}')[n,nr].slack())*mTEPES.pDuration[p,sc,n]()*mTEPES.pRampDw[nr]*(OptModel.vCommitment[p,sc,mTEPES.n.prev(n),nr]() - OptModel.vShutDown[p,sc,n,nr]()), OptModel.vOutput2ndBlock[p,sc,n,nr]()) for p,sc,st,n,nr in sPSSTNNR], index=pd.Index(sPSSTNNR), dtype='float64')
|
|
479
477
|
OutputToFile *= 1e3
|
|
480
478
|
OutputResults.append(OutputToFile)
|
|
481
479
|
OutputResults = pd.concat(OutputResults)
|
|
480
|
+
OutputResults.index = pd.MultiIndex.from_tuples(OutputResults.index, names=['level_0', 'level_1', 'level_2', 'level_3', 'level_4'])
|
|
482
481
|
if len(OutputResults):
|
|
483
482
|
OutputResults.to_frame(name='MW/h').reset_index().pivot_table(index=['level_0','level_1','level_3'], columns='level_4', values='MW/h', aggfunc='sum').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_GenerationRampDwSurplus_{CaseName}.csv', sep=',')
|
|
484
483
|
|
|
485
|
-
if
|
|
484
|
+
if mTEPES.re and mTEPES.rt:
|
|
486
485
|
OutputToFile1 = pd.Series(data=[(OptModel.vTotalOutput[p,sc,n,re].ub*OptModel.vGenerationInvest[p,re]() - OptModel.vTotalOutput[p,sc,n,re]())*mTEPES.pLoadLevelDuration[p,sc,n]() if re in mTEPES.gc else
|
|
487
486
|
(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)
|
|
488
487
|
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
|
|
@@ -536,9 +535,9 @@ def GenerationOperationResults(DirName, CaseName, OptModel, mTEPES, pIndTechnolo
|
|
|
536
535
|
if sum(1 for ar in mTEPES.ar if sum(1 for g in g2a[ar])) > 1:
|
|
537
536
|
if pIndAreaOutput == 1:
|
|
538
537
|
for ar in mTEPES.ar:
|
|
539
|
-
if sum(1 for g in g2a[ar]
|
|
538
|
+
if sum(1 for g in g2a[ar]):
|
|
540
539
|
sPSNGT = [(p,sc,n,gt) for p,sc,n,gt in mTEPES.psngt if sum(1 for g in g2a[ar] if (p,g) in mTEPES.pg and g in g2t[gt])]
|
|
541
|
-
if
|
|
540
|
+
if sPSNGT:
|
|
542
541
|
OutputResults = pd.Series(data=[sum(OutputToFile[p,sc,n,g] for g in g2a[ar] if (p,g) in mTEPES.pg and g in g2t[gt]) for p,sc,n,gt in sPSNGT], index=pd.Index(sPSNGT))
|
|
543
542
|
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_{ar}_{CaseName}.csv', sep=',')
|
|
544
543
|
|
|
@@ -573,9 +572,9 @@ def GenerationOperationResults(DirName, CaseName, OptModel, mTEPES, pIndTechnolo
|
|
|
573
572
|
if sum(1 for ar in mTEPES.ar if sum(1 for g in g2a[ar])) > 1:
|
|
574
573
|
if pIndAreaOutput == 1:
|
|
575
574
|
for ar in mTEPES.ar:
|
|
576
|
-
if sum(1 for g in g2a[ar]
|
|
575
|
+
if sum(1 for g in g2a[ar]):
|
|
577
576
|
sPSNGT = [(p,sc,n,gt) for p,sc,n,gt in mTEPES.psngt if sum(1 for g in g2a[ar] if (p,g) in mTEPES.pg and g in g2t[gt])]
|
|
578
|
-
if
|
|
577
|
+
if sPSNGT:
|
|
579
578
|
OutputToFile = pd.Series(data=[sum(OptModel.vTotalOutput[p,sc,n,g]()*mTEPES.pLoadLevelDuration[p,sc,n]() for g in g2a[ar] if (p,g) in mTEPES.pg and g in g2t[gt]) for p,sc,n,gt in sPSNGT], index=pd.Index(sPSNGT))
|
|
580
579
|
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_{ar}_{CaseName}.csv', sep=',')
|
|
581
580
|
|
|
@@ -653,7 +652,7 @@ def GenerationOperationHeatResults(DirName, CaseName, OptModel, mTEPES, pIndTech
|
|
|
653
652
|
for ar in mTEPES.ar:
|
|
654
653
|
if sum(1 for chp in g2a[ar] if chp in g2t[gt]):
|
|
655
654
|
sPSNGT = [(p,sc,n,gt) for p,sc,n,gt in mTEPES.psngt if sum(1 for chp in g2a[ar] if (p,chp) in mTEPES.pchp and chp in g2t[gt])]
|
|
656
|
-
if
|
|
655
|
+
if sPSNGT:
|
|
657
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 and chp in g2t[gt]) for p,sc,n,gt in sPSNGT], index=pd.Index(sPSNGT))
|
|
658
657
|
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_{ar}_{CaseName}.csv', sep=',')
|
|
659
658
|
|
|
@@ -696,23 +695,62 @@ def ESSOperationResults(DirName, CaseName, OptModel, mTEPES, pIndTechnologyOutpu
|
|
|
696
695
|
OutputToFile = pd.Series(data=[sum(OutputToFile[p,sc,n,es] for es in o2e[ot] if (p,es) in mTEPES.pes) for p,sc,n,ot in mTEPES.psnot], index=mTEPES.psnot)
|
|
697
696
|
OutputToFile.to_frame(name='MW').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_TechnologyOutflows_{CaseName}.csv', sep=',')
|
|
698
697
|
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
698
|
+
# Check if there are any ESS with consumption capabilities
|
|
699
|
+
# If there are none, just skip outputting consumption related files
|
|
700
|
+
if mTEPES.psnehc:
|
|
701
|
+
OutputToFile = pd.Series(data=[OptModel.vESSTotalCharge [p,sc,n,eh]() for p,sc,n,eh in mTEPES.psnehc], index=mTEPES.psnehc)
|
|
702
|
+
OutputToFile *= -1e3
|
|
703
|
+
OutputToFile.to_frame(name='MW').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_Consumption_{CaseName}.csv', sep=',')
|
|
702
704
|
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
705
|
+
# tolerance to consider that an ESS is not producing or consuming
|
|
706
|
+
pEpsilon = 1e-6
|
|
707
|
+
OutputToFile = pd.Series(data=[0.0 for p,sc,n,eh in mTEPES.psnehc], index=mTEPES.psnehc)
|
|
708
|
+
for p,sc,n,eh in mTEPES.psnehc:
|
|
709
|
+
OutputToFile[p,sc,n,eh] = -1.0 if OptModel.vESSTotalCharge[p,sc,n,eh]() and OptModel.vTotalOutput [p,sc,n,eh]() <= pEpsilon * mTEPES.pMaxPowerElec[p,sc,n,eh] else OutputToFile[p,sc,n,eh]
|
|
710
|
+
OutputToFile[p,sc,n,eh] = 1.0 if OptModel.vTotalOutput [p,sc,n,eh]() and OptModel.vESSTotalCharge[p,sc,n,eh]() <= pEpsilon * mTEPES.pMaxCharge [p,sc,n,eh] else OutputToFile[p,sc,n,eh]
|
|
711
|
+
if OptModel.vTotalOutput[p,sc,n,eh]() and OptModel.vESSTotalCharge[p,sc,n,eh]():
|
|
712
|
+
OutputToFile[p,sc,n,eh] = OptModel.vTotalOutput[p,sc,n,eh]()/OptModel.vESSTotalCharge[p,sc,n,eh]() if OptModel.vTotalOutput [p,sc,n,eh]() > pEpsilon * mTEPES.pMaxPowerElec[p,sc,n,eh] or OptModel.vESSTotalCharge[p,sc,n,eh]() > pEpsilon * mTEPES.pMaxCharge[p,sc,n,eh] else OutputToFile[p,sc,n,eh]
|
|
713
|
+
OutputToFile.to_frame(name='p.u.').reset_index().pivot_table(index=['level_0','level_1','level_2'], columns='level_3', values='p.u.', aggfunc='sum').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_GenerationConsumptionRatio_{CaseName}.csv', sep=',')
|
|
712
714
|
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
715
|
+
if pIndTechnologyOutput == 1 or pIndTechnologyOutput == 2:
|
|
716
|
+
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)
|
|
717
|
+
OutputToFile.to_frame(name='MW').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_TechnologyConsumption_{CaseName}.csv', sep=',')
|
|
718
|
+
|
|
719
|
+
OutputToFile = - pd.Series(data=[OptModel.vESSTotalCharge[p, sc, n, eh]() * mTEPES.pLoadLevelDuration[p, sc, n]() for p, sc, n, eh in mTEPES.psnehc], index=mTEPES.psnehc)
|
|
720
|
+
if pIndTechnologyOutput == 0 or pIndTechnologyOutput == 2:
|
|
721
|
+
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_ConsumptionEnergy_{CaseName}.csv', sep=',')
|
|
722
|
+
|
|
723
|
+
if pIndTechnologyOutput == 1 or pIndTechnologyOutput == 2:
|
|
724
|
+
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)
|
|
725
|
+
OutputToFile.to_frame(name='GWh').reset_index().pivot_table(index=['level_0', 'level_1', 'level_2'], columns='level_3', values='GWh').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_TechnologyConsumptionEnergy_{CaseName}.csv', sep=',')
|
|
726
|
+
|
|
727
|
+
if pIndPlotOutput == 1:
|
|
728
|
+
TechnologyCharge = OutputToFile.loc[:, :, :, :]
|
|
729
|
+
for p, sc in mTEPES.ps:
|
|
730
|
+
chart = AreaPlots(p, sc, TechnologyCharge, 'Technology', 'LoadLevel', 'MW', 'sum')
|
|
731
|
+
chart.save(f'{_path}/oT_Plot_TechnologyConsumption_{p}_{sc}_{CaseName}.html', embed_options={'renderer': 'svg'})
|
|
732
|
+
|
|
733
|
+
if pIndPlotOutput == 1:
|
|
734
|
+
OutputToFile *= -1.0
|
|
735
|
+
if OutputToFile.sum() < 0.0:
|
|
736
|
+
for p, sc in mTEPES.ps:
|
|
737
|
+
chart = PiePlots(p, sc, OutputToFile, 'Technology', '%')
|
|
738
|
+
chart.save(f'{_path}/oT_Plot_TechnologyConsumptionEnergy_{p}_{sc}_{CaseName}.html', embed_options={'renderer': 'svg'})
|
|
739
|
+
|
|
740
|
+
if sum(1 for ar in mTEPES.ar if sum(1 for eh in e2a[ar])) > 1:
|
|
741
|
+
if pIndAreaOutput == 1:
|
|
742
|
+
for ar in mTEPES.ar:
|
|
743
|
+
if sum(1 for eh in e2a[ar] if eh in e2e[et]):
|
|
744
|
+
sPSNET = [(p, sc, n, et) for p, sc, n, et in mTEPES.psnet if sum(1 for eh in e2a[ar] if (p, sc, n, eh) in mTEPES.psnehc and eh in e2e[et])]
|
|
745
|
+
if sPSNET:
|
|
746
|
+
OutputToFile = pd.Series(data=[sum(-OptModel.vESSTotalCharge[p, sc, n, eh]() * mTEPES.pLoadLevelDuration[p, sc, n]() for eh in e2a[ar] if (p,sc,n,eh) in mTEPES.psnehc and eh in e2e[et]) for p,sc,n,et in sPSNET], index=pd.Index(sPSNET))
|
|
747
|
+
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_TechnologyConsumptionEnergy_{ar}_{CaseName}.csv', sep=',')
|
|
748
|
+
|
|
749
|
+
if pIndPlotOutput == 1:
|
|
750
|
+
OutputToFile *= -1.0
|
|
751
|
+
for p, sc in mTEPES.ps:
|
|
752
|
+
chart = PiePlots(p, sc, OutputToFile, 'Technology', '%')
|
|
753
|
+
chart.save(f'{_path}/oT_Plot_TechnologyConsumptionEnergy_{p}_{sc}_{ar}_{CaseName}.html', embed_options={'renderer': 'svg'})
|
|
716
754
|
|
|
717
755
|
OutputToFile = pd.Series(data=[OptModel.vEnergyOutflows [p,sc,n,es]()*mTEPES.pLoadLevelDuration[p,sc,n]() for p,sc,n,es in mTEPES.psnes], index=mTEPES.psnes)
|
|
718
756
|
if pIndTechnologyOutput == 0 or pIndTechnologyOutput == 2:
|
|
@@ -722,43 +760,8 @@ def ESSOperationResults(DirName, CaseName, OptModel, mTEPES, pIndTechnologyOutpu
|
|
|
722
760
|
OutputToFile = pd.Series(data=[sum(OutputToFile[p,sc,n,es] for es in o2e[ot] if (p,es) in mTEPES.pes) for p,sc,n,ot in mTEPES.psnot], index=mTEPES.psnot)
|
|
723
761
|
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_TechnologyOutflowsEnergy_{CaseName}.csv', sep=',')
|
|
724
762
|
|
|
725
|
-
OutputToFile = - pd.Series(data=[OptModel.vESSTotalCharge [p,sc,n,eh]()*mTEPES.pLoadLevelDuration[p,sc,n]() for p,sc,n,eh in mTEPES.psnehc], index=mTEPES.psnehc)
|
|
726
|
-
if pIndTechnologyOutput == 0 or pIndTechnologyOutput == 2:
|
|
727
|
-
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_ConsumptionEnergy_{CaseName}.csv', sep=',')
|
|
728
|
-
|
|
729
|
-
if pIndTechnologyOutput == 1 or pIndTechnologyOutput == 2:
|
|
730
|
-
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)
|
|
731
|
-
OutputToFile.to_frame(name='GWh').reset_index().pivot_table(index=['level_0','level_1','level_2'], columns='level_3', values='GWh').rename_axis (['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_TechnologyConsumptionEnergy_{CaseName}.csv', sep=',')
|
|
732
763
|
|
|
733
|
-
|
|
734
|
-
TechnologyCharge = OutputToFile.loc[:,:,:,:]
|
|
735
|
-
for p,sc in mTEPES.ps:
|
|
736
|
-
chart = AreaPlots(p, sc, TechnologyCharge, 'Technology', 'LoadLevel', 'MW', 'sum')
|
|
737
|
-
chart.save(f'{_path}/oT_Plot_TechnologyConsumption_{p}_{sc}_{CaseName}.html', embed_options={'renderer': 'svg'})
|
|
738
|
-
|
|
739
|
-
if pIndPlotOutput == 1:
|
|
740
|
-
OutputToFile *= -1.0
|
|
741
|
-
if OutputToFile.sum() < 0.0:
|
|
742
|
-
for p,sc in mTEPES.ps:
|
|
743
|
-
chart = PiePlots(p, sc, OutputToFile, 'Technology', '%')
|
|
744
|
-
chart.save(f'{_path}/oT_Plot_TechnologyConsumptionEnergy_{p}_{sc}_{CaseName}.html', embed_options={'renderer': 'svg'})
|
|
745
|
-
|
|
746
|
-
if sum(1 for ar in mTEPES.ar if sum(1 for eh in e2a[ar])) > 1:
|
|
747
|
-
if pIndAreaOutput == 1:
|
|
748
|
-
for ar in mTEPES.ar:
|
|
749
|
-
if sum(1 for eh in e2a[ar] if eh in e2e[et]):
|
|
750
|
-
sPSNET = [(p,sc,n,et) for p,sc,n,et in mTEPES.psnet if sum(1 for eh in e2a[ar] if (p,sc,n,eh) in mTEPES.psnehc and eh in e2e[et])]
|
|
751
|
-
if len(sPSNET):
|
|
752
|
-
OutputToFile = pd.Series(data=[sum(-OptModel.vESSTotalCharge[p,sc,n,eh]()*mTEPES.pLoadLevelDuration[p,sc,n]() for eh in e2a[ar] if (p,sc,n,eh) in mTEPES.psnehc and eh in e2e[et]) for p,sc,n,et in sPSNET], index=pd.Index(sPSNET))
|
|
753
|
-
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_TechnologyConsumptionEnergy_{ar}_{CaseName}.csv', sep=',')
|
|
754
|
-
|
|
755
|
-
if pIndPlotOutput == 1:
|
|
756
|
-
OutputToFile *= -1.0
|
|
757
|
-
for p,sc in mTEPES.ps:
|
|
758
|
-
chart = PiePlots(p, sc, OutputToFile, 'Technology', '%')
|
|
759
|
-
chart.save(f'{_path}/oT_Plot_TechnologyConsumptionEnergy_{p}_{sc}_{ar}_{CaseName}.html', embed_options={'renderer': 'svg'})
|
|
760
|
-
|
|
761
|
-
# tolerance to consider avoid division by 0
|
|
764
|
+
# tolerance to avoid division by 0
|
|
762
765
|
pEpsilon = 1e-6
|
|
763
766
|
|
|
764
767
|
sPSNES = [(p,sc,n,es) for p,sc,n,es in mTEPES.ps*mTEPES.nesc if (p,es) in mTEPES.pes]
|
|
@@ -776,8 +779,8 @@ def ESSOperationResults(DirName, CaseName, OptModel, mTEPES, pIndTechnologyOutpu
|
|
|
776
779
|
|
|
777
780
|
if pIndTechnologyOutput == 1 or pIndTechnologyOutput == 2:
|
|
778
781
|
sPSNESOT = [(p,sc,n,es,ot) for p,sc,n,es,ot in sPSNES*mTEPES.ot if es in o2e[ot]]
|
|
779
|
-
OutputToFile = pd.Series(data=[OutputToFile[p,sc,n,es] for p,sc,n,es,ot in
|
|
780
|
-
OutputToFile.to_frame(name='GWh').reset_index().pivot_table(index=['level_0','level_1','level_2'], columns='
|
|
782
|
+
OutputToFile = pd.Series(data=[OutputToFile[p,sc,n,es] for p,sc,n,es,ot in sPSNESOT], index=pd.Index(sPSNESOT))
|
|
783
|
+
OutputToFile.to_frame(name='GWh').reset_index().pivot_table(index=['level_0','level_1','level_2'], columns='level_4', values='GWh', aggfunc='sum').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_TechnologySpillage_{CaseName}.csv', sep=',')
|
|
781
784
|
|
|
782
785
|
OutputToFile1 = pd.Series(data=[(OptModel.vTotalOutput[p,sc,n,es].ub*OptModel.vGenerationInvest[p,es]() - OptModel.vTotalOutput[p,sc,n,es]())*mTEPES.pLoadLevelDuration[p,sc,n]() if es in mTEPES.ec else
|
|
783
786
|
(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)
|
|
@@ -815,7 +818,7 @@ def ReservoirOperationResults(DirName, CaseName, OptModel, mTEPES, pIndTechnolog
|
|
|
815
818
|
if (ht,h ) in mTEPES.t2g:
|
|
816
819
|
o2h[ht].append(h )
|
|
817
820
|
|
|
818
|
-
# tolerance to
|
|
821
|
+
# tolerance to avoid division by 0
|
|
819
822
|
pEpsilon = 1e-6
|
|
820
823
|
|
|
821
824
|
VolumeConstraints = [(p,sc,n,rs) for p,sc,n,rs in mTEPES.ps*mTEPES.nrsc if (p,rs) in mTEPES.prs]
|
|
@@ -888,7 +891,7 @@ def NetworkH2OperationResults(DirName, CaseName, OptModel, mTEPES):
|
|
|
888
891
|
OutputResults6 = pd.Series(data=[ sum(OptModel.vFlowH2 [p,sc,n,ni,nd,cc]() for ni,cc in lin [nd]) for p,sc,n,ar,nd in sPSNARND ], index=pd.Index(sPSNARND )).to_frame(name='HydrogenFlowIn' )
|
|
889
892
|
OutputResults = pd.concat([OutputResults2, OutputResults3, OutputResults4, OutputResults5, OutputResults6], axis=1)
|
|
890
893
|
|
|
891
|
-
OutputResults.stack().rename_axis(['Period', 'Scenario', 'LoadLevel', 'Area', 'Node', 'Technology'], axis=0).reset_index().rename(columns={0: 'tH2'}, inplace=False).to_csv(f'{_path}/oT_Result_BalanceHydrogen_{CaseName}.csv', index=False, sep=',')
|
|
894
|
+
# OutputResults.stack().rename_axis(['Period', 'Scenario', 'LoadLevel', 'Area', 'Node', 'Technology'], axis=0).reset_index().rename(columns={0: 'tH2'}, inplace=False).to_csv(f'{_path}/oT_Result_BalanceHydrogen_{CaseName}.csv', index=False, sep=',')
|
|
892
895
|
|
|
893
896
|
OutputResults.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).to_csv(f'{_path}/oT_Result_BalanceHydrogenPerTech_{CaseName}.csv', sep=',')
|
|
894
897
|
OutputResults.stack().reset_index().pivot_table(index=['level_0','level_1','level_2' ,'level_5'], columns='level_4', values=0, aggfunc='sum').rename_axis(['Period', 'Scenario', 'LoadLevel', 'Technology' ], axis=0).to_csv(f'{_path}/oT_Result_BalanceHydrogenPerNode_{CaseName}.csv', sep=',')
|
|
@@ -987,7 +990,7 @@ def NetworkH2OperationResults(DirName, CaseName, OptModel, mTEPES):
|
|
|
987
990
|
|
|
988
991
|
return loc_df, line_df
|
|
989
992
|
|
|
990
|
-
# tolerance to
|
|
993
|
+
# tolerance to avoid division by 0
|
|
991
994
|
pEpsilon = 1e-6
|
|
992
995
|
|
|
993
996
|
p = list(mTEPES.p)[0]
|
|
@@ -1020,7 +1023,7 @@ def NetworkH2OperationResults(DirName, CaseName, OptModel, mTEPES):
|
|
|
1020
1023
|
|
|
1021
1024
|
# Add edges
|
|
1022
1025
|
for ni,nf,cc in mTEPES.pa:
|
|
1023
|
-
fig.add_trace(go.Scattermapbox(lon=[pos_dict[ni][0], pos_dict[nf][0]], lat=[pos_dict[ni][1], pos_dict[nf][1]], mode='lines+markers', marker=dict(size=0, showscale=True, colorbar={'title': 'Utilization [%]', '
|
|
1026
|
+
fig.add_trace(go.Scattermapbox(lon=[pos_dict[ni][0], pos_dict[nf][0]], lat=[pos_dict[ni][1], pos_dict[nf][1]], mode='lines+markers', marker=dict(size=0, showscale=True, colorbar={'title': 'Utilization [%]', 'title_side': 'top', 'thickness': 8, 'ticksuffix': '%'}, colorscale=[[0, 'lightgreen'], [1, 'darkred']], cmin=0, cmax=100,), line=dict(width=line_df.loc[(ni,nf),'width'], color=line_df.loc[(ni,nf),'color']), opacity=1, hoverinfo='text', textposition='middle center',))
|
|
1024
1027
|
|
|
1025
1028
|
# Add legends related to the lines
|
|
1026
1029
|
fig.add_trace(go.Scattermapbox(lat=line_df['lat'], lon=line_df['lon'], mode='markers', marker=go.scattermapbox.Marker(size=20, sizeref=1.1, sizemode='area', color='LightSkyBlue',), opacity=0, hoverinfo='text', text='<br>Line: '+line_df['ni']+' → '+line_df['nf']+'<br># circuits: '+line_df['cc'].astype(str)+'<br>NTC Forward: '+line_df['NTCFrw'].astype(str)+'<br>NTC Backward: '+line_df['NTCBck'].astype(str)+'<br>Power flow: '+line_df['vFlowH2'].astype(str)+'<br>Utilization [%]: '+line_df['utilization'].astype(str),))
|
|
@@ -1088,7 +1091,7 @@ def NetworkHeatOperationResults(DirName, CaseName, OptModel, mTEPES):
|
|
|
1088
1091
|
OutputResults8 = pd.Series(data=[ sum(OptModel.vFlowHeat [p,sc,n,ni,nd,cc]()*mTEPES.pLoadLevelDuration[p,sc,n]() for ni,cc in lin [nd]) for p,sc,n,ar,nd in sPSNARND ], index=pd.Index(sPSNARND )).to_frame(name='HeatFlowIn' )
|
|
1089
1092
|
OutputResults = pd.concat([OutputResults2, OutputResults3, OutputResults4, OutputResults5, OutputResults6, OutputResults7, OutputResults8], axis=1)
|
|
1090
1093
|
|
|
1091
|
-
OutputResults.stack().rename_axis(['Period', 'Scenario', 'LoadLevel', 'Area', 'Node', 'Technology'], axis=0).reset_index().rename(columns={0: 'GWh'}, inplace=False).to_csv(f'{_path}/oT_Result_BalanceHeat_{CaseName}.csv', index=False, sep=',')
|
|
1094
|
+
# OutputResults.stack().rename_axis(['Period', 'Scenario', 'LoadLevel', 'Area', 'Node', 'Technology'], axis=0).reset_index().rename(columns={0: 'GWh'}, inplace=False).to_csv(f'{_path}/oT_Result_BalanceHeat_{CaseName}.csv', index=False, sep=',')
|
|
1092
1095
|
|
|
1093
1096
|
OutputResults.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).to_csv(f'{_path}/oT_Result_BalanceHeatPerTech_{CaseName}.csv', sep=',')
|
|
1094
1097
|
OutputResults.stack().reset_index().pivot_table(index=['level_0','level_1','level_2' ,'level_5'], columns='level_4', values=0, aggfunc='sum').rename_axis(['Period', 'Scenario', 'LoadLevel', 'Technology' ], axis=0).to_csv(f'{_path}/oT_Result_BalanceHeatPerNode_{CaseName}.csv', sep=',')
|
|
@@ -1111,13 +1114,13 @@ def NetworkHeatOperationResults(DirName, CaseName, OptModel, mTEPES):
|
|
|
1111
1114
|
OutputToFile = pd.pivot_table(OutputToFile.to_frame(name='GWh'), values='GWh', index=['Period', 'Scenario'], columns=['InitialArea', 'FinalArea'], fill_value=0.0).rename_axis([None, None], axis=1)
|
|
1112
1115
|
OutputToFile.reset_index().to_csv(f'{_path}/oT_Result_NetworkEnergyHeatTotalPerArea_{CaseName}.csv', index=False, sep=',')
|
|
1113
1116
|
|
|
1114
|
-
if
|
|
1117
|
+
if mTEPES.ha:
|
|
1115
1118
|
OutputResults = pd.Series(data=[OptModel.vFlowHeat[p,sc,n,ni,nf,cc]()*(mTEPES.pLoadLevelDuration[p,sc,n]()*mTEPES.pPeriodProb[p,sc]())*(mTEPES.pHeatPipeLength[ni,nf,cc]()*1e-3) for p,sc,n,ni,nf,cc in mTEPES.psnha], index=mTEPES.psnha)
|
|
1116
1119
|
OutputResults.index.names = ['Scenario', 'Period', 'LoadLevel', 'InitialNode', 'FinalNode', 'Circuit']
|
|
1117
1120
|
OutputResults = OutputResults.reset_index().groupby(['InitialNode', 'FinalNode', 'Circuit']).sum(numeric_only=True)[0]
|
|
1118
1121
|
OutputResults.to_frame(name='GWh-Mkm').rename_axis(['InitialNode', 'FinalNode', 'Circuit'], axis=0).reset_index().to_csv(f'{_path}/oT_Result_NetworkEnergyHeatTransport_{CaseName}.csv', index=False, sep=',')
|
|
1119
1122
|
|
|
1120
|
-
# tolerance to
|
|
1123
|
+
# tolerance to avoid division by 0
|
|
1121
1124
|
pEpsilon = 1e-6
|
|
1122
1125
|
|
|
1123
1126
|
OutputToFile = pd.Series(data=[max(OptModel.vFlowHeat[p,sc,n,ni,nf,cc]()/(mTEPES.pHeatPipeNTCFrw[ni,nf,cc]+pEpsilon),-OptModel.vFlowHeat[p,sc,n,ni,nf,cc]()/(mTEPES.pHeatPipeNTCBck[ni,nf,cc]+pEpsilon)) for p,sc,n,ni,nf,cc in mTEPES.psnha], index=mTEPES.psnha)
|
|
@@ -1246,7 +1249,7 @@ def NetworkHeatOperationResults(DirName, CaseName, OptModel, mTEPES):
|
|
|
1246
1249
|
|
|
1247
1250
|
# Add edges
|
|
1248
1251
|
for ni,nf,cc in mTEPES.ha:
|
|
1249
|
-
fig.add_trace(go.Scattermapbox(lon=[pos_dict[ni][0], pos_dict[nf][0]], lat=[pos_dict[ni][1], pos_dict[nf][1]], mode='lines+markers', marker=dict(size=0, showscale=True, colorbar={'title': 'Utilization [%]', '
|
|
1252
|
+
fig.add_trace(go.Scattermapbox(lon=[pos_dict[ni][0], pos_dict[nf][0]], lat=[pos_dict[ni][1], pos_dict[nf][1]], mode='lines+markers', marker=dict(size=0, showscale=True, colorbar={'title': 'Utilization [%]', 'title_side': 'top', 'thickness': 8, 'ticksuffix': '%'}, colorscale=[[0, 'lightgreen'], [1, 'darkred']], cmin=0, cmax=100,), line=dict(width=line_df.loc[(ni,nf),'width'], color=line_df.loc[(ni,nf),'color']), opacity=1, hoverinfo='text', textposition='middle center',))
|
|
1250
1253
|
|
|
1251
1254
|
# Add legends related to the lines
|
|
1252
1255
|
fig.add_trace(go.Scattermapbox(lat=line_df['lat'], lon=line_df['lon'], mode='markers', marker=go.scattermapbox.Marker(size=20, sizeref=1.1, sizemode='area', color='LightSkyBlue',), opacity=0, hoverinfo='text', text='<br>Line: '+line_df['ni']+' → '+line_df['nf']+'<br># circuits: '+line_df['cc'].astype(str)+'<br>NTC Forward: '+line_df['NTCFrw'].astype(str)+'<br>NTC Backward: '+line_df['NTCBck'].astype(str)+'<br>Power flow: '+line_df['vFlowHeat'].astype(str)+'<br>Utilization [%]: '+line_df['utilization'].astype(str),))
|
|
@@ -1297,7 +1300,7 @@ def OperationSummaryResults(DirName, CaseName, OptModel, mTEPES):
|
|
|
1297
1300
|
TotalGeneration = sum(OptModel.vTotalOutput[p,sc,n,g ]()*mTEPES.pLoadLevelDuration[p,sc,n]() for p,sc,n,g in mTEPES.psng )
|
|
1298
1301
|
FossilFuelGeneration = sum(OptModel.vTotalOutput[p,sc,n,g ]()*mTEPES.pLoadLevelDuration[p,sc,n]() for p,sc,n,g in mTEPES.psng if g in mTEPES.t)
|
|
1299
1302
|
# Ratio Total Investments [%]
|
|
1300
|
-
TotalInvestmentCost = sum(mTEPES.pDiscountedWeight[p] * OptModel.vTotalFCost [p]()
|
|
1303
|
+
TotalInvestmentCost = sum(mTEPES.pDiscountedWeight[p] * OptModel.vTotalFCost [p ]() for p in mTEPES.p if len(mTEPES.gc) + len(mTEPES.gd) + len(mTEPES.lc))
|
|
1301
1304
|
GenInvestmentCost = sum(mTEPES.pDiscountedWeight[p] * mTEPES.pGenInvestCost[gc] * OptModel.vGenerationInvest[p,gc]() for p,gc in mTEPES.pgc)
|
|
1302
1305
|
GenRetirementCost = sum(mTEPES.pDiscountedWeight[p] * mTEPES.pGenRetireCost[gd] * OptModel.vGenerationRetire[p,gd]() for p,gd in mTEPES.pgd)
|
|
1303
1306
|
if mTEPES.pIndHydroTopology == 1:
|
|
@@ -1306,18 +1309,18 @@ def OperationSummaryResults(DirName, CaseName, OptModel, mTEPES):
|
|
|
1306
1309
|
RsrInvestmentCost = 0.0
|
|
1307
1310
|
NetInvestmentCost = sum(mTEPES.pDiscountedWeight[p] * mTEPES.pNetFixedCost [ni,nf,cc] * OptModel.vNetworkInvest [p,ni,nf,cc]() for p,ni,nf,cc in mTEPES.plc)
|
|
1308
1311
|
# Ratio Generation Investment cost/ Generation Installed Capacity [MEUR-MW]
|
|
1309
|
-
GenInvCostCapacity = sum(mTEPES.pGenInvestCost[gc] * OptModel.vGenerationInvest[p,gc]()/mTEPES.pRatedMaxPowerElec[gc]
|
|
1312
|
+
GenInvCostCapacity = sum(mTEPES.pDiscountedWeight[p] * mTEPES.pGenInvestCost[gc] * OptModel.vGenerationInvest[p,gc]()/mTEPES.pRatedMaxPowerElec[gc] for p,gc in mTEPES.pgc if mTEPES.pRatedMaxPowerElec[gc])
|
|
1310
1313
|
# Ratio Additional Transmission Capacity-Length [MW-km]
|
|
1311
1314
|
NetCapacityLength = sum(mTEPES.pLineNTCMax[ni,nf,cc]*OptModel.vNetworkInvest[p,ni,nf,cc]()/mTEPES.pLineLength[ni,nf,cc]() for p,ni,nf,cc in mTEPES.plc)
|
|
1312
1315
|
# Ratio Network Investment Cost/Variable RES Injection [EUR/MWh]
|
|
1313
|
-
if
|
|
1316
|
+
if mTEPES.gc and sum(OptModel.vTotalOutput[p,sc,n,gc]()*mTEPES.pLoadLevelDuration[p,sc,n]() for p,sc,n,gc in mTEPES.psngc if gc in mTEPES.re):
|
|
1314
1317
|
NetInvCostVRESInsCap = NetInvestmentCost*1e6/sum(OptModel.vTotalOutput[p,sc,n,gc]()*mTEPES.pLoadLevelDuration[p,sc,n]() for p,sc,n,gc in mTEPES.psngc if gc in mTEPES.re)
|
|
1315
1318
|
else:
|
|
1316
1319
|
NetInvCostVRESInsCap = 0.0
|
|
1317
1320
|
# Rate of return for VRE technologies
|
|
1318
1321
|
# warning division and multiplication
|
|
1319
1322
|
VRETechRevenue = sum(mTEPES.pDuals["".join([f"eBalanceElec_{p}_{sc}_{st}('{n}', '{nd}')"])]/mTEPES.pPeriodProb[p,sc]()/mTEPES.pLoadLevelDuration[p,sc,n]()*OptModel.vTotalOutput[p,sc,n,gc]() for p,sc,st,n,nd,gc in mTEPES.s2n*mTEPES.nd*mTEPES.gc if gc in g2n[nd] and gc in mTEPES.re and (p,gc) in mTEPES.pgc and (p,sc,n) in mTEPES.psn and sum(1 for g in g2n[nd]) + sum(1 for nf,cc in lout[nd]) + sum(1 for ni,cc in lin[nd]))
|
|
1320
|
-
VREInvCostCapacity = sum(mTEPES.pGenInvestCost[gc]*OptModel.vGenerationInvest[p,gc]() for p,gc in mTEPES.pgc if gc in mTEPES.re)
|
|
1323
|
+
VREInvCostCapacity = sum(mTEPES.pDiscountedWeight[p]*mTEPES.pGenInvestCost[gc]*OptModel.vGenerationInvest[p,gc]() for p,gc in mTEPES.pgc if gc in mTEPES.re)
|
|
1321
1324
|
|
|
1322
1325
|
K1 = pd.Series(data={'Ratio Fossil Fuel Generation/Total Generation [%]' : FossilFuelGeneration / TotalGeneration *1e2}).to_frame(name='Value')
|
|
1323
1326
|
if GenInvestmentCost:
|
|
@@ -1357,17 +1360,17 @@ def OperationSummaryResults(DirName, CaseName, OptModel, mTEPES):
|
|
|
1357
1360
|
OutputResults.to_csv(f'{_path}/oT_Result_SummaryKPIs_{CaseName}.csv', sep=',', index=True)
|
|
1358
1361
|
|
|
1359
1362
|
# LCOE per technology
|
|
1360
|
-
if
|
|
1361
|
-
GenTechInvestCost = pd.Series(data=[sum(
|
|
1362
|
-
GenTechInjection = pd.Series(data=[sum(OptModel.vTotalOutput [p,sc,n,gc]()*mTEPES.pLoadLevelDuration[p,sc,n ]()
|
|
1363
|
+
if mTEPES.gc:
|
|
1364
|
+
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)
|
|
1365
|
+
GenTechInjection = pd.Series(data=[sum(OptModel.vTotalOutput [p,sc,n,gc]()*mTEPES.pLoadLevelDuration[p,sc,n ]() for p,sc,n,gc in mTEPES.psngc if gc in g2t[gt]) for gt in mTEPES.gt], index=mTEPES.gt)
|
|
1363
1366
|
GenTechInvestCost *= 1e3
|
|
1364
1367
|
LCOE = GenTechInvestCost.div(GenTechInjection).to_frame(name='EUR/MWh')
|
|
1365
1368
|
LCOE.rename_axis(['Technology'], axis=0).to_csv(f'{_path}/oT_Result_TechnologyLCOE_{CaseName}.csv', index=True, sep=',')
|
|
1366
1369
|
|
|
1367
1370
|
# LCOE per technology
|
|
1368
|
-
if
|
|
1369
|
-
GenTechInvestCost = pd.Series(data=[sum(
|
|
1370
|
-
GenTechInjection = pd.Series(data=[sum(OptModel.vTotalOutputHeat [p,sc,n,gb]()*mTEPES.pLoadLevelDuration[p,sc,n ]()
|
|
1371
|
+
if mTEPES.gb:
|
|
1372
|
+
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)
|
|
1373
|
+
GenTechInjection = pd.Series(data=[sum(OptModel.vTotalOutputHeat [p,sc,n,gb]()*mTEPES.pLoadLevelDuration[p,sc,n ]() for p,sc,n,gb in mTEPES.psngb if gb in g2t[gt]) for gt in mTEPES.gt], index=mTEPES.gt)
|
|
1371
1374
|
GenTechInvestCost *= 1e3
|
|
1372
1375
|
LCOH = GenTechInvestCost.div(GenTechInjection).to_frame(name='EUR/MWh')
|
|
1373
1376
|
LCOH.rename_axis(['Technology'], axis=0).to_csv(f'{_path}/oT_Result_TechnologyLCOH_{CaseName}.csv', index=True, sep=',')
|
|
@@ -1388,9 +1391,9 @@ def OperationSummaryResults(DirName, CaseName, OptModel, mTEPES):
|
|
|
1388
1391
|
OutputToFile04 = pd.Series(data=[a2g[0][g] for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='Area' )
|
|
1389
1392
|
OutputToFile05 = pd.Series(data=[r2g[0][g] for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='Region' )
|
|
1390
1393
|
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]' )
|
|
1391
|
-
OutputToFile07 = pd.Series(data=[OptModel.vCommitment [p,sc,n,g]() if g in mTEPES.nr else 0
|
|
1392
|
-
OutputToFile08 = pd.Series(data=[OptModel.vStartUp [p,sc,n,g]() if g in mTEPES.nr else 0
|
|
1393
|
-
OutputToFile09 = pd.Series(data=[OptModel.vShutDown [p,sc,n,g]() if g in mTEPES.nr else 0
|
|
1394
|
+
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}' )
|
|
1395
|
+
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}' )
|
|
1396
|
+
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}' )
|
|
1394
1397
|
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]' )
|
|
1395
1398
|
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]' )
|
|
1396
1399
|
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]' )
|
|
@@ -1416,7 +1419,7 @@ def OperationSummaryResults(DirName, CaseName, OptModel, mTEPES):
|
|
|
1416
1419
|
|
|
1417
1420
|
OutputResults = pd.concat([OutputToFile01, OutputToFile02, OutputToFile03, OutputToFile04, OutputToFile05, OutputToFile06, OutputToFile07, OutputToFile08, OutputToFile09, OutputToFile10,
|
|
1418
1421
|
OutputToFile11, OutputToFile12, OutputToFile13, OutputToFile14, OutputToFile15, OutputToFile16, OutputToFile17, OutputToFile18, OutputToFile19, OutputToFile20,
|
|
1419
|
-
|
|
1422
|
+
OutputToFile21, OutputToFile22], axis=1)
|
|
1420
1423
|
# OutputResults.rename_axis(['Period', 'Scenario', 'LoadLevel', 'Generator'], axis=0).to_csv (f'{_path}/oT_Result_SummaryGeneration_{CaseName}.csv', sep=',')
|
|
1421
1424
|
# OutputResults.rename_axis(['Period', 'Scenario', 'LoadLevel', 'Generator'], axis=0).to_parquet(f'{_path}/oT_Result_SummaryGeneration_{CaseName}.parquet', engine='pyarrow')
|
|
1422
1425
|
|
|
@@ -1433,7 +1436,7 @@ def OperationSummaryResults(DirName, CaseName, OptModel, mTEPES):
|
|
|
1433
1436
|
OutputResults4 = pd.Series(data=[- mTEPES.pDemandElec [p,sc,n,nd ] *mTEPES.pLoadLevelDuration[p,sc,n]() for p,sc,n,nd in sPSNND], index=pd.Index(sPSNND)).to_frame(name='PowerDemand [GWh]' )
|
|
1434
1437
|
OutputResults5 = pd.Series(data=[-sum(OptModel.vFlowElec [p,sc,n,nd,nf,cc]()*mTEPES.pLoadLevelDuration[p,sc,n]() for nf,cc in lout [nd]) for p,sc,n,nd in sPSNND], index=pd.Index(sPSNND)).to_frame(name='PowerFlowOut [GWh]' )
|
|
1435
1438
|
OutputResults6 = pd.Series(data=[ sum(OptModel.vFlowElec [p,sc,n,ni,nd,cc]()*mTEPES.pLoadLevelDuration[p,sc,n]() for ni,cc in lin [nd]) for p,sc,n,nd in sPSNND], index=pd.Index(sPSNND)).to_frame(name='PowerFlowIn [GWh]' )
|
|
1436
|
-
if
|
|
1439
|
+
if mTEPES.ll:
|
|
1437
1440
|
OutputResults7 = pd.Series(data=[-sum(OptModel.vLineLosses[p,sc,n,nd,nf,cc]()*mTEPES.pLoadLevelDuration[p,sc,n]() for nf,cc in loutl[nd]) for p,sc,n,nd in sPSNND], index=pd.Index(sPSNND)).to_frame(name='LineLossesOut [GWh]')
|
|
1438
1441
|
OutputResults8 = pd.Series(data=[-sum(OptModel.vLineLosses[p,sc,n,ni,nd,cc]()*mTEPES.pLoadLevelDuration[p,sc,n]() for ni,cc in linl [nd]) for p,sc,n,nd in sPSNND], index=pd.Index(sPSNND)).to_frame(name='LineLossesIn [GWh]' )
|
|
1439
1442
|
|
|
@@ -1476,12 +1479,12 @@ def FlexibilityResults(DirName, CaseName, OptModel, mTEPES):
|
|
|
1476
1479
|
OutputToFile *= 1e3
|
|
1477
1480
|
TechnologyOutput = OutputToFile.loc[:,:,:,:]
|
|
1478
1481
|
MeanTechnologyOutput = OutputToFile.to_frame(name='MW').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).mean()
|
|
1479
|
-
NetTechnologyOutput = pd.Series([0.0]*len(mTEPES.psngt), index=mTEPES.psngt)
|
|
1482
|
+
NetTechnologyOutput = pd.Series([0.0] * len(mTEPES.psngt), index=mTEPES.psngt)
|
|
1480
1483
|
for p,sc,n,gt in mTEPES.psngt:
|
|
1481
1484
|
NetTechnologyOutput[p,sc,n,gt] = TechnologyOutput[p,sc,n,gt] - MeanTechnologyOutput[gt]
|
|
1482
1485
|
NetTechnologyOutput.to_frame(name='MW').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_FlexibilityTechnology_{CaseName}.csv', sep=',')
|
|
1483
1486
|
|
|
1484
|
-
if
|
|
1487
|
+
if mTEPES.es:
|
|
1485
1488
|
OutputToFile = pd.Series(data=[sum(OptModel.vTotalOutput[p,sc,n,es]() for es in o2e[ot] if (p,es) in mTEPES.pes) for p,sc,n,ot in mTEPES.psnot], index=mTEPES.psnot)
|
|
1486
1489
|
OutputToFile *= 1e3
|
|
1487
1490
|
ESSTechnologyOutput = -OutputToFile.loc[:,:,:,:]
|
|
@@ -1517,7 +1520,7 @@ def NetworkOperationResults(DirName, CaseName, OptModel, mTEPES):
|
|
|
1517
1520
|
StartTime = time.time()
|
|
1518
1521
|
|
|
1519
1522
|
if sum(mTEPES.pIndBinLineSwitch[:, :, :]):
|
|
1520
|
-
if
|
|
1523
|
+
if mTEPES.lc:
|
|
1521
1524
|
OutputToFile = pd.Series(data=[OptModel.vLineCommit [p,sc,n,ni,nf,cc]() for p,sc,n,ni,nf,cc in mTEPES.psnla], index=mTEPES.psnla)
|
|
1522
1525
|
OutputToFile.index.names = ['Period', 'Scenario', 'LoadLevel', 'InitialNode', 'FinalNode', 'Circuit']
|
|
1523
1526
|
OutputToFile = pd.pivot_table(OutputToFile.to_frame(name='p.u.'), values='p.u.', index=['Period', 'Scenario', 'LoadLevel'], columns=['InitialNode', 'FinalNode', 'Circuit'], fill_value=0.0).rename_axis([None, None, None], axis=1)
|
|
@@ -1548,22 +1551,22 @@ def NetworkOperationResults(DirName, CaseName, OptModel, mTEPES):
|
|
|
1548
1551
|
OutputToFile = pd.pivot_table(OutputToFile.to_frame(name='GWh'), values='GWh', index=['Period', 'Scenario'], columns=['InitialArea', 'FinalArea'], fill_value=0.0).rename_axis([None, None], axis=1)
|
|
1549
1552
|
OutputToFile.reset_index().to_csv(f'{_path}/oT_Result_NetworkEnergyElecTotalPerArea_{CaseName}.csv', index=False, sep=',')
|
|
1550
1553
|
|
|
1551
|
-
if
|
|
1554
|
+
if mTEPES.la:
|
|
1552
1555
|
OutputResults = pd.Series(data=[OptModel.vFlowElec[p,sc,n,ni,nf,cc]()*(mTEPES.pLoadLevelDuration[p,sc,n]()*mTEPES.pPeriodProb[p,sc]())*(mTEPES.pLineLength[ni,nf,cc]()*1e-3) for p,sc,n,ni,nf,cc in mTEPES.psnla], index=mTEPES.psnla)
|
|
1553
1556
|
OutputResults.index.names = ['Scenario', 'Period', 'LoadLevel', 'InitialNode', 'FinalNode', 'Circuit']
|
|
1554
1557
|
OutputResults = OutputResults.reset_index().groupby(['InitialNode', 'FinalNode', 'Circuit']).sum(numeric_only=True)[0]
|
|
1555
1558
|
OutputResults.to_frame(name='GWh-Mkm').rename_axis(['InitialNode', 'FinalNode', 'Circuit'], axis=0).reset_index().to_csv(f'{_path}/oT_Result_NetworkEnergyElecTransport_{CaseName}.csv', index=False, sep=',')
|
|
1556
1559
|
|
|
1557
|
-
# tolerance to
|
|
1560
|
+
# tolerance to avoid division by 0
|
|
1558
1561
|
pEpsilon = 1e-6
|
|
1559
1562
|
|
|
1560
|
-
OutputToFile = pd.Series(data=[max(OptModel.vFlowElec[p,sc,n,ni,nf,cc]()/(mTEPES.
|
|
1563
|
+
OutputToFile = pd.Series(data=[max(OptModel.vFlowElec[p,sc,n,ni,nf,cc]()/(mTEPES.pMaxNTCFrw[p,sc,n,ni,nf,cc]+pEpsilon),-OptModel.vFlowElec[p,sc,n,ni,nf,cc]()/(mTEPES.pMaxNTCBck[p,sc,n,ni,nf,cc]+pEpsilon)) for p,sc,n,ni,nf,cc in mTEPES.psnla], index=mTEPES.psnla)
|
|
1561
1564
|
OutputToFile.index.names = ['Period', 'Scenario', 'LoadLevel', 'InitialNode', 'FinalNode', 'Circuit']
|
|
1562
1565
|
OutputToFile = pd.pivot_table(OutputToFile.to_frame(name='p.u.'), values='p.u.', index=['Period', 'Scenario', 'LoadLevel'], columns=['InitialNode', 'FinalNode', 'Circuit'], fill_value=0.0).rename_axis([None, None, None], axis=1)
|
|
1563
1566
|
OutputToFile.reset_index().to_csv(f'{_path}/oT_Result_NetworkElecUtilization_{CaseName}.csv', index=False, sep=',')
|
|
1564
1567
|
|
|
1565
|
-
if mTEPES.pIndBinNetLosses() and
|
|
1566
|
-
OutputToFile = pd.Series(data=[OptModel.vLineLosses[p,sc,n,ni,nf,cc]()
|
|
1568
|
+
if mTEPES.pIndBinNetLosses() and mTEPES.psnll:
|
|
1569
|
+
OutputToFile = pd.Series(data=[OptModel.vLineLosses[p,sc,n,ni,nf,cc]()*2*1e3 for p,sc,n,ni,nf,cc in mTEPES.psnll], index=mTEPES.psnll)
|
|
1567
1570
|
OutputToFile.index.names = ['Period', 'Scenario', 'LoadLevel', 'InitialNode', 'FinalNode', 'Circuit']
|
|
1568
1571
|
OutputToFile = pd.pivot_table(OutputToFile.to_frame(name='p.u.'), values='p.u.', index=['Period', 'Scenario', 'LoadLevel'], columns=['InitialNode', 'FinalNode', 'Circuit'], fill_value=0.0).rename_axis([None, None, None], axis=1)
|
|
1569
1572
|
OutputToFile.reset_index().to_csv(f'{_path}/oT_Result_NetworkLosses_{CaseName}.csv', index=False, sep=',')
|
|
@@ -1639,7 +1642,7 @@ def MarginalResults(DirName, CaseName, OptModel, mTEPES, pIndPlotOutput):
|
|
|
1639
1642
|
OutputToFile.rename_axis(['Period', 'Scenario', 'LoadLevel', 'Area'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_MarginalIncrementalVariableCost_{CaseName}.csv', sep=',')
|
|
1640
1643
|
IncrementalGens = pd.Series('N/A', index=mTEPES.psnar).to_frame(name='Generating unit')
|
|
1641
1644
|
for p,sc,n,ar in mTEPES.psnar:
|
|
1642
|
-
if
|
|
1645
|
+
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):
|
|
1643
1646
|
if len(OutputToFile.loc[(p,sc,n,ar)]) > 1:
|
|
1644
1647
|
IncrementalGens.loc[p,sc,n,ar] = OutputToFile.loc[[(p,sc,n,ar)]].squeeze().idxmin()
|
|
1645
1648
|
else:
|
|
@@ -1649,7 +1652,7 @@ def MarginalResults(DirName, CaseName, OptModel, mTEPES, pIndPlotOutput):
|
|
|
1649
1652
|
OutputToFile = pd.Series(data=[mTEPES.pEmissionRate[g] for p,sc,n,ar,g in sPSNARG], index=pd.Index(sPSNARG))
|
|
1650
1653
|
OutputToFile.to_frame(name='tCO2/MWh').reset_index().pivot_table(index=['level_0','level_1','level_2','level_3'], columns='level_4', values='tCO2/MWh').rename_axis(['Period', 'Scenario', 'LoadLevel', 'Area'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_GenerationIncrementalEmission_{CaseName}.csv', sep=',')
|
|
1651
1654
|
|
|
1652
|
-
#%% outputting the LSRMC
|
|
1655
|
+
#%% outputting the LSRMC of electricity
|
|
1653
1656
|
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]
|
|
1654
1657
|
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,nd in sPSSTNND], index=pd.Index(sPSSTNND))
|
|
1655
1658
|
OutputResults *= 1e3
|
|
@@ -1702,37 +1705,37 @@ def MarginalResults(DirName, CaseName, OptModel, mTEPES, pIndPlotOutput):
|
|
|
1702
1705
|
|
|
1703
1706
|
if pIndPlotOutput == 1:
|
|
1704
1707
|
for p,sc in mTEPES.ps:
|
|
1705
|
-
chart = LinePlots(p, sc, OptModel.LSRMCHeat, 'Node', 'LoadLevel', 'EUR/
|
|
1708
|
+
chart = LinePlots(p, sc, OptModel.LSRMCHeat, 'Node', 'LoadLevel', 'EUR/GJ', 'average')
|
|
1706
1709
|
chart.save(f'{_path}/oT_Plot_NetworkSRMCHeat_{p}_{sc}_{CaseName}.html', embed_options={'renderer': 'svg'})
|
|
1707
1710
|
|
|
1708
1711
|
if sum(mTEPES.pReserveMargin[:,:]):
|
|
1709
|
-
if
|
|
1712
|
+
if mTEPES.gc:
|
|
1710
1713
|
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]]
|
|
1711
|
-
if
|
|
1714
|
+
if sPSSTAR:
|
|
1712
1715
|
OutputResults = pd.Series(data=[mTEPES.pDuals["".join([f"eAdequacyReserveMarginElec_{p}_{sc}_{st}{ar}"])] for p,sc,st,ar in sPSSTAR], index=pd.Index(sPSSTAR))
|
|
1713
1716
|
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=',')
|
|
1714
1717
|
|
|
1715
1718
|
if mTEPES.pIndHeat == 1:
|
|
1716
1719
|
if sum(mTEPES.pReserveMarginHeat[:,:]):
|
|
1717
|
-
if
|
|
1720
|
+
if mTEPES.gc:
|
|
1718
1721
|
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]]
|
|
1719
|
-
if
|
|
1722
|
+
if sPSSTAR:
|
|
1720
1723
|
OutputResults = pd.Series(data=[mTEPES.pDuals["".join([f"eAdequacyReserveMarginHeat_{p}_{sc}_{st}{ar}"])] for p,sc,st,ar in sPSSTAR], index=pd.Index(sPSSTAR))
|
|
1721
1724
|
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=',')
|
|
1722
1725
|
|
|
1723
1726
|
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)]
|
|
1724
|
-
if
|
|
1727
|
+
if sPSSTAR:
|
|
1725
1728
|
OutputResults = pd.Series(data=[mTEPES.pDuals["".join([f"eMaxSystemEmission_{p}_{sc}_{st}{ar}"])] for p,sc,st,ar in sPSSTAR], index=pd.Index(sPSSTAR))
|
|
1726
1729
|
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=',')
|
|
1727
1730
|
|
|
1728
1731
|
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]
|
|
1729
|
-
if
|
|
1732
|
+
if sPSSTAR:
|
|
1730
1733
|
OutputResults = pd.Series(data=[mTEPES.pDuals["".join([f"eMinSystemRESEnergy_{p}_{sc}_{st}{ar}"])] for p,sc,st,ar in sPSSTAR], index=pd.Index(sPSSTAR))
|
|
1731
1734
|
OutputResults *= 1e-3*sum(mTEPES.pLoadLevelDuration[p,sc,na]() for na in mTEPES.na)
|
|
1732
1735
|
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=',')
|
|
1733
1736
|
|
|
1734
1737
|
#%% outputting the up operating reserve marginal
|
|
1735
|
-
if sum(mTEPES.pOperReserveUp[:,:,:,:]) and sum(1 for ar,nr in mTEPES.ar*mTEPES.nr if nr in n2a[ar] and mTEPES.
|
|
1738
|
+
if sum(mTEPES.pOperReserveUp[:,:,:,:]) and sum(1 for ar,nr in mTEPES.ar*mTEPES.nr if nr in n2a[ar] and (mTEPES.pIndOperReserveGen[nr] == 0 or mTEPES.pIndOperReserveCon[nr] == 0)) + sum(1 for ar,es in mTEPES.ar*mTEPES.es if es in e2a[ar] if (mTEPES.pIndOperReserveGen[es] == 0 or mTEPES.pIndOperReserveCon[es] == 0)):
|
|
1736
1739
|
sPSSTNAR = [(p,sc,st,n,ar) for p,sc,st,n,ar in mTEPES.s2n*mTEPES.ar if mTEPES.pOperReserveUp[p,sc,n,ar] and sum(1 for nr in n2a[ar]) + sum(1 for es in e2a[ar]) and (p,sc,n) in mTEPES.psn]
|
|
1737
1740
|
OutputResults = pd.Series(data=[mTEPES.pDuals["".join([f"eOperReserveUp_{p}_{sc}_{st}('{n}', '{ar}')"])] for p,sc,st,n,ar in sPSSTNAR], index=pd.Index(sPSSTNAR))
|
|
1738
1741
|
OutputResults *= 1e3
|
|
@@ -1745,7 +1748,7 @@ def MarginalResults(DirName, CaseName, OptModel, mTEPES, pIndPlotOutput):
|
|
|
1745
1748
|
chart.save(f'{_path}/oT_Plot_MarginalOperatingReserveUpward_{p}_{sc}_{CaseName}.html', embed_options={'renderer': 'svg'})
|
|
1746
1749
|
|
|
1747
1750
|
#%% outputting the down operating reserve marginal
|
|
1748
|
-
if sum(mTEPES.pOperReserveDw[:,:,:,:]) and sum(1 for ar,nr in mTEPES.ar*mTEPES.nr if nr in n2a[ar] if mTEPES.
|
|
1751
|
+
if sum(mTEPES.pOperReserveDw[:,:,:,:]) and sum(1 for ar,nr in mTEPES.ar*mTEPES.nr if nr in n2a[ar] if (mTEPES.pIndOperReserveGen[nr] == 0 or mTEPES.pIndOperReserveCon[nr] == 0)) + sum(1 for ar,es in mTEPES.ar*mTEPES.es if es in e2a[ar] if (mTEPES.pIndOperReserveGen[es] == 0 or mTEPES.pIndOperReserveCon[nr] == 0)):
|
|
1749
1752
|
sPSSTNAR = [(p,sc,st,n,ar) for p,sc,st,n,ar in mTEPES.s2n*mTEPES.ar if mTEPES.pOperReserveDw[p,sc,n,ar] and sum(1 for nr in n2a[ar]) + sum(1 for es in e2a[ar]) and (p,sc,n) in mTEPES.psn]
|
|
1750
1753
|
OutputResults = pd.Series(data=[mTEPES.pDuals["".join([f"eOperReserveDw_{p}_{sc}_{st}('{n}', '{ar}')"])] for p,sc,st,n,ar in sPSSTNAR], index=pd.Index(sPSSTNAR))
|
|
1751
1754
|
OutputResults *= 1e3
|
|
@@ -1758,7 +1761,7 @@ def MarginalResults(DirName, CaseName, OptModel, mTEPES, pIndPlotOutput):
|
|
|
1758
1761
|
chart.save(f'{_path}/oT_Plot_MarginalOperatingReserveDownward_{p}_{sc}_{CaseName}.html', embed_options={'renderer': 'svg'})
|
|
1759
1762
|
|
|
1760
1763
|
#%% outputting the water values
|
|
1761
|
-
if
|
|
1764
|
+
if mTEPES.es:
|
|
1762
1765
|
OutputResults = []
|
|
1763
1766
|
sPSSTNES = [(p,sc,st,n,es) for p,sc,st,n,es in mTEPES.ps*mTEPES.st*mTEPES.nesc if (p,es) in mTEPES.pes and (p,sc,st,n) in mTEPES.s2n and (p,sc,n) in mTEPES.psn and (mTEPES.pTotalMaxCharge[es] or mTEPES.pTotalEnergyInflows[es])]
|
|
1764
1767
|
OutputToFile = pd.Series(data=[abs(mTEPES.pDuals["".join([f"eESSInventory_{p}_{sc}_{st}('{n}', '{es}')"])])*1e3 for p,sc,st,n,es in sPSSTNES], index=pd.Index(sPSSTNES))
|
|
@@ -1804,7 +1807,7 @@ def ReliabilityResults(DirName, CaseName, OptModel, mTEPES):
|
|
|
1804
1807
|
pDemandElec = pd.Series(data=[mTEPES.pDemandElec[p,sc,n,nd] for p,sc,n,nd in mTEPES.psnnd ], index=mTEPES.psnnd).sort_index()
|
|
1805
1808
|
ExistCapacity = [(p,sc,n,g) for p,sc,n,g in mTEPES.psng if g not in mTEPES.gc]
|
|
1806
1809
|
pExistMaxPower = pd.Series(data=[mTEPES.pMaxPowerElec[p,sc,n,g ] for p,sc,n,g in ExistCapacity], index=pd.Index(ExistCapacity))
|
|
1807
|
-
if
|
|
1810
|
+
if mTEPES.gc:
|
|
1808
1811
|
CandCapacity = [(p,sc,n,gc) for p,sc,n,gc in mTEPES.psngc]
|
|
1809
1812
|
pCandMaxPower = pd.Series(data=[mTEPES.pMaxPowerElec[p,sc,n,g ] * OptModel.vGenerationInvest[p,g]() for p,sc,n,g in CandCapacity], index=pd.Index(CandCapacity))
|
|
1810
1813
|
pMaxPowerElec = pd.concat([pExistMaxPower, pCandMaxPower])
|
|
@@ -1813,7 +1816,7 @@ def ReliabilityResults(DirName, CaseName, OptModel, mTEPES):
|
|
|
1813
1816
|
pMaxPowerElec = pMaxPowerElec.sort_index()
|
|
1814
1817
|
|
|
1815
1818
|
# Determination of the net demand
|
|
1816
|
-
if
|
|
1819
|
+
if mTEPES.re:
|
|
1817
1820
|
OutputToFile1 = pd.Series(data=[sum(OptModel.vTotalOutput[p,sc,n,re]() for rt in mTEPES.rt for re in r2r[rt] if (nd,re) in mTEPES.n2g and (p,re) in mTEPES.pre) for p,sc,n,nd in mTEPES.psnnd], index=mTEPES.psnnd)
|
|
1818
1821
|
else:
|
|
1819
1822
|
OutputToFile1 = pd.Series(data=[0.0 for p,sc,n,nd in mTEPES.psnnd], index=mTEPES.psnnd)
|
|
@@ -1880,7 +1883,7 @@ def EconomicResults(DirName, CaseName, OptModel, mTEPES, pIndAreaOutput, pIndPlo
|
|
|
1880
1883
|
_path = os.path.join(DirName, CaseName)
|
|
1881
1884
|
StartTime = time.time()
|
|
1882
1885
|
|
|
1883
|
-
# %%
|
|
1886
|
+
# %% Power balance per period, scenario, and load level
|
|
1884
1887
|
# incoming and outgoing lines (lin) (lout)
|
|
1885
1888
|
lin = defaultdict(list)
|
|
1886
1889
|
linl = defaultdict(list)
|
|
@@ -1932,12 +1935,18 @@ def EconomicResults(DirName, CaseName, OptModel, mTEPES, pIndAreaOutput, pIndPlo
|
|
|
1932
1935
|
for gt,g in mTEPES.t2g:
|
|
1933
1936
|
g2t[gt].append(g)
|
|
1934
1937
|
|
|
1938
|
+
# nodes to area (d2a)
|
|
1939
|
+
d2a = defaultdict(list)
|
|
1940
|
+
for ar,nd in mTEPES.ar*mTEPES.nd:
|
|
1941
|
+
if (nd,ar) in mTEPES.ndar:
|
|
1942
|
+
d2a[ar].append(nd)
|
|
1943
|
+
|
|
1935
1944
|
if sum(1 for ar in mTEPES.ar if sum(1 for g in g2a[ar])) > 1:
|
|
1936
1945
|
if pIndAreaOutput == 1:
|
|
1937
1946
|
for ar in mTEPES.ar:
|
|
1938
|
-
if sum(1 for g in g2a[ar]
|
|
1947
|
+
if sum(1 for g in g2a[ar]):
|
|
1939
1948
|
sPSNGT = [(p,sc,n,gt) for p,sc,n,gt in mTEPES.psngt if sum(1 for g in g2a[ar] if (p,g) in mTEPES.pg and g in g2t[gt])]
|
|
1940
|
-
if
|
|
1949
|
+
if sPSNGT:
|
|
1941
1950
|
OutputToFile = pd.Series(data=[sum(OptModel.vTotalOutput[p,sc,n,g]()*mTEPES.pLoadLevelDuration[p,sc,n]() for g in g2a[ar] if (p,g) in mTEPES.pg and g in g2t[gt]) for p,sc,n,gt in sPSNGT], index=pd.Index(sPSNGT))
|
|
1942
1951
|
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_{ar}_{CaseName}.csv', sep=',')
|
|
1943
1952
|
|
|
@@ -1951,45 +1960,90 @@ def EconomicResults(DirName, CaseName, OptModel, mTEPES, pIndAreaOutput, pIndPlo
|
|
|
1951
1960
|
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) and (nd,ar) in mTEPES.ndar]
|
|
1952
1961
|
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) and (nd,ar) in mTEPES.ndar]
|
|
1953
1962
|
|
|
1954
|
-
|
|
1955
|
-
|
|
1963
|
+
if sum(1 for nr in mTEPES.nr if nr not in mTEPES.eh):
|
|
1964
|
+
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')
|
|
1965
|
+
if mTEPES.re:
|
|
1956
1966
|
OutputResults02 = pd.Series(data=[ sum(OptModel.vTotalOutput [p,sc,n,re ]()*mTEPES.pLoadLevelDuration[p,sc,n]() for re in r2n[nd] if (p,re) in mTEPES.pre and re in r2r[rt] ) for p,sc,n,ar,nd,rt in sPSNARNDRT], index=pd.Index(sPSNARNDRT)).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')
|
|
1957
|
-
if
|
|
1967
|
+
if mTEPES.eh:
|
|
1958
1968
|
OutputResults03 = pd.Series(data=[ sum(OptModel.vTotalOutput [p,sc,n,eh ]()*mTEPES.pLoadLevelDuration[p,sc,n]() for eh in e2n[nd] if (p,eh) in mTEPES.peh and eh in e2e[et] ) for p,sc,n,ar,nd,et in sPSNARNDET], index=pd.Index(sPSNARNDET)).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')
|
|
1959
1969
|
OutputResults04 = pd.Series(data=[-sum(OptModel.vESSTotalCharge[p,sc,n,eh ]()*mTEPES.pLoadLevelDuration[p,sc,n]() for eh in e2n[nd] if (p,eh) in mTEPES.peh and eh in e2e[et] ) for p,sc,n,ar,nd,et in sPSNARNDET], index=pd.Index(sPSNARNDET)).to_frame(name='Consumption' ).reset_index().pivot_table(index=['level_0','level_1','level_2','level_3','level_4'], columns='level_5', values='Consumption', aggfunc='sum').rename(columns={et: et+str(' -') for et in mTEPES.et})
|
|
1960
1970
|
OutputResults05 = pd.Series(data=[ OptModel.vENS [p,sc,n,nd ]()*mTEPES.pLoadLevelDuration[p,sc,n]() for p,sc,n,ar,nd in sPSNARND ], index=pd.Index(sPSNARND )).to_frame(name='EnergyNotServed')
|
|
1961
1971
|
OutputResults06 = pd.Series(data=[- mTEPES.pDemandElec [p,sc,n,nd ] *mTEPES.pLoadLevelDuration[p,sc,n]() for p,sc,n,ar,nd in sPSNARND ], index=pd.Index(sPSNARND )).to_frame(name='EnergyDemand' )
|
|
1962
1972
|
OutputResults07 = pd.Series(data=[-sum(OptModel.vFlowElec [p,sc,n,nd,nf,cc]()*mTEPES.pLoadLevelDuration[p,sc,n]() for nf,cc in lout [nd]) for p,sc,n,ar,nd in sPSNARND ], index=pd.Index(sPSNARND )).to_frame(name='EnergyFlowOut' )
|
|
1963
1973
|
OutputResults08 = pd.Series(data=[ sum(OptModel.vFlowElec [p,sc,n,ni,nd,cc]()*mTEPES.pLoadLevelDuration[p,sc,n]() for ni,cc in lin [nd]) for p,sc,n,ar,nd in sPSNARND ], index=pd.Index(sPSNARND )).to_frame(name='EnergyFlowIn' )
|
|
1964
|
-
|
|
1965
|
-
if len(mTEPES.ll):
|
|
1974
|
+
if mTEPES.ll:
|
|
1966
1975
|
OutputResults09 = pd.Series(data=[-sum(OptModel.vLineLosses [p,sc,n,nd,nf,cc]()*mTEPES.pLoadLevelDuration[p,sc,n]() for nf,cc in loutl[nd]) for p,sc,n,ar,nd in sPSNARND ], index=pd.Index(sPSNARND )).to_frame(name='LineLossesOut' )
|
|
1967
1976
|
OutputResults10 = pd.Series(data=[-sum(OptModel.vLineLosses [p,sc,n,ni,nd,cc]()*mTEPES.pLoadLevelDuration[p,sc,n]() for ni,cc in linl [nd]) for p,sc,n,ar,nd in sPSNARND ], index=pd.Index(sPSNARND )).to_frame(name='LineLossesIn' )
|
|
1968
1977
|
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
OutputResults
|
|
1973
|
-
|
|
1974
|
-
OutputResults
|
|
1975
|
-
|
|
1976
|
-
OutputResults
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
OutputResults = pd.concat([OutputResults01, OutputResults03, OutputResults04, OutputResults05, OutputResults06, OutputResults07, OutputResults08 ], axis=1)
|
|
1981
|
-
elif len(mTEPES.eh) == 0 and len(mTEPES.re) == 0 and len(mTEPES.ll) > 0:
|
|
1982
|
-
OutputResults = pd.concat([OutputResults01, OutputResults05, OutputResults06, OutputResults07, OutputResults08, OutputResults09, OutputResults10], axis=1)
|
|
1983
|
-
elif len(mTEPES.eh) == 0 and len(mTEPES.re) == 0 and len(mTEPES.ll) == 0:
|
|
1984
|
-
OutputResults = pd.concat([OutputResults01, OutputResults05, OutputResults06, OutputResults07, OutputResults08 ], axis=1)
|
|
1985
|
-
|
|
1986
|
-
# OutputResults.stack().rename_axis(['Period', 'Scenario', 'LoadLevel', 'Area', 'Node', 'Technology'], axis=0).reset_index().rename(columns={0: 'GWh'}, inplace=False).to_csv (f'{_path}/oT_Result_BalanceEnergy_{CaseName}.csv', index=False, sep=',')
|
|
1987
|
-
# OutputResults.stack().rename_axis(['Period', 'Scenario', 'LoadLevel', 'Area', 'Node', 'Technology'], axis=0).reset_index().rename(columns={0: 'GWh'}, inplace=False).to_parquet(f'{_path}/oT_Result_BalanceEnergy_{CaseName}.parquet', index=False, engine='pyarrow')
|
|
1978
|
+
OutputResults = pd.DataFrame()
|
|
1979
|
+
# Check if there are any non-RES generators
|
|
1980
|
+
if sum(1 for nr in mTEPES.nr if nr not in mTEPES.eh):
|
|
1981
|
+
OutputResults = pd.concat([OutputResults,OutputResults01] ,axis=1)
|
|
1982
|
+
if mTEPES.re:
|
|
1983
|
+
OutputResults = pd.concat([OutputResults,OutputResults02] ,axis=1)
|
|
1984
|
+
if mTEPES.eh:
|
|
1985
|
+
OutputResults = pd.concat([OutputResults,OutputResults03,OutputResults04] ,axis=1)
|
|
1986
|
+
OutputResults = pd.concat([OutputResults,OutputResults05,OutputResults06,OutputResults07,OutputResults08],axis=1)
|
|
1987
|
+
if mTEPES.ll:
|
|
1988
|
+
OutputResults = pd.concat([OutputResults,OutputResults09,OutputResults10] , axis=1)
|
|
1988
1989
|
|
|
1989
1990
|
OutputResults.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).to_csv(f'{_path}/oT_Result_BalanceEnergyPerTech_{CaseName}.csv', sep=',')
|
|
1990
1991
|
OutputResults.stack().reset_index().pivot_table(index=['level_0','level_1','level_2' ,'level_5'], columns='level_4', values=0, aggfunc='sum').rename_axis(['Period', 'Scenario', 'LoadLevel', 'Technology' ], axis=0).to_csv(f'{_path}/oT_Result_BalanceEnergyPerNode_{CaseName}.csv', sep=',')
|
|
1991
1992
|
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=',')
|
|
1992
1993
|
|
|
1994
|
+
#%% outputting the demand and the LSRMC of electricity
|
|
1995
|
+
sPSSTNND = [(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]
|
|
1996
|
+
|
|
1997
|
+
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 sPSSTNND], index=pd.Index(sPSSTNND))
|
|
1998
|
+
OutputResults *= 1e3
|
|
1999
|
+
OutputResults.index = [idx[:2] + idx[3:] for idx in OutputResults.index]
|
|
2000
|
+
|
|
2001
|
+
#%% outputting the generator power output
|
|
2002
|
+
sPSNARNDNR = [(p,sc,n,ar,nd,nr) for p,sc,n,ar,nd,nr in mTEPES.psnar*mTEPES.nd*mTEPES.nr if nr in g2n[nd] and sum(1 for nf,cc in lout[nd]) + sum(1 for ni,cc in lin[nd]) and (nd,ar) in mTEPES.ndar and (p,nr) in mTEPES.pnr and nr not in mTEPES.eh]
|
|
2003
|
+
sPSNARNDRE = [(p,sc,n,ar,nd,re) for p,sc,n,ar,nd,re in mTEPES.psnar*mTEPES.nd*mTEPES.re if re in g2n[nd] and sum(1 for nf,cc in lout[nd]) + sum(1 for ni,cc in lin[nd]) and (nd,ar) in mTEPES.ndar and (p,re) in mTEPES.pre ]
|
|
2004
|
+
sPSNARNDEH = [(p,sc,n,ar,nd,eh) for p,sc,n,ar,nd,eh in mTEPES.psnar*mTEPES.nd*mTEPES.eh if eh in g2n[nd] and sum(1 for nf,cc in lout[nd]) + sum(1 for ni,cc in lin[nd]) and (nd,ar) in mTEPES.ndar and (p,eh) in mTEPES.peh ]
|
|
2005
|
+
|
|
2006
|
+
if sum(1 for nr in mTEPES.nr if nr not in mTEPES.eh):
|
|
2007
|
+
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')
|
|
2008
|
+
if mTEPES.re:
|
|
2009
|
+
OutputResults02 = pd.Series(data=[ OptModel.vTotalOutput [p,sc,n,re ]()*mTEPES.pLoadLevelDuration[p,sc,n]() for p,sc,n,ar,nd,re in sPSNARNDRE], index=pd.Index(sPSNARNDRE)).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')
|
|
2010
|
+
if mTEPES.eh:
|
|
2011
|
+
OutputResults03 = pd.Series(data=[ OptModel.vTotalOutput [p,sc,n,eh ]()*mTEPES.pLoadLevelDuration[p,sc,n]() for p,sc,n,ar,nd,eh in sPSNARNDEH], index=pd.Index(sPSNARNDEH)).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')
|
|
2012
|
+
OutputResults04 = pd.Series(data=[ -OptModel.vESSTotalCharge[p,sc,n,eh ]()*mTEPES.pLoadLevelDuration[p,sc,n]() for p,sc,n,ar,nd,eh in sPSNARNDEH], index=pd.Index(sPSNARNDEH)).to_frame(name='Consumption' ).reset_index().pivot_table(index=['level_0','level_1','level_2','level_3','level_4'], columns='level_5', values='Consumption', aggfunc='sum').rename(columns={et: et+str(' -') for et in mTEPES.et})
|
|
2013
|
+
OutputResults05 = pd.Series(data=[ OptModel.vENS [p,sc,n,nd ]()*mTEPES.pLoadLevelDuration[p,sc,n]() for p,sc,n,ar,nd in sPSNARND ], index=pd.Index(sPSNARND )).to_frame(name='EnergyNotServed')
|
|
2014
|
+
OutputResults06 = pd.Series(data=[ -mTEPES.pDemandElec [p,sc,n,nd ] *mTEPES.pLoadLevelDuration[p,sc,n]() for p,sc,n,ar,nd in sPSNARND ], index=pd.Index(sPSNARND )).to_frame(name='EnergyDemand' )
|
|
2015
|
+
OutputResults08 = pd.Series(data=[sum(OptModel.vFlowElec [p,sc,n,ni,nd,cc]()*mTEPES.pLoadLevelDuration[p,sc,n]() for ni,cc in lin [nd]) for p,sc,n,ar,nd in sPSNARND ], index=pd.Index(sPSNARND )).to_frame(name='EnergyFlowIn' )
|
|
2016
|
+
if mTEPES.ll:
|
|
2017
|
+
OutputResults09 = pd.Series(data=[-sum(OptModel.vLineLosses [p,sc,n,nd,nf,cc]()*mTEPES.pLoadLevelDuration[p,sc,n]() for nf,cc in loutl[nd]) for p,sc,n,ar,nd in sPSNARND ], index=pd.Index(sPSNARND )).to_frame(name='LineLossesOut' )
|
|
2018
|
+
OutputResults10 = pd.Series(data=[-sum(OptModel.vLineLosses [p,sc,n,ni,nd,cc]()*mTEPES.pLoadLevelDuration[p,sc,n]() for ni,cc in linl [nd]) for p,sc,n,ar,nd in sPSNARND ], index=pd.Index(sPSNARND )).to_frame(name='LineLossesIn' )
|
|
2019
|
+
|
|
2020
|
+
MarketResultsDem = pd.DataFrame()
|
|
2021
|
+
if mTEPES.eh:
|
|
2022
|
+
MarketResultsDem = pd.concat([MarketResultsDem, OutputResults04],axis=1)
|
|
2023
|
+
|
|
2024
|
+
MarketResultsDem = pd.concat([MarketResultsDem, OutputResults06],axis=1)
|
|
2025
|
+
|
|
2026
|
+
if mTEPES.ll:
|
|
2027
|
+
MarketResultsDem = pd.concat([MarketResultsDem, OutputResults09, OutputResults10], axis=1)
|
|
2028
|
+
|
|
2029
|
+
MarketResultsGen = pd.DataFrame()
|
|
2030
|
+
# Check if there are non-RES generators
|
|
2031
|
+
if sum(1 for nr in mTEPES.nr if nr not in mTEPES.eh):
|
|
2032
|
+
MarketResultsGen = pd.concat([MarketResultsGen,OutputResults01], axis=1)
|
|
2033
|
+
|
|
2034
|
+
if mTEPES.re:
|
|
2035
|
+
MarketResultsGen = pd.concat([MarketResultsGen, OutputResults02], axis=1)
|
|
2036
|
+
|
|
2037
|
+
if mTEPES.eh:
|
|
2038
|
+
MarketResultsGen = pd.concat([MarketResultsGen, OutputResults03], axis=1)
|
|
2039
|
+
|
|
2040
|
+
MarketResultsDem *= -1e3
|
|
2041
|
+
MarketResultsDem = pd.concat([MarketResultsDem.sum(axis=1), OutputResults], axis=1)
|
|
2042
|
+
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', 1: 'LSRMC'}, inplace=False).to_csv(f'{_path}/oT_Result_MarketResultsDemand_{CaseName}.csv', sep=',')
|
|
2043
|
+
|
|
2044
|
+
MarketResultsGen *= 1e3
|
|
2045
|
+
MarketResultsGen.stack().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'}, inplace=False).to_csv(f'{_path}/oT_Result_MarketResultsGeneration_{CaseName}.csv', sep=',')
|
|
2046
|
+
|
|
1993
2047
|
# df=OutputResults.stack().rename_axis(['Period', 'Scenario', 'LoadLevel', 'Area', 'Node', 'Technology'], axis=0).reset_index()
|
|
1994
2048
|
# df['AreaFin'] = df['Area']
|
|
1995
2049
|
# df['NodeFin'] = df['Node']
|
|
@@ -1999,23 +2053,23 @@ def EconomicResults(DirName, CaseName, OptModel, mTEPES, pIndAreaOutput, pIndPlo
|
|
|
1999
2053
|
mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelDuration[p,sc,n]() * mTEPES.pConstantVarCost[p,sc,n,nr] * OptModel.vCommitment [p,sc,n,nr]() +
|
|
2000
2054
|
mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelWeight [p,sc,n]() * mTEPES.pStartUpCost [ nr] * OptModel.vStartUp [p,sc,n,nr]() +
|
|
2001
2055
|
mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelWeight [p,sc,n]() * mTEPES.pShutDownCost [ nr] * OptModel.vShutDown [p,sc,n,nr]()) for p,sc,n,nr in mTEPES.psnnr if (p,nr) in mTEPES.pnr], index=mTEPES.psnnr)
|
|
2002
|
-
if
|
|
2056
|
+
if mTEPES.psnnr:
|
|
2003
2057
|
OutputToFile.to_frame(name='MEUR').reset_index().pivot_table(index=['level_0','level_1','level_2'], columns='level_3', values='MEUR', aggfunc='sum').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_GenerationCostOperation_{CaseName}.csv', sep=',')
|
|
2004
2058
|
|
|
2005
|
-
if
|
|
2059
|
+
if mTEPES.re:
|
|
2006
2060
|
OutputToFile = pd.Series(data=[mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelDuration[p,sc,n]() * mTEPES.pLinearOMCost [re] * OptModel.vTotalOutput [p,sc,n,re]() for p,sc,n,re in mTEPES.psnre if (p,re) in mTEPES.pre], index=mTEPES.psnre)
|
|
2007
2061
|
OutputToFile.to_frame(name='MEUR').reset_index().pivot_table(index=['level_0','level_1','level_2'], columns='level_3', values='MEUR', aggfunc='sum').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_GenerationCostOandM_{CaseName}.csv', sep=',')
|
|
2008
2062
|
|
|
2009
|
-
if
|
|
2063
|
+
if mTEPES.nr:
|
|
2010
2064
|
if sum(mTEPES.pOperReserveUp[:,:,:,:]) + sum(mTEPES.pOperReserveDw[:,:,:,:]):
|
|
2011
2065
|
OutputToFile = pd.Series(data=[(mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelWeight[p,sc,n]() * mTEPES.pOperReserveCost[nr] * OptModel.vReserveUp [p,sc,n,nr]() +
|
|
2012
2066
|
mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelWeight[p,sc,n]() * mTEPES.pOperReserveCost[nr] * OptModel.vReserveDown[p,sc,n,nr]()) for p,sc,n,nr in mTEPES.psnnr if (p,nr) in mTEPES.pnr], index=mTEPES.psnnr)
|
|
2013
2067
|
OutputToFile.to_frame(name='MEUR').reset_index().pivot_table(index=['level_0','level_1','level_2'], columns='level_3', values='MEUR', aggfunc='sum').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_GenerationCostOperatingReserve_{CaseName}.csv', sep=',')
|
|
2014
2068
|
|
|
2015
|
-
if
|
|
2069
|
+
if mTEPES.psnehc:
|
|
2016
2070
|
OutputToFile = pd.Series(data=[ mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelDuration[p,sc,n]() * mTEPES.pLinearVarCost[p,sc,n,eh] * OptModel.vESSTotalCharge[p,sc,n,eh]() for p,sc,n,eh in mTEPES.psnehc if (p,eh) in mTEPES.peh], index=mTEPES.psnehc)
|
|
2017
2071
|
OutputToFile.to_frame(name='MEUR').reset_index().pivot_table(index=['level_0','level_1','level_2'], columns='level_3', values='MEUR', aggfunc='sum').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_ConsumptionCostOperation_{CaseName}.csv', sep=',')
|
|
2018
|
-
if sum(mTEPES.
|
|
2072
|
+
if sum(mTEPES.pIndOperReserveGen[eh] for eh in mTEPES.eh if mTEPES.pIndOperReserveGen[eh] == 0) + sum(mTEPES.pIndOperReserveCon[eh] for eh in mTEPES.eh if mTEPES.pIndOperReserveCon[eh] == 0):
|
|
2019
2073
|
OutputToFile = pd.Series(data=[(mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelWeight[p,sc,n]() * mTEPES.pOperReserveCost[eh] * OptModel.vESSReserveUp [p,sc,n,eh]() +
|
|
2020
2074
|
mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelWeight[p,sc,n]() * mTEPES.pOperReserveCost[eh] * OptModel.vESSReserveDown[p,sc,n,eh]()) for p,sc,n,eh in mTEPES.psnehc if (p,eh) in mTEPES.peh], index=mTEPES.psnehc)
|
|
2021
2075
|
OutputToFile.to_frame(name='MEUR').reset_index().pivot_table(index=['level_0','level_1','level_2'], columns='level_3', values='MEUR', aggfunc='sum').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_ConsumptionCostOperatingReserve_{CaseName}.csv', sep=',')
|
|
@@ -2036,48 +2090,51 @@ def EconomicResults(DirName, CaseName, OptModel, mTEPES, pIndAreaOutput, pIndPlo
|
|
|
2036
2090
|
if pIndAreaOutput == 1:
|
|
2037
2091
|
for ar in mTEPES.ar:
|
|
2038
2092
|
if sum(1 for g in g2a[ar]):
|
|
2039
|
-
OutputResults1 = pd.DataFrame(data={'MEUR': [0.0]}, index=[(p,sc,'Generation Operation Cost' ) for p,sc in mTEPES.ps])
|
|
2040
|
-
OutputResults2 = pd.DataFrame(data={'MEUR': [0.0]}, index=[(p,sc,'Generation Operating Reserve Cost' ) for p,sc in mTEPES.ps])
|
|
2041
|
-
OutputResults3 = pd.DataFrame(data={'MEUR': [0.0]}, index=[(p,sc,'Generation O&M Cost' ) for p,sc in mTEPES.ps])
|
|
2042
|
-
OutputResults4 = pd.DataFrame(data={'MEUR': [0.0]}, index=[(p,sc,'Consumption Operation Cost' ) for p,sc in mTEPES.ps])
|
|
2043
|
-
OutputResults5 = pd.DataFrame(data={'MEUR': [0.0]}, index=[(p,sc,'Consumption Operating Reserve Cost') for p,sc in mTEPES.ps])
|
|
2044
|
-
OutputResults6 = pd.DataFrame(data={'MEUR': [0.0]}, index=[(p,sc,'Emission Cost' ) for p,sc in mTEPES.ps])
|
|
2045
|
-
OutputResults7 = pd.DataFrame(data={'MEUR': [0.0]}, index=[(p,sc,'Reliability Cost' ) for p,sc in mTEPES.ps])
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
if
|
|
2050
|
-
OutputResults1 =
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
OutputResults1 =
|
|
2055
|
-
OutputResults6 = pd.Series(data=[ mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelDuration[p,sc,n]() * mTEPES.pEmissionVarCost[p,sc,n,g ] * OptModel.vTotalOutput[p,sc,n,g ]() for p,sc,n,g in sPSNG if (p,g ) in mTEPES.pg ], index=pd.Index(sPSNG ))
|
|
2056
|
-
OutputResults6 = Transformation1(OutputResults6, 'Emission Cost')
|
|
2057
|
-
|
|
2093
|
+
OutputResults1 = pd.DataFrame(data={'MEUR': [0.0]}, index=pd.Index([(p,sc,'Generation Operation Cost' ) for p,sc in mTEPES.ps]))
|
|
2094
|
+
OutputResults2 = pd.DataFrame(data={'MEUR': [0.0]}, index=pd.Index([(p,sc,'Generation Operating Reserve Cost' ) for p,sc in mTEPES.ps]))
|
|
2095
|
+
OutputResults3 = pd.DataFrame(data={'MEUR': [0.0]}, index=pd.Index([(p,sc,'Generation O&M Cost' ) for p,sc in mTEPES.ps]))
|
|
2096
|
+
OutputResults4 = pd.DataFrame(data={'MEUR': [0.0]}, index=pd.Index([(p,sc,'Consumption Operation Cost' ) for p,sc in mTEPES.ps]))
|
|
2097
|
+
OutputResults5 = pd.DataFrame(data={'MEUR': [0.0]}, index=pd.Index([(p,sc,'Consumption Operating Reserve Cost') for p,sc in mTEPES.ps]))
|
|
2098
|
+
OutputResults6 = pd.DataFrame(data={'MEUR': [0.0]}, index=pd.Index([(p,sc,'Emission Cost' ) for p,sc in mTEPES.ps]))
|
|
2099
|
+
OutputResults7 = pd.DataFrame(data={'MEUR': [0.0]}, index=pd.Index([(p,sc,'Reliability Cost' ) for p,sc in mTEPES.ps]))
|
|
2100
|
+
|
|
2101
|
+
if mTEPES.nr:
|
|
2102
|
+
sPSNNR = [(p,sc,n,nr) for p,sc,n,nr in mTEPES.psnnr if nr in n2a[ar] and (p,nr) in mTEPES.pnr]
|
|
2103
|
+
if sPSNNR:
|
|
2104
|
+
OutputResults1 = pd.Series(data=[(mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelDuration[p,sc,n]() * mTEPES.pLinearVarCost [p,sc,n,nr] * OptModel.vTotalOutput[p,sc,n,nr]() +
|
|
2105
|
+
mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelDuration[p,sc,n]() * mTEPES.pConstantVarCost[p,sc,n,nr] * OptModel.vCommitment [p,sc,n,nr]() +
|
|
2106
|
+
mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelWeight [p,sc,n]() * mTEPES.pStartUpCost [ nr] * OptModel.vStartUp [p,sc,n,nr]() +
|
|
2107
|
+
mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelWeight [p,sc,n]() * mTEPES.pShutDownCost [ nr] * OptModel.vShutDown [p,sc,n,nr]()) for p,sc,n,nr in sPSNNR], index=pd.Index(sPSNNR))
|
|
2108
|
+
OutputResults1 = Transformation1(OutputResults1, 'Generation Operation Cost')
|
|
2058
2109
|
if sum(mTEPES.pOperReserveUp[:,:,:,:]) + sum(mTEPES.pOperReserveDw[:,:,:,:]):
|
|
2059
|
-
OutputResults2 = pd.Series(data=[(mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelWeight[p,sc,n]() * mTEPES.pOperReserveCost[nr] * OptModel.vReserveUp [p,sc,n,nr]() +
|
|
2060
|
-
mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelWeight[p,sc,n]() * mTEPES.pOperReserveCost[nr] * OptModel.vReserveDown[p,sc,n,nr]()) for p,sc,n,nr in sPSNNR
|
|
2110
|
+
OutputResults2 = pd.Series(data=[(mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelWeight [p,sc,n]() * mTEPES.pOperReserveCost[ nr] * OptModel.vReserveUp [p,sc,n,nr]() +
|
|
2111
|
+
mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelWeight [p,sc,n]() * mTEPES.pOperReserveCost[ nr] * OptModel.vReserveDown[p,sc,n,nr]()) for p,sc,n,nr in sPSNNR], index=pd.Index(sPSNNR))
|
|
2061
2112
|
OutputResults2 = Transformation1(OutputResults2, 'Generation Operating Reserve Cost')
|
|
2062
2113
|
|
|
2063
|
-
if
|
|
2064
|
-
|
|
2065
|
-
if
|
|
2066
|
-
|
|
2114
|
+
if mTEPES.g :
|
|
2115
|
+
sPSNG = [(p,sc,n,g ) for p,sc,n,g in mTEPES.psng if g in g2a[ar] and (p,g ) in mTEPES.pg ]
|
|
2116
|
+
if sPSNG:
|
|
2117
|
+
OutputResults6 = pd.Series(data=[ mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelDuration[p,sc,n]() * mTEPES.pEmissionVarCost[p,sc,n,g ] * OptModel.vTotalOutput[p,sc,n,g ]() for p,sc,n,g in sPSNG], index=pd.Index(sPSNG))
|
|
2118
|
+
OutputResults6 = Transformation1(OutputResults6, 'Emission Cost')
|
|
2119
|
+
|
|
2120
|
+
if mTEPES.re:
|
|
2121
|
+
sPSNRE = [(p,sc,n,re) for p,sc,n,re in mTEPES.psnre if re in g2a[ar] and (p,re) in mTEPES.pre]
|
|
2122
|
+
if sPSNRE:
|
|
2123
|
+
OutputResults3 = pd.Series(data=[mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelDuration[p,sc,n]() * mTEPES.pLinearOMCost [re] * OptModel.vTotalOutput [p,sc,n,re]() for p,sc,n,re in sPSNRE], index=pd.Index(sPSNRE))
|
|
2067
2124
|
OutputResults3 = Transformation1(OutputResults3, 'Generation O&M Cost')
|
|
2068
2125
|
|
|
2069
|
-
if
|
|
2070
|
-
sPSNES = [(p,sc,n,eh) for p,sc,n,eh in mTEPES.psnehc if eh in g2a[ar]]
|
|
2071
|
-
if
|
|
2072
|
-
OutputResults4 = pd.Series(data=[ mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelDuration[p,sc,n]() * mTEPES.pLinearVarCost [p,sc,n,eh] * OptModel.vESSTotalCharge[p,sc,n,eh]() for p,sc,n,eh in sPSNES
|
|
2126
|
+
if mTEPES.eh:
|
|
2127
|
+
sPSNES = [(p,sc,n,eh) for p,sc,n,eh in mTEPES.psnehc if eh in g2a[ar] and (p,eh) in mTEPES.peh]
|
|
2128
|
+
if sPSNES:
|
|
2129
|
+
OutputResults4 = pd.Series(data=[ mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelDuration[p,sc,n]() * mTEPES.pLinearVarCost [p,sc,n,eh] * OptModel.vESSTotalCharge[p,sc,n,eh]() for p,sc,n,eh in sPSNES], index=pd.Index(sPSNES))
|
|
2073
2130
|
OutputResults4 = Transformation1(OutputResults4, 'Consumption Operation Cost')
|
|
2074
|
-
if sum(mTEPES.
|
|
2131
|
+
if sum(mTEPES.pIndOperReserveGen[eh] for eh in mTEPES.eh if mTEPES.pIndOperReserveCon[eh] == 0) + sum(mTEPES.pIndOperReserveGen[eh] for eh in mTEPES.eh if mTEPES.pIndOperReserveCon[eh] == 0):
|
|
2075
2132
|
OutputResults5 = pd.Series(data=[(mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelWeight [p,sc,n]() * mTEPES.pOperReserveCost[ eh] * OptModel.vESSReserveUp [p,sc,n,eh]() +
|
|
2076
|
-
mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelWeight [p,sc,n]() * mTEPES.pOperReserveCost[ eh] * OptModel.vESSReserveDown[p,sc,n,eh]()) for p,sc,n,eh in sPSNES
|
|
2133
|
+
mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelWeight [p,sc,n]() * mTEPES.pOperReserveCost[ eh] * OptModel.vESSReserveDown[p,sc,n,eh]()) for p,sc,n,eh in sPSNES], index=pd.Index(sPSNES))
|
|
2077
2134
|
OutputResults5 = Transformation1(OutputResults5, 'Consumption Operating Reserve Cost')
|
|
2078
2135
|
|
|
2079
2136
|
sPSNND = [(p,sc,n,nd) for p,sc,n,nd in mTEPES.psnnd if (nd,ar) in mTEPES.ndar]
|
|
2080
|
-
if
|
|
2137
|
+
if sPSNND:
|
|
2081
2138
|
OutputResults7 = pd.Series(data=[mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelDuration[p,sc,n]() * mTEPES.pENSCost() * OptModel.vENS [p,sc,n,nd]() for p,sc,n,nd in sPSNND], index=pd.Index(sPSNND))
|
|
2082
2139
|
OutputResults7 = Transformation1(OutputResults7, 'Reliability Cost')
|
|
2083
2140
|
|
|
@@ -2091,12 +2148,12 @@ def EconomicResults(DirName, CaseName, OptModel, mTEPES, pIndAreaOutput, pIndPlo
|
|
|
2091
2148
|
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))
|
|
2092
2149
|
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=',')
|
|
2093
2150
|
|
|
2094
|
-
if
|
|
2151
|
+
if mTEPES.eh:
|
|
2095
2152
|
sPSSTNNDES = [(p,sc,st,n,nd,eh) for p,sc,st,n,nd,eh in mTEPES.s2n*mTEPES.n2g if eh in mTEPES.eh if (p,eh) in mTEPES.peh and (p,sc,n) in mTEPES.psn]
|
|
2096
2153
|
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 sPSSTNNDES], index=pd.Index(sPSSTNNDES))
|
|
2097
2154
|
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=',')
|
|
2098
2155
|
|
|
2099
|
-
if
|
|
2156
|
+
if mTEPES.gc:
|
|
2100
2157
|
GenRev = []
|
|
2101
2158
|
ChargeRev = []
|
|
2102
2159
|
sPSSTNNDGC1 = [(p,sc,st,n,nd,gc) for p,sc,st,n,nd,gc in mTEPES.s2n*mTEPES.n2g if gc in mTEPES.gc if (p,gc) in mTEPES.pgc and (p,sc,n) in mTEPES.psn]
|
|
@@ -2108,11 +2165,11 @@ def EconomicResults(DirName, CaseName, OptModel, mTEPES, pIndAreaOutput, pIndPlo
|
|
|
2108
2165
|
ChargeRev.append(OutputChargeRevESS)
|
|
2109
2166
|
if len([(p,sc,n,nd,gc) for p,sc,n,nd,gc in mTEPES.psn*mTEPES.n2g if gc in mTEPES.gc for rt in mTEPES.rt if (p,gc) in mTEPES.pgc and gc in r2r[rt]]):
|
|
2110
2167
|
sPSSTNNDGC3 = [(p,sc,st,n,nd,gc) for p,sc,st,n,nd,gc in sPSSTNNDGC1 for rt in mTEPES.rt if (p,gc) in mTEPES.pgc and gc in r2r[rt] and (p,sc,n) in mTEPES.psn]
|
|
2111
|
-
OutputChargeRevRES = pd.Series(data=[mTEPES.pDuals["".join([f"eBalanceElec_{p}_{sc}_{st}('{n}', '{nd}')"])]/mTEPES.pPeriodProb[p,sc]()/mTEPES.pLoadLevelDuration[p,sc,n]() * 0.0
|
|
2168
|
+
OutputChargeRevRES = pd.Series(data=[mTEPES.pDuals["".join([f"eBalanceElec_{p}_{sc}_{st}('{n}', '{nd}')"])]/mTEPES.pPeriodProb[p,sc]()/mTEPES.pLoadLevelDuration[p,sc,n]() * 0.0 for p,sc,st,n,nd,gc in sPSSTNNDGC3], index=pd.Index(sPSSTNNDGC3))
|
|
2112
2169
|
ChargeRev.append(OutputChargeRevRES)
|
|
2113
2170
|
if len([(p,sc,n,nd,gc) for p,sc,n,nd,gc in mTEPES.psn*mTEPES.n2g if gc in mTEPES.gc for ot in mTEPES.ot if (p,gc) in mTEPES.pgc and gc in o2e[ot]]):
|
|
2114
2171
|
sPSSTNNDGC4 = [(p,sc,st,n,nd,gc) for p,sc,st,n,nd,gc in sPSSTNNDGC1 for ot in mTEPES.ot if (p,gc) in mTEPES.pgc and gc in o2e[ot] and (p,sc,n) in mTEPES.psn]
|
|
2115
|
-
OutputChargeRevThr = pd.Series(data=[mTEPES.pDuals["".join([f"eBalanceElec_{p}_{sc}_{st}('{n}', '{nd}')"])]/mTEPES.pPeriodProb[p,sc]()/mTEPES.pLoadLevelDuration[p,sc,n]() * 0.0
|
|
2172
|
+
OutputChargeRevThr = pd.Series(data=[mTEPES.pDuals["".join([f"eBalanceElec_{p}_{sc}_{st}('{n}', '{nd}')"])]/mTEPES.pPeriodProb[p,sc]()/mTEPES.pLoadLevelDuration[p,sc,n]() * 0.0 for p,sc,st,n,nd,gc in sPSSTNNDGC4], index=pd.Index(sPSSTNNDGC4))
|
|
2116
2173
|
ChargeRev.append(OutputChargeRevThr)
|
|
2117
2174
|
if len(GenRev):
|
|
2118
2175
|
GenRev = pd.concat(GenRev)
|
|
@@ -2132,11 +2189,11 @@ def EconomicResults(DirName, CaseName, OptModel, mTEPES, pIndAreaOutput, pIndPlo
|
|
|
2132
2189
|
ChargeRev = pd.Series(data=[0.0 for gc in mTEPES.gc], index=mTEPES.gc, dtype='float64')
|
|
2133
2190
|
|
|
2134
2191
|
if sum(mTEPES.pReserveMargin[:,:]):
|
|
2135
|
-
if
|
|
2192
|
+
if mTEPES.gc:
|
|
2136
2193
|
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]]
|
|
2137
2194
|
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))
|
|
2138
2195
|
ResRev = pd.Series(data=[0.0 for gc in mTEPES.gc], index=mTEPES.gc, dtype='float64')
|
|
2139
|
-
if
|
|
2196
|
+
if sPSSTARGC:
|
|
2140
2197
|
OutputToResRev /= 1e3
|
|
2141
2198
|
OutputToResRev = OutputToResRev.to_frame(name='MEUR').reset_index().pivot_table(index=['level_0','level_1'], columns='level_4', values='MEUR').rename_axis(['Stages', 'Areas'], axis=0).rename_axis([None], axis=1).sum(axis=0)
|
|
2142
2199
|
for g in OutputToResRev.index:
|
|
@@ -2144,7 +2201,7 @@ def EconomicResults(DirName, CaseName, OptModel, mTEPES, pIndAreaOutput, pIndPlo
|
|
|
2144
2201
|
else:
|
|
2145
2202
|
ResRev = pd.Series(data=[0.0 for gc in mTEPES.gc], index=mTEPES.gc, dtype='float64')
|
|
2146
2203
|
|
|
2147
|
-
if sum(mTEPES.pOperReserveUp[:,:,:,:]) and sum(1 for ar,nr in mTEPES.ar*mTEPES.nr if nr in g2a[ar] and mTEPES.
|
|
2204
|
+
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)):
|
|
2148
2205
|
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]):
|
|
2149
2206
|
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]
|
|
2150
2207
|
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))
|
|
@@ -2171,7 +2228,7 @@ def EconomicResults(DirName, CaseName, OptModel, mTEPES, pIndAreaOutput, pIndPlo
|
|
|
2171
2228
|
else:
|
|
2172
2229
|
UpRev = pd.Series(data=[0.0 for gc in mTEPES.gc], index=mTEPES.gc, dtype='float64')
|
|
2173
2230
|
|
|
2174
|
-
if sum(mTEPES.pOperReserveDw[:,:,:,:]) and sum(1 for ar,nr in mTEPES.ar*mTEPES.nr if nr in g2a[ar] and mTEPES.
|
|
2231
|
+
if sum(mTEPES.pOperReserveDw[:,:,:,:]) and sum(1 for ar,nr in mTEPES.ar*mTEPES.nr if nr in g2a[ar] and (mTEPES.pIndOperReserveGen[nr] == 0 or mTEPES.pIndOperReserveGen[nr] == 0 )) + sum(1 for ar,es in mTEPES.ar*mTEPES.es if es in g2a[ar] and (mTEPES.pIndOperReserveGen[es] == 0 or mTEPES.pIndOperReserveCon[es] == 0 )):
|
|
2175
2232
|
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.pOperReserveDw[p,sc,n,ar] and (p,sc,n,nr) in mTEPES.psnnr]):
|
|
2176
2233
|
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.pOperReserveDw[p,sc,n,ar] and (p,sc,n,nr) in mTEPES.psnnr]
|
|
2177
2234
|
OutputResults = pd.Series(data=[mTEPES.pDuals["".join([f"eOperReserveDw_{p}_{sc}_{st}('{n}', '{ar}')"])]/mTEPES.pPeriodProb[p,sc]()*OptModel.vReserveDown [p,sc,n,nr]() for p,sc,st,n,ar,nr in sPSSTNARNR], index=pd.Index(sPSSTNARNR))
|
|
@@ -2197,7 +2254,7 @@ def EconomicResults(DirName, CaseName, OptModel, mTEPES, pIndAreaOutput, pIndPlo
|
|
|
2197
2254
|
else:
|
|
2198
2255
|
DwRev = pd.Series(data=[0.0 for gc in mTEPES.gc], index=mTEPES.gc, dtype='float64')
|
|
2199
2256
|
|
|
2200
|
-
if
|
|
2257
|
+
if mTEPES.gc:
|
|
2201
2258
|
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]() +
|
|
2202
2259
|
mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelDuration[p,sc,n]() * mTEPES.pConstantVarCost[p,sc,n,gc] * OptModel.vCommitment [p,sc,n,gc]() +
|
|
2203
2260
|
mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelWeight [p,sc,n]() * mTEPES.pStartUpCost [ gc] * OptModel.vStartUp [p,sc,n,gc]() +
|
|
@@ -2215,7 +2272,7 @@ def EconomicResults(DirName, CaseName, OptModel, mTEPES, pIndAreaOutput, pIndPlo
|
|
|
2215
2272
|
CnsCost[gc] = 0.0 if gc not in CnsCost.index else CnsCost[gc]
|
|
2216
2273
|
OpCCost[gc] = 0.0 if gc not in OpCCost.index else OpCCost[gc]
|
|
2217
2274
|
|
|
2218
|
-
InvCost = pd.Series(data=[sum(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')
|
|
2275
|
+
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')
|
|
2219
2276
|
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')
|
|
2220
2277
|
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]'])
|
|
2221
2278
|
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=',')
|
|
@@ -2256,11 +2313,11 @@ def NetworkMapResults(DirName, CaseName, OptModel, mTEPES):
|
|
|
2256
2313
|
OutputToFile.index.names = ['Period', 'Scenario', 'LoadLevel', 'InitialNode', 'FinalNode', 'Circuit']
|
|
2257
2314
|
OutputToFile = OutputToFile.to_frame(name='MW')
|
|
2258
2315
|
|
|
2259
|
-
# tolerance to
|
|
2316
|
+
# tolerance to avoid division by 0
|
|
2260
2317
|
pEpsilon = 1e-6
|
|
2261
2318
|
|
|
2262
|
-
line_df = pd.DataFrame(data={'NTCFrw': pd.Series(data=[mTEPES.pLineNTCFrw[
|
|
2263
|
-
'NTCBck': pd.Series(data=[mTEPES.pLineNTCBck[
|
|
2319
|
+
line_df = pd.DataFrame(data={'NTCFrw': pd.Series(data=[mTEPES.pLineNTCFrw[la] * 1e3 + pEpsilon for la in mTEPES.la], index=mTEPES.la),
|
|
2320
|
+
'NTCBck': pd.Series(data=[mTEPES.pLineNTCBck[la] * 1e3 + pEpsilon for la in mTEPES.la], index=mTEPES.la)}, index=mTEPES.la)
|
|
2264
2321
|
|
|
2265
2322
|
line_df = line_df.groupby(level=[0,1]).sum(numeric_only=False)
|
|
2266
2323
|
line_df['vFlowElec' ] = 0.0
|
|
@@ -2291,7 +2348,7 @@ def NetworkMapResults(DirName, CaseName, OptModel, mTEPES):
|
|
|
2291
2348
|
if 10*i <= line_df.loc[(ni,nf),'utilization'] <= 10*(i+1):
|
|
2292
2349
|
line_df.loc[(ni,nf),'color'] = colors[i]
|
|
2293
2350
|
|
|
2294
|
-
#
|
|
2351
|
+
# assigning black color to lines with utilization > 100%
|
|
2295
2352
|
if line_df.loc[(ni,nf),'utilization'] > 100:
|
|
2296
2353
|
line_df.loc[(ni,nf),'color'] = 'rgb(0,0,0)'
|
|
2297
2354
|
|
|
@@ -2316,7 +2373,7 @@ def NetworkMapResults(DirName, CaseName, OptModel, mTEPES):
|
|
|
2316
2373
|
|
|
2317
2374
|
return loc_df, line_df
|
|
2318
2375
|
|
|
2319
|
-
# tolerance to
|
|
2376
|
+
# tolerance to avoid division by 0
|
|
2320
2377
|
pEpsilon = 1e-6
|
|
2321
2378
|
|
|
2322
2379
|
p = list(mTEPES.p)[0]
|
|
@@ -2349,7 +2406,7 @@ def NetworkMapResults(DirName, CaseName, OptModel, mTEPES):
|
|
|
2349
2406
|
|
|
2350
2407
|
# Add edges
|
|
2351
2408
|
for ni,nf,cc in mTEPES.la:
|
|
2352
|
-
fig.add_trace(go.Scattermapbox(lon=[pos_dict[ni][0], pos_dict[nf][0]], lat=[pos_dict[ni][1], pos_dict[nf][1]], mode='lines+markers', marker=dict(size=0, showscale=True, colorbar={'title': 'Utilization [%]', '
|
|
2409
|
+
fig.add_trace(go.Scattermapbox(lon=[pos_dict[ni][0], pos_dict[nf][0]], lat=[pos_dict[ni][1], pos_dict[nf][1]], mode='lines+markers', marker=dict(size=0, showscale=True, colorbar={'title': 'Utilization [%]', 'title_side': 'top', 'thickness': 8, 'ticksuffix': '%'}, colorscale=[[0, 'lightgreen'], [1, 'darkred']], cmin=0, cmax=100,), line=dict(width=line_df.loc[(ni,nf),'width'], color=line_df.loc[(ni,nf),'color']), opacity=1, hoverinfo='text', textposition='middle center',))
|
|
2353
2410
|
|
|
2354
2411
|
# Add legends related to the lines
|
|
2355
2412
|
fig.add_trace(go.Scattermapbox(lat=line_df['lat'], lon=line_df['lon'], mode='markers', marker=go.scattermapbox.Marker(size=20, sizeref=1.1, sizemode='area', color='LightSkyBlue',), opacity=0, hoverinfo='text', text='<br>Line: '+line_df['ni']+' → '+line_df['nf']+'<br># circuits: '+line_df['cc'].astype(str)+'<br>NTC Forward: '+line_df['NTCFrw'].astype(str)+'<br>NTC Backward: '+line_df['NTCBck'].astype(str)+'<br>Power flow: '+line_df['vFlowElec'].astype(str)+'<br>Utilization [%]: '+line_df['utilization'].astype(str),))
|