Skip to content

Commit

Permalink
minor changes in output results
Browse files Browse the repository at this point in the history
  • Loading branch information
arght committed Dec 4, 2024
1 parent 2770932 commit 1953c33
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 22 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
Change Log
=============

[4.18.0] - 2024-12-04
-----------------------
- [FIXED] minor changes in output results

[4.17.9] - 2024-11-19
-----------------------
- [FIXED] fix error in network map
Expand Down
10 changes: 5 additions & 5 deletions doc/rst/OutputResults.rst
Original file line number Diff line number Diff line change
Expand Up @@ -640,39 +640,39 @@ Identifier Header Descr
Period Scenario Load level Initial node Final node Circuit Line switch off decision [p.u.]
============ ========== ========== ============ ========== ========= ================================

File ``oT_Result_NetworkFlowPerNode.csv``
File ``oT_Result_NetworkFlowElecPerNode.csv``

============ ========== ========== ============ ========== ========= =======================
Identifier Header Description
==================================== =================================== =======================
Period Scenario Load level Initial node Final node Circuit Electric line flow [MW]
============ ========== ========== ============ ========== ========= =======================

File ``oT_Result_NetworkEnergyPerArea.csv``
File ``oT_Result_NetworkEnergyElecPerArea.csv``

============ ========== ========== ============ ========== =======================
Identifier Header Description
============ ========== ========== ======================== =======================
Period Scenario Load level Initial area Final area Area flow energy [GWh]
============ ========== ========== ============ ========== =======================

File ``oT_Result_NetworkEnergyTotalPerArea.csv``
File ``oT_Result_NetworkEnergyElecTotalPerArea.csv``

============ ========== ============ ========== =======================
Identifier Header Description
============ ========== ======================== =======================
Period Scenario Initial area Final area Area flow energy [GWh]
============ ========== ============ ========== =======================

File ``oT_Result_NetworkEnergyTransport.csv``
File ``oT_Result_NetworkEnergyElecTransport.csv``

============ ========== ========== ============ ========== ========= ============================
Identifier Header Description
==================================== =================================== ============================
Period Scenario Load level Initial node Final node Circuit Energy transported [GWh-Mkm]
============ ========== ========== ============ ========== ========= ============================

File ``oT_Result_NetworkUtilization.csv``
File ``oT_Result_NetworkElecUtilization.csv``

============ ========== ========== ============ ========== ========== ================================================================
Identifier Header Description
Expand Down
2 changes: 1 addition & 1 deletion openTEPES/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
>>> import openTEPES as oT
>>> oT.routine("9n", "C:\\Users\\UserName\\Documents\\GitHub\\openTEPES", "glpk")
"""
__version__ = "4.17.9"
__version__ = "4.18.0"

from .openTEPES_Main import main
from .openTEPES import *
Expand Down
6 changes: 3 additions & 3 deletions openTEPES/openTEPES.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""
Open Generation, Storage, and Transmission Operation and Expansion Planning Model with RES and ESS (openTEPES) - November 19, 2024
Open Generation, Storage, and Transmission Operation and Expansion Planning Model with RES and ESS (openTEPES) - December 04, 2024
"""

# import dill as pickle
Expand Down Expand Up @@ -39,8 +39,8 @@ def openTEPES_run(DirName, CaseName, SolverName, pIndOutputResults, pIndLogConso
idxDict['y' ] = 1

#%% model declaration
mTEPES = ConcreteModel('Open Generation, Storage, and Transmission Operation and Expansion Planning Model with RES and ESS (openTEPES) - Version 4.17.9 - November 19, 2024')
print( 'Open Generation, Storage, and Transmission Operation and Expansion Planning Model with RES and ESS (openTEPES) - Version 4.17.9 - November 19, 2024', file=open(_path+f'/openTEPES_version_{CaseName}.log','w'))
mTEPES = ConcreteModel('Open Generation, Storage, and Transmission Operation and Expansion Planning Model with RES and ESS (openTEPES) - Version 4.18.0 - December 04, 2024')
print( 'Open Generation, Storage, and Transmission Operation and Expansion Planning Model with RES and ESS (openTEPES) - Version 4.18.0 - December 04, 2024', file=open(_path+f'/openTEPES_version_{CaseName}.log','w'))

pIndOutputResults = [j for i,j in idxDict.items() if i == pIndOutputResults][0]
pIndLogConsole = [j for i,j in idxDict.items() if i == pIndLogConsole ][0]
Expand Down
4 changes: 2 additions & 2 deletions openTEPES/openTEPES_Main.py
Original file line number Diff line number Diff line change
Expand Up @@ -660,7 +660,7 @@
# For more information on this, and how to apply and follow the GNU AGPL, see
# <https://www.gnu.org/licenses/>.

# Open Generation, Storage, and Transmission Operation and Expansion Planning Model with RES and ESS (openTEPES) - November 19, 2024
# Open Generation, Storage, and Transmission Operation and Expansion Planning Model with RES and ESS (openTEPES) - December 04, 2024
# simplicity and transparency in power systems planning

# Developed by
Expand All @@ -685,7 +685,7 @@
# import pkg_resources
from .openTEPES import openTEPES_run

print('\033[1;32mOpen Generation, Storage, and Transmission Operation and Expansion Planning Model with RES and ESS (openTEPES) - Version 4.17.9 - November 19, 2024\033[0m')
print('\033[1;32mOpen Generation, Storage, and Transmission Operation and Expansion Planning Model with RES and ESS (openTEPES) - Version 4.18.0 - December 04, 2024\033[0m')
print('\033[34m#### Academic research license - for non-commercial use only ####\033[0m \n')

parser = argparse.ArgumentParser(description='Introducing main parameters...')
Expand Down
47 changes: 36 additions & 11 deletions openTEPES/openTEPES_OutputResults.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""
Open Generation, Storage, and Transmission Operation and Expansion Planning Model with RES and ESS (openTEPES) - November 19, 2024
Open Generation, Storage, and Transmission Operation and Expansion Planning Model with RES and ESS (openTEPES) - December 04, 2024
"""

import time
Expand Down Expand Up @@ -34,10 +34,12 @@ def PiePlots(period, scenario, df, Category, Value):
ComposedCategory = Category+':N'
ComposedValue = Value +':Q'

base = alt.Chart(OutputToPlot).encode(theta=alt.Theta(ComposedValue, stack=True), color=alt.Color(ComposedCategory, legend=alt.Legend(title=Category))).properties(width=800, height=800)
base = alt.Chart(OutputToPlot).encode(theta=alt.Theta(ComposedValue, type="quantitative", stack=True), color=alt.Color(ComposedCategory, scale=alt.Scale(scheme='category20c'), type="nominal", legend=alt.Legend(title=Category))).properties(width=800, height=800)
pie = base.mark_arc(outerRadius=240)
text = base.mark_text(radius=340, size=15).encode(text='Label:N')
chart = pie+text
# chart = chart.resolve_scale(theta="independent")
chart = alt.layer(pie, text, data=OutputToPlot).resolve_scale(theta="independent")

return chart

Expand Down Expand Up @@ -710,8 +712,7 @@ def ESSOperationResults(DirName, CaseName, OptModel, mTEPES, pIndTechnologyOutpu
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=pd.Index(mTEPES.psnot))
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(_path+f'/oT_Result_TechnologyOutflowsEnergy_{CaseName}.csv', sep=',')

OutputToFile = pd.Series(data=[OptModel.vESSTotalCharge [p,sc,n,eh]()*mTEPES.pLoadLevelDuration[p,sc,n]() for p,sc,n,eh in mTEPES.psneh], index=pd.Index(mTEPES.psneh))
OutputToFile *= -1.0
OutputToFile = - pd.Series(data=[OptModel.vESSTotalCharge [p,sc,n,eh]()*mTEPES.pLoadLevelDuration[p,sc,n]() for p,sc,n,eh in mTEPES.psneh], index=pd.Index(mTEPES.psneh))
if pIndTechnologyOutput == 0 or pIndTechnologyOutput == 2:
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(_path+f'/oT_Result_ConsumptionEnergy_{CaseName}.csv', sep=',')

Expand Down Expand Up @@ -1089,6 +1090,30 @@ def NetworkHeatOperationResults(DirName, CaseName, OptModel, mTEPES):
OutputToFile = pd.pivot_table(OutputToFile.to_frame(name='MW'), values='MW', index=['Period', 'Scenario', 'LoadLevel'], columns=['InitialNode', 'FinalNode', 'Circuit'], fill_value=0.0).rename_axis([None, None, None], axis=1)
OutputToFile.reset_index().to_csv(_path+f'/oT_Result_NetworkFlowHeatPerNode_{CaseName}.csv', index=False, sep=',')

PSNHAARAR = [(p,sc,n,ni,nf,cc,ai,af) for p,sc,n,ni,nf,cc,ai,af in mTEPES.psnha*mTEPES.ar*mTEPES.ar if (ni,ai) in mTEPES.ndar and (nf,af) in mTEPES.ndar]
OutputToFile = pd.Series(data=[OptModel.vFlowHeat[p,sc,n,ni,nf,cc]()*mTEPES.pLoadLevelDuration[p,sc,n]() for p,sc,n,ni,nf,cc,ai,af in PSNHAARAR], index=pd.Index(PSNHAARAR))
OutputToFile.index.names = ['Period', 'Scenario', 'LoadLevel', 'InitialNode', 'FinalNode', 'Circuit', 'InitialArea', 'FinalArea']
OutputToFile = pd.pivot_table(OutputToFile.to_frame(name='GWh'), values='GWh', index=['Period', 'Scenario', 'LoadLevel'], columns=['InitialArea', 'FinalArea'], fill_value=0.0).rename_axis([None, None], axis=1)
OutputToFile.reset_index().to_csv(_path+f'/oT_Result_NetworkEnergyHeatPerArea_{CaseName}.csv', index=False, sep=',')

OutputToFile = pd.Series(data=[OptModel.vFlowHeat[p,sc,n,ni,nf,cc]()*mTEPES.pLoadLevelDuration[p,sc,n]() for p,sc,n,ni,nf,cc,ai,af in PSNHAARAR], index=pd.Index(PSNHAARAR))
OutputToFile.index.names = ['Period', 'Scenario', 'LoadLevel', 'InitialNode', 'FinalNode', 'Circuit', 'InitialArea', 'FinalArea']
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)
OutputToFile.reset_index().to_csv(_path+f'/oT_Result_NetworkEnergyHeatTotalPerArea_{CaseName}.csv', index=False, sep=',')

if len(mTEPES.ha):
OutputResults = pd.Series(data=[OptModel.vFlowHeat[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.psnha], index=pd.Index(mTEPES.psnha))
OutputResults.index.names = ['Scenario', 'Period', 'LoadLevel', 'InitialNode', 'FinalNode', 'Circuit']
OutputResults = OutputResults.reset_index().groupby(['InitialNode', 'FinalNode', 'Circuit']).sum(numeric_only=True)[0]
OutputResults.to_frame(name='GWh-Mkm').rename_axis(['InitialNode', 'FinalNode', 'Circuit'], axis=0).reset_index().to_csv(_path+f'/oT_Result_NetworkEnergyHeatTransport_{CaseName}.csv', index=False, sep=',')

# tolerance to consider avoid division by 0
pEpsilon = 1e-6

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=pd.Index(mTEPES.psnha))
OutputToFile.index.names = ['Period', 'Scenario', 'LoadLevel', 'InitialNode', 'FinalNode', 'Circuit']
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)
OutputToFile.reset_index().to_csv(_path+f'/oT_Result_NetworkHeatUtilization_{CaseName}.csv', index=False, sep=',')
sPSNND = [(p,sc,n,nd) for p,sc,n,nd in mTEPES.psnnd if sum(1 for ch in c2n[nd]) + sum(1 for hp in h2n[nd]) + sum(1 for nf,cc in lout[nd]) + sum(1 for ni,cc in lin[nd])]
OutputToFile = pd.Series(data=[OptModel.vHeatNS[p,sc,n,nd]() for p,sc,n,nd in sPSNND], index=pd.Index(sPSNND))
OutputToFile *= 1e3
Expand Down Expand Up @@ -1484,32 +1509,32 @@ def NetworkOperationResults(DirName, CaseName, OptModel, mTEPES):
OutputToFile *= 1e3
OutputToFile.index.names = ['Period', 'Scenario', 'LoadLevel', 'InitialNode', 'FinalNode', 'Circuit']
OutputToFile = pd.pivot_table(OutputToFile.to_frame(name='MW'), values='MW', index=['Period', 'Scenario', 'LoadLevel'], columns=['InitialNode', 'FinalNode', 'Circuit'], fill_value=0.0).rename_axis([None, None, None], axis=1)
OutputToFile.reset_index().to_csv(_path+f'/oT_Result_NetworkFlowPerNode_{CaseName}.csv', index=False, sep=',')
OutputToFile.reset_index().to_csv(_path+f'/oT_Result_NetworkFlowElecPerNode_{CaseName}.csv', index=False, sep=',')

PSNLAARAR = [(p,sc,n,ni,nf,cc,ai,af) for p,sc,n,ni,nf,cc,ai,af in mTEPES.psnla*mTEPES.ar*mTEPES.ar if (ni,ai) in mTEPES.ndar and (nf,af) in mTEPES.ndar]
OutputToFile = pd.Series(data=[OptModel.vFlowElec[p,sc,n,ni,nf,cc]()*mTEPES.pLoadLevelDuration[p,sc,n]() for p,sc,n,ni,nf,cc,ai,af in PSNLAARAR], index=pd.Index(PSNLAARAR))
OutputToFile.index.names = ['Period', 'Scenario', 'LoadLevel', 'InitialNode', 'FinalNode', 'Circuit', 'InitialArea', 'FinalArea']
OutputToFile = pd.pivot_table(OutputToFile.to_frame(name='GWh'), values='GWh', index=['Period', 'Scenario', 'LoadLevel'], columns=['InitialArea', 'FinalArea'], fill_value=0.0).rename_axis([None, None], axis=1)
OutputToFile.reset_index().to_csv(_path+f'/oT_Result_NetworkEnergyPerArea_{CaseName}.csv', index=False, sep=',')
OutputToFile.reset_index().to_csv(_path+f'/oT_Result_NetworkEnergyElecPerArea_{CaseName}.csv', index=False, sep=',')

OutputToFile = pd.Series(data=[OptModel.vFlowElec[p,sc,n,ni,nf,cc]()*mTEPES.pLoadLevelDuration[p,sc,n]() for p,sc,n,ni,nf,cc,ai,af in PSNLAARAR], index=pd.Index(PSNLAARAR))
OutputToFile.index.names = ['Period', 'Scenario', 'LoadLevel', 'InitialNode', 'FinalNode', 'Circuit', 'InitialArea', 'FinalArea']
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)
OutputToFile.reset_index().to_csv(_path+f'/oT_Result_NetworkEnergyTotalPerArea_{CaseName}.csv', index=False, sep=',')
OutputToFile.reset_index().to_csv(_path+f'/oT_Result_NetworkEnergyElecTotalPerArea_{CaseName}.csv', index=False, sep=',')

if len(mTEPES.la):
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=pd.Index(mTEPES.psnla))
OutputResults.index.names = ['Scenario', 'Period', 'LoadLevel', 'InitialNode', 'FinalNode', 'Circuit']
OutputResults = OutputResults.reset_index().groupby(['InitialNode', 'FinalNode', 'Circuit']).sum(numeric_only=True)[0]
OutputResults.to_frame(name='GWh-Mkm').rename_axis(['InitialNode', 'FinalNode', 'Circuit'], axis=0).reset_index().to_csv(_path+f'/oT_Result_NetworkEnergyTransport_{CaseName}.csv', index=False, sep=',')
OutputResults.to_frame(name='GWh-Mkm').rename_axis(['InitialNode', 'FinalNode', 'Circuit'], axis=0).reset_index().to_csv(_path+f'/oT_Result_NetworkEnergyElecTransport_{CaseName}.csv', index=False, sep=',')

# tolerance to consider avoid division by 0
pEpsilon = 1e-6

OutputToFile = pd.Series(data=[max(OptModel.vFlowElec[p,sc,n,ni,nf,cc]()/(mTEPES.pLineNTCFrw[ni,nf,cc]+pEpsilon),-OptModel.vFlowElec[p,sc,n,ni,nf,cc]()/(mTEPES.pLineNTCBck[ni,nf,cc]+pEpsilon)) for p,sc,n,ni,nf,cc in mTEPES.psnla], index=pd.Index(mTEPES.psnla))
OutputToFile.index.names = ['Period', 'Scenario', 'LoadLevel', 'InitialNode', 'FinalNode', 'Circuit']
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)
OutputToFile.reset_index().to_csv(_path+f'/oT_Result_NetworkUtilization_{CaseName}.csv', index=False, sep=',')
OutputToFile.reset_index().to_csv(_path+f'/oT_Result_NetworkElecUtilization_{CaseName}.csv', index=False, sep=',')

if mTEPES.pIndBinNetLosses() and len(mTEPES.psnll):
OutputToFile = pd.Series(data=[OptModel.vLineLosses[p,sc,n,ni,nf,cc]() for p,sc,n,ni,nf,cc in mTEPES.psnll], index=pd.Index(mTEPES.psnll))
Expand Down Expand Up @@ -2020,12 +2045,12 @@ def Transformation1(df, _name):
OutputResults.to_csv(_path+f'/oT_Result_CostSummary_{ar}_{CaseName}.csv', sep=',', index=False)

sPSSTNNDG = [(p,sc,st,n,nd,g) for p,sc,st,n,nd,g in mTEPES.s2n*mTEPES.n2g if (p,g) in mTEPES.pg and (p,sc,n) in mTEPES.psn]
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))
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))
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(_path+f'/oT_Result_RevenueEnergyGeneration_{CaseName}.csv', sep=',')

if len(mTEPES.eh):
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]
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))
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))
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(_path+f'/oT_Result_RevenueEnergyConsumption_{CaseName}.csv', sep=',')

if len(mTEPES.gc):
Expand Down

0 comments on commit 1953c33

Please sign in to comment.