Skip to content

Commit 166a93e

Browse files
committed
updated version
1 parent b5e6004 commit 166a93e

4 files changed

Lines changed: 56 additions & 50 deletions

File tree

openTEPES/openTEPES.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
"""
2-
Open Generation, Storage, and Transmission Operation and Expansion Planning Model with RES and ESS (openTEPES) - April 21, 2025
2+
Open Generation, Storage, and Transmission Operation and Expansion Planning Model with RES and ESS (openTEPES) - May 19, 2025
33
"""
44

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

4141
#%% model declaration
42-
mTEPES = ConcreteModel('Open Generation, Storage, and Transmission Operation and Expansion Planning Model with RES and ESS (openTEPES) - Version 4.18.5 - April 21, 2025')
43-
print( 'Open Generation, Storage, and Transmission Operation and Expansion Planning Model with RES and ESS (openTEPES) - Version 4.18.5 - April 21, 2025', file=open(f'{_path}/openTEPES_version_{CaseName}.log','w'))
42+
mTEPES = ConcreteModel('Open Generation, Storage, and Transmission Operation and Expansion Planning Model with RES and ESS (openTEPES) - Version 4.18.5 - May 19, 2025')
43+
print( 'Open Generation, Storage, and Transmission Operation and Expansion Planning Model with RES and ESS (openTEPES) - Version 4.18.5 - May 19, 2025', file=open(f'{_path}/openTEPES_version_{CaseName}.log','w'))
4444

4545
pIndOutputResults = [j for i,j in idxDict.items() if i == pIndOutputResults][0]
4646
pIndLogConsole = [j for i,j in idxDict.items() if i == pIndLogConsole ][0]

openTEPES/openTEPES_InputData.py

Lines changed: 33 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ def InputData(DirName, CaseName, mTEPES, pIndLogConsole):
5252
pIndVarTTC = 1
5353
except:
5454
pIndVarTTC = 0
55-
print('**** No variable transmission line capacities')
55+
print('**** No variable transmission line TTCs')
5656
try:
5757
dfVariablePTDF = pd.read_csv(f'{_path}/oT_Data_VariablePTDF_' f'{CaseName}.csv', header=[0,1,2,3], index_col=[0,1,2])
5858
pIndPTDF = 1
@@ -189,6 +189,12 @@ def InputData(DirName, CaseName, mTEPES, pIndLogConsole):
189189
print('Energy outflows \n', dfEnergyOutflows.describe (), '\n')
190190
print('Electric network \n', dfNetwork.describe (), '\n')
191191

192+
if pIndVarTTC == 1:
193+
print('Variable TTC forward \n', dfVariableTTCFrw.describe (), '\n')
194+
print('Variable TTC backward \n', dfVariableTTCBck.describe (), '\n')
195+
if pIndPTDF == 1:
196+
print('Variable PTDF \n', dfVariablePTDF.describe (), '\n')
197+
192198
if pIndHydroTopology == 1:
193199
print('Reservoir \n', dfReservoir.describe (), '\n')
194200
print('Variable minimum reservoir volume \n', dfVariableMinVolume.describe (), '\n')
@@ -205,12 +211,6 @@ def InputData(DirName, CaseName, mTEPES, pIndLogConsole):
205211
print('Reserve margin heat \n', dfReserveMarginHeat.describe (), '\n')
206212
print('Heat pipe network \n', dfNetworkHeat.describe (), '\n')
207213

208-
if pIndVarTTC == 1:
209-
print('Variable TTC forward \n', dfVariableTTCFrw.describe (), '\n')
210-
print('Variable TTC backward \n', dfVariableTTCBck.describe (), '\n')
211-
if pIndPTDF == 1:
212-
print('Variable PTDF \n', dfVariablePTDF.describe (), '\n')
213-
214214
#%% reading the sets
215215
dictSets = DataPortal()
216216
dictSets.load(filename=f'{_path}/oT_Dict_Period_' f'{CaseName}.csv', set='p' , format='set')
@@ -750,12 +750,12 @@ def CreateInstrumentalSets(mTEPES, pIndHydroTopology, pIndHydrogen, pIndHeat) ->
750750
mTEPES.psnnd = Set(initialize = [(p,sc,n,nd) for p,sc,n,nd in mTEPES.psn*mTEPES.nd ])
751751
mTEPES.psnar = Set(initialize = [(p,sc,n,ar) for p,sc,n,ar in mTEPES.psn*mTEPES.ar ])
752752

753-
mTEPES.psnla = Set(initialize = [(p,sc,n,ni,nf,cc) for p,sc,n,ni,nf,cc in mTEPES.psn*mTEPES.la if (p,ni,nf,cc) in mTEPES.pla])
754-
mTEPES.psnle = Set(initialize = [(p,sc,n,ni,nf,cc) for p,sc,n,ni,nf,cc in mTEPES.psn*mTEPES.le if (p,ni,nf,cc) in mTEPES.pla])
755-
mTEPES.psnll = Set(initialize = [(p,sc,n,ni,nf,cc) for p,sc,n,ni,nf,cc in mTEPES.psn*mTEPES.ll if (p,ni,nf,cc) in mTEPES.pll])
756-
mTEPES.psnls = Set(initialize = [(p,sc,n,ni,nf,cc) for p,sc,n,ni,nf,cc in mTEPES.psn*mTEPES.ls if (p,ni,nf,cc) in mTEPES.pla])
753+
mTEPES.psnla = Set(initialize = [(p,sc,n,ni,nf,cc) for p,sc,n,ni,nf,cc in mTEPES.psn*mTEPES.la if (p,ni,nf,cc) in mTEPES.pla ])
754+
mTEPES.psnle = Set(initialize = [(p,sc,n,ni,nf,cc) for p,sc,n,ni,nf,cc in mTEPES.psn*mTEPES.le if (p,ni,nf,cc) in mTEPES.pla ])
755+
mTEPES.psnll = Set(initialize = [(p,sc,n,ni,nf,cc) for p,sc,n,ni,nf,cc in mTEPES.psn*mTEPES.ll if (p,ni,nf,cc) in mTEPES.pll ])
756+
mTEPES.psnls = Set(initialize = [(p,sc,n,ni,nf,cc) for p,sc,n,ni,nf,cc in mTEPES.psn*mTEPES.ls if (p,ni,nf,cc) in mTEPES.pla ])
757757

758-
mTEPES.psnehc = Set(initialize = [(p,sc,n,eh) for p,sc,n,eh in mTEPES.psneh if pRatedMaxCharge[eh]>0.0 ])
758+
mTEPES.psnehc = Set(initialize = [(p,sc,n,eh) for p,sc,n,eh in mTEPES.psneh if pRatedMaxCharge[eh] > 0.0 ])
759759

760760
if pIndHydroTopology == 1:
761761
mTEPES.prs = Set(initialize = [(p, rs) for p, rs in mTEPES.p *mTEPES.rs if pRsrPeriodIni[rs] <= p and pRsrPeriodFin[rs] >= p])
@@ -945,10 +945,6 @@ def Create_ESS_RES_Sets(mTEPES) -> None:
945945
pStableTime = round(pStableTime/pTimeStep).astype('int')
946946
pShiftTime = round(pShiftTime /pTimeStep).astype('int')
947947

948-
if pIndVarTTC == 1:
949-
pMaxNTCFrw = pVariableTTCFrw.replace(0.0, pLineNTCFrw / dfNetwork['SecurityFactor' ]) * dfNetwork['SecurityFactor' ]
950-
pMaxNTCBck = pVariableTTCBck.replace(0.0, pLineNTCBck / dfNetwork['SecurityFactor' ]) * dfNetwork['SecurityFactor' ]
951-
952948
# %% definition of the time-steps leap to observe the stored energy at an ESS
953949
idxCycle = dict()
954950
idxCycle[0 ] = 1
@@ -1167,21 +1163,21 @@ def Create_ESS_RES_Sets(mTEPES) -> None:
11671163
pMaxPower2ndBlock [pMaxPower2ndBlock [[g for g in g2a[ar]]] < pEpsilonElec] = 0.0
11681164
pMaxCharge2ndBlock[pMaxCharge2ndBlock[[g for g in g2a[ar]]] < pEpsilonElec] = 0.0
11691165

1170-
pLineNTCFrw.update(pd.Series([0.0 for ni,nf,cc in mTEPES.la if pLineNTCFrw[ni,nf,cc] < pEpsilonElec], index=[(ni,nf,cc) for ni,nf,cc in mTEPES.la if pLineNTCFrw[ni,nf,cc] < pEpsilonElec], dtype='float64'))
1171-
pLineNTCBck.update(pd.Series([0.0 for ni,nf,cc in mTEPES.la if pLineNTCBck[ni,nf,cc] < pEpsilonElec], index=[(ni,nf,cc) for ni,nf,cc in mTEPES.la if pLineNTCBck[ni,nf,cc] < pEpsilonElec], dtype='float64'))
1166+
pLineNTCFrw.update(pd.Series([0.0 for la in mTEPES.la if pLineNTCFrw[la] < pEpsilonElec], index=[la for la in mTEPES.la if pLineNTCFrw[la] < pEpsilonElec], dtype='float64'))
1167+
pLineNTCBck.update(pd.Series([0.0 for la in mTEPES.la if pLineNTCBck[la] < pEpsilonElec], index=[la for la in mTEPES.la if pLineNTCBck[la] < pEpsilonElec], dtype='float64'))
11721168
pLineNTCMax = pLineNTCFrw.where(pLineNTCFrw > pLineNTCBck, pLineNTCBck)
11731169

11741170
if pIndHydrogen == 1:
11751171
pDemandH2[pDemandH2[[nd for nd in d2a[ar]]] < pEpsilonElec] = 0.0
1176-
pH2PipeNTCFrw.update(pd.Series([0.0 for ni,nf,cc in mTEPES.pa if pH2PipeNTCFrw[ni,nf,cc] < pEpsilonElec], index=[(ni,nf,cc) for ni,nf,cc in mTEPES.pa if pH2PipeNTCFrw[ni,nf,cc] < pEpsilonElec], dtype='float64'))
1177-
pH2PipeNTCBck.update(pd.Series([0.0 for ni,nf,cc in mTEPES.pa if pH2PipeNTCBck[ni,nf,cc] < pEpsilonElec], index=[(ni,nf,cc) for ni,nf,cc in mTEPES.pa if pH2PipeNTCBck[ni,nf,cc] < pEpsilonElec], dtype='float64'))
1172+
pH2PipeNTCFrw.update(pd.Series([0.0 for pa in mTEPES.pa if pH2PipeNTCFrw[pa] < pEpsilonElec], index=[pa for pa in mTEPES.pa if pH2PipeNTCFrw[pa] < pEpsilonElec], dtype='float64'))
1173+
pH2PipeNTCBck.update(pd.Series([0.0 for pa in mTEPES.pa if pH2PipeNTCBck[pa] < pEpsilonElec], index=[pa for pa in mTEPES.pa if pH2PipeNTCBck[pa] < pEpsilonElec], dtype='float64'))
11781174

11791175
if pIndHeat == 1:
11801176
pDemandHeatPeak[p,ar] = pDemandHeat.loc[p,:,:][[nd for nd in d2a[ar]]].sum(axis=1).max()
11811177
pEpsilonHeat = pDemandHeatPeak[p,ar]*1e-5
11821178
pDemandHeat [pDemandHeat [[nd for nd in d2a[ar]]] < pEpsilonHeat] = 0.0
1183-
pHeatPipeNTCFrw.update(pd.Series([0.0 for ni,nf,cc in mTEPES.ha if pHeatPipeNTCFrw[ni,nf,cc] < pEpsilonHeat], index=[(ni,nf,cc) for ni,nf,cc in mTEPES.ha if pHeatPipeNTCFrw[ni,nf,cc] < pEpsilonHeat], dtype='float64'))
1184-
pHeatPipeNTCBck.update(pd.Series([0.0 for ni,nf,cc in mTEPES.ha if pHeatPipeNTCBck[ni,nf,cc] < pEpsilonHeat], index=[(ni,nf,cc) for ni,nf,cc in mTEPES.ha if pHeatPipeNTCBck[ni,nf,cc] < pEpsilonHeat], dtype='float64'))
1179+
pHeatPipeNTCFrw.update(pd.Series([0.0 for ha in mTEPES.ha if pHeatPipeNTCFrw[ha] < pEpsilonHeat], index=[ha for ha in mTEPES.ha if pHeatPipeNTCFrw[ha] < pEpsilonHeat], dtype='float64'))
1180+
pHeatPipeNTCBck.update(pd.Series([0.0 for ha in mTEPES.ha if pHeatPipeNTCBck[ha] < pEpsilonHeat], index=[ha for ha in mTEPES.ha if pHeatPipeNTCBck[ha] < pEpsilonHeat], dtype='float64'))
11851181

11861182
# drop generators not g or es or eh or ch
11871183
pMinPowerElec = pMinPowerElec.loc [:,mTEPES.g ]
@@ -1266,6 +1262,17 @@ def Create_ESS_RES_Sets(mTEPES) -> None:
12661262
pNetUpInvest = pNetUpInvest.loc [mTEPES.lc]
12671263
pLineLossFactor = pLineLossFactor.loc [mTEPES.ll]
12681264

1265+
pMaxNTCFrw = pd.DataFrame([[pLineNTCFrw[la] for la in mTEPES.la] for p,sc,n in mTEPES.psn], index=mTEPES.psn, columns=mTEPES.la)
1266+
pMaxNTCBck = pd.DataFrame([[pLineNTCBck[la] for la in mTEPES.la] for p,sc,n in mTEPES.psn], index=mTEPES.psn, columns=mTEPES.la)
1267+
if pIndVarTTC == 1:
1268+
pMaxNTCFrw = pVariableTTCFrw.replace(0.0, pLineNTCFrw / dfNetwork['SecurityFactor']) * dfNetwork['SecurityFactor']
1269+
pMaxNTCBck = pVariableTTCBck.replace(0.0, pLineNTCBck / dfNetwork['SecurityFactor']) * dfNetwork['SecurityFactor']
1270+
pMaxNTCMax = pMaxNTCFrw.where(pMaxNTCFrw > pMaxNTCBck, pMaxNTCBck)
1271+
1272+
pMaxNTCBck = pMaxNTCBck.loc [:,mTEPES.la]
1273+
pMaxNTCFrw = pMaxNTCFrw.loc [:,mTEPES.la]
1274+
pMaxNTCMax = pMaxNTCFrw.loc [:,mTEPES.la]
1275+
12691276
if pIndHydroTopology == 1:
12701277
# drop generators not h
12711278
pProductionFunctionHydro = pProductionFunctionHydro.loc[mTEPES.h ]
@@ -1294,9 +1301,6 @@ def Create_ESS_RES_Sets(mTEPES) -> None:
12941301
pHeatPipeLoInvest = pHeatPipeLoInvest.loc [mTEPES.hc]
12951302
pHeatPipeUpInvest = pHeatPipeUpInvest.loc [mTEPES.hc]
12961303

1297-
pMaxNTCBck = pMaxNTCBck.loc [:,mTEPES.la]
1298-
pMaxNTCFrw = pMaxNTCFrw.loc [:,mTEPES.la]
1299-
13001304
# replace very small costs by 0
13011305
pEpsilon = 1e-5 # this value in EUR/GWh is lower than the O&M variable cost of any technology, independent of the area
13021306

@@ -1375,6 +1379,7 @@ def filter_rows(df, set):
13751379

13761380
pMaxNTCBck = filter_rows(pMaxNTCBck , mTEPES.psnla)
13771381
pMaxNTCFrw = filter_rows(pMaxNTCFrw , mTEPES.psnla)
1382+
pMaxNTCMax = filter_rows(pMaxNTCMax , mTEPES.psnla)
13781383

13791384
if pIndPTDF == 1:
13801385
pPTDF = pVariablePTDF.stack(level=list(range(pVariablePTDF.columns.nlevels)), future_stack=True)
@@ -1579,8 +1584,9 @@ def filter_rows(df, set):
15791584
mTEPES.pNetLoInvest = Param(mTEPES.lc, initialize=pNetLoInvest.to_dict() , within=NonNegativeReals, doc='Lower bound of the electric line investment decision', mutable=True)
15801585
mTEPES.pNetUpInvest = Param(mTEPES.lc, initialize=pNetUpInvest.to_dict() , within=NonNegativeReals, doc='Upper bound of the electric line investment decision', mutable=True)
15811586
mTEPES.pIndBinLinePTDF = Param(mTEPES.la, initialize=pIndBinLinePTDF.to_dict() , within=Binary , doc='Binary indicator of line with' )
1582-
mTEPES.pMaxNTCFrw = Param(mTEPES.psnla, initialize=pMaxNTCFrw.to_dict() , within= Reals, doc='Maximum NTC forward flow' )
1583-
mTEPES.pMaxNTCBck = Param(mTEPES.psnla, initialize=pMaxNTCBck.to_dict() , within= Reals, doc='Maximum NTC backward flow' )
1587+
mTEPES.pMaxNTCFrw = Param(mTEPES.psnla, initialize=pMaxNTCFrw.to_dict() , within= Reals, doc='Maximum NTC forward capacity' )
1588+
mTEPES.pMaxNTCBck = Param(mTEPES.psnla, initialize=pMaxNTCBck.to_dict() , within= Reals, doc='Maximum NTC backward capacity' )
1589+
mTEPES.pMaxNTCMax = Param(mTEPES.psnla, initialize=pMaxNTCMax.to_dict() , within= Reals, doc='Maximum NTC capacity' )
15841590

15851591
if pIndHydrogen == 1:
15861592
mTEPES.pH2PipeLength = Param(mTEPES.pn, initialize=pH2PipeLength.to_dict() , within=NonNegativeReals, doc='Hydrogen pipeline length', mutable=True)

openTEPES/openTEPES_Main.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -660,7 +660,7 @@
660660
# For more information on this, and how to apply and follow the GNU AGPL, see
661661
# <https://www.gnu.org/licenses/>.
662662

663-
# Open Generation, Storage, and Transmission Operation and Expansion Planning Model with RES and ESS (openTEPES) - April 21, 2025
663+
# Open Generation, Storage, and Transmission Operation and Expansion Planning Model with RES and ESS (openTEPES) - May 19, 2025
664664
# simplicity and transparency in power systems planning
665665

666666
# Developed by
@@ -686,7 +686,7 @@
686686
# import pkg_resources
687687
from .openTEPES import openTEPES_run
688688

689-
print('\033[1;32mOpen Generation, Storage, and Transmission Operation and Expansion Planning Model with RES and ESS (openTEPES) - Version 4.18.5 - April 21, 2025\033[0m')
689+
print('\033[1;32mOpen Generation, Storage, and Transmission Operation and Expansion Planning Model with RES and ESS (openTEPES) - Version 4.18.5 - May 19, 2025\033[0m')
690690
print('\033[34m#### Academic research license - for non-commercial use only ####\033[0m \n')
691691

692692
parser = argparse.ArgumentParser(description='Introducing main parameters...')

0 commit comments

Comments
 (0)