openTEPES 4.18.8__py3-none-any.whl → 4.18.10__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 -3
- openTEPES/openTEPES_InputData.py +10 -6
- openTEPES/openTEPES_Main.py +2 -2
- openTEPES/openTEPES_ModelFormulation.py +116 -91
- openTEPES/openTEPES_OutputResults.py +248 -79
- openTEPES/openTEPES_ProblemSolving.py +8 -8
- {opentepes-4.18.8.dist-info → opentepes-4.18.10.dist-info}/METADATA +16 -16
- {opentepes-4.18.8.dist-info → opentepes-4.18.10.dist-info}/RECORD +12 -12
- {opentepes-4.18.8.dist-info → opentepes-4.18.10.dist-info}/WHEEL +0 -0
- {opentepes-4.18.8.dist-info → opentepes-4.18.10.dist-info}/entry_points.txt +0 -0
- {opentepes-4.18.8.dist-info → opentepes-4.18.10.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"""
|
|
2
|
-
Open Generation, Storage, and Transmission Operation and Expansion Planning Model with RES and ESS (openTEPES) - January
|
|
2
|
+
Open Generation, Storage, and Transmission Operation and Expansion Planning Model with RES and ESS (openTEPES) - January 25, 2026
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
5
|
import time
|
|
@@ -14,6 +14,7 @@ import plotly.io as pio
|
|
|
14
14
|
import plotly.graph_objs as go
|
|
15
15
|
from collections import defaultdict
|
|
16
16
|
from colour import Color
|
|
17
|
+
import duckdb
|
|
17
18
|
|
|
18
19
|
# from line_profiler import profile
|
|
19
20
|
|
|
@@ -34,12 +35,12 @@ def PiePlots(period, scenario, df, Category, Value):
|
|
|
34
35
|
ComposedCategory = Category+':N'
|
|
35
36
|
ComposedValue = Value +':Q'
|
|
36
37
|
|
|
37
|
-
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)
|
|
38
39
|
pie = base.mark_arc(outerRadius=240)
|
|
39
40
|
text = base.mark_text(radius=340, size=15).encode(text='Label:N')
|
|
40
41
|
chart = pie+text
|
|
41
|
-
# chart = chart.resolve_scale(theta=
|
|
42
|
-
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')
|
|
43
44
|
|
|
44
45
|
return chart
|
|
45
46
|
|
|
@@ -103,6 +104,172 @@ def LinePlots(period, scenario, df, Category, X, Y, OperationType):
|
|
|
103
104
|
return plot
|
|
104
105
|
|
|
105
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
|
+
from pyomo.common.sorting import sorted_robust
|
|
186
|
+
|
|
187
|
+
if set_.is_indexed():
|
|
188
|
+
rows = []
|
|
189
|
+
for idx in sorted_robust(set_.keys()):
|
|
190
|
+
for m in set_[idx].sorted_data():
|
|
191
|
+
rows.append((idx, m))
|
|
192
|
+
df = pd.DataFrame(rows, columns=["index", "member"])
|
|
193
|
+
else:
|
|
194
|
+
df = pd.DataFrame({"member": list(set_.sorted_data())})
|
|
195
|
+
|
|
196
|
+
_set_df(con, f"s_{name}", df)
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
def _write_constraint_to_db(con, constraint, name, model):
|
|
200
|
+
"""
|
|
201
|
+
Write an indexed Pyomo Constraint's duals and bounds to DuckDB.
|
|
202
|
+
|
|
203
|
+
Parameters
|
|
204
|
+
----------
|
|
205
|
+
con : duckdb.DuckDBPyConnection
|
|
206
|
+
Open DuckDB connection.
|
|
207
|
+
constraint : pyomo.core.base.constraint.Constraint
|
|
208
|
+
Pyomo constraint component (must be indexed; scalar constraints are skipped).
|
|
209
|
+
name : str
|
|
210
|
+
Constraint name used to build the table name `c_{name}`.
|
|
211
|
+
model : pyomo.core.base.PyomoModel.ConcreteModel
|
|
212
|
+
Model providing `pDuals` (mapping from constraint+index string to dual value).
|
|
213
|
+
|
|
214
|
+
Notes
|
|
215
|
+
-----
|
|
216
|
+
Non-indexed constraints are ignored
|
|
217
|
+
"""
|
|
218
|
+
if not constraint.is_indexed():
|
|
219
|
+
return
|
|
220
|
+
|
|
221
|
+
records = []
|
|
222
|
+
for index in constraint:
|
|
223
|
+
key = str(constraint.name) + str(index)
|
|
224
|
+
records.append(
|
|
225
|
+
dict(
|
|
226
|
+
name=str(name),
|
|
227
|
+
index=index,
|
|
228
|
+
dual=model.pDuals.get(key),
|
|
229
|
+
lower_bound=constraint[index].lb,
|
|
230
|
+
upper_bound=constraint[index].ub,
|
|
231
|
+
)
|
|
232
|
+
)
|
|
233
|
+
|
|
234
|
+
df = pd.DataFrame(records)
|
|
235
|
+
_set_df(con, f'c_{name}', df.reset_index())
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
def write_model_to_db(model, filename):
|
|
239
|
+
"""
|
|
240
|
+
Export Pyomo model components to a DuckDB database file.
|
|
241
|
+
|
|
242
|
+
Parameters
|
|
243
|
+
----------
|
|
244
|
+
model : pyomo.core.base.PyomoModel.ConcreteModel
|
|
245
|
+
filename : str
|
|
246
|
+
"""
|
|
247
|
+
with duckdb.connect(filename) as con:
|
|
248
|
+
model_vars = model.component_map(ctype=pyo.Var)
|
|
249
|
+
for k in model_vars.keys():
|
|
250
|
+
var = model_vars[k]
|
|
251
|
+
name = var.getname()
|
|
252
|
+
_write_var_to_db(con, var, name)
|
|
253
|
+
|
|
254
|
+
model_params = model.component_map(ctype=pyo.Param)
|
|
255
|
+
for k in model_params.keys():
|
|
256
|
+
param = model_params[k]
|
|
257
|
+
name = param.getname()
|
|
258
|
+
_write_param_to_db(con, param, name)
|
|
259
|
+
|
|
260
|
+
model_sets = model.component_map(ctype=pyo.Set)
|
|
261
|
+
for k in model_sets.keys():
|
|
262
|
+
s = model_sets[k]
|
|
263
|
+
name = s.getname()
|
|
264
|
+
_write_set_to_db(con, s, name)
|
|
265
|
+
|
|
266
|
+
model_constraints = model.component_map(ctype=pyo.Constraint)
|
|
267
|
+
for k in model_constraints.keys():
|
|
268
|
+
constraint = model_constraints[k]
|
|
269
|
+
name = k
|
|
270
|
+
_write_constraint_to_db(con, constraint, name, model)
|
|
271
|
+
|
|
272
|
+
|
|
106
273
|
# write parameters, variables, and duals
|
|
107
274
|
# @profile
|
|
108
275
|
def OutputResultsParVarCon(DirName, CaseName, OptModel, mTEPES):
|
|
@@ -123,40 +290,42 @@ def OutputResultsParVarCon(DirName, CaseName, OptModel, mTEPES):
|
|
|
123
290
|
os.makedirs(dump_folder)
|
|
124
291
|
DateName = str(datetime.datetime.now().strftime('%Y%m%d'))
|
|
125
292
|
|
|
293
|
+
write_model_to_db(OptModel, f'{_path}/CaseDumpFolder_{CaseName}_{DateName}/oT_Case_{CaseName}.duckdb')
|
|
294
|
+
|
|
126
295
|
# Extract and write parameters from the case
|
|
127
|
-
with open(f'{_path}/CaseDumpFolder_{CaseName}_{DateName}/oT_Case_{CaseName}_Parameters.csv', 'w', newline='') as csvfile:
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
# Extract and write variables
|
|
142
|
-
with open(f'{_path}/CaseDumpFolder_{CaseName}_{DateName}/oT_Case_{CaseName}_Variables.csv', 'w', newline='') as csvfile:
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
# Extract and write dual variables
|
|
151
|
-
with open(f'{_path}/CaseDumpFolder_{CaseName}_{DateName}/oT_Case_{CaseName}_Constraints.csv', 'w', newline='') as csvfile:
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
296
|
+
# with open(f'{_path}/CaseDumpFolder_{CaseName}_{DateName}/oT_Case_{CaseName}_Parameters.csv', 'w', newline='') as csvfile:
|
|
297
|
+
# writer = csv.writer(csvfile)
|
|
298
|
+
# writer.writerow(['Name', 'Index', 'Value'])
|
|
299
|
+
# for par in OptModel.component_objects(pyo.Param):
|
|
300
|
+
# par_object = getattr(OptModel, str(par))
|
|
301
|
+
# if par_object.is_indexed():
|
|
302
|
+
# for index in par_object:
|
|
303
|
+
# if (isinstance(index, tuple) and par_object.mutable == False) or par_object.mutable == False:
|
|
304
|
+
# writer.writerow([str(par), index, par_object[index]])
|
|
305
|
+
# else:
|
|
306
|
+
# writer.writerow([str(par), index, par_object[index].value])
|
|
307
|
+
# else:
|
|
308
|
+
# writer.writerow ([str(par), 'NA', par_object.value])
|
|
309
|
+
#
|
|
310
|
+
# # Extract and write variables
|
|
311
|
+
# with open(f'{_path}/CaseDumpFolder_{CaseName}_{DateName}/oT_Case_{CaseName}_Variables.csv', 'w', newline='') as csvfile:
|
|
312
|
+
# writer = csv.writer(csvfile)
|
|
313
|
+
# writer.writerow(['Name', 'Index', 'Value', 'Lower Bound', 'Upper Bound'])
|
|
314
|
+
# for var in OptModel.component_objects(pyo.Var, active=True):
|
|
315
|
+
# var_object = getattr(OptModel, str(var))
|
|
316
|
+
# for index in var_object:
|
|
317
|
+
# writer.writerow([str(var), index, var_object[index].value, str(var_object[index].lb), str(var_object[index].ub)])
|
|
318
|
+
#
|
|
319
|
+
# # Extract and write dual variables
|
|
320
|
+
# with open(f'{_path}/CaseDumpFolder_{CaseName}_{DateName}/oT_Case_{CaseName}_Constraints.csv', 'w', newline='') as csvfile:
|
|
321
|
+
# writer = csv.writer(csvfile)
|
|
322
|
+
# writer.writerow(['Name', 'Index', 'Value', 'Lower Bound', 'Upper Bound'])
|
|
323
|
+
# for con in OptModel.component_objects(pyo.Constraint, active=True):
|
|
324
|
+
# con_object = getattr(OptModel, str(con))
|
|
325
|
+
# if con.is_indexed():
|
|
326
|
+
# for index in con_object:
|
|
327
|
+
# writer.writerow([str(con), index, mTEPES.pDuals[str(con_object.name)+str(index)], str(con_object[index].lb), str(con_object[index].ub)])
|
|
328
|
+
# # writer.writerow([str(con), index, OptModel.dual[con_object[index]], str(con_object[index].lb), str(con_object[index].ub)])
|
|
160
329
|
|
|
161
330
|
# NameList = ['Parameters', 'Variables', 'Constraints']
|
|
162
331
|
#
|
|
@@ -267,9 +436,9 @@ def InvestmentResults(DirName, CaseName, OptModel, mTEPES, pIndTechnologyOutput,
|
|
|
267
436
|
|
|
268
437
|
MarketResultsInv = pd.concat([MarketResultsInv, OutputResults], axis=1)
|
|
269
438
|
|
|
270
|
-
GenTechInvestCost = pd.Series(data=[sum(mTEPES.pDiscountedWeight[p] * mTEPES.pGenInvestCost[eb] * OptModel.vGenerationInvest[p,eb]() for eb in mTEPES.eb if eb in g2t[gt]
|
|
439
|
+
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)
|
|
271
440
|
GenTechInvestCost *= 1e3
|
|
272
|
-
GenTechInjection = pd.Series(data=[sum(mTEPES.pDiscountedWeight[p] * mTEPES.pLoadLevelDuration[p,sc,n]() * OptModel.vTotalOutput[p,sc,n,eb]() for sc,n,eb in mTEPES.sc*mTEPES.n*mTEPES.eb if eb in g2t[gt] and (p,sc,n) in mTEPES.
|
|
441
|
+
GenTechInjection = pd.Series(data=[sum(mTEPES.pDiscountedWeight[p] * mTEPES.pLoadLevelDuration[p,sc,n]() * OptModel.vTotalOutput[p,sc,n,eb]() for sc,n,eb in mTEPES.sc*mTEPES.n*mTEPES.eb if eb in g2t[gt] and (p,sc,n,eb) in mTEPES.psneb) for p,gt in mTEPES.p*mTEPES.gt], index=mTEPES.p*mTEPES.gt)
|
|
273
442
|
GenTechInjection.name = 'Generation'
|
|
274
443
|
MarketResultsInv = pd.concat([MarketResultsInv, GenTechInjection], axis=1)
|
|
275
444
|
LCOE = GenTechInvestCost.div(GenTechInjection)
|
|
@@ -887,7 +1056,7 @@ def ReservoirOperationResults(DirName, CaseName, OptModel, mTEPES, pIndTechnolog
|
|
|
887
1056
|
|
|
888
1057
|
#%% outputting the water volume values
|
|
889
1058
|
OutputResults = []
|
|
890
|
-
sPSSTNES = [(p,sc,st,n,rs) for p,sc,st,n,rs in mTEPES.
|
|
1059
|
+
sPSSTNES = [(p,sc,st,n,rs) for p,sc,st,n,rs in mTEPES.s2n*mTEPES.rs if (p,sc,n,rs) in mTEPES.psnrs]
|
|
891
1060
|
OutputToFile = pd.Series(data=[abs(mTEPES.pDuals["".join([f"eHydroInventory_{p}_{sc}_{st}('{n}', '{rs}')"])])*1e3 for p,sc,st,n,rs in sPSSTNES], index=pd.Index(sPSSTNES))
|
|
892
1061
|
if len(OutputToFile):
|
|
893
1062
|
OutputToFile.to_frame(name='WaterValue').reset_index().pivot_table(index=['level_0','level_1','level_3'], columns='level_4', values='WaterValue').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_MarginalWaterValue_{CaseName}.csv', sep=',')
|
|
@@ -1385,7 +1554,7 @@ def OperationSummaryResults(DirName, CaseName, OptModel, mTEPES):
|
|
|
1385
1554
|
NetInvCostVRESInsCap = 0.0
|
|
1386
1555
|
# Rate of return for VRE technologies
|
|
1387
1556
|
# warning division and multiplication
|
|
1388
|
-
VRETechRevenue = sum(mTEPES.pDuals["".join([f"eBalanceElec_{p}_{sc}_{st}('{n}', '{nd}')"])]/mTEPES.pPeriodProb[p,sc]()/mTEPES.pLoadLevelDuration[p,sc,n]()*OptModel.vTotalOutput[p,sc,n,gc]() for p,sc,st,n,nd,gc in mTEPES.s2n*mTEPES.nd*mTEPES.gc if gc in g2n[nd] and gc in mTEPES.re and (p,
|
|
1557
|
+
VRETechRevenue = sum(mTEPES.pDuals["".join([f"eBalanceElec_{p}_{sc}_{st}('{n}', '{nd}')"])]/mTEPES.pPeriodProb[p,sc]()/mTEPES.pLoadLevelDuration[p,sc,n]()*OptModel.vTotalOutput[p,sc,n,gc]() for p,sc,st,n,nd,gc in mTEPES.s2n*mTEPES.nd*mTEPES.gc if gc in g2n[nd] and gc in mTEPES.re and (p,sc,n,gc) in mTEPES.psngc and sum(1 for g in g2n[nd]) + sum(1 for nf,cc in lout[nd]) + sum(1 for ni,cc in lin[nd]))
|
|
1389
1558
|
VREInvCostCapacity = sum(mTEPES.pDiscountedWeight[p]*mTEPES.pGenInvestCost[gc]*OptModel.vGenerationInvest[p,gc]() for p,gc in mTEPES.pgc if gc in mTEPES.re)
|
|
1390
1559
|
|
|
1391
1560
|
K1 = pd.Series(data={'Ratio Fossil Fuel Generation/Total Generation [%]' : FossilFuelGeneration / TotalGeneration *1e2}).to_frame(name='Value')
|
|
@@ -1709,7 +1878,7 @@ def MarginalResults(DirName, CaseName, OptModel, mTEPES, pIndPlotOutput):
|
|
|
1709
1878
|
OutputToFile.rename_axis(['Period', 'Scenario', 'LoadLevel', 'Area'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_MarginalIncrementalVariableCost_{CaseName}.csv', sep=',')
|
|
1710
1879
|
IncrementalGens = pd.Series('N/A', index=mTEPES.psnar).to_frame(name='Generator')
|
|
1711
1880
|
for p,sc,n,ar in mTEPES.psnar:
|
|
1712
|
-
if all(g not in mTEPES.eh and g not in mTEPES.bo and (p, g) in mTEPES.pg and (ar,
|
|
1881
|
+
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):
|
|
1713
1882
|
if len(OutputToFile.loc[(p,sc,n,ar)]) > 1:
|
|
1714
1883
|
IncrementalGens.loc[p,sc,n,ar] = OutputToFile.loc[[(p,sc,n,ar)]].squeeze().idxmin()
|
|
1715
1884
|
else:
|
|
@@ -1830,7 +1999,7 @@ def MarginalResults(DirName, CaseName, OptModel, mTEPES, pIndPlotOutput):
|
|
|
1830
1999
|
#%% outputting the water values
|
|
1831
2000
|
if mTEPES.es:
|
|
1832
2001
|
OutputResults = []
|
|
1833
|
-
sPSSTNES = [(p,sc,st,n,es) for p,sc,st,n,es in mTEPES.
|
|
2002
|
+
sPSSTNES = [(p,sc,st,n,es) for p,sc,st,n,es in mTEPES.s2n*mTEPES.es if (p,sc,n,es) in mTEPES.psnes and (mTEPES.pTotalMaxCharge[es] or mTEPES.pTotalEnergyInflows[es])]
|
|
1834
2003
|
OutputToFile = pd.Series(data=[abs(mTEPES.pDuals["".join([f"eESSInventory_{p}_{sc}_{st}('{n}', '{es}')"])])*1e3 for p,sc,st,n,es in sPSSTNES], index=pd.Index(sPSSTNES))
|
|
1835
2004
|
if len(OutputToFile):
|
|
1836
2005
|
OutputToFile.to_frame(name='WaterValue').reset_index().pivot_table(index=['level_0','level_1','level_3'], columns='level_4', values='WaterValue').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_MarginalEnergyValue_{CaseName}.csv', sep=',')
|
|
@@ -2131,29 +2300,29 @@ def EconomicResults(DirName, CaseName, OptModel, mTEPES, pIndAreaOutput, pIndPlo
|
|
|
2131
2300
|
OutputToFile = pd.Series(data=[(mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelDuration[p,sc,n]() * mTEPES.pLinearVarCost [p,sc,n,nr] * OptModel.vTotalOutput[p,sc,n,nr]() +
|
|
2132
2301
|
mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelDuration[p,sc,n]() * mTEPES.pConstantVarCost[p,sc,n,nr] * OptModel.vCommitment [p,sc,n,nr]() +
|
|
2133
2302
|
mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelWeight [p,sc,n]() * mTEPES.pStartUpCost [ nr] * OptModel.vStartUp [p,sc,n,nr]() +
|
|
2134
|
-
mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelWeight [p,sc,n]() * mTEPES.pShutDownCost [ nr] * OptModel.vShutDown [p,sc,n,nr]()) for p,sc,n,nr in mTEPES.psnnr
|
|
2303
|
+
mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelWeight [p,sc,n]() * mTEPES.pShutDownCost [ nr] * OptModel.vShutDown [p,sc,n,nr]()) for p,sc,n,nr in mTEPES.psnnr], index=mTEPES.psnnr)
|
|
2135
2304
|
if mTEPES.psnnr:
|
|
2136
2305
|
OutputToFile.to_frame(name='MEUR').reset_index().pivot_table(index=['level_0','level_1','level_2'], columns='level_3', values='MEUR', aggfunc='sum').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_GenerationCostOperation_{CaseName}.csv', sep=',')
|
|
2137
2306
|
|
|
2138
2307
|
if mTEPES.re:
|
|
2139
|
-
OutputToFile = pd.Series(data=[mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelDuration[p,sc,n]() * mTEPES.pLinearOMCost [re] * OptModel.vTotalOutput [p,sc,n,re]() for p,sc,n,re in mTEPES.psnre
|
|
2308
|
+
OutputToFile = pd.Series(data=[mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelDuration[p,sc,n]() * mTEPES.pLinearOMCost [re] * OptModel.vTotalOutput [p,sc,n,re]() for p,sc,n,re in mTEPES.psnre], index=mTEPES.psnre)
|
|
2140
2309
|
OutputToFile.to_frame(name='MEUR').reset_index().pivot_table(index=['level_0','level_1','level_2'], columns='level_3', values='MEUR', aggfunc='sum').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_GenerationCostOandM_{CaseName}.csv', sep=',')
|
|
2141
2310
|
|
|
2142
2311
|
if mTEPES.nr:
|
|
2143
2312
|
if sum(mTEPES.pOperReserveUp[:,:,:,:]) + sum(mTEPES.pOperReserveDw[:,:,:,:]):
|
|
2144
2313
|
OutputToFile = pd.Series(data=[(mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelWeight[p,sc,n]() * mTEPES.pOperReserveCost[nr] * OptModel.vReserveUp [p,sc,n,nr]() +
|
|
2145
|
-
mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelWeight[p,sc,n]() * mTEPES.pOperReserveCost[nr] * OptModel.vReserveDown[p,sc,n,nr]()) for p,sc,n,nr in mTEPES.psnnr
|
|
2314
|
+
mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelWeight[p,sc,n]() * mTEPES.pOperReserveCost[nr] * OptModel.vReserveDown[p,sc,n,nr]()) for p,sc,n,nr in mTEPES.psnnr], index=mTEPES.psnnr)
|
|
2146
2315
|
OutputToFile.to_frame(name='MEUR').reset_index().pivot_table(index=['level_0','level_1','level_2'], columns='level_3', values='MEUR', aggfunc='sum').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_GenerationCostOperatingReserve_{CaseName}.csv', sep=',')
|
|
2147
2316
|
|
|
2148
2317
|
if mTEPES.psnehc:
|
|
2149
|
-
OutputToFile = pd.Series(data=[ mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelDuration[p,sc,n]() * mTEPES.pLinearVarCost[p,sc,n,eh] * OptModel.vESSTotalCharge[p,sc,n,eh]() for p,sc,n,eh in mTEPES.psnehc
|
|
2318
|
+
OutputToFile = pd.Series(data=[ mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelDuration[p,sc,n]() * mTEPES.pLinearVarCost[p,sc,n,eh] * OptModel.vESSTotalCharge[p,sc,n,eh]() for p,sc,n,eh in mTEPES.psnehc], index=mTEPES.psnehc)
|
|
2150
2319
|
OutputToFile.to_frame(name='MEUR').reset_index().pivot_table(index=['level_0','level_1','level_2'], columns='level_3', values='MEUR', aggfunc='sum').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_ConsumptionCostOperation_{CaseName}.csv', sep=',')
|
|
2151
2320
|
if sum(mTEPES.pIndOperReserveGen[eh] for eh in mTEPES.eh if mTEPES.pIndOperReserveGen[eh] == 0) + sum(mTEPES.pIndOperReserveCon[eh] for eh in mTEPES.eh if mTEPES.pIndOperReserveCon[eh] == 0):
|
|
2152
2321
|
OutputToFile = pd.Series(data=[(mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelWeight[p,sc,n]() * mTEPES.pOperReserveCost[eh] * OptModel.vESSReserveUp [p,sc,n,eh]() +
|
|
2153
|
-
mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelWeight[p,sc,n]() * mTEPES.pOperReserveCost[eh] * OptModel.vESSReserveDown[p,sc,n,eh]()) for p,sc,n,eh in mTEPES.psnehc
|
|
2322
|
+
mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelWeight[p,sc,n]() * mTEPES.pOperReserveCost[eh] * OptModel.vESSReserveDown[p,sc,n,eh]()) for p,sc,n,eh in mTEPES.psnehc], index=mTEPES.psnehc)
|
|
2154
2323
|
OutputToFile.to_frame(name='MEUR').reset_index().pivot_table(index=['level_0','level_1','level_2'], columns='level_3', values='MEUR', aggfunc='sum').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_ConsumptionCostOperatingReserve_{CaseName}.csv', sep=',')
|
|
2155
2324
|
|
|
2156
|
-
OutputToFile = pd.Series(data=[mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelDuration[p,sc,n]() * mTEPES.pEmissionVarCost[p,sc,n,g] * OptModel.vTotalOutput[p,sc,n,g]() for p,sc,n,g in mTEPES.psng
|
|
2325
|
+
OutputToFile = pd.Series(data=[mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelDuration[p,sc,n]() * mTEPES.pEmissionVarCost[p,sc,n,g] * OptModel.vTotalOutput[p,sc,n,g]() for p,sc,n,g in mTEPES.psng], index=mTEPES.psng)
|
|
2157
2326
|
OutputToFile.to_frame(name='MEUR').reset_index().pivot_table(index=['level_0','level_1','level_2'], columns='level_3', values='MEUR', aggfunc='sum').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_GenerationCostEmission_{CaseName}.csv', sep=',')
|
|
2158
2327
|
|
|
2159
2328
|
OutputToFile = pd.Series(data=[mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelDuration[p,sc,n]() * mTEPES.pENSCost() * OptModel.vENS [p,sc,n,nd]() for p,sc,n,nd in mTEPES.psnnd], index=mTEPES.psnnd)
|
|
@@ -2178,35 +2347,35 @@ def EconomicResults(DirName, CaseName, OptModel, mTEPES, pIndAreaOutput, pIndPlo
|
|
|
2178
2347
|
OutputResults7 = pd.DataFrame(data={'MEUR': [0.0]}, index=pd.Index([(p,sc,'Reliability Cost' ) for p,sc in mTEPES.ps]))
|
|
2179
2348
|
|
|
2180
2349
|
if mTEPES.nr:
|
|
2181
|
-
sPSNNR = [(p,sc,n,nr) for p,sc,n,nr in mTEPES.psnnr if nr in n2a[ar]
|
|
2350
|
+
sPSNNR = [(p,sc,n,nr) for p,sc,n,nr in mTEPES.psnnr if nr in n2a[ar]]
|
|
2182
2351
|
if sPSNNR:
|
|
2183
2352
|
OutputResults1 = pd.Series(data=[(mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelDuration[p,sc,n]() * mTEPES.pLinearVarCost [p,sc,n,nr] * OptModel.vTotalOutput[p,sc,n,nr]() +
|
|
2184
2353
|
mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelDuration[p,sc,n]() * mTEPES.pConstantVarCost[p,sc,n,nr] * OptModel.vCommitment [p,sc,n,nr]() +
|
|
2185
2354
|
mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelWeight [p,sc,n]() * mTEPES.pStartUpCost [ nr] * OptModel.vStartUp [p,sc,n,nr]() +
|
|
2186
2355
|
mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelWeight [p,sc,n]() * mTEPES.pShutDownCost [ nr] * OptModel.vShutDown [p,sc,n,nr]()) for p,sc,n,nr in sPSNNR], index=pd.Index(sPSNNR))
|
|
2187
2356
|
OutputResults1 = Transformation1(OutputResults1, 'Operation Cost Generation')
|
|
2188
|
-
sPSNNR = [(p,sc,n,nr) for p,sc,n,nr in mTEPES.psnnr if nr in n2a[ar]
|
|
2357
|
+
sPSNNR = [(p,sc,n,nr) for p,sc,n,nr in mTEPES.psnnr if nr in n2a[ar]]
|
|
2189
2358
|
if sum(mTEPES.pOperReserveUp[:,:,:,:]) + sum(mTEPES.pOperReserveDw[:,:,:,:]):
|
|
2190
2359
|
OutputResults2 = pd.Series(data=[(mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelWeight [p,sc,n]() * mTEPES.pOperReserveCost[ nr] * OptModel.vReserveUp [p,sc,n,nr]() +
|
|
2191
2360
|
mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelWeight [p,sc,n]() * mTEPES.pOperReserveCost[ nr] * OptModel.vReserveDown[p,sc,n,nr]()) for p,sc,n,nr in sPSNNR], index=pd.Index(sPSNNR))
|
|
2192
2361
|
OutputResults2 = Transformation1(OutputResults2, 'Operating Reserve Cost Generation')
|
|
2193
2362
|
|
|
2194
2363
|
if mTEPES.g :
|
|
2195
|
-
sPSNG = [(p,sc,n,g ) for p,sc,n,g in mTEPES.psng if g in g2a[ar]
|
|
2364
|
+
sPSNG = [(p,sc,n,g ) for p,sc,n,g in mTEPES.psng if g in g2a[ar]]
|
|
2196
2365
|
if sPSNG:
|
|
2197
2366
|
if sum(mTEPES.pEmissionVarCost[:,:,:,:]):
|
|
2198
2367
|
OutputResults6 = pd.Series(data=[ mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelDuration[p,sc,n]() * mTEPES.pEmissionVarCost[p,sc,n,g ] * OptModel.vTotalOutput[p,sc,n,g ]() for p,sc,n,g in sPSNG], index=pd.Index(sPSNG))
|
|
2199
2368
|
OutputResults6 = Transformation1(OutputResults6, 'Emission Cost')
|
|
2200
2369
|
|
|
2201
2370
|
if mTEPES.re:
|
|
2202
|
-
sPSNRE = [(p,sc,n,re) for p,sc,n,re in mTEPES.psnre if re in g2a[ar]
|
|
2371
|
+
sPSNRE = [(p,sc,n,re) for p,sc,n,re in mTEPES.psnre if re in g2a[ar]]
|
|
2203
2372
|
if sPSNRE:
|
|
2204
2373
|
if sum(mTEPES.pLinearOMCost[:]):
|
|
2205
2374
|
OutputResults3 = pd.Series(data=[mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelDuration[p,sc,n]() * mTEPES.pLinearOMCost [re] * OptModel.vTotalOutput [p,sc,n,re]() for p,sc,n,re in sPSNRE], index=pd.Index(sPSNRE))
|
|
2206
2375
|
OutputResults3 = Transformation1(OutputResults3, 'O&M Cost Generation')
|
|
2207
2376
|
|
|
2208
2377
|
if mTEPES.eh:
|
|
2209
|
-
sPSNES = [(p,sc,n,eh) for p,sc,n,eh in mTEPES.psnehc if eh in g2a[ar]
|
|
2378
|
+
sPSNES = [(p,sc,n,eh) for p,sc,n,eh in mTEPES.psnehc if eh in g2a[ar]]
|
|
2210
2379
|
if sPSNES:
|
|
2211
2380
|
if sum(mTEPES.pLinearVarCost [:,:,:,:]):
|
|
2212
2381
|
OutputResults4 = pd.Series(data=[ mTEPES.pDiscountedWeight[p] * mTEPES.pScenProb[p,sc]() * mTEPES.pLoadLevelDuration[p,sc,n]() * mTEPES.pLinearVarCost [p,sc,n,eh] * OptModel.vESSTotalCharge[p,sc,n,eh]() for p,sc,n,eh in sPSNES], index=pd.Index(sPSNES))
|
|
@@ -2227,9 +2396,9 @@ def EconomicResults(DirName, CaseName, OptModel, mTEPES, pIndAreaOutput, pIndPlo
|
|
|
2227
2396
|
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]()
|
|
2228
2397
|
OutputResults.to_csv(f'{_path}/oT_Result_CostSummary_{CaseName}_{ar}.csv', sep=',', index=False)
|
|
2229
2398
|
|
|
2230
|
-
sPSSTNG = [(p,sc,st,n, g) for p,sc,st,n, g in mTEPES.s2n*mTEPES.g if (p,sc,n) in mTEPES.
|
|
2399
|
+
sPSSTNG = [(p,sc,st,n, g) for p,sc,st,n, g in mTEPES.s2n*mTEPES.g if (p,sc,n,g) in mTEPES.psng]
|
|
2231
2400
|
sPSSTNND = [(p,sc,st,n,nd ) for p,sc,st,n,nd in mTEPES.s2n*mTEPES.nd if sum(1 for g in g2n[nd]) + sum(1 for nf,cc in lout[nd]) + sum(1 for ni,cc in lin[nd]) and (p,sc,n) in mTEPES.psn]
|
|
2232
|
-
sPSSTNNDG = [(p,sc,st,n,nd,g) for p,sc,st,n,nd,g in sPSSTNND*mTEPES.g
|
|
2401
|
+
sPSSTNNDG = [(p,sc,st,n,nd,g) for p,sc,st,n,nd,g in sPSSTNND*mTEPES.g if (p,sc,n,g) in mTEPES.psng and (nd,g) in mTEPES.n2g]
|
|
2233
2402
|
OutputResults = pd.Series(data=[ mTEPES.pDuals["".join([f"eBalanceElec_{p}_{sc}_{st}('{n}', '{nd}')"])]/mTEPES.pPeriodProb[p,sc]()/mTEPES.pLoadLevelDuration[p,sc,n]()*OptModel.vTotalOutput [p,sc,n,g]() for p,sc,st,n,nd,g in sPSSTNNDG], index=pd.Index(sPSSTNNDG))
|
|
2234
2403
|
MeanOutput = pd.Series(data=[ OptModel.vTotalOutput [p,sc,n,g]() for p,sc,st,n, g in sPSSTNG ], index=pd.Index(sPSSTNG )).groupby(level=4).mean()
|
|
2235
2404
|
MeanOutput *= 1e-3
|
|
@@ -2238,8 +2407,8 @@ def EconomicResults(DirName, CaseName, OptModel, mTEPES, pIndAreaOutput, pIndPlo
|
|
|
2238
2407
|
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=',')
|
|
2239
2408
|
|
|
2240
2409
|
if mTEPES.eh:
|
|
2241
|
-
sPSSTNES = [(p,sc,st,n, eh) for p,sc,st,n, eh in mTEPES.s2n*mTEPES.eh if (p,sc,n) in mTEPES.
|
|
2242
|
-
sPSSTNNDEH = [(p,sc,st,n,nd,eh) for p,sc,st,n,nd,eh in sPSSTNND*mTEPES.eh
|
|
2410
|
+
sPSSTNES = [(p,sc,st,n, eh) for p,sc,st,n, eh in mTEPES.s2n*mTEPES.eh if (p,sc,n,eh) in mTEPES.psneh]
|
|
2411
|
+
sPSSTNNDEH = [(p,sc,st,n,nd,eh) for p,sc,st,n,nd,eh in sPSSTNND*mTEPES.eh if (p,sc,n,eh) in mTEPES.psneh and (nd,eh) in mTEPES.n2g]
|
|
2243
2412
|
OutputResults = pd.Series(data=[-mTEPES.pDuals["".join([f"eBalanceElec_{p}_{sc}_{st}('{n}', '{nd}')"])]/mTEPES.pPeriodProb[p,sc]()/mTEPES.pLoadLevelDuration[p,sc,n]()*OptModel.vESSTotalCharge[p,sc,n,eh]() for p,sc,st,n,nd,eh in sPSSTNNDEH], index=pd.Index(sPSSTNNDEH))
|
|
2244
2413
|
MeanOutput = pd.Series(data=[ OptModel.vESSTotalCharge[p,sc,n,eh]() for p,sc,st,n, eh in sPSSTNES ], index=pd.Index(sPSSTNES )).groupby(level=4).mean()
|
|
2245
2414
|
MeanOutput *= 1e-3
|
|
@@ -2250,19 +2419,19 @@ def EconomicResults(DirName, CaseName, OptModel, mTEPES, pIndAreaOutput, pIndPlo
|
|
|
2250
2419
|
if mTEPES.gc:
|
|
2251
2420
|
GenRev = []
|
|
2252
2421
|
ChargeRev = []
|
|
2253
|
-
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,
|
|
2422
|
+
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,sc,n,gc) in mTEPES.psngc]
|
|
2254
2423
|
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))
|
|
2255
2424
|
GenRev.append(OutputToGenRev)
|
|
2256
|
-
if len([(p,sc,n,nd,gc)
|
|
2257
|
-
sPSSTNNDGC2 = [(p,sc,st,n,nd,gc) for p,sc,st,n,nd,gc in sPSSTNNDGC1
|
|
2425
|
+
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,gc) in mTEPES.psngc and gc in o2e[ot]]):
|
|
2426
|
+
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,gc) in mTEPES.psngc and gc in o2e[ot]]
|
|
2258
2427
|
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))
|
|
2259
2428
|
ChargeRev.append(OutputChargeRevESS)
|
|
2260
|
-
if len([(p,sc,n,nd,gc)
|
|
2261
|
-
sPSSTNNDGC3 = [(p,sc,st,n,nd,gc) for p,sc,st,n,nd,gc in sPSSTNNDGC1
|
|
2429
|
+
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,gc) in mTEPES.psngc and gc in r2r[rt]]):
|
|
2430
|
+
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,gc) in mTEPES.psngc and gc in r2r[rt]]
|
|
2262
2431
|
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))
|
|
2263
2432
|
ChargeRev.append(OutputChargeRevRES)
|
|
2264
|
-
if len([(p,sc,n,nd,gc)
|
|
2265
|
-
sPSSTNNDGC4 = [(p,sc,st,n,nd,gc) for p,sc,st,n,nd,gc in sPSSTNNDGC1
|
|
2433
|
+
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,gc) in mTEPES.psngc and gc in o2e[ot]]):
|
|
2434
|
+
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,gc) in mTEPES.psngc and gc in o2e[ot]]
|
|
2266
2435
|
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))
|
|
2267
2436
|
ChargeRev.append(OutputChargeRevThr)
|
|
2268
2437
|
if len(GenRev):
|
|
@@ -2284,7 +2453,7 @@ def EconomicResults(DirName, CaseName, OptModel, mTEPES, pIndAreaOutput, pIndPlo
|
|
|
2284
2453
|
|
|
2285
2454
|
if sum(mTEPES.pReserveMargin[:,:]):
|
|
2286
2455
|
if mTEPES.gc:
|
|
2287
|
-
sPSSTARGC = [(p,sc,st,ar,gc) for p,sc,st,ar,gc in mTEPES.ps*mTEPES.st*mTEPES.ar*mTEPES.gc if gc in g2a[ar] and mTEPES.pReserveMargin[p,ar] and st == mTEPES.Last_st and sum(1 for gc in mTEPES.gc if gc in g2a[ar]) and sum(mTEPES.pRatedMaxPowerElec[g] * mTEPES.pAvailability[g]() / (1.0-mTEPES.pEFOR[g]) for g in mTEPES.g if g in g2a[ar] and g not in (mTEPES.gc or mTEPES.gd)) <= mTEPES.pDemandElecPeak[p,ar] * mTEPES.pReserveMargin[p,ar]]
|
|
2456
|
+
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]]
|
|
2288
2457
|
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))
|
|
2289
2458
|
ResRev = pd.Series(data=[0.0 for gc in mTEPES.gc], index=mTEPES.gc, dtype='float64')
|
|
2290
2459
|
if sPSSTARGC:
|
|
@@ -2296,17 +2465,17 @@ def EconomicResults(DirName, CaseName, OptModel, mTEPES, pIndAreaOutput, pIndPlo
|
|
|
2296
2465
|
ResRev = pd.Series(data=[0.0 for gc in mTEPES.gc], index=mTEPES.gc, dtype='float64')
|
|
2297
2466
|
|
|
2298
2467
|
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)):
|
|
2299
|
-
if len([(p,sc,n,ar,nr)
|
|
2468
|
+
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]):
|
|
2300
2469
|
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]
|
|
2301
2470
|
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))
|
|
2302
2471
|
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=',')
|
|
2303
2472
|
|
|
2304
|
-
if len([(p,sc,n,ar,eh)
|
|
2473
|
+
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]):
|
|
2305
2474
|
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]
|
|
2306
2475
|
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))
|
|
2307
2476
|
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=',')
|
|
2308
2477
|
|
|
2309
|
-
if len([(p,sc,n,ar,ec)
|
|
2478
|
+
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]):
|
|
2310
2479
|
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]
|
|
2311
2480
|
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')
|
|
2312
2481
|
if len(OutputResults):
|
|
@@ -2323,17 +2492,17 @@ def EconomicResults(DirName, CaseName, OptModel, mTEPES, pIndAreaOutput, pIndPlo
|
|
|
2323
2492
|
UpRev = pd.Series(data=[0.0 for gc in mTEPES.gc], index=mTEPES.gc, dtype='float64')
|
|
2324
2493
|
|
|
2325
2494
|
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 )):
|
|
2326
|
-
if len([(p,sc,n,ar,nr)
|
|
2495
|
+
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]):
|
|
2327
2496
|
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]
|
|
2328
2497
|
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))
|
|
2329
2498
|
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=',')
|
|
2330
2499
|
|
|
2331
|
-
if len([(p,sc,n,ar,eh)
|
|
2500
|
+
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]):
|
|
2332
2501
|
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]
|
|
2333
2502
|
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))
|
|
2334
2503
|
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=',')
|
|
2335
2504
|
|
|
2336
|
-
if len([(p,sc,n,ar,ec)
|
|
2505
|
+
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]):
|
|
2337
2506
|
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]
|
|
2338
2507
|
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')
|
|
2339
2508
|
if len(OutputResults):
|
|
@@ -2349,17 +2518,17 @@ def EconomicResults(DirName, CaseName, OptModel, mTEPES, pIndAreaOutput, pIndPlo
|
|
|
2349
2518
|
DwRev = pd.Series(data=[0.0 for gc in mTEPES.gc], index=mTEPES.gc, dtype='float64')
|
|
2350
2519
|
|
|
2351
2520
|
if mTEPES.pIndRampReserves == 1 and sum(mTEPES.pRampReserveUp[:,:,:,:]):
|
|
2352
|
-
if len([(p,sc,n,nr)
|
|
2353
|
-
sPSSTNNR = [(p,sc,st,n,nr) for p,sc,st,n,nr in mTEPES.s2n*mTEPES.nr if sum(mTEPES.pRampReserveUp[p,sc,n,ar] for ar in mTEPES.ar) and (p,sc,n,nr) in mTEPES.
|
|
2521
|
+
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.psnnrr]):
|
|
2522
|
+
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.psnnrr]
|
|
2354
2523
|
OutputResults = pd.Series(data=[mTEPES.pDuals["".join([f"eSystemRampUp_{p}_{sc}_{st}{n}"])]/mTEPES.pPeriodProb[p,sc]()*OptModel.vRampReserveUp[p,sc,n,nr]() for p,sc,st,n,nr in sPSSTNNR], index=pd.Index(sPSSTNNR))
|
|
2355
2524
|
OutputResults.to_frame(name='MEUR').reset_index().pivot_table(index=['level_0','level_1','level_3'], columns='level_4', values='MEUR').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_RevenueRampReserveUp_{CaseName}.csv', sep=',')
|
|
2356
2525
|
|
|
2357
|
-
# if len([(p,sc,n,eh)
|
|
2526
|
+
# if len([(p,sc,n,eh) for p,sc, n,eh in mTEPES.psn*mTEPES.eh if sum(mTEPES.pRampReserveUp[p,sc,n,ar] for ar in mTEPES.ar) and (p,sc,n,eh) in mTEPES.psnehc]):
|
|
2358
2527
|
# sPSSTNES = [(p,sc,st,n,eh) for p,sc,st,n,eh in mTEPES.s2n*mTEPES.eh if sum(mTEPES.pRampReserveUp[p,sc,n,ar] for ar in mTEPES.ar) and (p,sc,n,eh) in mTEPES.psnehc]
|
|
2359
2528
|
# OutputResults = pd.Series(data=[mTEPES.pDuals["".join([f"eSystemRampUp_{p}_{sc}_{st}{n}"])]/mTEPES.pPeriodProb[p,sc]()*OptModel.vRampReserveUp[p,sc,n,eh]() for p,sc,st,n,eh in sPSSTNES], index=pd.Index(sPSSTNES))
|
|
2360
2529
|
# OutputResults.to_frame(name='MEUR').reset_index().pivot_table(index=['level_0','level_1','level_3'], columns='level_4', values='MEUR').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_RevenueRampReserveUpESS_{CaseName}.csv', sep=',')
|
|
2361
2530
|
|
|
2362
|
-
if len([(p,sc,n,ec)
|
|
2531
|
+
if len([(p,sc,n,ec) for p,sc, n,ec in mTEPES.psn*mTEPES.gc if sum(mTEPES.pRampReserveUp[p,sc,n,ar] for ar in mTEPES.ar) and (p,sc,n,ec) in mTEPES.psnec]):
|
|
2363
2532
|
sPSSTNEC = [(p,sc,st,n,ec) for p,sc,st,n,ec in mTEPES.s2n*mTEPES.ec if sum(mTEPES.pRampReserveUp[p,sc,n,ar] for ar in mTEPES.ar) and (p,sc,n,ec) in mTEPES.psnec]
|
|
2364
2533
|
OutputResults = pd.Series(data=[mTEPES.pDuals["".join([f"eSystemRampUp_{p}_{sc}_{st}{n}"])]/mTEPES.pPeriodProb[p,sc]()*OptModel.vRampReserveUp[p,sc,n,ec]() for p,sc,st,n,ec in sPSSTNEC], index=pd.Index(sPSSTNEC), dtype='float64')
|
|
2365
2534
|
if len(OutputResults):
|
|
@@ -2376,17 +2545,17 @@ def EconomicResults(DirName, CaseName, OptModel, mTEPES, pIndAreaOutput, pIndPlo
|
|
|
2376
2545
|
RampUpRev = pd.Series(data=[0.0 for gc in mTEPES.gc], index=mTEPES.gc, dtype='float64')
|
|
2377
2546
|
|
|
2378
2547
|
if mTEPES.pIndRampReserves == 1 and sum(mTEPES.pRampReserveDw[:,:,:,:]):
|
|
2379
|
-
if len([(p,sc,n,nr)
|
|
2548
|
+
if len([(p,sc,n,nr) for p,sc, n,nr in mTEPES.psn*mTEPES.nr if sum(mTEPES.pRampReserveDw[p,sc,n,ar] for ar in mTEPES.ar) and (p,sc,n,nr) in mTEPES.psnnr]):
|
|
2380
2549
|
sPSSTNNR = [(p,sc,st,n,nr) for p,sc,st,n,nr in mTEPES.s2n*mTEPES.nr if sum(mTEPES.pRampReserveDw[p,sc,n,ar] for ar in mTEPES.ar) and (p,sc,n,nr) in mTEPES.psnnr]
|
|
2381
2550
|
OutputResults = pd.Series(data=[mTEPES.pDuals["".join([f"eSystemRampDw_{p}_{sc}_{st}{n}"])]/mTEPES.pPeriodProb[p,sc]()*OptModel.vRampReserveDw[p,sc,n,nr]() for p,sc,st,n,nr in sPSSTNNR], index=pd.Index(sPSSTNNR))
|
|
2382
2551
|
OutputResults.to_frame(name='MEUR').reset_index().pivot_table(index=['level_0','level_1','level_3'], columns='level_4', values='MEUR').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_RevenueRampReserveDw_{CaseName}.csv', sep=',')
|
|
2383
2552
|
|
|
2384
|
-
# if len([(p,sc,n,eh)
|
|
2553
|
+
# if len([(p,sc,n,eh) for p,sc, n,eh in mTEPES.psn*mTEPES.eh if sum(mTEPES.pRampReserveDw[p,sc,n,ar] for ar in mTEPES.ar) and (p,sc,n,eh) in mTEPES.psnehc]):
|
|
2385
2554
|
# sPSSTNES = [(p,sc,st,n,eh) for p,sc,st,n,eh in mTEPES.s2n*mTEPES.eh if sum(mTEPES.pRampReserveDw[p,sc,n,ar] for ar in mTEPES.ar) and (p,sc,n,eh) in mTEPES.psnehc]
|
|
2386
2555
|
# OutputResults = pd.Series(data=[mTEPES.pDuals["".join([f"eSystemRampDw_{p}_{sc}_{st}{n}"])]/mTEPES.pPeriodProb[p,sc]()*OptModel.vRampReserveDw[p,sc,n,eh]() for p,sc,st,n,eh in sPSSTNES], index=pd.Index(sPSSTNES))
|
|
2387
2556
|
# OutputResults.to_frame(name='MEUR').reset_index().pivot_table(index=['level_0','level_1','level_3'], columns='level_4', values='MEUR').rename_axis(['Period', 'Scenario', 'LoadLevel'], axis=0).rename_axis([None], axis=1).to_csv(f'{_path}/oT_Result_RevenueRampReserveDwESS_{CaseName}.csv', sep=',')
|
|
2388
2557
|
|
|
2389
|
-
if len([(p,sc,n,ec)
|
|
2558
|
+
if len([(p,sc,n,ec) for p,sc, n,ec in mTEPES.psn*mTEPES.gc if sum(mTEPES.pRampReserveDw[p,sc,n,ar] for ar in mTEPES.ar) and (p,sc,n,ec) in mTEPES.psnec]):
|
|
2390
2559
|
sPSSTNEC = [(p,sc,st,n,ec) for p,sc,st,n,ec in mTEPES.s2n*mTEPES.ec if sum(mTEPES.pRampReserveDw[p,sc,n,ar] for ar in mTEPES.ar) and (p,sc,n,ec) in mTEPES.psnec]
|
|
2391
2560
|
OutputResults = pd.Series(data=[mTEPES.pDuals["".join([f"eSystemRampDw_{p}_{sc}_{st}{n}"])]/mTEPES.pPeriodProb[p,sc]()*OptModel.vRampReserveUp[p,sc,n,ec]() for p,sc,st,n,ec in sPSSTNEC], index=pd.Index(sPSSTNEC), dtype='float64')
|
|
2392
2561
|
if len(OutputResults):
|