openTEPES 4.18.7__py3-none-any.whl → 4.18.9__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- openTEPES/__init__.py +1 -1
- openTEPES/openTEPES.py +3 -4
- openTEPES/openTEPES_InputData.py +213 -113
- openTEPES/openTEPES_Main.py +17 -7
- openTEPES/openTEPES_ModelFormulation.py +101 -60
- openTEPES/openTEPES_OutputResults.py +496 -196
- openTEPES/openTEPES_ProblemSolving.py +35 -34
- openTEPES/sSEP/oT_Data_RampReserveDown_sSEP.csv +8737 -0
- openTEPES/sSEP/oT_Data_RampReserveUp_sSEP.csv +8737 -0
- {opentepes-4.18.7.dist-info → opentepes-4.18.9.dist-info}/METADATA +20 -19
- {opentepes-4.18.7.dist-info → opentepes-4.18.9.dist-info}/RECORD +14 -12
- {opentepes-4.18.7.dist-info → opentepes-4.18.9.dist-info}/WHEEL +0 -0
- {opentepes-4.18.7.dist-info → opentepes-4.18.9.dist-info}/entry_points.txt +0 -0
- {opentepes-4.18.7.dist-info → opentepes-4.18.9.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
"""
|
|
2
|
-
Open Generation, Storage, and Transmission Operation and Expansion Planning Model with RES and ESS (openTEPES) -
|
|
2
|
+
Open Generation, Storage, and Transmission Operation and Expansion Planning Model with RES and ESS (openTEPES) - January 22, 2026
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
5
|
import time
|
|
6
6
|
import datetime
|
|
7
7
|
import os
|
|
8
|
-
# import ast
|
|
9
8
|
import math
|
|
10
9
|
import csv
|
|
11
10
|
import pandas as pd
|
|
@@ -15,9 +14,13 @@ import plotly.io as pio
|
|
|
15
14
|
import plotly.graph_objs as go
|
|
16
15
|
from collections import defaultdict
|
|
17
16
|
from colour import Color
|
|
17
|
+
import duckdb
|
|
18
|
+
|
|
19
|
+
# from line_profiler import profile
|
|
18
20
|
|
|
19
21
|
|
|
20
22
|
# Definition of Pie plots
|
|
23
|
+
# @profile
|
|
21
24
|
def PiePlots(period, scenario, df, Category, Value):
|
|
22
25
|
df = df.reset_index()
|
|
23
26
|
df = df.loc[(df['level_0'] == period) & (df['level_1'] == scenario)]
|
|
@@ -32,17 +35,18 @@ def PiePlots(period, scenario, df, Category, Value):
|
|
|
32
35
|
ComposedCategory = Category+':N'
|
|
33
36
|
ComposedValue = Value +':Q'
|
|
34
37
|
|
|
35
|
-
base = alt.Chart(OutputToPlot).encode(theta=alt.Theta(ComposedValue, type=
|
|
38
|
+
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)
|
|
36
39
|
pie = base.mark_arc(outerRadius=240)
|
|
37
40
|
text = base.mark_text(radius=340, size=15).encode(text='Label:N')
|
|
38
41
|
chart = pie+text
|
|
39
|
-
# chart = chart.resolve_scale(theta=
|
|
40
|
-
chart = alt.layer(pie, text, data=OutputToPlot).resolve_scale(theta=
|
|
42
|
+
# chart = chart.resolve_scale(theta='independent')
|
|
43
|
+
chart = alt.layer(pie, text, data=OutputToPlot).resolve_scale(theta='independent')
|
|
41
44
|
|
|
42
45
|
return chart
|
|
43
46
|
|
|
44
47
|
|
|
45
48
|
# Definition of Area plots
|
|
49
|
+
# @profile
|
|
46
50
|
def AreaPlots(period, scenario, df, Category, X, Y, OperationType):
|
|
47
51
|
Results = df.loc[period,scenario,:,:]
|
|
48
52
|
Results = Results.reset_index().rename(columns={'level_0': X, 'level_1': Category, 0: Y})
|
|
@@ -71,6 +75,7 @@ def AreaPlots(period, scenario, df, Category, X, Y, OperationType):
|
|
|
71
75
|
|
|
72
76
|
|
|
73
77
|
# Definition of Line plots
|
|
78
|
+
# @profile
|
|
74
79
|
def LinePlots(period, scenario, df, Category, X, Y, OperationType):
|
|
75
80
|
Results = df.loc[period,scenario,:,:].rename_axis(['level_0', 'level_1'], axis=0)
|
|
76
81
|
Results.columns = [0]
|
|
@@ -99,7 +104,165 @@ def LinePlots(period, scenario, df, Category, X, Y, OperationType):
|
|
|
99
104
|
return plot
|
|
100
105
|
|
|
101
106
|
|
|
107
|
+
def _set_df(con, name: str, df: pd.DataFrame):
|
|
108
|
+
"""
|
|
109
|
+
Insert a pandas DataFrame into an existing DuckDB table.
|
|
110
|
+
|
|
111
|
+
Parameters
|
|
112
|
+
----------
|
|
113
|
+
con : duckdb.DuckDBPyConnection
|
|
114
|
+
Open DuckDB connection.
|
|
115
|
+
name : str
|
|
116
|
+
Target table name.
|
|
117
|
+
df : pandas.DataFrame
|
|
118
|
+
DataFrame to insert into the target table.
|
|
119
|
+
"""
|
|
120
|
+
con.cursor().execute(f"CREATE OR REPLACE TABLE '{name}' AS SELECT * FROM df;")
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def _write_var_to_db(con, var, name):
|
|
124
|
+
"""
|
|
125
|
+
Write a Pyomo Var's values and bounds to DuckDB.
|
|
126
|
+
|
|
127
|
+
Parameters
|
|
128
|
+
----------
|
|
129
|
+
con : duckdb.DuckDBPyConnection
|
|
130
|
+
Open DuckDB connection.
|
|
131
|
+
var : pyomo.core.base.var.Var
|
|
132
|
+
Pyomo variable (indexed or scalar).
|
|
133
|
+
name : str
|
|
134
|
+
Variable/table name to use in the database.
|
|
135
|
+
"""
|
|
136
|
+
values = var.extract_values()
|
|
137
|
+
s = pd.Series(values, index=values.keys())
|
|
138
|
+
df = s.to_frame(name=name).reset_index()
|
|
139
|
+
df = pd.concat(
|
|
140
|
+
[
|
|
141
|
+
df,
|
|
142
|
+
pd.DataFrame([dict(upper_bound=var[index].ub, lower_bound=var[index].lb) for index in var]),
|
|
143
|
+
],
|
|
144
|
+
axis=1,
|
|
145
|
+
)
|
|
146
|
+
_set_df(con, f'v_{name}', df)
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def _write_param_to_db(con, param, name):
|
|
150
|
+
"""
|
|
151
|
+
Write a Pyomo Param's values to DuckDB.
|
|
152
|
+
|
|
153
|
+
Creates/inserts into a table named `{name}` with:
|
|
154
|
+
- the Param index (via reset_index)
|
|
155
|
+
- a column named `{name}` containing the Param value
|
|
156
|
+
|
|
157
|
+
Parameters
|
|
158
|
+
----------
|
|
159
|
+
con : duckdb.DuckDBPyConnection
|
|
160
|
+
Open DuckDB connection.
|
|
161
|
+
param : pyomo.core.base.param.Param
|
|
162
|
+
Pyomo parameter (indexed or scalar).
|
|
163
|
+
name : str
|
|
164
|
+
Parameter/table name to use in the database.
|
|
165
|
+
"""
|
|
166
|
+
values = param.extract_values()
|
|
167
|
+
s = pd.Series(values, index=values.keys())
|
|
168
|
+
df = s.to_frame(name=name).reset_index()
|
|
169
|
+
_set_df(con, f'p_{name}', df)
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
def _write_set_to_db(con, set_, name):
|
|
173
|
+
"""
|
|
174
|
+
Write a Pyomo Set's elements to DuckDB.
|
|
175
|
+
|
|
176
|
+
Parameters
|
|
177
|
+
----------
|
|
178
|
+
con : duckdb.DuckDBPyConnection
|
|
179
|
+
Open DuckDB connection.
|
|
180
|
+
set_ : pyomo.core.base.set.Set
|
|
181
|
+
Pyomo set.
|
|
182
|
+
name : str
|
|
183
|
+
Base name used to build the table name `s_{name}`.
|
|
184
|
+
"""
|
|
185
|
+
s = pd.Series(set_.sorted_data())
|
|
186
|
+
df = s.to_frame(name=name).reset_index()
|
|
187
|
+
_set_df(con, f's_{name}', df)
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
def _write_constraint_to_db(con, constraint, name, model):
|
|
191
|
+
"""
|
|
192
|
+
Write an indexed Pyomo Constraint's duals and bounds to DuckDB.
|
|
193
|
+
|
|
194
|
+
Parameters
|
|
195
|
+
----------
|
|
196
|
+
con : duckdb.DuckDBPyConnection
|
|
197
|
+
Open DuckDB connection.
|
|
198
|
+
constraint : pyomo.core.base.constraint.Constraint
|
|
199
|
+
Pyomo constraint component (must be indexed; scalar constraints are skipped).
|
|
200
|
+
name : str
|
|
201
|
+
Constraint name used to build the table name `c_{name}`.
|
|
202
|
+
model : pyomo.core.base.PyomoModel.ConcreteModel
|
|
203
|
+
Model providing `pDuals` (mapping from constraint+index string to dual value).
|
|
204
|
+
|
|
205
|
+
Notes
|
|
206
|
+
-----
|
|
207
|
+
Non-indexed constraints are ignored
|
|
208
|
+
"""
|
|
209
|
+
if not constraint.is_indexed():
|
|
210
|
+
return
|
|
211
|
+
|
|
212
|
+
records = []
|
|
213
|
+
for index in constraint:
|
|
214
|
+
key = str(constraint.name) + str(index)
|
|
215
|
+
records.append(
|
|
216
|
+
dict(
|
|
217
|
+
name=str(name),
|
|
218
|
+
index=index,
|
|
219
|
+
dual=model.pDuals.get(key),
|
|
220
|
+
lower_bound=constraint[index].lb,
|
|
221
|
+
upper_bound=constraint[index].ub,
|
|
222
|
+
)
|
|
223
|
+
)
|
|
224
|
+
|
|
225
|
+
df = pd.DataFrame(records)
|
|
226
|
+
_set_df(con, f'c_{name}', df.reset_index())
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
def write_model_to_db(model, filename):
|
|
230
|
+
"""
|
|
231
|
+
Export Pyomo model components to a DuckDB database file.
|
|
232
|
+
|
|
233
|
+
Parameters
|
|
234
|
+
----------
|
|
235
|
+
model : pyomo.core.base.PyomoModel.ConcreteModel
|
|
236
|
+
filename : str
|
|
237
|
+
"""
|
|
238
|
+
with duckdb.connect(filename) as con:
|
|
239
|
+
model_vars = model.component_map(ctype=pyo.Var)
|
|
240
|
+
for k in model_vars.keys():
|
|
241
|
+
var = model_vars[k]
|
|
242
|
+
name = var.getname()
|
|
243
|
+
_write_var_to_db(con, var, name)
|
|
244
|
+
|
|
245
|
+
model_params = model.component_map(ctype=pyo.Param)
|
|
246
|
+
for k in model_params.keys():
|
|
247
|
+
param = model_params[k]
|
|
248
|
+
name = param.getname()
|
|
249
|
+
_write_param_to_db(con, param, name)
|
|
250
|
+
|
|
251
|
+
model_sets = model.component_map(ctype=pyo.Set)
|
|
252
|
+
for k in model_sets.keys():
|
|
253
|
+
s = model_sets[k]
|
|
254
|
+
name = s.getname()
|
|
255
|
+
_write_set_to_db(con, s, name)
|
|
256
|
+
|
|
257
|
+
model_constraints = model.component_map(ctype=pyo.Constraint)
|
|
258
|
+
for k in model_constraints.keys():
|
|
259
|
+
constraint = model_constraints[k]
|
|
260
|
+
name = k
|
|
261
|
+
_write_constraint_to_db(con, constraint, name, model)
|
|
262
|
+
|
|
263
|
+
|
|
102
264
|
# write parameters, variables, and duals
|
|
265
|
+
# @profile
|
|
103
266
|
def OutputResultsParVarCon(DirName, CaseName, OptModel, mTEPES):
|
|
104
267
|
# print('Writing pars, vars, and duals results ... ', end='')
|
|
105
268
|
# DirName = os.path.dirname(DirName)
|
|
@@ -118,40 +281,42 @@ def OutputResultsParVarCon(DirName, CaseName, OptModel, mTEPES):
|
|
|
118
281
|
os.makedirs(dump_folder)
|
|
119
282
|
DateName = str(datetime.datetime.now().strftime('%Y%m%d'))
|
|
120
283
|
|
|
284
|
+
write_model_to_db(OptModel, f'{_path}/CaseDumpFolder_{CaseName}_{DateName}/oT_Case_{CaseName}.duckdb')
|
|
285
|
+
|
|
121
286
|
# Extract and write parameters from the case
|
|
122
|
-
with open(f'{_path}/CaseDumpFolder_{CaseName}_{DateName}/oT_Case_{CaseName}_Parameters.csv', 'w', newline='') as csvfile:
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
# Extract and write variables
|
|
137
|
-
with open(f'{_path}/CaseDumpFolder_{CaseName}_{DateName}/oT_Case_{CaseName}_Variables.csv', 'w', newline='') as csvfile:
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
# Extract and write dual variables
|
|
146
|
-
with open(f'{_path}/CaseDumpFolder_{CaseName}_{DateName}/oT_Case_{CaseName}_Constraints.csv', 'w', newline='') as csvfile:
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
287
|
+
# with open(f'{_path}/CaseDumpFolder_{CaseName}_{DateName}/oT_Case_{CaseName}_Parameters.csv', 'w', newline='') as csvfile:
|
|
288
|
+
# writer = csv.writer(csvfile)
|
|
289
|
+
# writer.writerow(['Name', 'Index', 'Value'])
|
|
290
|
+
# for par in OptModel.component_objects(pyo.Param):
|
|
291
|
+
# par_object = getattr(OptModel, str(par))
|
|
292
|
+
# if par_object.is_indexed():
|
|
293
|
+
# for index in par_object:
|
|
294
|
+
# if (isinstance(index, tuple) and par_object.mutable == False) or par_object.mutable == False:
|
|
295
|
+
# writer.writerow([str(par), index, par_object[index]])
|
|
296
|
+
# else:
|
|
297
|
+
# writer.writerow([str(par), index, par_object[index].value])
|
|
298
|
+
# else:
|
|
299
|
+
# writer.writerow ([str(par), 'NA', par_object.value])
|
|
300
|
+
#
|
|
301
|
+
# # Extract and write variables
|
|
302
|
+
# with open(f'{_path}/CaseDumpFolder_{CaseName}_{DateName}/oT_Case_{CaseName}_Variables.csv', 'w', newline='') as csvfile:
|
|
303
|
+
# writer = csv.writer(csvfile)
|
|
304
|
+
# writer.writerow(['Name', 'Index', 'Value', 'Lower Bound', 'Upper Bound'])
|
|
305
|
+
# for var in OptModel.component_objects(pyo.Var, active=True):
|
|
306
|
+
# var_object = getattr(OptModel, str(var))
|
|
307
|
+
# for index in var_object:
|
|
308
|
+
# writer.writerow([str(var), index, var_object[index].value, str(var_object[index].lb), str(var_object[index].ub)])
|
|
309
|
+
#
|
|
310
|
+
# # Extract and write dual variables
|
|
311
|
+
# with open(f'{_path}/CaseDumpFolder_{CaseName}_{DateName}/oT_Case_{CaseName}_Constraints.csv', 'w', newline='') as csvfile:
|
|
312
|
+
# writer = csv.writer(csvfile)
|
|
313
|
+
# writer.writerow(['Name', 'Index', 'Value', 'Lower Bound', 'Upper Bound'])
|
|
314
|
+
# for con in OptModel.component_objects(pyo.Constraint, active=True):
|
|
315
|
+
# con_object = getattr(OptModel, str(con))
|
|
316
|
+
# if con.is_indexed():
|
|
317
|
+
# for index in con_object:
|
|
318
|
+
# writer.writerow([str(con), index, mTEPES.pDuals[str(con_object.name)+str(index)], str(con_object[index].lb), str(con_object[index].ub)])
|
|
319
|
+
# # writer.writerow([str(con), index, OptModel.dual[con_object[index]], str(con_object[index].lb), str(con_object[index].ub)])
|
|
155
320
|
|
|
156
321
|
# NameList = ['Parameters', 'Variables', 'Constraints']
|
|
157
322
|
#
|
|
@@ -178,6 +343,7 @@ def OutputResultsParVarCon(DirName, CaseName, OptModel, mTEPES):
|
|
|
178
343
|
print('Writing pars, vars, and duals results ... ', round(WritingResultsTime), 's')
|
|
179
344
|
|
|
180
345
|
|
|
346
|
+
# @profile
|
|
181
347
|
def InvestmentResults(DirName, CaseName, OptModel, mTEPES, pIndTechnologyOutput, pIndPlotOutput):
|
|
182
348
|
#%% outputting the investment decisions
|
|
183
349
|
_path = os.path.join(DirName, CaseName)
|
|
@@ -201,26 +367,28 @@ def InvestmentResults(DirName, CaseName, OptModel, mTEPES, pIndTechnologyOutput,
|
|
|
201
367
|
|
|
202
368
|
# Saving generation investments
|
|
203
369
|
OutputToFile = pd.Series(data=[OptModel.vGenerationInvest[p,eb]() for p,eb in mTEPES.peb], index=mTEPES.peb)
|
|
204
|
-
OutputToFile = OutputToFile.fillna(0).to_frame(name='InvestmentDecision').reset_index().rename(columns={'level_0': 'Period', 'level_1': '
|
|
370
|
+
OutputToFile = OutputToFile.fillna(0).to_frame(name='InvestmentDecision').reset_index().rename(columns={'level_0': 'Period', 'level_1': 'Generator'})
|
|
205
371
|
if pIndTechnologyOutput == 0 or pIndTechnologyOutput == 2:
|
|
206
|
-
OutputToFile.pivot_table(index=['Period'], columns=['
|
|
207
|
-
OutputToFile = OutputToFile.set_index(['Period', '
|
|
372
|
+
OutputToFile.pivot_table(index=['Period'], columns=['Generator'], values='InvestmentDecision').rename_axis(['Period'], axis=0).to_csv(f'{_path}/oT_Result_GenerationInvestmentPerUnit_{CaseName}.csv', index=True, sep=',')
|
|
373
|
+
OutputToFile = OutputToFile.set_index(['Period', 'Generator'])
|
|
374
|
+
|
|
208
375
|
OutputToFile = pd.Series(data=[OptModel.vGenerationInvest[p,eb]()*max(mTEPES.pRatedMaxPowerElec[eb],mTEPES.pRatedMaxCharge[eb]) for p,eb in mTEPES.peb], index=mTEPES.peb)
|
|
209
376
|
OutputToFile *= 1e3
|
|
210
|
-
OutputToFile = OutputToFile.fillna(0).to_frame(name='MW'
|
|
377
|
+
OutputToFile = OutputToFile.fillna(0).to_frame(name='MW').reset_index().rename(columns={'level_0': 'Period', 'level_1': 'Generator'})
|
|
211
378
|
if pIndTechnologyOutput == 0 or pIndTechnologyOutput == 2:
|
|
212
|
-
OutputToFile.pivot_table(index=['Period'], columns=['
|
|
213
|
-
|
|
379
|
+
OutputToFile.pivot_table(index=['Period'], columns=['Generator'], values='MW').rename_axis(['Period'], axis=0).to_csv(f'{_path}/oT_Result_GenerationInvestment_{CaseName}.csv', index=True, sep=',')
|
|
380
|
+
OutputToFile.pivot_table(index=['Period', 'Generator'], values='MW').rename_axis(['Period', 'Generator'], axis=0).rename(columns={'MW': 'Power [MW]'}, inplace=False).to_csv(f'{_path}/oT_Result_MarketResultsGenerationInvestment_{CaseName}.csv', index=True, sep=',')
|
|
381
|
+
OutputToFile = OutputToFile.set_index(['Period', 'Generator'])
|
|
214
382
|
|
|
215
383
|
if sum(1 for ar in mTEPES.ar if sum(1 for g in g2a[ar])) > 1:
|
|
216
384
|
if pIndPlotOutput == 1:
|
|
217
385
|
sPAREB = [(p,ar,eb) for p,ar,eb in mTEPES.par*mTEPES.eb if (p,eb) in mTEPES.peb and eb in g2a[ar]]
|
|
218
386
|
GenInvestToArea = pd.Series(data=[OutputToFile['MW'][p,eb] for p,ar,eb in sPAREB], index=pd.Index(sPAREB)).to_frame(name='MW')
|
|
219
|
-
GenInvestToArea.index.names = ['Period', 'Area', '
|
|
220
|
-
chart = alt.Chart(GenInvestToArea.reset_index()).mark_bar().encode(x='
|
|
387
|
+
GenInvestToArea.index.names = ['Period', 'Area', 'Generator']
|
|
388
|
+
chart = alt.Chart(GenInvestToArea.reset_index()).mark_bar().encode(x='Generator:O', y='sum(MW):Q', color='Area:N', column='Period:N').properties(width=600, height=400)
|
|
221
389
|
chart.save(f'{_path}/oT_Plot_GenerationInvestmentPerArea_{CaseName}.html', embed_options={'renderer':'svg'})
|
|
222
|
-
TechInvestToArea = pd.Series(data=[sum(OutputToFile['MW'][p,eb] for eb in mTEPES.eb if (p,eb) in mTEPES.peb and eb in
|
|
223
|
-
TechInvestToArea.index.names = ['Period', 'Area', 'Technology'
|
|
390
|
+
TechInvestToArea = pd.Series(data=[sum(OutputToFile['MW'][p,eb] for eb in mTEPES.eb if (p,eb) in mTEPES.peb and eb in g2t[gt] and eb in g2a[ar]) for p,ar,gt in mTEPES.par*mTEPES.gt], index=mTEPES.par*mTEPES.gt).to_frame(name='MW')
|
|
391
|
+
TechInvestToArea.index.names = ['Period', 'Area', 'Technology']
|
|
224
392
|
chart = alt.Chart(TechInvestToArea.reset_index()).mark_bar().encode(x='Technology:O', y='sum(MW):Q', color='Area:N', column='Period:N').properties(width=600, height=400)
|
|
225
393
|
chart.save(f'{_path}/oT_Plot_TechnologyInvestmentPerArea_{CaseName}.html', embed_options={'renderer':'svg'})
|
|
226
394
|
|
|
@@ -230,11 +398,14 @@ def InvestmentResults(DirName, CaseName, OptModel, mTEPES, pIndTechnologyOutput,
|
|
|
230
398
|
OutputResults1 = OutputResults1.to_frame(name='Technology')
|
|
231
399
|
OutputResults2 = OutputToFile
|
|
232
400
|
OutputResults = pd.concat([OutputResults1, OutputResults2], axis=1)
|
|
233
|
-
OutputResults.index.names = ['Period', '
|
|
401
|
+
OutputResults.index.names = ['Period', 'Generator']
|
|
234
402
|
OutputResults = OutputResults.reset_index().groupby(['Period', 'Technology']).sum(numeric_only=True)
|
|
235
403
|
OutputResults['MW'] = round(OutputResults['MW'], 2)
|
|
236
404
|
OutputResults.reset_index().pivot_table(index=['Period'], columns=['Technology'], values='MW').rename_axis(['Period'], axis=0).to_csv(f'{_path}/oT_Result_TechnologyInvestment_{CaseName}.csv', index=True, sep=',')
|
|
237
405
|
|
|
406
|
+
MarketResultsInv = pd.DataFrame()
|
|
407
|
+
MarketResultsInv = pd.concat([MarketResultsInv, OutputResults], axis=1)
|
|
408
|
+
|
|
238
409
|
if pIndPlotOutput == 1:
|
|
239
410
|
chart = alt.Chart(OutputResults.reset_index()).mark_bar().encode(x='Technology:O', y='sum(MW):Q', color='Technology:N', column='Period:N').properties(width=600, height=400)
|
|
240
411
|
chart.save(f'{_path}/oT_Plot_TechnologyInvestment_{CaseName}.html', embed_options={'renderer':'svg'})
|
|
@@ -242,18 +413,30 @@ def InvestmentResults(DirName, CaseName, OptModel, mTEPES, pIndTechnologyOutput,
|
|
|
242
413
|
# Saving and plotting generation investment cost
|
|
243
414
|
OutputResults0 = OutputResults
|
|
244
415
|
OutputToFile = pd.Series(data=[mTEPES.pDiscountedWeight[p] * mTEPES.pGenInvestCost[eb] * OptModel.vGenerationInvest[p,eb]() for p,eb in mTEPES.peb], index=mTEPES.peb)
|
|
245
|
-
OutputToFile = OutputToFile.fillna(0).to_frame(name='MEUR').reset_index().rename(columns={'level_0': 'Period', 'level_1': '
|
|
416
|
+
OutputToFile = OutputToFile.fillna(0).to_frame(name='MEUR').reset_index().rename(columns={'level_0': 'Period', 'level_1': 'Generator'}).set_index(['Period', 'Generator'])
|
|
246
417
|
|
|
247
418
|
OutputResults1 = pd.Series(data=[gt for p,eb,gt in mTEPES.peb*mTEPES.gt if eb in g2t[gt]], index=mTEPES.peb)
|
|
248
419
|
OutputResults1 = OutputResults1.to_frame(name='Technology')
|
|
249
420
|
OutputResults2 = OutputToFile
|
|
250
421
|
OutputResults = pd.concat([OutputResults1, OutputResults2], axis=1)
|
|
251
|
-
OutputResults.index.names = ['Period', '
|
|
422
|
+
OutputResults.index.names = ['Period', 'Generator']
|
|
252
423
|
OutputResults = OutputResults.reset_index().groupby(['Period', 'Technology']).sum(numeric_only=True)
|
|
253
424
|
OutputResults['MEUR'] = round(OutputResults['MEUR'], 2)
|
|
254
425
|
|
|
255
426
|
OutputResults.reset_index().pivot_table(index=['Period'], columns=['Technology'], values='MEUR').rename_axis(['Period'], axis=0).to_csv(f'{_path}/oT_Result_TechnologyInvestmentCost_{CaseName}.csv', index=True, sep=',')
|
|
256
427
|
|
|
428
|
+
MarketResultsInv = pd.concat([MarketResultsInv, OutputResults], axis=1)
|
|
429
|
+
|
|
430
|
+
GenTechInvestCost = pd.Series(data=[sum(mTEPES.pDiscountedWeight[p] * mTEPES.pGenInvestCost[eb] * OptModel.vGenerationInvest[p,eb]() for eb in mTEPES.eb if eb in g2t[gt] and (p,eb) in mTEPES.peb ) for p,gt in mTEPES.p*mTEPES.gt], index=mTEPES.p*mTEPES.gt)
|
|
431
|
+
GenTechInvestCost *= 1e3
|
|
432
|
+
GenTechInjection = pd.Series(data=[sum(mTEPES.pDiscountedWeight[p] * mTEPES.pLoadLevelDuration[p,sc,n]() * OptModel.vTotalOutput[p,sc,n,eb]() for sc,n,eb in mTEPES.sc*mTEPES.n*mTEPES.eb if eb in g2t[gt] and (p,eb) in mTEPES.peb and (p,sc,n) in mTEPES.psn) for p,gt in mTEPES.p*mTEPES.gt], index=mTEPES.p*mTEPES.gt)
|
|
433
|
+
GenTechInjection.name = 'Generation'
|
|
434
|
+
MarketResultsInv = pd.concat([MarketResultsInv, GenTechInjection], axis=1)
|
|
435
|
+
LCOE = GenTechInvestCost.div(GenTechInjection)
|
|
436
|
+
LCOE.name = 'LCOE'
|
|
437
|
+
MarketResultsInv = pd.concat([MarketResultsInv, LCOE], axis=1)
|
|
438
|
+
MarketResultsInv.stack().reset_index().pivot_table(index=['level_0','level_1'], columns='level_2', values=0, aggfunc='sum').rename_axis(['Period', 'Technology'], axis=0).rename(columns={'MW': 'Power [MW]', 'MEUR': 'Cost [MEUR]', 'Generation': 'Generation [GWh]', 'LCOE': 'LCOE [EUR/MWh]'}, inplace=False).to_csv(f'{_path}/oT_Result_MarketResultsTechnologyInvestment_{CaseName}.csv', sep=',')
|
|
439
|
+
|
|
257
440
|
if pIndPlotOutput == 1:
|
|
258
441
|
chart = alt.Chart(OutputResults.reset_index()).mark_bar().encode(x='Technology:O', y='sum(MEUR):Q', color='Technology:N', column='Period:N').properties(width=600, height=400)
|
|
259
442
|
chart.save(f'{_path}/oT_Plot_TechnologyInvestmentCost_{CaseName}.html', embed_options={'renderer':'svg'})
|
|
@@ -276,23 +459,23 @@ def InvestmentResults(DirName, CaseName, OptModel, mTEPES, pIndTechnologyOutput,
|
|
|
276
459
|
|
|
277
460
|
if pIndTechnologyOutput == 0 or pIndTechnologyOutput == 2:
|
|
278
461
|
# Saving generation retirement
|
|
279
|
-
OutputToFile = pd.Series(data=[OptModel.vGenerationRetire[p,gd]()
|
|
280
|
-
OutputToFile = OutputToFile.fillna(0).to_frame(name='RetirementDecision').reset_index().rename(columns={'level_0': 'Period', 'level_1': '
|
|
281
|
-
OutputToFile.pivot_table(index=['Period'], columns=['
|
|
462
|
+
OutputToFile = pd.Series(data=[OptModel.vGenerationRetire[p,gd]() for p,gd in mTEPES.pgd], index=mTEPES.pgd)
|
|
463
|
+
OutputToFile = OutputToFile.fillna(0).to_frame(name='RetirementDecision').reset_index().rename(columns={'level_0': 'Period', 'level_1': 'Generator'})
|
|
464
|
+
OutputToFile.pivot_table(index=['Period'], columns=['Generator'], values='RetirementDecision').rename_axis(['Period'], axis=0).to_csv(f'{_path}/oT_Result_GenerationRetirementPerUnit_{CaseName}.csv', index=True, sep=',')
|
|
282
465
|
OutputToFile = pd.Series(data=[OptModel.vGenerationRetire[p,gd]()*max(mTEPES.pRatedMaxPowerElec[gd],mTEPES.pRatedMaxCharge[gd]) for p,gd in mTEPES.pgd], index=mTEPES.pgd)
|
|
283
466
|
OutputToFile *= 1e3
|
|
284
|
-
OutputToFile = OutputToFile.fillna(0).to_frame(name='MW' ).reset_index().rename(columns={'level_0': 'Period', 'level_1': '
|
|
285
|
-
OutputToFile.pivot_table(index=['Period'], columns=['
|
|
286
|
-
OutputToFile = OutputToFile.set_index(['Period', '
|
|
467
|
+
OutputToFile = OutputToFile.fillna(0).to_frame(name='MW' ).reset_index().rename(columns={'level_0': 'Period', 'level_1': 'Generator'})
|
|
468
|
+
OutputToFile.pivot_table(index=['Period'], columns=['Generator'], values='MW').rename_axis(['Period'], axis=0).to_csv(f'{_path}/oT_Result_GenerationRetirement_{CaseName}.csv', index=True, sep=',')
|
|
469
|
+
OutputToFile = OutputToFile.set_index(['Period', 'Generator'])
|
|
287
470
|
|
|
288
471
|
if sum(1 for ar in mTEPES.ar if sum(1 for g in g2a[ar])) > 1:
|
|
289
472
|
if pIndPlotOutput == 1:
|
|
290
473
|
sPARGD = [(p,ar,gd) for p,ar,gd in mTEPES.par*mTEPES.gd if (p,gd) in mTEPES.pgd and gd in g2a[ar]]
|
|
291
474
|
GenRetireToArea = pd.Series(data=[OutputToFile['MW'][p,gd] for p,ar,gd in sPARGD], index=pd.Index(sPARGD)).to_frame(name='MW')
|
|
292
|
-
GenRetireToArea.index.names = ['Period', 'Area', '
|
|
293
|
-
chart = alt.Chart(GenRetireToArea.reset_index()).mark_bar().encode(x='
|
|
475
|
+
GenRetireToArea.index.names = ['Period', 'Area', 'Generator']
|
|
476
|
+
chart = alt.Chart(GenRetireToArea.reset_index()).mark_bar().encode(x='Generator:O', y='sum(MW):Q', color='Area:N', column='Period:N').properties(width=600, height=400)
|
|
294
477
|
chart.save(f'{_path}/oT_Plot_GenerationRetirementPerArea_{CaseName}.html', embed_options={'renderer':'svg'})
|
|
295
|
-
TechRetireToArea = pd.Series(data=[sum(OutputToFile['MW'][p,gd] for gd in mTEPES.gd if gd in
|
|
478
|
+
TechRetireToArea = pd.Series(data=[sum(OutputToFile['MW'][p,gd] for gd in mTEPES.gd if (p,gd) in mTEPES.pgd and gd in g2t[gt] and gd in g2a[ar]) for p,ar,gt in mTEPES.par*mTEPES.gt], index=mTEPES.par*mTEPES.gt).to_frame(name='MW')
|
|
296
479
|
TechRetireToArea.index.names = ['Period', 'Area', 'Technology' ]
|
|
297
480
|
chart = alt.Chart(TechRetireToArea.reset_index()).mark_bar().encode(x='Technology:O', y='sum(MW):Q', color='Area:N', column='Period:N').properties(width=600, height=400)
|
|
298
481
|
chart.save(f'{_path}/oT_Plot_TechnologyRetirementPerArea_{CaseName}.html', embed_options={'renderer':'svg'})
|
|
@@ -303,7 +486,7 @@ def InvestmentResults(DirName, CaseName, OptModel, mTEPES, pIndTechnologyOutput,
|
|
|
303
486
|
OutputResults1 = OutputResults1.to_frame(name='Technology')
|
|
304
487
|
OutputResults2 = OutputToFile
|
|
305
488
|
OutputResults = pd.concat([OutputResults1, OutputResults2], axis=1)
|
|
306
|
-
OutputResults.index.names = ['Period', '
|
|
489
|
+
OutputResults.index.names = ['Period', 'Generator']
|
|
307
490
|
OutputResults = OutputResults.reset_index().groupby(['Period', 'Technology']).sum(numeric_only=True)
|
|
308
491
|
OutputResults['MW'] = round(OutputResults['MW'], 2)
|
|
309
492
|
OutputResults.reset_index().pivot_table(index=['Period'], columns=['Technology'], values='MW').rename_axis([None], axis=0).to_csv(f'{_path}/oT_Result_TechnologyRetirement_{CaseName}.csv', sep=',', index=False)
|
|
@@ -356,6 +539,7 @@ def InvestmentResults(DirName, CaseName, OptModel, mTEPES, pIndTechnologyOutput,
|
|
|
356
539
|
print('Writing investment results ... ', round(WritingResultsTime), 's')
|
|
357
540
|
|
|
358
541
|
|
|
542
|
+
# @profile
|
|
359
543
|
def GenerationOperationResults(DirName, CaseName, OptModel, mTEPES, pIndTechnologyOutput, pIndAreaOutput, pIndPlotOutput):
|
|
360
544
|
#%% outputting the generation operation
|
|
361
545
|
_path = os.path.join(DirName, CaseName)
|
|
@@ -405,7 +589,7 @@ def GenerationOperationResults(DirName, CaseName, OptModel, mTEPES, pIndTechnolo
|
|
|
405
589
|
OutputToFile = OutputToFile.fillna(0.0)
|
|
406
590
|
OutputToFile *= 1e3
|
|
407
591
|
if pIndTechnologyOutput == 0 or pIndTechnologyOutput == 2:
|
|
408
|
-
OutputToFile.to_frame(name='MW').reset_index().pivot_table(index=['level_0','level_1','level_2'], columns='level_3', values='MW').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/
|
|
592
|
+
OutputToFile.to_frame(name='MW').reset_index().pivot_table(index=['level_0','level_1','level_2'], columns='level_3', values='MW').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_GenerationOperatingReserveUp_{CaseName}.csv', sep=',')
|
|
409
593
|
|
|
410
594
|
if pIndTechnologyOutput == 1 or pIndTechnologyOutput == 2:
|
|
411
595
|
OutputToFile = pd.Series(data=[sum(OutputToFile[p,sc,n,nr] for nr in n2n[nt] if (p,nr) in mTEPES.pnr) for p,sc,n,nt in mTEPES.psnnt], index=mTEPES.psnnt)
|
|
@@ -428,7 +612,7 @@ def GenerationOperationResults(DirName, CaseName, OptModel, mTEPES, pIndTechnolo
|
|
|
428
612
|
OutputToFile = OutputToFile.fillna(0.0)
|
|
429
613
|
OutputToFile *= 1e3
|
|
430
614
|
if pIndTechnologyOutput == 0 or pIndTechnologyOutput == 2:
|
|
431
|
-
OutputToFile.to_frame(name='MW').reset_index().pivot_table(index=['level_0','level_1','level_2'], columns='level_3', values='MW').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/
|
|
615
|
+
OutputToFile.to_frame(name='MW').reset_index().pivot_table(index=['level_0','level_1','level_2'], columns='level_3', values='MW').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_GenerationOperatingReserveDown_{CaseName}.csv', sep=',')
|
|
432
616
|
|
|
433
617
|
if pIndTechnologyOutput == 1 or pIndTechnologyOutput == 2:
|
|
434
618
|
OutputToFile = pd.Series(data=[sum(OutputToFile[p,sc,n,nr] for nr in n2n[nt] if (p,nr) in mTEPES.pnr) for p,sc,n,nt in mTEPES.psnnt], index=mTEPES.psnnt)
|
|
@@ -445,6 +629,26 @@ def GenerationOperationResults(DirName, CaseName, OptModel, mTEPES, pIndTechnolo
|
|
|
445
629
|
OutputToFile = pd.Series(data=[sum(OutputToFile[p,sc,n,eh] for eh in e2e[et] if (p,eh) in mTEPES.peh and mTEPES.pRatedMaxCharge[eh]) for p,sc,n,et in mTEPES.psnet], index=mTEPES.psnet)
|
|
446
630
|
OutputToFile.to_frame(name='MW').reset_index().pivot_table(index=['level_0','level_1','level_2'], columns='level_3', values='MW').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_TechnologyOperatingReserveDownESS_{CaseName}.csv', sep=',')
|
|
447
631
|
|
|
632
|
+
if mTEPES.pIndRampReserves == 1 and sum(mTEPES.pRampReserveUp[:,:,:,:]) and mTEPES.nr:
|
|
633
|
+
OutputToFile = pd.Series(data=[OptModel.vRampReserveUp[p,sc,n,nr]() for p,sc,n,nr in mTEPES.psnnr], index=mTEPES.psnnr)
|
|
634
|
+
OutputToFile = OutputToFile.fillna(0.0)
|
|
635
|
+
OutputToFile *= 1e3
|
|
636
|
+
if pIndTechnologyOutput == 0 or pIndTechnologyOutput == 2:
|
|
637
|
+
OutputToFile.to_frame(name='MW').reset_index().pivot_table(index=['level_0','level_1','level_2'], columns='level_3', values='MW').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_GenerationRampReserveUp_{CaseName}.csv', sep=',')
|
|
638
|
+
if pIndTechnologyOutput == 1 or pIndTechnologyOutput == 2:
|
|
639
|
+
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)
|
|
640
|
+
OutputToFile.to_frame(name='MW').reset_index().pivot_table(index=['level_0','level_1','level_2'], columns='level_3', values='MW').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_TechnologyRampReserveUp_{CaseName}.csv', sep=',')
|
|
641
|
+
|
|
642
|
+
if mTEPES.pIndRampReserves == 1 and sum(mTEPES.pRampReserveDw[:,:,:,:]) and mTEPES.nr:
|
|
643
|
+
OutputToFile = pd.Series(data=[OptModel.vRampReserveDw[p,sc,n,nr]() for p,sc,n,nr in mTEPES.psnnr], index=mTEPES.psnnr)
|
|
644
|
+
OutputToFile = OutputToFile.fillna(0.0)
|
|
645
|
+
OutputToFile *= 1e3
|
|
646
|
+
if pIndTechnologyOutput == 0 or pIndTechnologyOutput == 2:
|
|
647
|
+
OutputToFile.to_frame(name='MW').reset_index().pivot_table(index=['level_0','level_1','level_2'], columns='level_3', values='MW').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_GenerationRampReserveDown_{CaseName}.csv', sep=',')
|
|
648
|
+
if pIndTechnologyOutput == 1 or pIndTechnologyOutput == 2:
|
|
649
|
+
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)
|
|
650
|
+
OutputToFile.to_frame(name='MW').reset_index().pivot_table(index=['level_0','level_1','level_2'], columns='level_3', values='MW').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_TechnologyRampReserveDown_{CaseName}.csv', sep=',')
|
|
651
|
+
|
|
448
652
|
OutputToFile = pd.Series(data=[OptModel.vTotalOutput[p,sc,n,g]() for p,sc,n,g in mTEPES.psng], index=mTEPES.psng)
|
|
449
653
|
OutputToFile *= 1e3
|
|
450
654
|
OutputToFile.to_frame(name='MW').reset_index().pivot_table(index=['level_0','level_1','level_2'], columns='level_3', values='MW').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_Generation_{CaseName}.csv', sep=',')
|
|
@@ -484,8 +688,8 @@ def GenerationOperationResults(DirName, CaseName, OptModel, mTEPES, pIndTechnolo
|
|
|
484
688
|
(OptModel.vTotalOutput[p,sc,n,re].ub - OptModel.vTotalOutput[p,sc,n,re]())*mTEPES.pLoadLevelDuration[p,sc,n]() for p,sc,n,re in mTEPES.psnre], index=mTEPES.psnre)
|
|
485
689
|
OutputToFile2 = pd.Series(data=[(OptModel.vTotalOutput[p,sc,n,re].ub*OptModel.vGenerationInvest[p,re]() )*mTEPES.pLoadLevelDuration[p,sc,n]() if re in mTEPES.gc else
|
|
486
690
|
(OptModel.vTotalOutput[p,sc,n,re].ub )*mTEPES.pLoadLevelDuration[p,sc,n]() for p,sc,n,re in mTEPES.psnre], index=mTEPES.psnre)
|
|
487
|
-
OutputToFile1 = OutputToFile1.to_frame(name='GWh').reset_index().pivot_table(index=['level_0','level_1','level_3'], values='GWh', aggfunc='sum').rename_axis(['Period', 'Scenario', '
|
|
488
|
-
OutputToFile2 = OutputToFile2.to_frame(name='GWh').reset_index().pivot_table(index=['level_0','level_1','level_3'], values='GWh', aggfunc='sum').rename_axis(['Period', 'Scenario', '
|
|
691
|
+
OutputToFile1 = OutputToFile1.to_frame(name='GWh').reset_index().pivot_table(index=['level_0','level_1','level_3'], values='GWh', aggfunc='sum').rename_axis(['Period', 'Scenario', 'Generator'], axis=0).rename_axis([None], axis=1)
|
|
692
|
+
OutputToFile2 = OutputToFile2.to_frame(name='GWh').reset_index().pivot_table(index=['level_0','level_1','level_3'], values='GWh', aggfunc='sum').rename_axis(['Period', 'Scenario', 'Generator'], axis=0).rename_axis([None], axis=1)
|
|
489
693
|
if pIndTechnologyOutput == 0 or pIndTechnologyOutput == 2:
|
|
490
694
|
OutputToFile = OutputToFile1.div(OutputToFile2)*1e2
|
|
491
695
|
OutputToFile = OutputToFile.fillna(0.0)
|
|
@@ -534,10 +738,10 @@ def GenerationOperationResults(DirName, CaseName, OptModel, mTEPES, pIndTechnolo
|
|
|
534
738
|
if pIndAreaOutput == 1:
|
|
535
739
|
for ar in mTEPES.ar:
|
|
536
740
|
if sum(1 for g in g2a[ar]):
|
|
537
|
-
sPSNGT = [(p,sc,n,gt) for p,sc,n,gt in mTEPES.psngt if sum(1 for g in g2a[ar]
|
|
741
|
+
sPSNGT = [(p,sc,n,gt) for p,sc,n,gt in mTEPES.psngt if sum(1 for g in g2t[gt] if g in g2a[ar] and (p,g) in mTEPES.pg)]
|
|
538
742
|
if sPSNGT:
|
|
539
743
|
if sum(OutputToFile[:,:,:,:]):
|
|
540
|
-
OutputResults = pd.Series(data=[sum(OutputToFile[p,sc,n,g] for g in g2a[ar]
|
|
744
|
+
OutputResults = pd.Series(data=[sum(OutputToFile[p,sc,n,g] for g in g2t[gt] if g in g2a[ar] and (p,g) in mTEPES.pg) for p,sc,n,gt in sPSNGT], index=pd.Index(sPSNGT))
|
|
541
745
|
OutputResults.to_frame(name='MtCO2').reset_index().pivot_table(index=['level_0','level_1','level_2'], columns='level_3', values='MtCO2', aggfunc='sum').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_TechnologyEmission_{CaseName}_{ar}.csv', sep=',')
|
|
542
746
|
|
|
543
747
|
if sum(OutputToFile[:,:,:,:]):
|
|
@@ -573,9 +777,9 @@ def GenerationOperationResults(DirName, CaseName, OptModel, mTEPES, pIndTechnolo
|
|
|
573
777
|
if pIndAreaOutput == 1:
|
|
574
778
|
for ar in mTEPES.ar:
|
|
575
779
|
if sum(1 for g in g2a[ar]):
|
|
576
|
-
sPSNGT = [(p,sc,n,gt) for p,sc,n,gt in mTEPES.psngt if sum(1 for g in g2a[ar]
|
|
780
|
+
sPSNGT = [(p,sc,n,gt) for p,sc,n,gt in mTEPES.psngt if sum(1 for g in g2t[gt] if g in g2a[ar] and (p,g) in mTEPES.pg)]
|
|
577
781
|
if sPSNGT:
|
|
578
|
-
OutputToFile = pd.Series(data=[sum(OptModel.vTotalOutput[p,sc,n,g]()*mTEPES.pLoadLevelDuration[p,sc,n]() for g in g2a[ar]
|
|
782
|
+
OutputToFile = pd.Series(data=[sum(OptModel.vTotalOutput[p,sc,n,g]()*mTEPES.pLoadLevelDuration[p,sc,n]() for g in g2t[gt] if g in g2a[ar] and (p,g) in mTEPES.pg) for p,sc,n,gt in sPSNGT], index=pd.Index(sPSNGT))
|
|
579
783
|
OutputToFile.to_frame(name='GWh').reset_index().pivot_table(index=['level_0','level_1','level_2'], columns='level_3', values='GWh', aggfunc='sum').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_TechnologyGenerationEnergy_{CaseName}_{ar}.csv', sep=',')
|
|
580
784
|
|
|
581
785
|
if pIndPlotOutput == 1:
|
|
@@ -588,6 +792,7 @@ def GenerationOperationResults(DirName, CaseName, OptModel, mTEPES, pIndTechnolo
|
|
|
588
792
|
print('Writing generation operation results ... ', round(WritingResultsTime), 's')
|
|
589
793
|
|
|
590
794
|
|
|
795
|
+
# @profile
|
|
591
796
|
def GenerationOperationHeatResults(DirName, CaseName, OptModel, mTEPES, pIndTechnologyOutput, pIndAreaOutput, pIndPlotOutput):
|
|
592
797
|
#%% outputting the generation operation
|
|
593
798
|
_path = os.path.join(DirName, CaseName)
|
|
@@ -650,10 +855,10 @@ def GenerationOperationHeatResults(DirName, CaseName, OptModel, mTEPES, pIndTech
|
|
|
650
855
|
if sum(1 for ar in mTEPES.ar if sum(1 for chp in g2a[ar])) > 1:
|
|
651
856
|
if pIndAreaOutput == 1:
|
|
652
857
|
for ar in mTEPES.ar:
|
|
653
|
-
if sum(1 for chp in
|
|
654
|
-
sPSNGT = [(p,sc,n,gt) for p,sc,n,gt in mTEPES.psngt if sum(1 for chp in g2a[ar]
|
|
858
|
+
if sum(1 for chp in g2t[gt] if chp in g2a[ar]):
|
|
859
|
+
sPSNGT = [(p,sc,n,gt) for p,sc,n,gt in mTEPES.psngt if sum(1 for chp in g2t[gt] if chp in g2a[ar] and (p,chp) in mTEPES.pchp)]
|
|
655
860
|
if sPSNGT:
|
|
656
|
-
OutputToFile = pd.Series(data=[sum(OptModel.vTotalOutputHeat[p,sc,n,chp]()*mTEPES.pLoadLevelDuration[p,sc,n]() for chp in g2a[ar] if (p,chp) in mTEPES.pchp
|
|
861
|
+
OutputToFile = pd.Series(data=[sum(OptModel.vTotalOutputHeat[p,sc,n,chp]()*mTEPES.pLoadLevelDuration[p,sc,n]() for chp in g2a[ar] if chp in g2t[gt] and (p,chp) in mTEPES.pchp) for p,sc,n,gt in sPSNGT], index=pd.Index(sPSNGT))
|
|
657
862
|
OutputToFile.to_frame(name='GWh').reset_index().pivot_table(index=['level_0','level_1','level_2'], columns='level_3', values='GWh', aggfunc='sum').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_TechnologyGenerationEnergyHeat_{CaseName}_{ar}.csv', sep=',')
|
|
658
863
|
|
|
659
864
|
if pIndPlotOutput == 1:
|
|
@@ -666,6 +871,7 @@ def GenerationOperationHeatResults(DirName, CaseName, OptModel, mTEPES, pIndTech
|
|
|
666
871
|
print('Writing heat operation results ... ', round(WritingResultsTime), 's')
|
|
667
872
|
|
|
668
873
|
|
|
874
|
+
# @profile
|
|
669
875
|
def ESSOperationResults(DirName, CaseName, OptModel, mTEPES, pIndTechnologyOutput, pIndAreaOutput, pIndPlotOutput):
|
|
670
876
|
# %% outputting the ESS operation
|
|
671
877
|
_path = os.path.join(DirName, CaseName)
|
|
@@ -786,8 +992,8 @@ def ESSOperationResults(DirName, CaseName, OptModel, mTEPES, pIndTechnologyOutpu
|
|
|
786
992
|
(OptModel.vTotalOutput[p,sc,n,es].ub - OptModel.vTotalOutput[p,sc,n,es]())*mTEPES.pLoadLevelDuration[p,sc,n]() for p,sc,n,es in mTEPES.psnes], index=mTEPES.psnes)
|
|
787
993
|
OutputToFile2 = pd.Series(data=[(OptModel.vTotalOutput[p,sc,n,es].ub*OptModel.vGenerationInvest[p,es]() )*mTEPES.pLoadLevelDuration[p,sc,n]() if es in mTEPES.ec else
|
|
788
994
|
(OptModel.vTotalOutput[p,sc,n,es].ub )*mTEPES.pLoadLevelDuration[p,sc,n]() for p,sc,n,es in mTEPES.psnes], index=mTEPES.psnes)
|
|
789
|
-
OutputToFile1 = OutputToFile1.to_frame(name='GWh').reset_index().pivot_table(index=['level_0','level_1','level_3'], values='GWh', aggfunc='sum').rename_axis(['Period', 'Scenario', '
|
|
790
|
-
OutputToFile2 = OutputToFile2.to_frame(name='GWh').reset_index().pivot_table(index=['level_0','level_1','level_3'], values='GWh', aggfunc='sum').rename_axis(['Period', 'Scenario', '
|
|
995
|
+
OutputToFile1 = OutputToFile1.to_frame(name='GWh').reset_index().pivot_table(index=['level_0','level_1','level_3'], values='GWh', aggfunc='sum').rename_axis(['Period', 'Scenario', 'Generator'], axis=0).rename_axis([None], axis=1)
|
|
996
|
+
OutputToFile2 = OutputToFile2.to_frame(name='GWh').reset_index().pivot_table(index=['level_0','level_1','level_3'], values='GWh', aggfunc='sum').rename_axis(['Period', 'Scenario', 'Generator'], axis=0).rename_axis([None], axis=1)
|
|
791
997
|
|
|
792
998
|
if pIndTechnologyOutput == 0 or pIndTechnologyOutput == 2:
|
|
793
999
|
OutputToFile = OutputToFile1.div(OutputToFile2)*1e2
|
|
@@ -807,6 +1013,7 @@ def ESSOperationResults(DirName, CaseName, OptModel, mTEPES, pIndTechnologyOutpu
|
|
|
807
1013
|
print('Writing ESS operation results ... ', round(WritingResultsTime), 's')
|
|
808
1014
|
|
|
809
1015
|
|
|
1016
|
+
# @profile
|
|
810
1017
|
def ReservoirOperationResults(DirName, CaseName, OptModel, mTEPES, pIndTechnologyOutput, pIndPlotOutput):
|
|
811
1018
|
# %% outputting the reservoir operation
|
|
812
1019
|
_path = os.path.join(DirName, CaseName)
|
|
@@ -814,9 +1021,9 @@ def ReservoirOperationResults(DirName, CaseName, OptModel, mTEPES, pIndTechnolog
|
|
|
814
1021
|
|
|
815
1022
|
# technology to hydro units (o2h)
|
|
816
1023
|
o2h = defaultdict(list)
|
|
817
|
-
for ht,h
|
|
818
|
-
if (ht,h
|
|
819
|
-
o2h[ht].append(h
|
|
1024
|
+
for ht,h in mTEPES.ht*mTEPES.h:
|
|
1025
|
+
if (ht,h) in mTEPES.t2g:
|
|
1026
|
+
o2h[ht].append(h)
|
|
820
1027
|
|
|
821
1028
|
# tolerance to avoid division by 0
|
|
822
1029
|
pEpsilon = 1e-6
|
|
@@ -848,7 +1055,7 @@ def ReservoirOperationResults(DirName, CaseName, OptModel, mTEPES, pIndTechnolog
|
|
|
848
1055
|
if len(OutputToFile) and pIndPlotOutput == 1:
|
|
849
1056
|
WaterValue = OutputToFile.to_frame(name='WaterValue').reset_index().pivot_table(index=['level_0','level_1','level_3','level_4'], values='WaterValue').rename_axis(['level_0','level_1','level_2','level_3'], axis=0).loc[:,:,:,:]
|
|
850
1057
|
for p,sc in mTEPES.ps:
|
|
851
|
-
chart = LinePlots(p, sc, WaterValue, '
|
|
1058
|
+
chart = LinePlots(p, sc, WaterValue, 'Generator', 'LoadLevel', 'EUR/dam3', 'average')
|
|
852
1059
|
chart.save(f'{_path}/oT_Plot_MarginalWaterValue_{CaseName}_{p}_{sc}.html', embed_options={'renderer': 'svg'})
|
|
853
1060
|
|
|
854
1061
|
WritingResultsTime = time.time() - StartTime
|
|
@@ -856,6 +1063,7 @@ def ReservoirOperationResults(DirName, CaseName, OptModel, mTEPES, pIndTechnolog
|
|
|
856
1063
|
print('Writing reservoir operation results ... ', round(WritingResultsTime), 's')
|
|
857
1064
|
|
|
858
1065
|
|
|
1066
|
+
# @profile
|
|
859
1067
|
def NetworkH2OperationResults(DirName, CaseName, OptModel, mTEPES):
|
|
860
1068
|
# %% outputting the hydrogen pipeline network operation
|
|
861
1069
|
_path = os.path.join(DirName, CaseName)
|
|
@@ -881,8 +1089,14 @@ def NetworkH2OperationResults(DirName, CaseName, OptModel, mTEPES):
|
|
|
881
1089
|
if (gt,el) in mTEPES.t2g:
|
|
882
1090
|
e2t[gt].append(el)
|
|
883
1091
|
|
|
884
|
-
|
|
885
|
-
|
|
1092
|
+
# nodes to area (d2a)
|
|
1093
|
+
d2a = defaultdict(list)
|
|
1094
|
+
for ar,nd in mTEPES.ar*mTEPES.nd:
|
|
1095
|
+
if (nd,ar) in mTEPES.ndar:
|
|
1096
|
+
d2a[ar].append(nd)
|
|
1097
|
+
|
|
1098
|
+
sPSNARND = [(p,sc,n,ar,nd) for p,sc,n,ar,nd in mTEPES.psn*mTEPES.ar*mTEPES.nd if nd in d2a[ar] and sum(1 for el in e2n[nd]) + sum(1 for nf,cc in lout[nd]) + sum(1 for ni,cc in lin[nd])]
|
|
1099
|
+
sPSNARNDGT = [(p,sc,n,ar,nd,gt) for p,sc,n,ar,nd,gt in sPSNARND*mTEPES.gt if nd in d2a[ar] and sum(1 for el in e2t[gt] if (p,el) in mTEPES.pg) ]
|
|
886
1100
|
|
|
887
1101
|
OutputResults2 = pd.Series(data=[ sum(OptModel.vESSTotalCharge[p,sc,n,el ]()*mTEPES.pLoadLevelDuration[p,sc,n]()/mTEPES.pProductionFunctionH2[el] for el in mTEPES.el if el in e2n[nd] and el in e2t[gt]) for p,sc,n,ar,nd,gt in sPSNARNDGT], index=pd.Index(sPSNARNDGT)).to_frame(name='Generation' ).reset_index().pivot_table(index=['level_0','level_1','level_2','level_3','level_4'], columns='level_5', values='Generation', aggfunc='sum')
|
|
888
1102
|
OutputResults3 = pd.Series(data=[ OptModel.vH2NS [p,sc,n,nd ]() for p,sc,n,ar,nd in sPSNARND ], index=pd.Index(sPSNARND )).to_frame(name='HydrogenNotServed')
|
|
@@ -1044,6 +1258,7 @@ def NetworkH2OperationResults(DirName, CaseName, OptModel, mTEPES):
|
|
|
1044
1258
|
print('Writing hydrogen operation results ... ', round(WritingResultsTime), 's')
|
|
1045
1259
|
|
|
1046
1260
|
|
|
1261
|
+
# @profile
|
|
1047
1262
|
def NetworkHeatOperationResults(DirName, CaseName, OptModel, mTEPES):
|
|
1048
1263
|
# %% outputting the heat pipe network operation
|
|
1049
1264
|
_path = os.path.join(DirName, CaseName)
|
|
@@ -1081,8 +1296,14 @@ def NetworkHeatOperationResults(DirName, CaseName, OptModel, mTEPES):
|
|
|
1081
1296
|
if (gt,hp) in mTEPES.t2g:
|
|
1082
1297
|
h2t[gt].append(hp)
|
|
1083
1298
|
|
|
1084
|
-
|
|
1085
|
-
|
|
1299
|
+
# nodes to area (d2a)
|
|
1300
|
+
d2a = defaultdict(list)
|
|
1301
|
+
for ar,nd in mTEPES.ar*mTEPES.nd:
|
|
1302
|
+
if (nd,ar) in mTEPES.ndar:
|
|
1303
|
+
d2a[ar].append(nd)
|
|
1304
|
+
|
|
1305
|
+
sPSNARND = [(p,sc,n,ar,nd) for p,sc,n,ar,nd in mTEPES.psn*mTEPES.ar*mTEPES.nd if nd in d2a[ar] and sum(1 for ch in c2n[nd]) + sum(1 for hp in h2n[nd]) + sum(1 for nf,cc in lout[nd]) + sum(1 for ni,cc in lin[nd])]
|
|
1306
|
+
sPSNARNDGT = [(p,sc,n,ar,nd,gt) for p,sc,n,ar,nd,gt in sPSNARND*mTEPES.gt if nd in d2a[ar] and sum(1 for ch in c2t[gt] if (p,ch) in mTEPES.pg) + sum(1 for hp in h2t[gt] if (p,hp) in mTEPES.pg) ]
|
|
1086
1307
|
|
|
1087
1308
|
OutputResults2 = pd.Series(data=[ sum(OptModel.vESSTotalCharge [p,sc,n,hp ]()*mTEPES.pLoadLevelDuration[p,sc,n]()/mTEPES.pProductionFunctionHeat[hp] for hp in mTEPES.hp if hp in h2n[nd] and hp in h2t[gt]) for p,sc,n,ar,nd,gt in sPSNARNDGT], index=pd.Index(sPSNARNDGT)).to_frame(name='GenerationHeatPumps').reset_index().pivot_table(index=['level_0','level_1','level_2','level_3','level_4'], columns='level_5', values='GenerationHeatPumps', aggfunc='sum')
|
|
1088
1309
|
OutputResults3 = pd.Series(data=[ sum(OptModel.vTotalOutput [p,sc,n,ch ]()*mTEPES.pLoadLevelDuration[p,sc,n]()/mTEPES.pPower2HeatRatio [ch] for ch in mTEPES.ch if ch in c2n[nd] and ch in c2t[gt] and ch not in mTEPES.bo) for p,sc,n,ar,nd,gt in sPSNARNDGT], index=pd.Index(sPSNARNDGT)).to_frame(name='GenerationCHPs' ).reset_index().pivot_table(index=['level_0','level_1','level_2','level_3','level_4'], columns='level_5', values='GenerationCHPs' , aggfunc='sum')
|
|
@@ -1272,6 +1493,7 @@ def NetworkHeatOperationResults(DirName, CaseName, OptModel, mTEPES):
|
|
|
1272
1493
|
print('Writing heat netwk operation results ... ', round(WritingResultsTime), 's')
|
|
1273
1494
|
|
|
1274
1495
|
|
|
1496
|
+
# @profile
|
|
1275
1497
|
def OperationSummaryResults(DirName, CaseName, OptModel, mTEPES):
|
|
1276
1498
|
#%% outputting the generation operation
|
|
1277
1499
|
_path = os.path.join(DirName, CaseName)
|
|
@@ -1365,71 +1587,69 @@ def OperationSummaryResults(DirName, CaseName, OptModel, mTEPES):
|
|
|
1365
1587
|
|
|
1366
1588
|
# LCOE per technology
|
|
1367
1589
|
if mTEPES.gc:
|
|
1368
|
-
GenTechInvestCost = pd.Series(data=[sum(mTEPES.pDiscountedWeight[p] * mTEPES.pGenInvestCost[gc]
|
|
1369
|
-
GenTechInjection = pd.Series(data=[sum(
|
|
1590
|
+
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)
|
|
1591
|
+
GenTechInjection = pd.Series(data=[sum(mTEPES.pDiscountedWeight[p] * mTEPES.pLoadLevelDuration[p,sc,n]() * OptModel.vTotalOutput[p,sc,n,gc]() for p,sc,n,gc in mTEPES.psngc if gc in g2t[gt]) for gt in mTEPES.gt], index=mTEPES.gt)
|
|
1370
1592
|
GenTechInvestCost *= 1e3
|
|
1371
|
-
LCOE = GenTechInvestCost.div(GenTechInjection).to_frame(name='EUR/MWh')
|
|
1372
|
-
LCOE.rename_axis(['Technology'], axis=0).to_csv(f'{_path}/oT_Result_TechnologyLCOE_{CaseName}.csv', index=True, sep=',')
|
|
1593
|
+
LCOE = GenTechInvestCost.div(GenTechInjection).to_frame(name='EUR/MWh').rename_axis(['Technology'], axis=0).to_csv(f'{_path}/oT_Result_TechnologyLCOE_{CaseName}.csv', index=True, sep=',')
|
|
1373
1594
|
|
|
1374
|
-
#
|
|
1595
|
+
# LCOH per technology
|
|
1375
1596
|
if mTEPES.gb:
|
|
1376
|
-
GenTechInvestCost = pd.Series(data=[sum(mTEPES.pDiscountedWeight[p] * mTEPES.pGenInvestCost[gb]
|
|
1377
|
-
GenTechInjection = pd.Series(data=[sum(
|
|
1597
|
+
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)
|
|
1598
|
+
GenTechInjection = pd.Series(data=[sum(mTEPES.pDiscountedWeight[p] * mTEPES.pLoadLevelDuration[p,sc,n]() * OptModel.vTotalOutputHeat[p,sc,n,gb]() for p,sc,n,gb in mTEPES.psngb if gb in g2t[gt]) for gt in mTEPES.gt], index=mTEPES.gt)
|
|
1378
1599
|
GenTechInvestCost *= 1e3
|
|
1379
|
-
LCOH = GenTechInvestCost.div(GenTechInjection).to_frame(name='EUR/MWh')
|
|
1380
|
-
LCOH.rename_axis(['Technology'], axis=0).to_csv(f'{_path}/oT_Result_TechnologyLCOH_{CaseName}.csv', index=True, sep=',')
|
|
1600
|
+
LCOH = GenTechInvestCost.div(GenTechInjection).to_frame(name='EUR/MWh').rename_axis(['Technology'], axis=0).to_csv(f'{_path}/oT_Result_TechnologyLCOH_{CaseName}.csv', index=True, sep=',')
|
|
1381
1601
|
|
|
1382
1602
|
WritingResultsTime = time.time() - StartTime
|
|
1383
1603
|
StartTime = time.time()
|
|
1384
1604
|
print('Writing KPI summary results ... ', round(WritingResultsTime), 's')
|
|
1385
|
-
|
|
1386
|
-
StartTime = time.time()
|
|
1387
|
-
t2g = pd.DataFrame(mTEPES.t2g).set_index(1)
|
|
1388
|
-
n2g = pd.DataFrame(mTEPES.n2g).set_index(1)
|
|
1389
|
-
z2g = pd.DataFrame(mTEPES.z2g).set_index(1)
|
|
1390
|
-
a2g = pd.DataFrame(mTEPES.a2g).set_index(1)
|
|
1391
|
-
r2g = pd.DataFrame(mTEPES.r2g).set_index(1)
|
|
1392
|
-
OutputToFile01 = pd.Series(data=[t2g[0][g] for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='Technology' )
|
|
1393
|
-
OutputToFile02 = pd.Series(data=[n2g[0][g] for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='Node' )
|
|
1394
|
-
OutputToFile03 = pd.Series(data=[z2g[0][g] for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='Zone' )
|
|
1395
|
-
OutputToFile04 = pd.Series(data=[a2g[0][g] for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='Area' )
|
|
1396
|
-
OutputToFile05 = pd.Series(data=[r2g[0][g] for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='Region' )
|
|
1397
|
-
OutputToFile06 = pd.Series(data=[mTEPES.pLoadLevelDuration[p,sc,n ]() for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='LoadLevelDuration [h]' )
|
|
1398
|
-
OutputToFile07 = pd.Series(data=[OptModel.vCommitment [p,sc,n,g]() if g in mTEPES.nr else 0 for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='Commitment {0,1}' )
|
|
1399
|
-
OutputToFile08 = pd.Series(data=[OptModel.vStartUp [p,sc,n,g]() if g in mTEPES.nr else 0 for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='StartUp {0,1}' )
|
|
1400
|
-
OutputToFile09 = pd.Series(data=[OptModel.vShutDown [p,sc,n,g]() if g in mTEPES.nr else 0 for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='ShutDown {0,1}' )
|
|
1401
|
-
OutputToFile10 = pd.Series(data=[OptModel.vTotalOutput [p,sc,n,g].ub for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='MaxPower [MW]' )
|
|
1402
|
-
OutputToFile11 = pd.Series(data=[OptModel.vTotalOutput [p,sc,n,g].lb for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='MinPower [MW]' )
|
|
1403
|
-
OutputToFile12 = pd.Series(data=[OptModel.vTotalOutput [p,sc,n,g]()*mTEPES.pLoadLevelDuration[p,sc,n]() for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='EnergyProduction [GWh]' )
|
|
1404
|
-
OutputToFile13 = pd.Series(data=[OptModel.vESSTotalCharge [p,sc,n,g]()*mTEPES.pLoadLevelDuration[p,sc,n]() if g in mTEPES.es else 0.0 for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='EnergyConsumption [GWh]')
|
|
1405
|
-
OutputToFile14 = pd.Series(data=[OptModel.vEnergyOutflows [p,sc,n,g]()*mTEPES.pLoadLevelDuration[p,sc,n]() if g in mTEPES.es else 0.0 for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='Outflows [GWh]' )
|
|
1406
|
-
OutputToFile15 = pd.Series(data=[OptModel.vESSInventory [p,sc,n,g]() if g in mTEPES.es else 0.0 for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='Inventory [GWh]' )
|
|
1407
|
-
OutputToFile16 = pd.Series(data=[OptModel.vESSSpillage [p,sc,n,g]() if g in mTEPES.es else 0.0 for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='Spillage [GWh]' )
|
|
1408
|
-
OutputToFile17 = pd.Series(data=[(OptModel.vTotalOutput [p,sc,n,g].ub-OptModel.vTotalOutput[p,sc,n,g]())*mTEPES.pLoadLevelDuration[p,sc,n]() if g in mTEPES.re else 0.0 for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='Curtailment [GWh]' )
|
|
1409
|
-
OutputToFile18 = pd.Series(data=[OptModel.vReserveUp [p,sc,n,g]() if g in mTEPES.nr else 0.0 for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='ReserveUpGen [MW]' )
|
|
1410
|
-
OutputToFile19 = pd.Series(data=[OptModel.vReserveDown [p,sc,n,g]() if g in mTEPES.nr else 0.0 for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='ReserveDownGen [MW]' )
|
|
1411
|
-
OutputToFile20 = pd.Series(data=[OptModel.vESSReserveUp [p,sc,n,g]() if g in mTEPES.es else 0.0 for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='ReserveUpCons [MW]' )
|
|
1412
|
-
OutputToFile21 = pd.Series(data=[OptModel.vESSReserveDown [p,sc,n,g]() if g in mTEPES.es else 0.0 for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='ReserveDownCons [MW]' )
|
|
1413
|
-
OutputToFile22 = pd.Series(data=[OptModel.vTotalOutput [p,sc,n,g]()*mTEPES.pLoadLevelDuration[p,sc,n]()*mTEPES.pEmissionRate[g] if g not in mTEPES.bo
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
OutputToFile10 *= 1e3
|
|
1417
|
-
OutputToFile11 *= 1e3
|
|
1418
|
-
OutputToFile18 *= 1e3
|
|
1419
|
-
OutputToFile19 *= 1e3
|
|
1420
|
-
OutputToFile20 *= 1e3
|
|
1421
|
-
OutputToFile21 *= 1e3
|
|
1422
|
-
OutputToFile22 *= 1e-3
|
|
1423
|
-
|
|
1424
|
-
OutputResults = pd.concat([OutputToFile01, OutputToFile02, OutputToFile03, OutputToFile04, OutputToFile05, OutputToFile06, OutputToFile07, OutputToFile08, OutputToFile09, OutputToFile10,
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
# OutputResults.rename_axis(['Period', 'Scenario', 'LoadLevel', 'Generator'], axis=0).to_csv (f'{_path}/oT_Result_SummaryGeneration_{CaseName}.csv', sep=',')
|
|
1428
|
-
# OutputResults.rename_axis(['Period', 'Scenario', 'LoadLevel', 'Generator'], axis=0).to_parquet(f'{_path}/oT_Result_SummaryGeneration_{CaseName}.parquet', engine='pyarrow')
|
|
1429
|
-
|
|
1430
|
-
WritingResultsTime = time.time() - StartTime
|
|
1431
|
-
StartTime = time.time()
|
|
1432
|
-
print('Writing generation summary results ... ', round(WritingResultsTime), 's')
|
|
1605
|
+
#
|
|
1606
|
+
# StartTime = time.time()
|
|
1607
|
+
# t2g = pd.DataFrame(mTEPES.t2g).set_index(1)
|
|
1608
|
+
# n2g = pd.DataFrame(mTEPES.n2g).set_index(1)
|
|
1609
|
+
# z2g = pd.DataFrame(mTEPES.z2g).set_index(1)
|
|
1610
|
+
# a2g = pd.DataFrame(mTEPES.a2g).set_index(1)
|
|
1611
|
+
# r2g = pd.DataFrame(mTEPES.r2g).set_index(1)
|
|
1612
|
+
# OutputToFile01 = pd.Series(data=[t2g[0][g] for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='Technology' )
|
|
1613
|
+
# OutputToFile02 = pd.Series(data=[n2g[0][g] for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='Node' )
|
|
1614
|
+
# OutputToFile03 = pd.Series(data=[z2g[0][g] for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='Zone' )
|
|
1615
|
+
# OutputToFile04 = pd.Series(data=[a2g[0][g] for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='Area' )
|
|
1616
|
+
# OutputToFile05 = pd.Series(data=[r2g[0][g] for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='Region' )
|
|
1617
|
+
# 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]' )
|
|
1618
|
+
# 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}' )
|
|
1619
|
+
# 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}' )
|
|
1620
|
+
# 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}' )
|
|
1621
|
+
# 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]' )
|
|
1622
|
+
# 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]' )
|
|
1623
|
+
# 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]' )
|
|
1624
|
+
# OutputToFile13 = pd.Series(data=[OptModel.vESSTotalCharge [p,sc,n,g]()*mTEPES.pLoadLevelDuration[p,sc,n]() if g in mTEPES.es else 0.0 for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='EnergyConsumption [GWh]')
|
|
1625
|
+
# OutputToFile14 = pd.Series(data=[OptModel.vEnergyOutflows [p,sc,n,g]()*mTEPES.pLoadLevelDuration[p,sc,n]() if g in mTEPES.es else 0.0 for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='Outflows [GWh]' )
|
|
1626
|
+
# OutputToFile15 = pd.Series(data=[OptModel.vESSInventory [p,sc,n,g]() if g in mTEPES.es else 0.0 for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='Inventory [GWh]' )
|
|
1627
|
+
# OutputToFile16 = pd.Series(data=[OptModel.vESSSpillage [p,sc,n,g]() if g in mTEPES.es else 0.0 for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='Spillage [GWh]' )
|
|
1628
|
+
# OutputToFile17 = pd.Series(data=[(OptModel.vTotalOutput [p,sc,n,g].ub-OptModel.vTotalOutput[p,sc,n,g]())*mTEPES.pLoadLevelDuration[p,sc,n]() if g in mTEPES.re else 0.0 for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='Curtailment [GWh]' )
|
|
1629
|
+
# OutputToFile18 = pd.Series(data=[OptModel.vReserveUp [p,sc,n,g]() if g in mTEPES.nr else 0.0 for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='ReserveUpGen [MW]' )
|
|
1630
|
+
# OutputToFile19 = pd.Series(data=[OptModel.vReserveDown [p,sc,n,g]() if g in mTEPES.nr else 0.0 for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='ReserveDownGen [MW]' )
|
|
1631
|
+
# OutputToFile20 = pd.Series(data=[OptModel.vESSReserveUp [p,sc,n,g]() if g in mTEPES.es else 0.0 for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='ReserveUpCons [MW]' )
|
|
1632
|
+
# OutputToFile21 = pd.Series(data=[OptModel.vESSReserveDown [p,sc,n,g]() if g in mTEPES.es else 0.0 for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='ReserveDownCons [MW]' )
|
|
1633
|
+
# OutputToFile22 = pd.Series(data=[OptModel.vTotalOutput [p,sc,n,g]()*mTEPES.pLoadLevelDuration[p,sc,n]()*mTEPES.pEmissionRate[g] if g not in mTEPES.bo
|
|
1634
|
+
# else OptModel.vTotalOutputHeat [p,sc,n,g]()*mTEPES.pLoadLevelDuration[p,sc,n]()*mTEPES.pEmissionRate[g] for p,sc,n,g in mTEPES.psng], index=mTEPES.psng).to_frame(name='Emissions [MtCO2]' )
|
|
1635
|
+
#
|
|
1636
|
+
# OutputToFile10 *= 1e3
|
|
1637
|
+
# OutputToFile11 *= 1e3
|
|
1638
|
+
# OutputToFile18 *= 1e3
|
|
1639
|
+
# OutputToFile19 *= 1e3
|
|
1640
|
+
# OutputToFile20 *= 1e3
|
|
1641
|
+
# OutputToFile21 *= 1e3
|
|
1642
|
+
# OutputToFile22 *= 1e-3
|
|
1643
|
+
#
|
|
1644
|
+
# OutputResults = pd.concat([OutputToFile01, OutputToFile02, OutputToFile03, OutputToFile04, OutputToFile05, OutputToFile06, OutputToFile07, OutputToFile08, OutputToFile09, OutputToFile10,
|
|
1645
|
+
# OutputToFile11, OutputToFile12, OutputToFile13, OutputToFile14, OutputToFile15, OutputToFile16, OutputToFile17, OutputToFile18, OutputToFile19, OutputToFile20,
|
|
1646
|
+
# OutputToFile21, OutputToFile22], axis=1)
|
|
1647
|
+
# # OutputResults.rename_axis(['Period', 'Scenario', 'LoadLevel', 'Generator'], axis=0).to_csv (f'{_path}/oT_Result_SummaryGeneration_{CaseName}.csv', sep=',')
|
|
1648
|
+
# # OutputResults.rename_axis(['Period', 'Scenario', 'LoadLevel', 'Generator'], axis=0).to_parquet(f'{_path}/oT_Result_SummaryGeneration_{CaseName}.parquet', engine='pyarrow')
|
|
1649
|
+
#
|
|
1650
|
+
# WritingResultsTime = time.time() - StartTime
|
|
1651
|
+
# StartTime = time.time()
|
|
1652
|
+
# print('Writing generation summary results ... ', round(WritingResultsTime), 's')
|
|
1433
1653
|
|
|
1434
1654
|
ndzn = pd.DataFrame(mTEPES.ndzn).set_index(0)
|
|
1435
1655
|
ndar = pd.DataFrame(mTEPES.ndar).set_index(0)
|
|
@@ -1455,6 +1675,7 @@ def OperationSummaryResults(DirName, CaseName, OptModel, mTEPES):
|
|
|
1455
1675
|
print('Writing elect network summary results ... ', round(WritingResultsTime), 's')
|
|
1456
1676
|
|
|
1457
1677
|
|
|
1678
|
+
# @profile
|
|
1458
1679
|
def FlexibilityResults(DirName, CaseName, OptModel, mTEPES):
|
|
1459
1680
|
# %% outputting the flexibility
|
|
1460
1681
|
_path = os.path.join(DirName, CaseName)
|
|
@@ -1518,6 +1739,7 @@ def FlexibilityResults(DirName, CaseName, OptModel, mTEPES):
|
|
|
1518
1739
|
print('Writing flexibility results ... ', round(WritingResultsTime), 's')
|
|
1519
1740
|
|
|
1520
1741
|
|
|
1742
|
+
# @profile
|
|
1521
1743
|
def NetworkOperationResults(DirName, CaseName, OptModel, mTEPES):
|
|
1522
1744
|
# %% outputting the electric network operation
|
|
1523
1745
|
_path = os.path.join(DirName, CaseName)
|
|
@@ -1590,6 +1812,7 @@ def NetworkOperationResults(DirName, CaseName, OptModel, mTEPES):
|
|
|
1590
1812
|
print('Writing elect netwk operation results ... ', round(WritingResultsTime), 's')
|
|
1591
1813
|
|
|
1592
1814
|
|
|
1815
|
+
# @profile
|
|
1593
1816
|
def MarginalResults(DirName, CaseName, OptModel, mTEPES, pIndPlotOutput):
|
|
1594
1817
|
# %% outputting marginal results
|
|
1595
1818
|
_path = os.path.join(DirName, CaseName)
|
|
@@ -1637,14 +1860,14 @@ def MarginalResults(DirName, CaseName, OptModel, mTEPES, pIndPlotOutput):
|
|
|
1637
1860
|
# tolerance to consider 0 a number
|
|
1638
1861
|
pEpsilon = 1e-6
|
|
1639
1862
|
|
|
1640
|
-
#%% outputting the incremental variable cost of each
|
|
1863
|
+
#%% outputting the incremental variable cost of each Generator (neither ESS nor boilers) with power surplus
|
|
1641
1864
|
sPSNARG = [(p,sc,n,ar,g) for p,sc,n,ar,g in mTEPES.psn*mTEPES.a2g if g not in mTEPES.eh and g not in mTEPES.bo and (p,g) in mTEPES.pg]
|
|
1642
1865
|
OutputToFile = pd.Series(data=[(mTEPES.pLinearVarCost[p,sc,n,g]+mTEPES.pEmissionVarCost[p,sc,n,g]) if OptModel.vTotalOutput[p,sc,n,g].ub - OptModel.vTotalOutput[p,sc,n,g]() > pEpsilon else math.inf for p,sc,n,ar,g in sPSNARG], index=pd.Index(sPSNARG))
|
|
1643
1866
|
OutputToFile *= 1e3
|
|
1644
1867
|
|
|
1645
1868
|
OutputToFile = OutputToFile.to_frame(name='EUR/MWh').reset_index().pivot_table(index=['level_0','level_1','level_2','level_3'], columns='level_4', values='EUR/MWh')
|
|
1646
1869
|
OutputToFile.rename_axis(['Period', 'Scenario', 'LoadLevel', 'Area'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_MarginalIncrementalVariableCost_{CaseName}.csv', sep=',')
|
|
1647
|
-
IncrementalGens = pd.Series('N/A', index=mTEPES.psnar).to_frame(name='
|
|
1870
|
+
IncrementalGens = pd.Series('N/A', index=mTEPES.psnar).to_frame(name='Generator')
|
|
1648
1871
|
for p,sc,n,ar in mTEPES.psnar:
|
|
1649
1872
|
if all(g not in mTEPES.eh and g not in mTEPES.bo and (p, g) in mTEPES.pg and (ar, g) in mTEPES.a2g for g in mTEPES.g):
|
|
1650
1873
|
if len(OutputToFile.loc[(p,sc,n,ar)]) > 1:
|
|
@@ -1716,7 +1939,7 @@ def MarginalResults(DirName, CaseName, OptModel, mTEPES, pIndPlotOutput):
|
|
|
1716
1939
|
if mTEPES.gc:
|
|
1717
1940
|
sPSSTAR = [(p,sc,st,ar) for p,sc,st,ar in mTEPES.ps*mTEPES.st*mTEPES.ar if mTEPES.pReserveMargin[p,ar] and st == mTEPES.Last_st and sum(1 for g in mTEPES.g if g in g2a[ar]) and (p,sc,n) in mTEPES.psn and sum(mTEPES.pRatedMaxPowerElec[g] * mTEPES.pAvailability[g]() / (1.0-mTEPES.pEFOR[g]) for g in mTEPES.g if g in g2a[ar] and g not in (mTEPES.gc or mTEPES.gd)) <= mTEPES.pDemandElecPeak[p,ar] * mTEPES.pReserveMargin[p,ar]]
|
|
1718
1941
|
if sPSSTAR:
|
|
1719
|
-
OutputResults = pd.Series(data=[mTEPES.pDuals[
|
|
1942
|
+
OutputResults = pd.Series(data=[mTEPES.pDuals[''.join([f'eAdequacyReserveMarginElec_{p}_{sc}_{st}{ar}'])] for p,sc,st,ar in sPSSTAR], index=pd.Index(sPSSTAR))
|
|
1720
1943
|
OutputResults.to_frame(name='RM').reset_index().pivot_table(index=['level_0','level_1'], columns='level_3', values='RM').rename_axis(['Period', 'Scenario'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_MarginalReserveMargin_{CaseName}.csv', sep=',')
|
|
1721
1944
|
|
|
1722
1945
|
if mTEPES.pIndHeat == 1:
|
|
@@ -1724,17 +1947,17 @@ def MarginalResults(DirName, CaseName, OptModel, mTEPES, pIndPlotOutput):
|
|
|
1724
1947
|
if mTEPES.gc:
|
|
1725
1948
|
sPSSTAR = [(p,sc,st,ar) for p,sc,st,ar in mTEPES.ps*mTEPES.st*mTEPES.ar if mTEPES.pReserveMarginHeat[p,ar] and st == mTEPES.Last_st and sum(1 for g in mTEPES.g if g in g2a[ar]) and (p,sc,n) in mTEPES.psn and sum(mTEPES.pRatedMaxPowerHeat[g] * mTEPES.pAvailability[g]() / (1.0-mTEPES.pEFOR[g]) for g in mTEPES.g if g in g2a[ar] and g not in (mTEPES.gc or mTEPES.gd)) <= mTEPES.pDemandHeatPeak[p,ar] * mTEPES.pReserveMarginHeat[p,ar]]
|
|
1726
1949
|
if sPSSTAR:
|
|
1727
|
-
OutputResults = pd.Series(data=[mTEPES.pDuals[
|
|
1950
|
+
OutputResults = pd.Series(data=[mTEPES.pDuals[''.join([f'eAdequacyReserveMarginHeat_{p}_{sc}_{st}{ar}'])] for p,sc,st,ar in sPSSTAR], index=pd.Index(sPSSTAR))
|
|
1728
1951
|
OutputResults.to_frame(name='RM').reset_index().pivot_table(index=['level_0','level_1'], columns='level_3', values='RM').rename_axis(['Period', 'Scenario'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_MarginalReserveMarginHeat_{CaseName}.csv', sep=',')
|
|
1729
1952
|
|
|
1730
1953
|
sPSSTAR = [(p,sc,st,ar) for p,sc,st,ar in mTEPES.ps*mTEPES.st*mTEPES.ar if mTEPES.pEmission[p,ar] < math.inf and st == mTEPES.Last_st and (p,sc,n) in mTEPES.psn and sum(mTEPES.pEmissionVarCost[p,sc,na,g] for na,g in mTEPES.na*mTEPES.g if (ar,g) in mTEPES.a2g and (p,g) in mTEPES.pg)]
|
|
1731
1954
|
if sPSSTAR:
|
|
1732
|
-
OutputResults = pd.Series(data=[mTEPES.pDuals[
|
|
1955
|
+
OutputResults = pd.Series(data=[mTEPES.pDuals[''.join([f'eMaxSystemEmission_{p}_{sc}_{st}{ar}'])] for p,sc,st,ar in sPSSTAR], index=pd.Index(sPSSTAR))
|
|
1733
1956
|
OutputResults.to_frame(name='EM').reset_index().pivot_table(index=['level_0','level_1'], columns='level_3', values='EM').rename_axis(['Period', 'Scenario'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_MarginalEmission_{CaseName}.csv', sep=',')
|
|
1734
1957
|
|
|
1735
1958
|
sPSSTAR = [(p,sc,st,ar) for p,sc,st,ar in mTEPES.ps*mTEPES.st*mTEPES.ar if mTEPES.pRESEnergy[p,ar] and st == mTEPES.Last_st and (p,sc,n) in mTEPES.psn]
|
|
1736
1959
|
if sPSSTAR:
|
|
1737
|
-
OutputResults = pd.Series(data=[mTEPES.pDuals[
|
|
1960
|
+
OutputResults = pd.Series(data=[mTEPES.pDuals[''.join([f'eMinSystemRESEnergy_{p}_{sc}_{st}{ar}'])] for p,sc,st,ar in sPSSTAR], index=pd.Index(sPSSTAR))
|
|
1738
1961
|
OutputResults *= 1e-3*sum(mTEPES.pLoadLevelDuration[p,sc,na]() for na in mTEPES.na)
|
|
1739
1962
|
OutputResults.to_frame(name='RES').reset_index().pivot_table(index=['level_0','level_1'], columns='level_3', values='RES').rename_axis(['Period', 'Scenario'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_MarginalRESEnergy_{CaseName}.csv', sep=',')
|
|
1740
1963
|
|
|
@@ -1775,7 +1998,7 @@ def MarginalResults(DirName, CaseName, OptModel, mTEPES, pIndPlotOutput):
|
|
|
1775
1998
|
if len(OutputToFile) and pIndPlotOutput == 1:
|
|
1776
1999
|
WaterValue = OutputToFile.to_frame(name='WaterValue').reset_index().pivot_table(index=['level_0','level_1','level_3','level_4'], values='WaterValue').rename_axis(['level_0','level_1','level_2','level_3'], axis=0).loc[:,:,:,:]
|
|
1777
2000
|
for p,sc in mTEPES.ps:
|
|
1778
|
-
chart = LinePlots(p, sc, WaterValue, '
|
|
2001
|
+
chart = LinePlots(p, sc, WaterValue, 'Generator', 'LoadLevel', 'EUR/MWh', 'average')
|
|
1779
2002
|
chart.save(f'{_path}/oT_Plot_MarginalEnergyValue_{CaseName}_{p}_{sc}.html', embed_options={'renderer': 'svg'})
|
|
1780
2003
|
|
|
1781
2004
|
# #%% Reduced cost for NetworkInvestment
|
|
@@ -1798,6 +2021,7 @@ def MarginalResults(DirName, CaseName, OptModel, mTEPES, pIndPlotOutput):
|
|
|
1798
2021
|
print('Writing marginal information results ... ', round(WritingResultsTime), 's')
|
|
1799
2022
|
|
|
1800
2023
|
|
|
2024
|
+
# @profile
|
|
1801
2025
|
def ReliabilityResults(DirName, CaseName, OptModel, mTEPES):
|
|
1802
2026
|
# %% outputting the reliability indexes
|
|
1803
2027
|
_path = os.path.join(DirName, CaseName)
|
|
@@ -1827,7 +2051,7 @@ def ReliabilityResults(DirName, CaseName, OptModel, mTEPES):
|
|
|
1827
2051
|
OutputToFile2 = pd.Series(data=[ mTEPES.pDemandElec [p,sc,n,nd] for p,sc,n,nd in mTEPES.psnnd], index=mTEPES.psnnd)
|
|
1828
2052
|
OutputToFile = OutputToFile2 - OutputToFile1
|
|
1829
2053
|
OutputToFile *= 1e3
|
|
1830
|
-
OutputToFile = OutputToFile.to_frame(name='MW'
|
|
2054
|
+
OutputToFile = OutputToFile.to_frame(name='MW')
|
|
1831
2055
|
OutputToFile.reset_index().pivot_table(index=['level_0','level_1','level_2'], columns='level_3', values='MW', aggfunc='sum').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_NetDemandNetwork_{CaseName}.csv', sep=',')
|
|
1832
2056
|
OutputToFile.reset_index().pivot_table(index=['level_0','level_1','level_2'], values='MW', aggfunc='sum').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_NetDemand_{CaseName}.csv', sep=',')
|
|
1833
2057
|
|
|
@@ -1839,7 +2063,7 @@ def ReliabilityResults(DirName, CaseName, OptModel, mTEPES):
|
|
|
1839
2063
|
OutputToFile2[p,sc] = pDemandElec.loc [(p,sc)].reset_index().pivot_table(index=['level_0'], values=0, aggfunc='sum')[0].max()
|
|
1840
2064
|
ReserveMargin1 = OutputToFile1 - OutputToFile2
|
|
1841
2065
|
ReserveMargin2 = (OutputToFile1 - OutputToFile2)/OutputToFile2
|
|
1842
|
-
ReserveMargin1.to_frame(name='MW' ).rename_axis(['Period', 'Scenario'], axis=0).to_csv(f'{_path}/oT_Result_ReserveMargin_{CaseName}.csv',
|
|
2066
|
+
ReserveMargin1.to_frame(name='MW' ).rename_axis(['Period', 'Scenario'], axis=0).to_csv(f'{_path}/oT_Result_ReserveMargin_{CaseName}.csv', sep=',')
|
|
1843
2067
|
ReserveMargin2.to_frame(name='p.u.').rename_axis(['Period', 'Scenario'], axis=0).to_csv(f'{_path}/oT_Result_ReserveMarginPerUnit_{CaseName}.csv', sep=',')
|
|
1844
2068
|
|
|
1845
2069
|
# Determination of the index: Largest Unit
|
|
@@ -1853,6 +2077,8 @@ def ReliabilityResults(DirName, CaseName, OptModel, mTEPES):
|
|
|
1853
2077
|
WritingResultsTime = time.time() - StartTime
|
|
1854
2078
|
print('Writing reliability indexes ... ', round(WritingResultsTime), 's')
|
|
1855
2079
|
|
|
2080
|
+
|
|
2081
|
+
# @profile
|
|
1856
2082
|
def CostSummaryResults(DirName, CaseName, OptModel, mTEPES):
|
|
1857
2083
|
# %% outputting the system costs and revenues
|
|
1858
2084
|
_path = os.path.join(DirName, CaseName)
|
|
@@ -1883,6 +2109,7 @@ def CostSummaryResults(DirName, CaseName, OptModel, mTEPES):
|
|
|
1883
2109
|
print('Writing cost summary results ... ', round(WritingResultsTime), 's')
|
|
1884
2110
|
|
|
1885
2111
|
|
|
2112
|
+
# @profile
|
|
1886
2113
|
def EconomicResults(DirName, CaseName, OptModel, mTEPES, pIndAreaOutput, pIndPlotOutput):
|
|
1887
2114
|
# %% outputting the system costs and revenues
|
|
1888
2115
|
_path = os.path.join(DirName, CaseName)
|
|
@@ -1950,9 +2177,9 @@ def EconomicResults(DirName, CaseName, OptModel, mTEPES, pIndAreaOutput, pIndPlo
|
|
|
1950
2177
|
if pIndAreaOutput == 1:
|
|
1951
2178
|
for ar in mTEPES.ar:
|
|
1952
2179
|
if sum(1 for g in g2a[ar]):
|
|
1953
|
-
sPSNGT = [(p,sc,n,gt) for p,sc,n,gt in mTEPES.psngt if sum(1 for g in g2a[ar]
|
|
2180
|
+
sPSNGT = [(p,sc,n,gt) for p,sc,n,gt in mTEPES.psngt if sum(1 for g in g2t[gt] if g in g2a[ar] and (p,g) in mTEPES.pg)]
|
|
1954
2181
|
if sPSNGT:
|
|
1955
|
-
OutputToFile = pd.Series(data=[sum(OptModel.vTotalOutput[p,sc,n,g]()*mTEPES.pLoadLevelDuration[p,sc,n]() for g in g2a[ar]
|
|
2182
|
+
OutputToFile = pd.Series(data=[sum(OptModel.vTotalOutput[p,sc,n,g]()*mTEPES.pLoadLevelDuration[p,sc,n]() for g in g2t[gt] if g in g2a[ar] and (p,g) in mTEPES.pg) for p,sc,n,gt in sPSNGT], index=pd.Index(sPSNGT))
|
|
1956
2183
|
OutputToFile.to_frame(name='GWh').reset_index().pivot_table(index=['level_0','level_1','level_2'], columns='level_3', values='GWh', aggfunc='sum').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_TechnologyGenerationEnergy_{CaseName}_{ar}.csv', sep=',')
|
|
1957
2184
|
|
|
1958
2185
|
if pIndPlotOutput == 1:
|
|
@@ -1960,10 +2187,10 @@ def EconomicResults(DirName, CaseName, OptModel, mTEPES, pIndAreaOutput, pIndPlo
|
|
|
1960
2187
|
chart = PiePlots(p, sc, OutputToFile, 'Technology', '%')
|
|
1961
2188
|
chart.save(f'{_path}/oT_Plot_TechnologyGenerationEnergy_{CaseName}_{p}_{sc}_{ar}.html', embed_options={'renderer': 'svg'})
|
|
1962
2189
|
|
|
1963
|
-
sPSNARND = [(p,sc,n,ar,nd) for p,sc,n,ar,nd in mTEPES.
|
|
1964
|
-
sPSNARNDGT = [(p,sc,n,ar,nd,gt) for p,sc,n,ar,nd,gt in sPSNARND*mTEPES.gt
|
|
1965
|
-
sPSNARNDRT = [(p,sc,n,ar,nd,rt) for p,sc,n,ar,nd,rt in sPSNARND*mTEPES.rt
|
|
1966
|
-
sPSNARNDET = [(p,sc,n,ar,nd,et) for p,sc,n,ar,nd,et in sPSNARND*mTEPES.et
|
|
2190
|
+
sPSNARND = [(p,sc,n,ar,nd) for p,sc,n,ar,nd in mTEPES.psn*mTEPES.ar*mTEPES.nd if nd in d2a[ar] and sum(1 for g in g2n[nd]) + sum(1 for nf,cc in lout[nd]) + sum(1 for ni,cc in lin[nd])]
|
|
2191
|
+
sPSNARNDGT = [(p,sc,n,ar,nd,gt) for p,sc,n,ar,nd,gt in sPSNARND*mTEPES.gt if sum(1 for g in g2t[gt] if (p,g ) in mTEPES.pg )]
|
|
2192
|
+
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)]
|
|
2193
|
+
sPSNARNDET = [(p,sc,n,ar,nd,et) for p,sc,n,ar,nd,et in sPSNARND*mTEPES.et if sum(1 for eh in e2e[et] if (p,eh) in mTEPES.peh)]
|
|
1967
2194
|
|
|
1968
2195
|
if sum(1 for nr in mTEPES.nr if nr not in mTEPES.eh):
|
|
1969
2196
|
OutputResults01 = pd.Series(data=[ sum(OptModel.vTotalOutput [p,sc,n,nr ]()*mTEPES.pLoadLevelDuration[p,sc,n]() for nr in g2n[nd] if (p,nr) in mTEPES.pnr and nr in g2t[gt] and nr not in mTEPES.eh) for p,sc,n,ar,nd,gt in sPSNARNDGT], index=pd.Index(sPSNARNDGT)).to_frame(name='Generation' ).reset_index().pivot_table(index=['level_0','level_1','level_2','level_3','level_4'], columns='level_5', values='Generation' , aggfunc='sum')
|
|
@@ -1997,16 +2224,17 @@ def EconomicResults(DirName, CaseName, OptModel, mTEPES, pIndAreaOutput, pIndPlo
|
|
|
1997
2224
|
OutputResults.stack().reset_index().pivot_table(index=['level_0','level_1' ,'level_5'], columns='level_3', values=0, aggfunc='sum').rename_axis(['Period', 'Scenario' , 'Technology' ], axis=0).to_csv(f'{_path}/oT_Result_BalanceEnergyPerArea_{CaseName}.csv', sep=',')
|
|
1998
2225
|
|
|
1999
2226
|
#%% outputting the demand and the LSRMC of electricity
|
|
2000
|
-
|
|
2227
|
+
sPSSTNARND = [(p,sc,st,n,ar,nd) for p,sc,st,n,ar,nd in mTEPES.s2n*mTEPES.ar*mTEPES.nd if nd in d2a[ar] and sum(1 for g in g2n[nd]) + sum(1 for nf,cc in lout[nd]) + sum(1 for ni,cc in lin[nd]) and (p,sc,n) in mTEPES.psn]
|
|
2001
2228
|
|
|
2002
|
-
OutputResults = pd.Series(data=[mTEPES.pDuals["".join([f"eBalanceElec_{p}_{sc}_{st}('{n}', '{nd}')"])]/mTEPES.pPeriodProb[p,sc]()/mTEPES.pLoadLevelDuration[p,sc,n]() for p,sc,st,n,ar,nd in
|
|
2229
|
+
OutputResults = pd.Series(data=[mTEPES.pDuals["".join([f"eBalanceElec_{p}_{sc}_{st}('{n}', '{nd}')"])]/mTEPES.pPeriodProb[p,sc]()/mTEPES.pLoadLevelDuration[p,sc,n]() for p,sc,st,n,ar,nd in sPSSTNARND], index=pd.Index(sPSSTNARND))
|
|
2003
2230
|
OutputResults *= 1e3
|
|
2004
2231
|
OutputResults.index = [idx[:2] + idx[3:] for idx in OutputResults.index]
|
|
2005
2232
|
|
|
2006
2233
|
#%% outputting the generator power output
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2234
|
+
sPSNARNDG = [(p,sc,n,ar,nd,g ) for p,sc,n,ar,nd,g in sPSNARND*mTEPES.g if g in g2n[nd] and (p,g ) in mTEPES.pg ]
|
|
2235
|
+
sPSNARNDNR = [(p,sc,n,ar,nd,nr) for p,sc,n,ar,nd,nr in sPSNARND*mTEPES.nr if nr in g2n[nd] and (p,nr) in mTEPES.pnr and nr not in mTEPES.eh]
|
|
2236
|
+
sPSNARNDRE = [(p,sc,n,ar,nd,re) for p,sc,n,ar,nd,re in sPSNARND*mTEPES.re if re in g2n[nd] and (p,re) in mTEPES.pre ]
|
|
2237
|
+
sPSNARNDEH = [(p,sc,n,ar,nd,eh) for p,sc,n,ar,nd,eh in sPSNARND*mTEPES.eh if eh in g2n[nd] and (p,eh) in mTEPES.peh ]
|
|
2010
2238
|
|
|
2011
2239
|
if sum(1 for nr in mTEPES.nr if nr not in mTEPES.eh):
|
|
2012
2240
|
OutputResults01 = pd.Series(data=[ OptModel.vTotalOutput [p,sc,n,nr ]()*mTEPES.pLoadLevelDuration[p,sc,n]() for p,sc,n,ar,nd,nr in sPSNARNDNR], index=pd.Index(sPSNARNDNR)).to_frame(name='Generation' ).reset_index().pivot_table(index=['level_0','level_1','level_2','level_3','level_4'], columns='level_5', values='Generation' , aggfunc='sum')
|
|
@@ -2022,32 +2250,38 @@ def EconomicResults(DirName, CaseName, OptModel, mTEPES, pIndAreaOutput, pIndPlo
|
|
|
2022
2250
|
OutputResults09 = pd.Series(data=[-sum(OptModel.vLineLosses [p,sc,n,nd,nf,cc]()*mTEPES.pLoadLevelDuration[p,sc,n]() for nf,cc in loutl[nd] if (p,nd,nf,cc) in mTEPES.pla) for p,sc,n,ar,nd in sPSNARND ], index=pd.Index(sPSNARND )).to_frame(name='LineLossesOut' )
|
|
2023
2251
|
OutputResults10 = pd.Series(data=[-sum(OptModel.vLineLosses [p,sc,n,ni,nd,cc]()*mTEPES.pLoadLevelDuration[p,sc,n]() for ni,cc in linl [nd] if (p,ni,nd,cc) in mTEPES.pla) for p,sc,n,ar,nd in sPSNARND ], index=pd.Index(sPSNARND )).to_frame(name='LineLossesIn' )
|
|
2024
2252
|
|
|
2025
|
-
MarketResultsDem
|
|
2253
|
+
MarketResultsDem = pd.DataFrame()
|
|
2026
2254
|
if mTEPES.eh:
|
|
2027
2255
|
MarketResultsDem = pd.concat([MarketResultsDem, OutputResults04],axis=1)
|
|
2028
|
-
|
|
2029
2256
|
MarketResultsDem = pd.concat([MarketResultsDem, OutputResults06],axis=1)
|
|
2030
|
-
|
|
2031
2257
|
if mTEPES.ll:
|
|
2032
2258
|
MarketResultsDem = pd.concat([MarketResultsDem, OutputResults09, OutputResults10], axis=1)
|
|
2033
2259
|
|
|
2260
|
+
MarketResultsDem *= -1e3
|
|
2261
|
+
MarketResultsDem = pd.concat([MarketResultsDem.sum(axis=1), OutputResults], axis=1)
|
|
2262
|
+
MarketResultsDem.stack().reset_index().pivot_table(index=['level_0','level_1','level_2','level_3','level_4'], columns='level_5', values=0, aggfunc='sum').rename_axis(['Period', 'Scenario', 'LoadLevel', 'Area', 'Node'], axis=0).rename(columns={0: 'Demand [MWh]', 1: 'LSRMC [EUR/MWh]'}, inplace=False).to_csv(f'{_path}/oT_Result_MarketResultsDemand_{CaseName}.csv', sep=',')
|
|
2263
|
+
|
|
2034
2264
|
MarketResultsGen = pd.DataFrame()
|
|
2035
2265
|
# Check if there are non-RES generators
|
|
2036
2266
|
if sum(1 for nr in mTEPES.nr if nr not in mTEPES.eh):
|
|
2037
|
-
MarketResultsGen = pd.concat([MarketResultsGen,OutputResults01], axis=1)
|
|
2038
|
-
|
|
2267
|
+
MarketResultsGen = pd.concat([MarketResultsGen, OutputResults01], axis=1)
|
|
2039
2268
|
if mTEPES.re:
|
|
2040
2269
|
MarketResultsGen = pd.concat([MarketResultsGen, OutputResults02], axis=1)
|
|
2041
|
-
|
|
2042
2270
|
if mTEPES.eh:
|
|
2043
2271
|
MarketResultsGen = pd.concat([MarketResultsGen, OutputResults03], axis=1)
|
|
2044
2272
|
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2273
|
+
OutputResults11 = pd.Series(data=[(OptModel.vTotalOutput[p,sc,n,g].ub*OptModel.vGenerationInvest[p,g]() - OptModel.vTotalOutput[p,sc,n,g]())*mTEPES.pLoadLevelDuration[p,sc,n]() if g in mTEPES.re and g in mTEPES.gc else
|
|
2274
|
+
(OptModel.vTotalOutput[p,sc,n,g].ub - OptModel.vTotalOutput[p,sc,n,g]())*mTEPES.pLoadLevelDuration[p,sc,n]() if g in mTEPES.re and g not in mTEPES.gc else
|
|
2275
|
+
OptModel.vESSSpillage[p,sc,n,g]() if g in mTEPES.es else 0.0 for p,sc,n,ar,nd,g in sPSNARNDG], index=pd.Index(sPSNARNDG))
|
|
2276
|
+
OutputResults12 = pd.Series(data=[ OptModel.vTotalOutput [p,sc,n,g]()*mTEPES.pLoadLevelDuration[p,sc,n]()*mTEPES.pEmissionRate[g]/1e3 if g not in mTEPES.bo else
|
|
2277
|
+
OptModel.vTotalOutputHeat[p,sc,n,g]()*mTEPES.pLoadLevelDuration[p,sc,n]()*mTEPES.pEmissionRate[g]/1e3 for p,sc,n,ar,nd,g in sPSNARNDG], index=pd.Index(sPSNARNDG))
|
|
2278
|
+
|
|
2279
|
+
OutputResults11.index = [idx[:6] for idx in OutputResults11.index]
|
|
2280
|
+
OutputResults12.index = [idx[:6] for idx in OutputResults12.index]
|
|
2048
2281
|
|
|
2049
2282
|
MarketResultsGen *= 1e3
|
|
2050
|
-
MarketResultsGen.
|
|
2283
|
+
MarketResultsGen = pd.concat([MarketResultsGen.stack(), OutputResults11, OutputResults12], axis=1)
|
|
2284
|
+
MarketResultsGen.reset_index().pivot_table(index=['level_0','level_1','level_2','level_3','level_4','level_5']).rename_axis(['Period', 'Scenario', 'LoadLevel', 'Area', 'Node', 'Generator'], axis=0).rename(columns={0: 'Generation [MWh]', 1: 'Curtailment [MWh]', 2: 'Emissions [MtCO2]'}, inplace=False).to_csv(f'{_path}/oT_Result_MarketResultsGeneration_{CaseName}.csv', sep=',')
|
|
2051
2285
|
|
|
2052
2286
|
# df=OutputResults.stack().rename_axis(['Period', 'Scenario', 'LoadLevel', 'Area', 'Node', 'Technology'], axis=0).reset_index()
|
|
2053
2287
|
# df['AreaFin'] = df['Area']
|
|
@@ -2153,14 +2387,25 @@ def EconomicResults(DirName, CaseName, OptModel, mTEPES, pIndAreaOutput, pIndPlo
|
|
|
2153
2387
|
OutputResults.loc[(OutputResults['Period'] == p) & (OutputResults['Scenario'] == sc), 'MEUR/year'] = OutputResults.loc[(OutputResults['Period'] == p) & (OutputResults['Scenario'] == sc), 'MEUR'] / mTEPES.pDiscountedWeight[p] / mTEPES.pScenProb[p,sc]()
|
|
2154
2388
|
OutputResults.to_csv(f'{_path}/oT_Result_CostSummary_{CaseName}_{ar}.csv', sep=',', index=False)
|
|
2155
2389
|
|
|
2156
|
-
|
|
2157
|
-
|
|
2390
|
+
sPSSTNG = [(p,sc,st,n, g) for p,sc,st,n, g in mTEPES.s2n*mTEPES.g if (p,sc,n) in mTEPES.psn and (p,g) in mTEPES.pg]
|
|
2391
|
+
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]
|
|
2392
|
+
sPSSTNNDG = [(p,sc,st,n,nd,g) for p,sc,st,n,nd,g in sPSSTNND*mTEPES.g if (nd,g) in mTEPES.n2g and (p,g) in mTEPES.pg]
|
|
2393
|
+
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 if (p,g) in mTEPES.pg], index=pd.Index(sPSSTNNDG))
|
|
2394
|
+
MeanOutput = pd.Series(data=[ OptModel.vTotalOutput [p,sc,n,g]() for p,sc,st,n, g in sPSSTNG if (p,g) in mTEPES.pg], index=pd.Index(sPSSTNG )).groupby(level=4).mean()
|
|
2395
|
+
MeanOutput *= 1e-3
|
|
2158
2396
|
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=',')
|
|
2397
|
+
OutputResults = pd.Series(data=[ mTEPES.pDuals["".join([f"eBalanceElec_{p}_{sc}_{st}('{n}', '{nd}')"])]/mTEPES.pPeriodProb[p,sc]()/mTEPES.pLoadLevelDuration[p,sc,n]()*OptModel.vTotalOutput [p,sc,n,g]()/MeanOutput[g] for p,sc,st,n,nd,g in sPSSTNNDG], index=pd.Index(sPSSTNNDG))
|
|
2398
|
+
OutputResults.to_frame(name='EUR/MWh').reset_index().pivot_table(index=['level_0','level_1','level_3'], columns='level_5', values='EUR/MWh').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_GenerationCapturedSRMC_{CaseName}.csv', sep=',')
|
|
2159
2399
|
|
|
2160
2400
|
if mTEPES.eh:
|
|
2161
|
-
|
|
2162
|
-
|
|
2401
|
+
sPSSTNES = [(p,sc,st,n, eh) for p,sc,st,n, eh in mTEPES.s2n*mTEPES.eh if (p,sc,n) in mTEPES.psn and (p,eh) in mTEPES.peh]
|
|
2402
|
+
sPSSTNNDEH = [(p,sc,st,n,nd,eh) for p,sc,st,n,nd,eh in sPSSTNND*mTEPES.eh if (nd,eh) in mTEPES.n2g and (p,eh) in mTEPES.peh]
|
|
2403
|
+
OutputResults = pd.Series(data=[-mTEPES.pDuals["".join([f"eBalanceElec_{p}_{sc}_{st}('{n}', '{nd}')"])]/mTEPES.pPeriodProb[p,sc]()/mTEPES.pLoadLevelDuration[p,sc,n]()*OptModel.vESSTotalCharge[p,sc,n,eh]() for p,sc,st,n,nd,eh in sPSSTNNDEH if (p,eh) in mTEPES.peh], index=pd.Index(sPSSTNNDEH))
|
|
2404
|
+
MeanOutput = pd.Series(data=[ OptModel.vESSTotalCharge[p,sc,n,eh]() for p,sc,st,n, eh in sPSSTNES if (p,eh) in mTEPES.peh], index=pd.Index(sPSSTNES )).groupby(level=4).mean()
|
|
2405
|
+
MeanOutput *= 1e-3
|
|
2163
2406
|
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=',')
|
|
2407
|
+
OutputResults = pd.Series(data=[-mTEPES.pDuals["".join([f"eBalanceElec_{p}_{sc}_{st}('{n}', '{nd}')"])]/mTEPES.pPeriodProb[p,sc]()/mTEPES.pLoadLevelDuration[p,sc,n]()*OptModel.vESSTotalCharge[p,sc,n,eh]()/MeanOutput[eh] for p,sc,st,n,nd,eh in sPSSTNNDEH if (p,eh) in mTEPES.peh], index=pd.Index(sPSSTNNDEH))
|
|
2408
|
+
OutputResults.to_frame(name='EUR/MWh').reset_index().pivot_table(index=['level_0','level_1','level_3'], columns='level_5', values='EUR/MWh').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_ConsumptionCapturedSRMC_{CaseName}.csv', sep=',')
|
|
2164
2409
|
|
|
2165
2410
|
if mTEPES.gc:
|
|
2166
2411
|
GenRev = []
|
|
@@ -2168,16 +2413,16 @@ def EconomicResults(DirName, CaseName, OptModel, mTEPES, pIndAreaOutput, pIndPlo
|
|
|
2168
2413
|
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]
|
|
2169
2414
|
OutputToGenRev = 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,gc]() for p,sc,st,n,nd,gc in sPSSTNNDGC1], index=pd.Index(sPSSTNNDGC1))
|
|
2170
2415
|
GenRev.append(OutputToGenRev)
|
|
2171
|
-
if len([(p,sc,n,nd,gc)
|
|
2172
|
-
sPSSTNNDGC2 = [(p,sc,st,n,nd,gc) for p,sc,st,n,nd,gc in sPSSTNNDGC1
|
|
2416
|
+
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,sc,n) in mTEPES.psn and (p,gc) in mTEPES.pgc and gc in o2e[ot]]):
|
|
2417
|
+
sPSSTNNDGC2 = [(p,sc,st,n,nd,gc) for p,sc,st,n,nd,gc in sPSSTNNDGC1 for ot in mTEPES.ot if (p,sc,n) in mTEPES.psn and (p,gc) in mTEPES.pgc and gc in o2e[ot]]
|
|
2173
2418
|
OutputChargeRevESS = 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,gc]() for p,sc,st,n,nd,gc in sPSSTNNDGC2], index=pd.Index(sPSSTNNDGC2))
|
|
2174
2419
|
ChargeRev.append(OutputChargeRevESS)
|
|
2175
|
-
if len([(p,sc,n,nd,gc)
|
|
2176
|
-
sPSSTNNDGC3 = [(p,sc,st,n,nd,gc) for p,sc,st,n,nd,gc in sPSSTNNDGC1
|
|
2420
|
+
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,sc,n) in mTEPES.psn and (p,gc) in mTEPES.pgc and gc in r2r[rt]]):
|
|
2421
|
+
sPSSTNNDGC3 = [(p,sc,st,n,nd,gc) for p,sc,st,n,nd,gc in sPSSTNNDGC1 for rt in mTEPES.rt if (p,sc,n) in mTEPES.psn and (p,gc) in mTEPES.pgc and gc in r2r[rt]]
|
|
2177
2422
|
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))
|
|
2178
2423
|
ChargeRev.append(OutputChargeRevRES)
|
|
2179
|
-
if len([(p,sc,n,nd,gc)
|
|
2180
|
-
sPSSTNNDGC4 = [(p,sc,st,n,nd,gc) for p,sc,st,n,nd,gc in sPSSTNNDGC1
|
|
2424
|
+
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,sc,n) in mTEPES.psn and (p,gc) in mTEPES.pgc and gc in o2e[ot]]):
|
|
2425
|
+
sPSSTNNDGC4 = [(p,sc,st,n,nd,gc) for p,sc,st,n,nd,gc in sPSSTNNDGC1 for ot in mTEPES.ot if (p,sc,n) in mTEPES.psn and (p,gc) in mTEPES.pgc and gc in o2e[ot]]
|
|
2181
2426
|
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))
|
|
2182
2427
|
ChargeRev.append(OutputChargeRevThr)
|
|
2183
2428
|
if len(GenRev):
|
|
@@ -2199,8 +2444,8 @@ def EconomicResults(DirName, CaseName, OptModel, mTEPES, pIndAreaOutput, pIndPlo
|
|
|
2199
2444
|
|
|
2200
2445
|
if sum(mTEPES.pReserveMargin[:,:]):
|
|
2201
2446
|
if mTEPES.gc:
|
|
2202
|
-
sPSSTARGC = [(p,sc,st,ar,gc) for p,sc,st,ar,gc in mTEPES.ps*mTEPES.st*mTEPES.ar*mTEPES.gc if gc in g2a[ar] and mTEPES.pReserveMargin[p,ar] and st == mTEPES.Last_st and sum(1 for gc in mTEPES.gc if gc in g2a[ar]) and sum(mTEPES.pRatedMaxPowerElec[g] * mTEPES.pAvailability[g]() / (1.0-mTEPES.pEFOR[g]) for g in mTEPES.g if g in g2a[ar] and g not in (mTEPES.gc or mTEPES.gd)) <= mTEPES.pDemandElecPeak[p,ar] * mTEPES.pReserveMargin[p,ar]]
|
|
2203
|
-
OutputToResRev = pd.Series(data=[mTEPES.pDuals[
|
|
2447
|
+
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 (p,gc) in mTEPES.pgc 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]]
|
|
2448
|
+
OutputToResRev = pd.Series(data=[mTEPES.pDuals[''.join([f'eAdequacyReserveMarginElec_{p}_{sc}_{st}{ar}'])]*mTEPES.pRatedMaxPowerElec[gc]*mTEPES.pAvailability[gc]() for p,sc,st,ar,gc in sPSSTARGC], index=pd.Index(sPSSTARGC))
|
|
2204
2449
|
ResRev = pd.Series(data=[0.0 for gc in mTEPES.gc], index=mTEPES.gc, dtype='float64')
|
|
2205
2450
|
if sPSSTARGC:
|
|
2206
2451
|
OutputToResRev /= 1e3
|
|
@@ -2210,19 +2455,19 @@ def EconomicResults(DirName, CaseName, OptModel, mTEPES, pIndAreaOutput, pIndPlo
|
|
|
2210
2455
|
else:
|
|
2211
2456
|
ResRev = pd.Series(data=[0.0 for gc in mTEPES.gc], index=mTEPES.gc, dtype='float64')
|
|
2212
2457
|
|
|
2213
|
-
if sum(mTEPES.pOperReserveUp[:,:,:,:]) and sum(1 for ar,nr in mTEPES.ar*mTEPES.nr if nr in g2a[ar] and (mTEPES.pIndOperReserveGen[nr] == 0 or mTEPES.pIndOperReserveCon[nr] == 0)
|
|
2214
|
-
if len([(p,sc,n,ar,nr)
|
|
2215
|
-
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]
|
|
2458
|
+
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)):
|
|
2459
|
+
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 and (p,nr) in mTEPES.pnr]):
|
|
2460
|
+
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 and (p,nr) in mTEPES.pnr]
|
|
2216
2461
|
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))
|
|
2217
2462
|
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_RevenueOperatingReserveUp_{CaseName}.csv', sep=',')
|
|
2218
2463
|
|
|
2219
|
-
if len([(p,sc,n,ar,eh)
|
|
2220
|
-
sPSSTNARES = [(p,sc,st,n,ar,eh) for p,sc,st,n,ar,eh in mTEPES.s2n*mTEPES.ar*mTEPES.eh if eh in g2a[ar] and mTEPES.pOperReserveUp[p,sc,n,ar] and (p,sc,n,eh) in mTEPES.psnehc]
|
|
2464
|
+
if len([(p,sc,n,ar,eh) for p,sc, n,ar,eh in mTEPES.psn*mTEPES.ar*mTEPES.eh if eh in g2a[ar] and mTEPES.pOperReserveUp[p,sc,n,ar] and (p,sc,n,eh) in mTEPES.psnehc and (p,eh) in mTEPES.peh]):
|
|
2465
|
+
sPSSTNARES = [(p,sc,st,n,ar,eh) for p,sc,st,n,ar,eh in mTEPES.s2n*mTEPES.ar*mTEPES.eh if eh in g2a[ar] and mTEPES.pOperReserveUp[p,sc,n,ar] and (p,sc,n,eh) in mTEPES.psnehc and (p,eh) in mTEPES.peh]
|
|
2221
2466
|
OutputResults = pd.Series(data=[mTEPES.pDuals["".join([f"eOperReserveUp_{p}_{sc}_{st}('{n}', '{ar}')"])]/mTEPES.pPeriodProb[p,sc]()*OptModel.vESSReserveUp[p,sc,n,eh]() for p,sc,st,n,ar,eh in sPSSTNARES], index=pd.Index(sPSSTNARES))
|
|
2222
2467
|
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_RevenueOperatingReserveUpESS_{CaseName}.csv', sep=',')
|
|
2223
2468
|
|
|
2224
|
-
if len([(p,sc,n,ar,ec)
|
|
2225
|
-
sPSSTNAREC = [(p,sc,st,n,ar,ec) for p,sc,st,n,ar,ec in mTEPES.s2n*mTEPES.ar*mTEPES.ec if ec in g2a[ar] and mTEPES.pOperReserveUp[p,sc,n,ar] and (p,sc,n,ec) in mTEPES.psnec]
|
|
2469
|
+
if len([(p,sc,n,ar,ec) for p,sc, n,ar,ec in mTEPES.psn*mTEPES.ar*mTEPES.gc if ec in g2a[ar] and mTEPES.pOperReserveUp[p,sc,n,ar] and (p,sc,n,ec) in mTEPES.psnec and (p,ec) in mTEPES.pec]):
|
|
2470
|
+
sPSSTNAREC = [(p,sc,st,n,ar,ec) for p,sc,st,n,ar,ec in mTEPES.s2n*mTEPES.ar*mTEPES.ec if ec in g2a[ar] and mTEPES.pOperReserveUp[p,sc,n,ar] and (p,sc,n,ec) in mTEPES.psnec and (p,ec) in mTEPES.pec]
|
|
2226
2471
|
OutputResults = pd.Series(data=[mTEPES.pDuals["".join([f"eOperReserveUp_{p}_{sc}_{st}('{n}', '{ar}')"])]/mTEPES.pPeriodProb[p,sc]()*(OptModel.vReserveUp[p,sc,n,ec]()+OptModel.vESSReserveUp[p,sc,n,ec]()) for p,sc,st,n,ar,ec in sPSSTNAREC], index=pd.Index(sPSSTNAREC), dtype='float64')
|
|
2227
2472
|
if len(OutputResults):
|
|
2228
2473
|
OutputToUpRev = OutputResults.to_frame('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).sum(axis=0)
|
|
@@ -2238,18 +2483,18 @@ def EconomicResults(DirName, CaseName, OptModel, mTEPES, pIndAreaOutput, pIndPlo
|
|
|
2238
2483
|
UpRev = pd.Series(data=[0.0 for gc in mTEPES.gc], index=mTEPES.gc, dtype='float64')
|
|
2239
2484
|
|
|
2240
2485
|
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 )):
|
|
2241
|
-
if len([(p,sc,n,ar,nr)
|
|
2242
|
-
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]
|
|
2486
|
+
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 and (p,nr) in mTEPES.pnr]):
|
|
2487
|
+
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 and (p,nr) in mTEPES.pnr]
|
|
2243
2488
|
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))
|
|
2244
2489
|
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_RevenueOperatingReserveDw_{CaseName}.csv', sep=',')
|
|
2245
2490
|
|
|
2246
|
-
if len([(p,sc,n,ar,eh)
|
|
2247
|
-
sPSSTNARES = [(p,sc,st,n,ar,eh) for p,sc,st,n,ar,eh in mTEPES.s2n*mTEPES.ar*mTEPES.eh if eh in g2a[ar] and mTEPES.pOperReserveDw[p,sc,n,ar] and (p,sc,n,eh) in mTEPES.psnehc]
|
|
2491
|
+
if len([(p,sc,n,ar,eh) for p,sc, n,ar,eh in mTEPES.psn*mTEPES.ar*mTEPES.eh if eh in g2a[ar] and mTEPES.pOperReserveDw[p,sc,n,ar] and (p,sc,n,eh) in mTEPES.psnehc and (p,eh) in mTEPES.peh]):
|
|
2492
|
+
sPSSTNARES = [(p,sc,st,n,ar,eh) for p,sc,st,n,ar,eh in mTEPES.s2n*mTEPES.ar*mTEPES.eh if eh in g2a[ar] and mTEPES.pOperReserveDw[p,sc,n,ar] and (p,sc,n,eh) in mTEPES.psnehc and (p,eh) in mTEPES.peh]
|
|
2248
2493
|
OutputResults = pd.Series(data=[mTEPES.pDuals["".join([f"eOperReserveDw_{p}_{sc}_{st}('{n}', '{ar}')"])]/mTEPES.pPeriodProb[p,sc]()*OptModel.vESSReserveDown[p,sc,n,eh]() for p,sc,st,n,ar,eh in sPSSTNARES], index=pd.Index(sPSSTNARES))
|
|
2249
2494
|
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_RevenueOperatingReserveDwESS_{CaseName}.csv', sep=',')
|
|
2250
2495
|
|
|
2251
|
-
if len([(p,sc,n,ar,ec)
|
|
2252
|
-
sPSSTNAREC = [(p,sc,st,n,ar,ec) for p,sc,st,n,ar,ec in mTEPES.s2n*mTEPES.ar*mTEPES.ec if ec in g2a[ar] and mTEPES.pOperReserveDw[p,sc,n,ar] and (p,sc,n,ec) in mTEPES.psnec]
|
|
2496
|
+
if len([(p,sc,n,ar,ec) for p,sc, n,ar,ec in mTEPES.psn*mTEPES.ar*mTEPES.ec if ec in g2a[ar] and mTEPES.pOperReserveDw[p,sc,n,ar] and (p,sc,n,ec) in mTEPES.psnec and (p,ec) in mTEPES.pec]):
|
|
2497
|
+
sPSSTNAREC = [(p,sc,st,n,ar,ec) for p,sc,st,n,ar,ec in mTEPES.s2n*mTEPES.ar*mTEPES.ec if ec in g2a[ar] and mTEPES.pOperReserveDw[p,sc,n,ar] and (p,sc,n,ec) in mTEPES.psnec and (p,ec) in mTEPES.pec]
|
|
2253
2498
|
OutputResults = pd.Series(data=[mTEPES.pDuals["".join([f"eOperReserveDw_{p}_{sc}_{st}('{n}', '{ar}')"])]/mTEPES.pPeriodProb[p,sc]()*(OptModel.vReserveDown[p,sc,n,ec]()+OptModel.vESSReserveDown[p,sc,n,ec]()) for p,sc,st,n,ar,ec in sPSSTNAREC], index=pd.Index(sPSSTNAREC), dtype='float64')
|
|
2254
2499
|
if len(OutputResults):
|
|
2255
2500
|
OutputToDwRev = OutputResults.to_frame('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).sum(axis=0)
|
|
@@ -2263,6 +2508,60 @@ def EconomicResults(DirName, CaseName, OptModel, mTEPES, pIndAreaOutput, pIndPlo
|
|
|
2263
2508
|
else:
|
|
2264
2509
|
DwRev = pd.Series(data=[0.0 for gc in mTEPES.gc], index=mTEPES.gc, dtype='float64')
|
|
2265
2510
|
|
|
2511
|
+
if mTEPES.pIndRampReserves == 1 and sum(mTEPES.pRampReserveUp[:,:,:,:]):
|
|
2512
|
+
if len([(p,sc,n,nr) for p,sc, n,nr in mTEPES.psn*mTEPES.nr if sum(mTEPES.pRampReserveUp[p,sc,n,ar] for ar in mTEPES.ar) and (p,sc,n,nr) in mTEPES.psnnr and (p,nr) in mTEPES.pnr]):
|
|
2513
|
+
sPSSTNNR = [(p,sc,st,n,nr) for p,sc,st,n,nr in mTEPES.s2n*mTEPES.nr if sum(mTEPES.pRampReserveUp[p,sc,n,ar] for ar in mTEPES.ar) and (p,sc,n,nr) in mTEPES.psnnr and (p,nr) in mTEPES.pnr]
|
|
2514
|
+
OutputResults = pd.Series(data=[mTEPES.pDuals["".join([f"eSystemRampUp_{p}_{sc}_{st}{n}"])]/mTEPES.pPeriodProb[p,sc]()*OptModel.vRampReserveUp[p,sc,n,nr]() for p,sc,st,n,nr in sPSSTNNR], index=pd.Index(sPSSTNNR))
|
|
2515
|
+
OutputResults.to_frame(name='MEUR').reset_index().pivot_table(index=['level_0','level_1','level_3'], columns='level_4', values='MEUR').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_RevenueRampReserveUp_{CaseName}.csv', sep=',')
|
|
2516
|
+
|
|
2517
|
+
# if len([(p,sc,n,eh) for p,sc, n,eh in mTEPES.psn*mTEPES.eh if sum(mTEPES.pRampReserveUp[p,sc,n,ar] for ar in mTEPES.ar) and (p,sc,n,eh) in mTEPES.psnehc and (p,eh) in mTEPES.peh]):
|
|
2518
|
+
# sPSSTNES = [(p,sc,st,n,eh) for p,sc,st,n,eh in mTEPES.s2n*mTEPES.eh if sum(mTEPES.pRampReserveUp[p,sc,n,ar] for ar in mTEPES.ar) and (p,sc,n,eh) in mTEPES.psnehc and (p,eh) in mTEPES.peh]
|
|
2519
|
+
# OutputResults = pd.Series(data=[mTEPES.pDuals["".join([f"eSystemRampUp_{p}_{sc}_{st}{n}"])]/mTEPES.pPeriodProb[p,sc]()*OptModel.vRampReserveUp[p,sc,n,eh]() for p,sc,st,n,eh in sPSSTNES], index=pd.Index(sPSSTNES))
|
|
2520
|
+
# OutputResults.to_frame(name='MEUR').reset_index().pivot_table(index=['level_0','level_1','level_3'], columns='level_4', values='MEUR').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_RevenueRampReserveUpESS_{CaseName}.csv', sep=',')
|
|
2521
|
+
|
|
2522
|
+
if len([(p,sc,n,ec) for p,sc, n,ec in mTEPES.psn*mTEPES.gc if sum(mTEPES.pRampReserveUp[p,sc,n,ar] for ar in mTEPES.ar) and (p,sc,n,ec) in mTEPES.psnec and (p,ec) in mTEPES.pec]):
|
|
2523
|
+
sPSSTNEC = [(p,sc,st,n,ec) for p,sc,st,n,ec in mTEPES.s2n*mTEPES.ec if sum(mTEPES.pRampReserveUp[p,sc,n,ar] for ar in mTEPES.ar) and (p,sc,n,ec) in mTEPES.psnec and (p,ec) in mTEPES.pec]
|
|
2524
|
+
OutputResults = pd.Series(data=[mTEPES.pDuals["".join([f"eSystemRampUp_{p}_{sc}_{st}{n}"])]/mTEPES.pPeriodProb[p,sc]()*OptModel.vRampReserveUp[p,sc,n,ec]() for p,sc,st,n,ec in sPSSTNEC], index=pd.Index(sPSSTNEC), dtype='float64')
|
|
2525
|
+
if len(OutputResults):
|
|
2526
|
+
OutputToUpRev = OutputResults.to_frame('MEUR').reset_index().pivot_table(index=['level_0','level_1','level_3'], columns='level_4', values='MEUR').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).sum(axis=0)
|
|
2527
|
+
else:
|
|
2528
|
+
OutputToUpRev = pd.Series(data=[0.0 for gc in mTEPES.gc], index=mTEPES.gc, dtype='float64')
|
|
2529
|
+
RampUpRev = pd.Series(data=[0.0 for gc in mTEPES.gc], index=mTEPES.gc, dtype='float64')
|
|
2530
|
+
|
|
2531
|
+
for g in OutputToUpRev.index:
|
|
2532
|
+
RampUpRev[g] = OutputToUpRev[g]
|
|
2533
|
+
else:
|
|
2534
|
+
RampUpRev = pd.Series(data=[0.0 for gc in mTEPES.gc], index=mTEPES.gc, dtype='float64')
|
|
2535
|
+
else:
|
|
2536
|
+
RampUpRev = pd.Series(data=[0.0 for gc in mTEPES.gc], index=mTEPES.gc, dtype='float64')
|
|
2537
|
+
|
|
2538
|
+
if mTEPES.pIndRampReserves == 1 and sum(mTEPES.pRampReserveDw[:,:,:,:]):
|
|
2539
|
+
if len([(p,sc,n,nr) for p,sc, n,nr in mTEPES.psn*mTEPES.nr if sum(mTEPES.pRampReserveDw[p,sc,n,ar] for ar in mTEPES.ar) and (p,sc,n,nr) in mTEPES.psnnr and (p,nr) in mTEPES.pnr]):
|
|
2540
|
+
sPSSTNNR = [(p,sc,st,n,nr) for p,sc,st,n,nr in mTEPES.s2n*mTEPES.nr if sum(mTEPES.pRampReserveDw[p,sc,n,ar] for ar in mTEPES.ar) and (p,sc,n,nr) in mTEPES.psnnr and (p,nr) in mTEPES.pnr]
|
|
2541
|
+
OutputResults = pd.Series(data=[mTEPES.pDuals["".join([f"eSystemRampDw_{p}_{sc}_{st}{n}"])]/mTEPES.pPeriodProb[p,sc]()*OptModel.vRampReserveDw[p,sc,n,nr]() for p,sc,st,n,nr in sPSSTNNR], index=pd.Index(sPSSTNNR))
|
|
2542
|
+
OutputResults.to_frame(name='MEUR').reset_index().pivot_table(index=['level_0','level_1','level_3'], columns='level_4', values='MEUR').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_RevenueRampReserveDw_{CaseName}.csv', sep=',')
|
|
2543
|
+
|
|
2544
|
+
# if len([(p,sc,n,eh) for p,sc, n,eh in mTEPES.psn*mTEPES.eh if sum(mTEPES.pRampReserveDw[p,sc,n,ar] for ar in mTEPES.ar) and (p,sc,n,eh) in mTEPES.psnehc and (p,eh) in mTEPES.peh]):
|
|
2545
|
+
# sPSSTNES = [(p,sc,st,n,eh) for p,sc,st,n,eh in mTEPES.s2n*mTEPES.eh if sum(mTEPES.pRampReserveDw[p,sc,n,ar] for ar in mTEPES.ar) and (p,sc,n,eh) in mTEPES.psnehc and (p,eh) in mTEPES.peh]
|
|
2546
|
+
# OutputResults = pd.Series(data=[mTEPES.pDuals["".join([f"eSystemRampDw_{p}_{sc}_{st}{n}"])]/mTEPES.pPeriodProb[p,sc]()*OptModel.vRampReserveDw[p,sc,n,eh]() for p,sc,st,n,eh in sPSSTNES], index=pd.Index(sPSSTNES))
|
|
2547
|
+
# OutputResults.to_frame(name='MEUR').reset_index().pivot_table(index=['level_0','level_1','level_3'], columns='level_4', values='MEUR').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_RevenueRampReserveDwESS_{CaseName}.csv', sep=',')
|
|
2548
|
+
|
|
2549
|
+
if len([(p,sc,n,ec) for p,sc, n,ec in mTEPES.psn*mTEPES.gc if sum(mTEPES.pRampReserveDw[p,sc,n,ar] for ar in mTEPES.ar) and (p,sc,n,ec) in mTEPES.psnec and (p,ec) in mTEPES.pec]):
|
|
2550
|
+
sPSSTNEC = [(p,sc,st,n,ec) for p,sc,st,n,ec in mTEPES.s2n*mTEPES.ec if sum(mTEPES.pRampReserveDw[p,sc,n,ar] for ar in mTEPES.ar) and (p,sc,n,ec) in mTEPES.psnec and (p,ec) in mTEPES.pec]
|
|
2551
|
+
OutputResults = pd.Series(data=[mTEPES.pDuals["".join([f"eSystemRampDw_{p}_{sc}_{st}{n}"])]/mTEPES.pPeriodProb[p,sc]()*OptModel.vRampReserveUp[p,sc,n,ec]() for p,sc,st,n,ec in sPSSTNEC], index=pd.Index(sPSSTNEC), dtype='float64')
|
|
2552
|
+
if len(OutputResults):
|
|
2553
|
+
OutputToDwRev = OutputResults.to_frame('MEUR').reset_index().pivot_table(index=['level_0','level_1','level_3'], columns='level_4', values='MEUR').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).sum(axis=0)
|
|
2554
|
+
else:
|
|
2555
|
+
OutputToDwRev = pd.Series(data=[0.0 for gc in mTEPES.gc], index=mTEPES.gc, dtype='float64')
|
|
2556
|
+
RampDwRev = pd.Series(data=[0.0 for gc in mTEPES.gc], index=mTEPES.gc, dtype='float64')
|
|
2557
|
+
|
|
2558
|
+
for g in OutputToUpRev.index:
|
|
2559
|
+
RampDwRev[g] = OutputToDwRev[g]
|
|
2560
|
+
else:
|
|
2561
|
+
RampDwRev = pd.Series(data=[0.0 for gc in mTEPES.gc], index=mTEPES.gc, dtype='float64')
|
|
2562
|
+
else:
|
|
2563
|
+
RampDwRev = pd.Series(data=[0.0 for gc in mTEPES.gc], index=mTEPES.gc, dtype='float64')
|
|
2564
|
+
|
|
2266
2565
|
if mTEPES.gc:
|
|
2267
2566
|
GenCost = pd.Series(data=[sum(mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelDuration[p,sc,n]() * mTEPES.pLinearVarCost [p,sc,n,gc] * OptModel.vTotalOutput [p,sc,n,gc]() +
|
|
2268
2567
|
mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelDuration[p,sc,n]() * mTEPES.pConstantVarCost[p,sc,n,gc] * OptModel.vCommitment [p,sc,n,gc]() +
|
|
@@ -2282,14 +2581,15 @@ def EconomicResults(DirName, CaseName, OptModel, mTEPES, pIndAreaOutput, pIndPlo
|
|
|
2282
2581
|
OpCCost[gc] = 0.0 if gc not in OpCCost.index else OpCCost[gc]
|
|
2283
2582
|
|
|
2284
2583
|
InvCost = pd.Series(data=[sum(mTEPES.pDiscountedWeight[p] * mTEPES.pGenInvestCost[gc] * OptModel.vGenerationInvest[p,gc]() for p in mTEPES.p if (p,gc) in mTEPES.pgc) for gc in mTEPES.gc], index=mTEPES.gc, dtype='float64')
|
|
2285
|
-
Balance = pd.Series(data=[GenRev[gc]+ChargeRev[gc]+UpRev[gc]+DwRev[gc]+ResRev[gc]-GenCost[gc]-EmsCost[gc]-OpGCost[gc]-CnsCost[gc]-OpCCost[gc]-InvCost[gc] for gc in mTEPES.gc], index=mTEPES.gc, dtype='float64')
|
|
2286
|
-
CostRecovery = pd.concat([GenRev,ChargeRev,UpRev,DwRev,ResRev,-GenCost,-EmsCost,-OpGCost,-CnsCost,-OpCCost,-InvCost,Balance], axis=1, keys=['Revenue generation [MEUR]', 'Revenue consumption [MEUR]', 'Revenue operating reserve up [MEUR]', 'Revenue operating reserve down [MEUR]', 'Revenue reserve margin [MEUR]', 'Cost operation generation [MEUR]', 'Cost emission [MEUR]', 'Cost operating reserves generation [MEUR]', 'Cost operation consumption [MEUR]', 'Cost operating reserves consumption [MEUR]', 'Cost investment [MEUR]', ' Total [MEUR]'])
|
|
2584
|
+
Balance = pd.Series(data=[GenRev[gc]+ChargeRev[gc]+UpRev[gc]+DwRev[gc]+RampUpRev[gc]+RampDwRev[gc]+ResRev[gc]-GenCost[gc]-EmsCost[gc]-OpGCost[gc]-CnsCost[gc]-OpCCost[gc]-InvCost[gc] for gc in mTEPES.gc], index=mTEPES.gc, dtype='float64')
|
|
2585
|
+
CostRecovery = pd.concat([GenRev,ChargeRev,UpRev,DwRev,RampUpRev,RampDwRev,ResRev,-GenCost,-EmsCost,-OpGCost,-CnsCost,-OpCCost,-InvCost,Balance], axis=1, keys=['Revenue generation [MEUR]', 'Revenue consumption [MEUR]', 'Revenue operating reserve up [MEUR]', 'Revenue operating reserve down [MEUR]' 'Revenue ramp reserve up [MEUR]', 'Revenue ramp reserve down [MEUR]', 'Revenue reserve margin [MEUR]', 'Cost operation generation [MEUR]', 'Cost emission [MEUR]', 'Cost operating reserves generation [MEUR]', 'Cost operation consumption [MEUR]', 'Cost operating reserves consumption [MEUR]', 'Cost investment [MEUR]', ' Total [MEUR]'])
|
|
2287
2586
|
CostRecovery.stack().to_frame(name='MEUR').reset_index().pivot_table(values='MEUR', index=['level_1'], columns=['level_0']).rename_axis([None], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_CostRecovery_{CaseName}.csv', sep=',')
|
|
2288
2587
|
|
|
2289
2588
|
WritingResultsTime = time.time() - StartTime
|
|
2290
2589
|
print('Writing economic results ... ', round(WritingResultsTime), 's')
|
|
2291
2590
|
|
|
2292
2591
|
|
|
2592
|
+
# @profile
|
|
2293
2593
|
def NetworkMapResults(DirName, CaseName, OptModel, mTEPES):
|
|
2294
2594
|
# %% plotting the network in a map
|
|
2295
2595
|
_path = os.path.join(DirName, CaseName)
|