openTEPES 4.18.5__py3-none-any.whl → 4.18.6__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- openTEPES/RTS-GMLC/oT_Data_VariableMinGeneration_RTS-GMLC.csv +1 -1
- openTEPES/RTS-GMLC_6y/oT_Data_VariableFuelCost_RTS-GMLC_6y.csv +1 -1
- openTEPES/__init__.py +1 -1
- openTEPES/openTEPES.py +8 -5
- openTEPES/openTEPES_InputData.py +1120 -1142
- openTEPES/openTEPES_Main.py +3 -3
- openTEPES/openTEPES_ModelFormulation.py +5 -5
- openTEPES/openTEPES_OutputResults.py +54 -59
- openTEPES/openTEPES_ProblemSolving.py +6 -1
- openTEPES/sSEP/oT_Data_DemandHydrogen_sSEP.csv +8736 -8736
- openTEPES/sSEP/oT_Data_Generation_sSEP.csv +1 -1
- openTEPES/sSEP/oT_Data_HydroOutflows_sSEP.csv +1 -1
- {openTEPES-4.18.5.dist-info → opentepes-4.18.6.dist-info}/METADATA +54 -34
- {openTEPES-4.18.5.dist-info → opentepes-4.18.6.dist-info}/RECORD +17 -17
- {openTEPES-4.18.5.dist-info → opentepes-4.18.6.dist-info}/WHEEL +1 -1
- {openTEPES-4.18.5.dist-info → opentepes-4.18.6.dist-info}/entry_points.txt +0 -0
- {openTEPES-4.18.5.dist-info → opentepes-4.18.6.dist-info/licenses}/LICENSE +0 -0
openTEPES/openTEPES_InputData.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"""
|
|
2
|
-
Open Generation, Storage, and Transmission Operation and Expansion Planning Model with RES and ESS (openTEPES) -
|
|
2
|
+
Open Generation, Storage, and Transmission Operation and Expansion Planning Model with RES and ESS (openTEPES) - September 17, 2025
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
5
|
import datetime
|
|
@@ -9,6 +9,7 @@ import os
|
|
|
9
9
|
import pandas as pd
|
|
10
10
|
from collections import defaultdict
|
|
11
11
|
from pyomo.environ import DataPortal, Set, Param, Var, Binary, NonNegativeReals, NonNegativeIntegers, PositiveReals, PositiveIntegers, Reals, UnitInterval, Any
|
|
12
|
+
from pyomo.environ import Block, Boolean
|
|
12
13
|
|
|
13
14
|
def InputData(DirName, CaseName, mTEPES, pIndLogConsole):
|
|
14
15
|
print('Input data ****')
|
|
@@ -16,246 +17,164 @@ def InputData(DirName, CaseName, mTEPES, pIndLogConsole):
|
|
|
16
17
|
_path = os.path.join(DirName, CaseName)
|
|
17
18
|
StartTime = time.time()
|
|
18
19
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
dfEmission = pd.read_csv(f'{_path}/oT_Data_Emission_' f'{CaseName}.csv', header=0, index_col=[0,1 ])
|
|
28
|
-
dfRESEnergy = pd.read_csv(f'{_path}/oT_Data_RESEnergy_' f'{CaseName}.csv', header=0, index_col=[0,1 ])
|
|
29
|
-
dfDemand = pd.read_csv(f'{_path}/oT_Data_Demand_' f'{CaseName}.csv', header=0, index_col=[0,1,2])
|
|
30
|
-
dfInertia = pd.read_csv(f'{_path}/oT_Data_Inertia_' f'{CaseName}.csv', header=0, index_col=[0,1,2])
|
|
31
|
-
dfUpOperatingReserve = pd.read_csv(f'{_path}/oT_Data_OperatingReserveUp_' f'{CaseName}.csv', header=0, index_col=[0,1,2])
|
|
32
|
-
dfDwOperatingReserve = pd.read_csv(f'{_path}/oT_Data_OperatingReserveDown_' f'{CaseName}.csv', header=0, index_col=[0,1,2])
|
|
33
|
-
dfGeneration = pd.read_csv(f'{_path}/oT_Data_Generation_' f'{CaseName}.csv', header=0, index_col=[0 ])
|
|
34
|
-
dfVariableMinPower = pd.read_csv(f'{_path}/oT_Data_VariableMinGeneration_' f'{CaseName}.csv', header=0, index_col=[0,1,2])
|
|
35
|
-
dfVariableMaxPower = pd.read_csv(f'{_path}/oT_Data_VariableMaxGeneration_' f'{CaseName}.csv', header=0, index_col=[0,1,2])
|
|
36
|
-
dfVariableMinCharge = pd.read_csv(f'{_path}/oT_Data_VariableMinConsumption_'f'{CaseName}.csv', header=0, index_col=[0,1,2])
|
|
37
|
-
dfVariableMaxCharge = pd.read_csv(f'{_path}/oT_Data_VariableMaxConsumption_'f'{CaseName}.csv', header=0, index_col=[0,1,2])
|
|
38
|
-
dfVariableMinStorage = pd.read_csv(f'{_path}/oT_Data_VariableMinStorage_' f'{CaseName}.csv', header=0, index_col=[0,1,2])
|
|
39
|
-
dfVariableMaxStorage = pd.read_csv(f'{_path}/oT_Data_VariableMaxStorage_' f'{CaseName}.csv', header=0, index_col=[0,1,2])
|
|
40
|
-
dfVariableMinEnergy = pd.read_csv(f'{_path}/oT_Data_VariableMinEnergy_' f'{CaseName}.csv', header=0, index_col=[0,1,2])
|
|
41
|
-
dfVariableMaxEnergy = pd.read_csv(f'{_path}/oT_Data_VariableMaxEnergy_' f'{CaseName}.csv', header=0, index_col=[0,1,2])
|
|
42
|
-
dfVariableFuelCost = pd.read_csv(f'{_path}/oT_Data_VariableFuelCost_' f'{CaseName}.csv', header=0, index_col=[0,1,2])
|
|
43
|
-
dfVariableEmissionCost = pd.read_csv(f'{_path}/oT_Data_VariableEmissionCost_' f'{CaseName}.csv', header=0, index_col=[0,1,2])
|
|
44
|
-
dfEnergyInflows = pd.read_csv(f'{_path}/oT_Data_EnergyInflows_' f'{CaseName}.csv', header=0, index_col=[0,1,2])
|
|
45
|
-
dfEnergyOutflows = pd.read_csv(f'{_path}/oT_Data_EnergyOutflows_' f'{CaseName}.csv', header=0, index_col=[0,1,2])
|
|
46
|
-
dfNodeLocation = pd.read_csv(f'{_path}/oT_Data_NodeLocation_' f'{CaseName}.csv', header=0, index_col=[0 ])
|
|
47
|
-
dfNetwork = pd.read_csv(f'{_path}/oT_Data_Network_' f'{CaseName}.csv', header=0, index_col=[0,1,2])
|
|
20
|
+
set_definitions = {
|
|
21
|
+
'pp': ('Period', 'p' ), 'scc': ('Scenario', 'sc'), 'stt': ('Stage', 'st'),
|
|
22
|
+
'nn': ('LoadLevel', 'n' ), 'gg': ('Generation','g'), 'gt': ('Technology', 'gt'),
|
|
23
|
+
'nd': ('Node', 'nd'), 'ni': ('Node', 'nd'), 'nf': ('Node', 'nd'),
|
|
24
|
+
'zn': ('Zone', 'zn'), 'ar': ('Area', 'ar'), 'rg': ('Region', 'rg'),
|
|
25
|
+
'cc': ('Circuit', 'cc'), 'c2': ('Circuit', 'cc'), 'lt': ('Line', 'lt'),
|
|
26
|
+
'ndzn': ('NodeToZone', 'ndzn'), 'znar': ('ZoneToArea', 'znar'), 'arrg': ('AreaToRegion', 'arrg'),
|
|
27
|
+
}
|
|
48
28
|
|
|
49
|
-
|
|
50
|
-
dfVariableTTCFrw = pd.read_csv(f'{_path}/oT_Data_VariableTTCFrw_' f'{CaseName}.csv', header=[0,1,2 ], index_col=[0,1,2])
|
|
51
|
-
dfVariableTTCBck = pd.read_csv(f'{_path}/oT_Data_VariableTTCBck_' f'{CaseName}.csv', header=[0,1,2 ], index_col=[0,1,2])
|
|
52
|
-
pIndVarTTC = 1
|
|
53
|
-
except:
|
|
54
|
-
pIndVarTTC = 0
|
|
55
|
-
print('**** No variable transmission line TTCs')
|
|
56
|
-
try:
|
|
57
|
-
dfVariablePTDF = pd.read_csv(f'{_path}/oT_Data_VariablePTDF_' f'{CaseName}.csv', header=[0,1,2,3], index_col=[0,1,2])
|
|
58
|
-
pIndPTDF = 1
|
|
59
|
-
except:
|
|
60
|
-
pIndPTDF = 0
|
|
61
|
-
print('**** No flow-based market coupling method')
|
|
62
|
-
|
|
63
|
-
try:
|
|
64
|
-
dfReservoir = pd.read_csv(f'{_path}/oT_Data_Reservoir_' f'{CaseName}.csv', header=0, index_col=[0 ])
|
|
65
|
-
dfVariableMinVolume = pd.read_csv(f'{_path}/oT_Data_VariableMinVolume_' f'{CaseName}.csv', header=0, index_col=[0,1,2])
|
|
66
|
-
dfVariableMaxVolume = pd.read_csv(f'{_path}/oT_Data_VariableMaxVolume_' f'{CaseName}.csv', header=0, index_col=[0,1,2])
|
|
67
|
-
dfHydroInflows = pd.read_csv(f'{_path}/oT_Data_HydroInflows_' f'{CaseName}.csv', header=0, index_col=[0,1,2])
|
|
68
|
-
dfHydroOutflows = pd.read_csv(f'{_path}/oT_Data_HydroOutflows_' f'{CaseName}.csv', header=0, index_col=[0,1,2])
|
|
69
|
-
pIndHydroTopology = 1
|
|
70
|
-
except:
|
|
71
|
-
pIndHydroTopology = 0
|
|
72
|
-
print('**** No hydropower topology')
|
|
29
|
+
dictSets = DataPortal()
|
|
73
30
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
31
|
+
# Reading dictionaries from CSV and adding elements to the dictSets
|
|
32
|
+
for set_name, (file_set_name, set_key) in set_definitions.items():
|
|
33
|
+
filename = f'oT_Dict_{file_set_name}_{CaseName}.csv'
|
|
34
|
+
dictSets.load(filename=os.path.join(_path, filename), set=set_key, format='set')
|
|
35
|
+
is_ordered = set_name not in {'gt', 'nd', 'ni', 'nf', 'cc', 'c2', 'ndzn', 'znar', 'arrg'}
|
|
36
|
+
setattr(mTEPES, set_name, Set(initialize=dictSets[set_key], ordered=is_ordered, doc=f'{file_set_name}'))
|
|
37
|
+
|
|
38
|
+
# # Defining sets in the model
|
|
39
|
+
# for set_name, (file_set_name, set_key) in set_definitions.items():
|
|
40
|
+
# is_ordered = set_name not in {'stt', 'gt', 'nd', 'ni', 'nf', 'cc', 'c2', 'ndzn', 'znar', 'arrg'}
|
|
41
|
+
# setattr(model, set_name, Set(initialize=dictSets[set_key], ordered=is_ordered, doc=f'{file_set_name}'))
|
|
42
|
+
|
|
43
|
+
# Constants
|
|
44
|
+
DEFAULT_IDX_COLS = ['Period', 'Scenario', 'LoadLevel', 'Area', 'Generator', 'InitialNode', 'FinalNode', 'Circuit', 'Node', 'Stage']
|
|
45
|
+
SPECIAL_IDX_COLS = {'Generation': ['Generator'], 'Reservoir': ['Reservoir']}
|
|
46
|
+
HEADER_LEVELS = {
|
|
47
|
+
'VariableTTCFrw': [0, 1, 2 ],
|
|
48
|
+
'VariableTTCBck': [0, 1, 2 ],
|
|
49
|
+
'VariablePTDF' : [0, 1, 2, 3],
|
|
50
|
+
}
|
|
51
|
+
FLAG_MAPPING = {
|
|
52
|
+
'VariableTTCFrw' : ('pIndVarTTC' , None, 'No variable transmission line TTCs' ),
|
|
53
|
+
'VariableTTCBck' : ('pIndVarTTC' , None, 'No variable transmission line TTCs' ),
|
|
54
|
+
'VariablePTDF' : ('pIndPTDF' , None, 'No flow-based market coupling method'),
|
|
55
|
+
'Reservoir' : ('pIndHydroTopology', None, 'No hydropower topology' ),
|
|
56
|
+
'VariableMinVolume': ('pIndHydroTopology', None, 'No hydropower topology' ),
|
|
57
|
+
'VariableMaxVolume': ('pIndHydroTopology', None, 'No hydropower topology' ),
|
|
58
|
+
'HydroInflows' : ('pIndHydroTopology', None, 'No hydropower topology' ),
|
|
59
|
+
'HydroOutflows' : ('pIndHydroTopology', None, 'No hydropower topology' ),
|
|
60
|
+
'DemandHydrogen' : ('pIndHydrogen' , None, 'No hydrogen energy carrier' ),
|
|
61
|
+
'NetworkHydrogen' : ('pIndHydrogen' , None, 'No hydrogen energy carrier' ),
|
|
62
|
+
'DemandHeat' : ('pIndHeat' , None, 'No heat energy carrier' ),
|
|
63
|
+
'ReserveMarginHeat': ('pIndHeat' , None, 'No heat energy carrier' ),
|
|
64
|
+
'NetworkHeat' : ('pIndHeat' , None, 'No heat energy carrier' ),
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
factor_1 = 1e-3
|
|
68
|
+
factor_2 = 1e-6
|
|
69
|
+
|
|
70
|
+
def load_csv_with_index(path, file_name, idx_cols, header_levels=None):
|
|
71
|
+
"""
|
|
72
|
+
Load a CSV file into a DataFrame and set its index based on provided columns.
|
|
73
|
+
"""
|
|
74
|
+
full_path = os.path.join(path, file_name)
|
|
75
|
+
if header_levels:
|
|
76
|
+
df = pd.read_csv(full_path, header=header_levels, index_col=[0, 1, 2])
|
|
77
|
+
else:
|
|
78
|
+
df = pd.read_csv(full_path)
|
|
79
|
+
|
|
80
|
+
present_idx = [col for col in df.columns if col in idx_cols]
|
|
81
|
+
file_key = file_name.split('_')[2]
|
|
82
|
+
idx_to_set = SPECIAL_IDX_COLS.get(file_key, present_idx)
|
|
83
|
+
if file_key == 'Duration':
|
|
84
|
+
idx_to_set = idx_to_set[:-1] # Exclude 'Stage' for Duration
|
|
85
|
+
df.set_index(idx_to_set, inplace=True, drop=True)
|
|
86
|
+
return df
|
|
81
87
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
88
|
+
def read_input_data(path, case_name):
|
|
89
|
+
"""
|
|
90
|
+
Read all oT_Data files from the given directory, returning
|
|
91
|
+
a dict of DataFrames and a dict of flags for loaded data.
|
|
92
|
+
"""
|
|
93
|
+
dfs = {}
|
|
94
|
+
par = {}
|
|
95
|
+
|
|
96
|
+
# Identify unique file types
|
|
97
|
+
files = [f for f in os.listdir(path) if 'oT_Data' in f]
|
|
98
|
+
file_sets = set(f.split('_')[2] for f in files)
|
|
99
|
+
|
|
100
|
+
for fs in file_sets:
|
|
101
|
+
file_name = f'oT_Data_{fs}_{case_name}.csv'
|
|
102
|
+
dp_key, _, error_msg = FLAG_MAPPING.get(fs, (None, None, None))
|
|
103
|
+
header = HEADER_LEVELS.get(fs)
|
|
104
|
+
|
|
105
|
+
try:
|
|
106
|
+
if fs in ('Option', 'Parameter'):
|
|
107
|
+
dfs[f'df{fs}'] = pd.read_csv(os.path.join(path, file_name))
|
|
108
|
+
else:
|
|
109
|
+
dfs[f'df{fs}'] = load_csv_with_index(path, file_name, DEFAULT_IDX_COLS, header)
|
|
110
|
+
|
|
111
|
+
if dp_key:
|
|
112
|
+
par[dp_key] = 1
|
|
113
|
+
except FileNotFoundError:
|
|
114
|
+
print(f'WARNING: File not found: {file_name}')
|
|
115
|
+
if dp_key:
|
|
116
|
+
par[dp_key] = 0
|
|
117
|
+
except Exception as e:
|
|
118
|
+
print(f'No file {file_name}')
|
|
119
|
+
if dp_key:
|
|
120
|
+
par[dp_key] = 0
|
|
121
|
+
|
|
122
|
+
return dfs, par
|
|
123
|
+
|
|
124
|
+
dfs, par = read_input_data(_path, CaseName)
|
|
125
|
+
# if 'pIndVarTTC', 'pIndPTDF', 'pIndHydroTopology', 'pIndHydrogen', 'pIndHeat' not in par include them and set value to zero
|
|
126
|
+
for key in ['pIndVarTTC', 'pIndPTDF', 'pIndHydroTopology', 'pIndHydrogen', 'pIndHeat']:
|
|
127
|
+
if key not in par.keys():
|
|
128
|
+
par[key] = 0
|
|
90
129
|
|
|
91
130
|
# substitute NaN by 0
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
if pIndHydroTopology == 1:
|
|
129
|
-
dfReservoir.fillna (0.0, inplace=True)
|
|
130
|
-
dfVariableMinVolume.fillna(0.0, inplace=True)
|
|
131
|
-
dfVariableMaxVolume.fillna(0.0, inplace=True)
|
|
132
|
-
dfHydroInflows.fillna (0.0, inplace=True)
|
|
133
|
-
dfHydroOutflows.fillna (0.0, inplace=True)
|
|
134
|
-
|
|
135
|
-
if pIndHydrogen == 1:
|
|
136
|
-
dfDemandHydrogen.fillna (0.0, inplace=True)
|
|
137
|
-
dfNetworkHydrogen.fillna (0.0, inplace=True)
|
|
138
|
-
|
|
139
|
-
if pIndHeat == 1:
|
|
140
|
-
dfDemandHeat.fillna (0.0, inplace=True)
|
|
141
|
-
dfReserveMarginHeat.fillna(0.0, inplace=True)
|
|
142
|
-
dfNetworkHeat.fillna (0.0, inplace=True)
|
|
143
|
-
|
|
144
|
-
dfReserveMargin = dfReserveMargin.where (dfReserveMargin > 0.0, 0.0)
|
|
145
|
-
dfEmission = dfEmission.where (dfEmission > 0.0, 0.0)
|
|
146
|
-
dfRESEnergy = dfRESEnergy.where (dfRESEnergy > 0.0, 0.0)
|
|
147
|
-
dfInertia = dfInertia.where (dfInertia > 0.0, 0.0)
|
|
148
|
-
dfUpOperatingReserve = dfUpOperatingReserve.where (dfUpOperatingReserve > 0.0, 0.0)
|
|
149
|
-
dfDwOperatingReserve = dfDwOperatingReserve.where (dfDwOperatingReserve > 0.0, 0.0)
|
|
150
|
-
dfVariableMinPower = dfVariableMinPower.where (dfVariableMinPower > 0.0, 0.0)
|
|
151
|
-
dfVariableMaxPower = dfVariableMaxPower.where (dfVariableMaxPower > 0.0, 0.0)
|
|
152
|
-
dfVariableMinCharge = dfVariableMinCharge.where (dfVariableMinCharge > 0.0, 0.0)
|
|
153
|
-
dfVariableMaxCharge = dfVariableMaxCharge.where (dfVariableMaxCharge > 0.0, 0.0)
|
|
154
|
-
dfVariableMinStorage = dfVariableMinStorage.where (dfVariableMinStorage > 0.0, 0.0)
|
|
155
|
-
dfVariableMaxStorage = dfVariableMaxStorage.where (dfVariableMaxStorage > 0.0, 0.0)
|
|
156
|
-
dfVariableMinEnergy = dfVariableMinEnergy.where (dfVariableMinEnergy > 0.0, 0.0)
|
|
157
|
-
dfVariableMaxEnergy = dfVariableMaxEnergy.where (dfVariableMaxEnergy > 0.0, 0.0)
|
|
158
|
-
dfVariableFuelCost = dfVariableFuelCost.where (dfVariableFuelCost > 0.0, 0.0)
|
|
159
|
-
dfVariableEmissionCost = dfVariableEmissionCost.where(dfVariableEmissionCost > 0.0, 0.0)
|
|
160
|
-
dfEnergyInflows = dfEnergyInflows.where (dfEnergyInflows > 0.0, 0.0)
|
|
161
|
-
dfEnergyOutflows = dfEnergyOutflows.where (dfEnergyOutflows > 0.0, 0.0)
|
|
162
|
-
|
|
163
|
-
if (dfGeneration["Efficiency"] == 0).any():
|
|
164
|
-
print("WARNING: Efficiency values of 0.0 are not valid. They have been changed to 1.0.")
|
|
165
|
-
print("If you want to disable charging, set 'MaximumCharge' to 0.0 or leave it empty.")
|
|
166
|
-
dfGeneration["Efficiency"] = dfGeneration["Efficiency"].where(dfGeneration["Efficiency"] != 0.0, 1.0)
|
|
131
|
+
for key, df in dfs.items():
|
|
132
|
+
if 'dfEmission' in key:
|
|
133
|
+
df.fillna(math.inf, inplace=True)
|
|
134
|
+
elif 'dfGeneration' in key:
|
|
135
|
+
# build a dict that gives 1.0 for 'Efficiency', 0.0 for everything else
|
|
136
|
+
fill_values = {col: (1.0 if col == 'Efficiency' else 0.0) for col in df.columns}
|
|
137
|
+
# one pass over the DataFrame
|
|
138
|
+
df.fillna(fill_values, inplace=True)
|
|
139
|
+
else:
|
|
140
|
+
df.fillna(0.0, inplace=True)
|
|
141
|
+
|
|
142
|
+
# Define prefixes and suffixes
|
|
143
|
+
mTEPES.gen_frames_suffixes = ['VariableMinGeneration', 'VariableMaxGeneration',
|
|
144
|
+
'VariableMinConsumption', 'VariableMaxConsumption',
|
|
145
|
+
'VariableMinStorage', 'VariableMaxStorage',
|
|
146
|
+
'EnergyInflows',
|
|
147
|
+
'EnergyOutflows',
|
|
148
|
+
'VariableMinEnergy', 'VariableMaxEnergy',
|
|
149
|
+
'VariableFuelCost',
|
|
150
|
+
'VariableEmissionCost',]
|
|
151
|
+
mTEPES.node_frames_suffixes = ['Demand', 'Inertia']
|
|
152
|
+
mTEPES.area_frames_suffixes = ['OperatingReserveUp', 'OperatingReserveDown', 'ReserveMargin', 'Emission', 'RESEnergy']
|
|
153
|
+
mTEPES.hydro_frames_suffixes = ['Reservoir', 'VariableMinVolume', 'VariableMaxVolume', 'HydroInflows', 'HydroOutflows']
|
|
154
|
+
mTEPES.hydrogen_frames_suffixes = ['DemandHydrogen']
|
|
155
|
+
mTEPES.heat_frames_suffixes = ['DemandHeat', 'ReserveMarginHeat']
|
|
156
|
+
mTEPES.frames_suffixes = (mTEPES.gen_frames_suffixes + mTEPES.node_frames_suffixes + mTEPES.area_frames_suffixes +
|
|
157
|
+
mTEPES.hydro_frames_suffixes+ mTEPES.hydrogen_frames_suffixes + mTEPES.heat_frames_suffixes)
|
|
158
|
+
|
|
159
|
+
# Apply the condition to each specified column
|
|
160
|
+
for keys, df in dfs.items():
|
|
161
|
+
if [1 for suffix in mTEPES.gen_frames_suffixes if suffix in keys]:
|
|
162
|
+
dfs[keys] = df.where(df > 0.0, 0.0)
|
|
163
|
+
|
|
164
|
+
reading_time = round(time.time() - StartTime)
|
|
165
|
+
print('Reading the CSV files ... {} s'.format(reading_time))
|
|
166
|
+
StartTime = time.time()
|
|
167
167
|
|
|
168
|
-
if
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
dfHydroOutflows = dfHydroOutflows.where (dfHydroOutflows > 0.0, 0.0)
|
|
168
|
+
if (dfs['dfGeneration']['Efficiency'] == 0).any():
|
|
169
|
+
print('WARNING: Efficiency values of 0.0 are not valid. They have been changed to 1.0.')
|
|
170
|
+
print("If you want to disable charging, set 'MaximumCharge' to 0.0 or leave it empty.")
|
|
171
|
+
dfs['dfGeneration']['Efficiency'] = dfs['dfGeneration']['Efficiency'].where(dfs['dfGeneration']['Efficiency'] != 0.0, 1.0)
|
|
173
172
|
|
|
174
173
|
# show some statistics of the data
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
print('Electricity demand \n', dfDemand.describe (), '\n')
|
|
180
|
-
print('Inertia \n', dfInertia.describe (), '\n')
|
|
181
|
-
print('Upward operating reserves \n', dfUpOperatingReserve.describe (), '\n')
|
|
182
|
-
print('Downward operating reserves \n', dfDwOperatingReserve.describe (), '\n')
|
|
183
|
-
print('Generation \n', dfGeneration.describe (), '\n')
|
|
184
|
-
print('Variable minimum generation \n', dfVariableMinPower.describe (), '\n')
|
|
185
|
-
print('Variable maximum generation \n', dfVariableMaxPower.describe (), '\n')
|
|
186
|
-
print('Variable minimum consumption \n', dfVariableMinCharge.describe (), '\n')
|
|
187
|
-
print('Variable maximum consumption \n', dfVariableMaxCharge.describe (), '\n')
|
|
188
|
-
print('Variable minimum storage \n', dfVariableMinStorage.describe (), '\n')
|
|
189
|
-
print('Variable maximum storage \n', dfVariableMaxStorage.describe (), '\n')
|
|
190
|
-
print('Variable minimum energy \n', dfVariableMinEnergy.describe (), '\n')
|
|
191
|
-
print('Variable maximum energy \n', dfVariableMaxEnergy.describe (), '\n')
|
|
192
|
-
print('Variable fuel cost \n', dfVariableFuelCost.describe (), '\n')
|
|
193
|
-
print('Variable emission cost \n', dfVariableEmissionCost.describe(), '\n')
|
|
194
|
-
print('Energy inflows \n', dfEnergyInflows.describe (), '\n')
|
|
195
|
-
print('Energy outflows \n', dfEnergyOutflows.describe (), '\n')
|
|
196
|
-
print('Electric network \n', dfNetwork.describe (), '\n')
|
|
197
|
-
|
|
198
|
-
if pIndVarTTC == 1:
|
|
199
|
-
print('Variable TTC forward \n', dfVariableTTCFrw.describe (), '\n')
|
|
200
|
-
print('Variable TTC backward \n', dfVariableTTCBck.describe (), '\n')
|
|
201
|
-
if pIndPTDF == 1:
|
|
202
|
-
print('Variable PTDF \n', dfVariablePTDF.describe (), '\n')
|
|
203
|
-
|
|
204
|
-
if pIndHydroTopology == 1:
|
|
205
|
-
print('Reservoir \n', dfReservoir.describe (), '\n')
|
|
206
|
-
print('Variable minimum reservoir volume \n', dfVariableMinVolume.describe (), '\n')
|
|
207
|
-
print('Variable maximum reservoir volume \n', dfVariableMaxVolume.describe (), '\n')
|
|
208
|
-
print('Hydro inflows \n', dfHydroInflows.describe (), '\n')
|
|
209
|
-
print('Hydro outflows \n', dfHydroOutflows.describe (), '\n')
|
|
210
|
-
|
|
211
|
-
if pIndHydrogen == 1:
|
|
212
|
-
print('Hydrogen demand \n', dfDemandHydrogen.describe (), '\n')
|
|
213
|
-
print('Hydrogen pipeline network \n', dfNetworkHydrogen.describe (), '\n')
|
|
214
|
-
|
|
215
|
-
if pIndHeat == 1:
|
|
216
|
-
print('Heat demand \n', dfDemandHeat.describe (), '\n')
|
|
217
|
-
print('Reserve margin heat \n', dfReserveMarginHeat.describe (), '\n')
|
|
218
|
-
print('Heat pipe network \n', dfNetworkHeat.describe (), '\n')
|
|
219
|
-
|
|
220
|
-
#%% reading the sets
|
|
221
|
-
dictSets = DataPortal()
|
|
222
|
-
dictSets.load(filename=f'{_path}/oT_Dict_Period_' f'{CaseName}.csv', set='p' , format='set')
|
|
223
|
-
dictSets.load(filename=f'{_path}/oT_Dict_Scenario_' f'{CaseName}.csv', set='sc' , format='set')
|
|
224
|
-
dictSets.load(filename=f'{_path}/oT_Dict_Stage_' f'{CaseName}.csv', set='st' , format='set')
|
|
225
|
-
dictSets.load(filename=f'{_path}/oT_Dict_LoadLevel_' f'{CaseName}.csv', set='n' , format='set')
|
|
226
|
-
dictSets.load(filename=f'{_path}/oT_Dict_Generation_' f'{CaseName}.csv', set='g' , format='set')
|
|
227
|
-
dictSets.load(filename=f'{_path}/oT_Dict_Technology_' f'{CaseName}.csv', set='gt' , format='set')
|
|
228
|
-
dictSets.load(filename=f'{_path}/oT_Dict_Storage_' f'{CaseName}.csv', set='et' , format='set')
|
|
229
|
-
dictSets.load(filename=f'{_path}/oT_Dict_Node_' f'{CaseName}.csv', set='nd' , format='set')
|
|
230
|
-
dictSets.load(filename=f'{_path}/oT_Dict_Zone_' f'{CaseName}.csv', set='zn' , format='set')
|
|
231
|
-
dictSets.load(filename=f'{_path}/oT_Dict_Area_' f'{CaseName}.csv', set='ar' , format='set')
|
|
232
|
-
dictSets.load(filename=f'{_path}/oT_Dict_Region_' f'{CaseName}.csv', set='rg' , format='set')
|
|
233
|
-
dictSets.load(filename=f'{_path}/oT_Dict_Circuit_' f'{CaseName}.csv', set='cc' , format='set')
|
|
234
|
-
dictSets.load(filename=f'{_path}/oT_Dict_Line_' f'{CaseName}.csv', set='lt' , format='set')
|
|
235
|
-
|
|
236
|
-
dictSets.load(filename=f'{_path}/oT_Dict_NodeToZone_' f'{CaseName}.csv', set='ndzn', format='set')
|
|
237
|
-
dictSets.load(filename=f'{_path}/oT_Dict_ZoneToArea_' f'{CaseName}.csv', set='znar', format='set')
|
|
238
|
-
dictSets.load(filename=f'{_path}/oT_Dict_AreaToRegion_' f'{CaseName}.csv', set='arrg', format='set')
|
|
239
|
-
|
|
240
|
-
mTEPES.pp = Set(initialize=dictSets['p' ], doc='periods', within=PositiveIntegers)
|
|
241
|
-
mTEPES.scc = Set(initialize=dictSets['sc' ], doc='scenarios' )
|
|
242
|
-
mTEPES.stt = Set(initialize=dictSets['st' ], doc='stages' )
|
|
243
|
-
mTEPES.nn = Set(initialize=dictSets['n' ], doc='load levels' )
|
|
244
|
-
mTEPES.gg = Set(initialize=dictSets['g' ], doc='units' )
|
|
245
|
-
mTEPES.gt = Set(initialize=dictSets['gt' ], doc='technologies' )
|
|
246
|
-
mTEPES.nd = Set(initialize=dictSets['nd' ], doc='nodes' )
|
|
247
|
-
mTEPES.ni = Set(initialize=dictSets['nd' ], doc='nodes' )
|
|
248
|
-
mTEPES.nf = Set(initialize=dictSets['nd' ], doc='nodes' )
|
|
249
|
-
mTEPES.zn = Set(initialize=dictSets['zn' ], doc='zones' )
|
|
250
|
-
mTEPES.ar = Set(initialize=dictSets['ar' ], doc='areas' )
|
|
251
|
-
mTEPES.rg = Set(initialize=dictSets['rg' ], doc='regions' )
|
|
252
|
-
mTEPES.cc = Set(initialize=dictSets['cc' ], doc='circuits' )
|
|
253
|
-
mTEPES.c2 = Set(initialize=dictSets['cc' ], doc='circuits' )
|
|
254
|
-
mTEPES.lt = Set(initialize=dictSets['lt' ], doc='electric line types' )
|
|
255
|
-
mTEPES.ndzn = Set(initialize=dictSets['ndzn'], doc='node to zone' )
|
|
256
|
-
mTEPES.znar = Set(initialize=dictSets['znar'], doc='zone to area' )
|
|
257
|
-
mTEPES.arrg = Set(initialize=dictSets['arrg'], doc='area to region' )
|
|
258
|
-
|
|
174
|
+
for key, df in dfs.items():
|
|
175
|
+
if pIndLogConsole == 1 and [1 for suffix in mTEPES.frames_suffixes if suffix in key]:
|
|
176
|
+
print(f'{key}:\n', df.describe(), '\n')
|
|
177
|
+
# reading additional data sets related to reservoirs and hydro
|
|
259
178
|
try:
|
|
260
179
|
import csv
|
|
261
180
|
def count_lines_in_csv(csv_file_path):
|
|
@@ -298,80 +217,64 @@ def InputData(DirName, CaseName, mTEPES, pIndLogConsole):
|
|
|
298
217
|
except:
|
|
299
218
|
pass
|
|
300
219
|
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
pIndBinRsrInvest = dfOption ['IndBinRsrInvest' ].iloc[0].astype('int') # Indicator of binary reservoir expansion decisions, 0 continuous - 1 binary - 2 no investment variables
|
|
305
|
-
pIndBinNetElecInvest = dfOption ['IndBinNetInvest' ].iloc[0].astype('int') # Indicator of binary electric network expansion decisions, 0 continuous - 1 binary - 2 no investment variables
|
|
306
|
-
pIndBinNetH2Invest = dfOption ['IndBinNetH2Invest' ].iloc[0].astype('int') # Indicator of binary hydrogen pipeline expansion decisions, 0 continuous - 1 binary - 2 no investment variables
|
|
307
|
-
pIndBinNetHeatInvest = dfOption ['IndBinNetHeatInvest'].iloc[0].astype('int') # Indicator of binary heat pipe expansion decisions, 0 continuous - 1 binary - 2 no investment variables
|
|
308
|
-
pIndBinGenOperat = dfOption ['IndBinGenOperat' ].iloc[0].astype('int') # Indicator of binary generation operation decisions, 0 continuous - 1 binary
|
|
309
|
-
pIndBinSingleNode = dfOption ['IndBinSingleNode' ].iloc[0].astype('int') # Indicator of single node although with electric network, 0 electric network - 1 single node
|
|
310
|
-
pIndBinGenRamps = dfOption ['IndBinGenRamps' ].iloc[0].astype('int') # Indicator of ramp constraints, 0 no ramps - 1 ramp constraints
|
|
311
|
-
pIndBinGenMinTime = dfOption ['IndBinGenMinTime' ].iloc[0].astype('int') # Indicator of minimum up/downtime constraints, 0 no min time - 1 min time constraints
|
|
312
|
-
pIndBinLineCommit = dfOption ['IndBinLineCommit' ].iloc[0].astype('int') # Indicator of binary electric network switching decisions, 0 continuous - 1 binary
|
|
313
|
-
pIndBinNetLosses = dfOption ['IndBinNetLosses' ].iloc[0].astype('int') # Indicator of electric network losses, 0 lossless - 1 ohmic losses
|
|
314
|
-
pENSCost = dfParameter['ENSCost' ].iloc[0] * 1e-3 # cost of energy not served [MEUR/GWh]
|
|
315
|
-
pH2NSCost = dfParameter['HNSCost' ].iloc[0] * 1e-3 # cost of hydrogen not served [MEUR/tH2]
|
|
316
|
-
pHeatNSCost = dfParameter['HTNSCost' ].iloc[0] * 1e-3 # cost of heat not served [MEUR/GWh]
|
|
317
|
-
pCO2Cost = dfParameter['CO2Cost' ].iloc[0] # cost of CO2 emission [EUR/tCO2]
|
|
318
|
-
pEconomicBaseYear = dfParameter['EconomicBaseYear' ].iloc[0] # economic base year [year]
|
|
319
|
-
pAnnualDiscRate = dfParameter['AnnualDiscountRate' ].iloc[0] # annual discount rate [p.u.]
|
|
320
|
-
pUpReserveActivation = dfParameter['UpReserveActivation'].iloc[0] # upward reserve activation [p.u.]
|
|
321
|
-
pDwReserveActivation = dfParameter['DwReserveActivation'].iloc[0] # downward reserve activation [p.u.]
|
|
322
|
-
pMinRatioDwUp = dfParameter['MinRatioDwUp' ].iloc[0] # minimum ratio down up operating reserves [p.u.]
|
|
323
|
-
pMaxRatioDwUp = dfParameter['MaxRatioDwUp' ].iloc[0] # maximum ratio down up operating reserves [p.u.]
|
|
324
|
-
pSBase = dfParameter['SBase' ].iloc[0] * 1e-3 # base power [GW]
|
|
325
|
-
pReferenceNode = dfParameter['ReferenceNode' ].iloc[0] # reference node
|
|
326
|
-
pTimeStep = dfParameter['TimeStep' ].iloc[0].astype('int') # duration of the unit time step [h]
|
|
327
|
-
|
|
328
|
-
pPeriodWeight = dfPeriod ['Weight' ].astype('int') # weights of periods [p.u.]
|
|
329
|
-
pScenProb = dfScenario ['Probability' ].astype('float64') # probabilities of scenarios [p.u.]
|
|
330
|
-
pStageWeight = dfStage ['Weight' ].astype('float64') # weights of stages
|
|
331
|
-
pDuration = dfDuration ['Duration' ] * pTimeStep # duration of load levels [h]
|
|
332
|
-
pLevelToStage = dfDuration ['Stage' ] # load levels assignment to stages
|
|
333
|
-
pReserveMargin = dfReserveMargin['ReserveMargin' ] # minimum adequacy reserve margin [p.u.]
|
|
334
|
-
pEmission = dfEmission ['CO2Emission' ] # maximum CO2 emission [MtCO2]
|
|
335
|
-
pRESEnergy = dfRESEnergy ['RESEnergy' ] # minimum RES energy [GWh]
|
|
336
|
-
pDemandElec = dfDemand.reindex (columns=mTEPES.nd, fill_value=0.0) * 1e-3 # electric demand [GW]
|
|
337
|
-
pSystemInertia = dfInertia.reindex (columns=mTEPES.ar, fill_value=0.0) # inertia [s]
|
|
338
|
-
pOperReserveUp = dfUpOperatingReserve.reindex (columns=mTEPES.ar, fill_value=0.0) * 1e-3 # upward operating reserve [GW]
|
|
339
|
-
pOperReserveDw = dfDwOperatingReserve.reindex (columns=mTEPES.ar, fill_value=0.0) * 1e-3 # downward operating reserve [GW]
|
|
340
|
-
|
|
341
|
-
pVariableMinPowerElec = dfVariableMinPower.reindex (columns=mTEPES.gg, fill_value=0.0) * 1e-3 # dynamic variable minimum power [GW]
|
|
342
|
-
pVariableMaxPowerElec = dfVariableMaxPower.reindex (columns=mTEPES.gg, fill_value=0.0) * 1e-3 # dynamic variable maximum power [GW]
|
|
343
|
-
pVariableMinCharge = dfVariableMinCharge.reindex (columns=mTEPES.gg, fill_value=0.0) * 1e-3 # dynamic variable minimum charge [GW]
|
|
344
|
-
pVariableMaxCharge = dfVariableMaxCharge.reindex (columns=mTEPES.gg, fill_value=0.0) * 1e-3 # dynamic variable maximum charge [GW]
|
|
345
|
-
pVariableMinStorage = dfVariableMinStorage.reindex (columns=mTEPES.gg, fill_value=0.0) # dynamic variable minimum storage [GWh]
|
|
346
|
-
pVariableMaxStorage = dfVariableMaxStorage.reindex (columns=mTEPES.gg, fill_value=0.0) # dynamic variable maximum storage [GWh]
|
|
347
|
-
pVariableMinEnergy = dfVariableMinEnergy.reindex (columns=mTEPES.gg, fill_value=0.0) * 1e-3 # dynamic variable minimum energy [GW]
|
|
348
|
-
pVariableMaxEnergy = dfVariableMaxEnergy.reindex (columns=mTEPES.gg, fill_value=0.0) * 1e-3 # dynamic variable maximum energy [GW]
|
|
349
|
-
pVariableFuelCost = dfVariableFuelCost.reindex (columns=mTEPES.gg, fill_value=0.0) # dynamic variable fuel cost [EUR/Mcal]
|
|
350
|
-
pVariableEmissionCost = dfVariableEmissionCost.reindex(columns=mTEPES.gg, fill_value=0.0) # dynamic variable emission cost [EUR/tCO2]
|
|
351
|
-
pEnergyInflows = dfEnergyInflows.reindex (columns=mTEPES.gg, fill_value=0.0) * 1e-3 # dynamic energy inflows [GW]
|
|
352
|
-
pEnergyOutflows = dfEnergyOutflows.reindex (columns=mTEPES.gg, fill_value=0.0) * 1e-3 # dynamic energy outflows [GW]
|
|
353
|
-
|
|
354
|
-
if pIndVarTTC == 1:
|
|
355
|
-
pVariableTTCFrw = dfVariableTTCFrw * 1e-3 # variable TTC forward [GW]
|
|
356
|
-
pVariableTTCBck = dfVariableTTCBck * 1e-3 # variable TTC backward [GW]
|
|
357
|
-
if pIndPTDF == 1:
|
|
358
|
-
pVariablePTDF = dfVariablePTDF # variable PTDF [p.u.]
|
|
359
|
-
|
|
360
|
-
if pIndHydroTopology == 1:
|
|
361
|
-
pVariableMinVolume = dfVariableMinVolume.reindex (columns=mTEPES.rs, fill_value=0.0) # dynamic variable minimum reservoir volume [hm3]
|
|
362
|
-
pVariableMaxVolume = dfVariableMaxVolume.reindex (columns=mTEPES.rs, fill_value=0.0) # dynamic variable maximum reservoir volume [hm3]
|
|
363
|
-
pHydroInflows = dfHydroInflows.reindex (columns=mTEPES.rs, fill_value=0.0) # dynamic hydro inflows [m3/s]
|
|
364
|
-
pHydroOutflows = dfHydroOutflows.reindex (columns=mTEPES.rs, fill_value=0.0) # dynamic hydro outflows [m3/s]
|
|
365
|
-
|
|
366
|
-
if pIndHydrogen == 1:
|
|
367
|
-
pDemandH2 = dfDemandHydrogen [mTEPES.nd] # hydrogen demand [tH2/h]
|
|
368
|
-
|
|
369
|
-
if pIndHeat == 1:
|
|
370
|
-
pReserveMarginHeat = dfReserveMarginHeat ['ReserveMargin'] # minimum adequacy reserve margin [p.u.]
|
|
371
|
-
pDemandHeat = dfDemandHeat [mTEPES.nd] * 1e-3 # heat demand [GW]
|
|
372
|
-
|
|
373
|
-
if pTimeStep > 1:
|
|
220
|
+
# load parameters from dfOption
|
|
221
|
+
for col in dfs['dfOption'].columns:
|
|
222
|
+
par[f'p{col}'] = dfs['dfOption'][col].iloc[0].astype('int')
|
|
374
223
|
|
|
224
|
+
# load parameters from dfParameter
|
|
225
|
+
for col in dfs['dfParameter'].columns:
|
|
226
|
+
if col in ['ENSCost', 'HNSCost', 'HTNSCost', 'SBase']:
|
|
227
|
+
par[f'p{col}'] = dfs['dfParameter'][col].iloc[0] * factor_1
|
|
228
|
+
elif col in ['TimeStep']:
|
|
229
|
+
par[f'p{col}'] = dfs['dfParameter'][col].iloc[0].astype('int')
|
|
230
|
+
else:
|
|
231
|
+
par[f'p{col}'] = dfs['dfParameter'][col].iloc[0]
|
|
232
|
+
|
|
233
|
+
par['pPeriodWeight'] = dfs['dfPeriod'] ['Weight' ].astype('int') # weights of periods [p.u.]
|
|
234
|
+
par['pScenProb'] = dfs['dfScenario'] ['Probability' ].astype('float64') # probabilities of scenarios [p.u.]
|
|
235
|
+
par['pStageWeight'] = dfs['dfStage'] ['Weight' ].astype('float64') # weights of stages
|
|
236
|
+
par['pDuration'] = dfs['dfDuration'] ['Duration' ] * par['pTimeStep'] # duration of load levels [h]
|
|
237
|
+
par['pLevelToStage'] = dfs['dfDuration'] ['Stage' ] # load levels assignment to stages
|
|
238
|
+
par['pReserveMargin'] = dfs['dfReserveMargin']['ReserveMargin' ] # minimum adequacy reserve margin [p.u.]
|
|
239
|
+
par['pEmission'] = dfs['dfEmission'] ['CO2Emission' ] # maximum CO2 emission [MtCO2]
|
|
240
|
+
par['pRESEnergy'] = dfs['dfRESEnergy'] ['RESEnergy' ] # minimum RES energy [GWh]
|
|
241
|
+
par['pDemandElec'] = dfs['dfDemand'].reindex (columns=mTEPES.nd, fill_value=0.0) * 1e-3 # electric demand [GW]
|
|
242
|
+
par['pSystemInertia'] = dfs['dfInertia'].reindex (columns=mTEPES.ar, fill_value=0.0) # inertia [s]
|
|
243
|
+
par['pOperReserveUp'] = dfs['dfOperatingReserveUp'].reindex (columns=mTEPES.ar, fill_value=0.0) * 1e-3 # upward operating reserve [GW]
|
|
244
|
+
par['pOperReserveDw'] = dfs['dfOperatingReserveDown'].reindex (columns=mTEPES.ar, fill_value=0.0) * 1e-3 # downward operating reserve [GW]
|
|
245
|
+
par['pVariableMinPowerElec'] = dfs['dfVariableMinGeneration'].reindex (columns=mTEPES.gg, fill_value=0.0) * 1e-3 # dynamic variable minimum power [GW]
|
|
246
|
+
par['pVariableMaxPowerElec'] = dfs['dfVariableMaxGeneration'].reindex (columns=mTEPES.gg, fill_value=0.0) * 1e-3 # dynamic variable maximum power [GW]
|
|
247
|
+
par['pVariableMinCharge'] = dfs['dfVariableMinConsumption'].reindex(columns=mTEPES.gg, fill_value=0.0) * 1e-3 # dynamic variable minimum charge [GW]
|
|
248
|
+
par['pVariableMaxCharge'] = dfs['dfVariableMaxConsumption'].reindex(columns=mTEPES.gg, fill_value=0.0) * 1e-3 # dynamic variable maximum charge [GW]
|
|
249
|
+
par['pVariableMinStorage'] = dfs['dfVariableMinStorage'].reindex (columns=mTEPES.gg, fill_value=0.0) # dynamic variable minimum storage [GWh]
|
|
250
|
+
par['pVariableMaxStorage'] = dfs['dfVariableMaxStorage'].reindex (columns=mTEPES.gg, fill_value=0.0) # dynamic variable maximum storage [GWh]
|
|
251
|
+
par['pVariableMinEnergy'] = dfs['dfVariableMinEnergy'].reindex (columns=mTEPES.gg, fill_value=0.0) * 1e-3 # dynamic variable minimum energy [GW]
|
|
252
|
+
par['pVariableMaxEnergy'] = dfs['dfVariableMaxEnergy'].reindex (columns=mTEPES.gg, fill_value=0.0) * 1e-3 # dynamic variable maximum energy [GW]
|
|
253
|
+
par['pVariableFuelCost'] = dfs['dfVariableFuelCost'].reindex (columns=mTEPES.gg, fill_value=0.0) # dynamic variable fuel cost [EUR/MJ]
|
|
254
|
+
par['pVariableEmissionCost'] = dfs['dfVariableEmissionCost'].reindex (columns=mTEPES.gg, fill_value=0.0) # dynamic variable emission cost [EUR/tCO2]
|
|
255
|
+
par['pEnergyInflows'] = dfs['dfEnergyInflows'].reindex (columns=mTEPES.gg, fill_value=0.0) * 1e-3 # dynamic energy inflows [GW]
|
|
256
|
+
par['pEnergyOutflows'] = dfs['dfEnergyOutflows'].reindex (columns=mTEPES.gg, fill_value=0.0) * 1e-3 # dynamic energy outflows [GW]
|
|
257
|
+
|
|
258
|
+
if par['pIndVarTTC'] == 1:
|
|
259
|
+
par['pVariableNTCFrw'] = dfs['dfVariableTTCFrw'] * 1e-3 # variable TTC forward [GW]
|
|
260
|
+
par['pVariableNTCBck'] = dfs['dfVariableTTCBck'] * 1e-3 # variable TTC backward [GW]
|
|
261
|
+
if par['pIndPTDF'] == 1:
|
|
262
|
+
par['pVariablePTDF'] = dfs['dfVariablePTDF'] # variable PTDF [p.u.]
|
|
263
|
+
|
|
264
|
+
if par['pIndHydroTopology'] == 1:
|
|
265
|
+
par['pVariableMinVolume'] = dfs['dfVariableMinVolume'].reindex (columns=mTEPES.rs, fill_value=0.0) # dynamic variable minimum reservoir volume [hm3]
|
|
266
|
+
par['pVariableMaxVolume'] = dfs['dfVariableMaxVolume'].reindex (columns=mTEPES.rs, fill_value=0.0) # dynamic variable maximum reservoir volume [hm3]
|
|
267
|
+
par['pHydroInflows'] = dfs['dfHydroInflows'].reindex (columns=mTEPES.rs, fill_value=0.0) # dynamic hydro inflows [m3/s]
|
|
268
|
+
par['pHydroOutflows'] = dfs['dfHydroOutflows'].reindex (columns=mTEPES.rs, fill_value=0.0) # dynamic hydro outflows [m3/s]
|
|
269
|
+
|
|
270
|
+
if par['pIndHydrogen'] == 1:
|
|
271
|
+
par['pDemandH2'] = dfs['dfDemandHydrogen'] [mTEPES.nd] # hydrogen demand [tH2/h]
|
|
272
|
+
|
|
273
|
+
if par['pIndHeat'] == 1:
|
|
274
|
+
par['pReserveMarginHeat'] = dfs['dfReserveMarginHeat'] ['ReserveMargin'] # minimum adequacy reserve margin [p.u.]
|
|
275
|
+
par['pDemandHeat'] = dfs['dfDemandHeat'] [mTEPES.nd] * 1e-3 # heat demand [GW]
|
|
276
|
+
|
|
277
|
+
if par['pTimeStep'] > 1:
|
|
375
278
|
# compute the demand as the mean over the time step load levels and assign it to active load levels. Idem for the remaining parameters
|
|
376
279
|
# Skip mean calculation for empty DataFrames (either full of 0s or NaNs)
|
|
377
280
|
def ProcessParameter(pDataFrame: pd.DataFrame, pTimeStep: int) -> pd.DataFrame:
|
|
@@ -381,259 +284,267 @@ def InputData(DirName, CaseName, mTEPES, pIndLogConsole):
|
|
|
381
284
|
return pDataFrame
|
|
382
285
|
|
|
383
286
|
# Apply the ProcessParameter function to each DataFrame
|
|
384
|
-
pDemandElec = ProcessParameter(pDemandElec, pTimeStep)
|
|
385
|
-
pSystemInertia = ProcessParameter(pSystemInertia, pTimeStep)
|
|
386
|
-
pOperReserveUp = ProcessParameter(pOperReserveUp, pTimeStep)
|
|
387
|
-
pOperReserveDw = ProcessParameter(pOperReserveDw, pTimeStep)
|
|
388
|
-
pVariableMinPowerElec = ProcessParameter(pVariableMinPowerElec, pTimeStep)
|
|
389
|
-
pVariableMaxPowerElec = ProcessParameter(pVariableMaxPowerElec, pTimeStep)
|
|
390
|
-
pVariableMinCharge = ProcessParameter(pVariableMinCharge, pTimeStep)
|
|
391
|
-
pVariableMaxCharge = ProcessParameter(pVariableMaxCharge, pTimeStep)
|
|
392
|
-
pVariableMinStorage = ProcessParameter(pVariableMinStorage, pTimeStep)
|
|
393
|
-
pVariableMaxStorage = ProcessParameter(pVariableMaxStorage, pTimeStep)
|
|
394
|
-
pVariableMinEnergy = ProcessParameter(pVariableMinEnergy, pTimeStep)
|
|
395
|
-
pVariableMaxEnergy = ProcessParameter(pVariableMaxEnergy, pTimeStep)
|
|
396
|
-
pVariableFuelCost = ProcessParameter(pVariableFuelCost, pTimeStep)
|
|
397
|
-
pVariableEmissionCost = ProcessParameter(pVariableEmissionCost, pTimeStep)
|
|
398
|
-
pEnergyInflows = ProcessParameter(pEnergyInflows, pTimeStep)
|
|
399
|
-
pEnergyOutflows = ProcessParameter(pEnergyOutflows, pTimeStep)
|
|
400
|
-
|
|
401
|
-
if pIndVarTTC == 1:
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
if pIndPTDF == 1:
|
|
405
|
-
pVariablePTDF = ProcessParameter(pVariablePTDF, pTimeStep)
|
|
406
|
-
|
|
407
|
-
if pIndHydroTopology == 1:
|
|
408
|
-
pVariableMinVolume = ProcessParameter(pVariableMinVolume, pTimeStep)
|
|
409
|
-
pVariableMaxVolume = ProcessParameter(pVariableMaxVolume, pTimeStep)
|
|
410
|
-
pHydroInflows = ProcessParameter(pHydroInflows, pTimeStep)
|
|
411
|
-
pHydroOutflows = ProcessParameter(pHydroOutflows, pTimeStep)
|
|
412
|
-
|
|
413
|
-
if pIndHydrogen == 1:
|
|
414
|
-
pDemandH2 = ProcessParameter(pDemandH2, pTimeStep)
|
|
415
|
-
|
|
416
|
-
if pIndHeat == 1:
|
|
417
|
-
pDemandHeat = ProcessParameter(pDemandHeat, pTimeStep)
|
|
287
|
+
par['pDemandElec'] = ProcessParameter(par['pDemandElec'], par['pTimeStep'])
|
|
288
|
+
par['pSystemInertia'] = ProcessParameter(par['pSystemInertia'], par['pTimeStep'])
|
|
289
|
+
par['pOperReserveUp'] = ProcessParameter(par['pOperReserveUp'], par['pTimeStep'])
|
|
290
|
+
par['pOperReserveDw'] = ProcessParameter(par['pOperReserveDw'], par['pTimeStep'])
|
|
291
|
+
par['pVariableMinPowerElec'] = ProcessParameter(par['pVariableMinPowerElec'], par['pTimeStep'])
|
|
292
|
+
par['pVariableMaxPowerElec'] = ProcessParameter(par['pVariableMaxPowerElec'], par['pTimeStep'])
|
|
293
|
+
par['pVariableMinCharge'] = ProcessParameter(par['pVariableMinCharge'], par['pTimeStep'])
|
|
294
|
+
par['pVariableMaxCharge'] = ProcessParameter(par['pVariableMaxCharge'], par['pTimeStep'])
|
|
295
|
+
par['pVariableMinStorage'] = ProcessParameter(par['pVariableMinStorage'], par['pTimeStep'])
|
|
296
|
+
par['pVariableMaxStorage'] = ProcessParameter(par['pVariableMaxStorage'], par['pTimeStep'])
|
|
297
|
+
par['pVariableMinEnergy'] = ProcessParameter(par['pVariableMinEnergy'], par['pTimeStep'])
|
|
298
|
+
par['pVariableMaxEnergy'] = ProcessParameter(par['pVariableMaxEnergy'], par['pTimeStep'])
|
|
299
|
+
par['pVariableFuelCost'] = ProcessParameter(par['pVariableFuelCost'], par['pTimeStep'])
|
|
300
|
+
par['pVariableEmissionCost'] = ProcessParameter(par['pVariableEmissionCost'], par['pTimeStep'])
|
|
301
|
+
par['pEnergyInflows'] = ProcessParameter(par['pEnergyInflows'], par['pTimeStep'])
|
|
302
|
+
par['pEnergyOutflows'] = ProcessParameter(par['pEnergyOutflows'], par['pTimeStep'])
|
|
303
|
+
|
|
304
|
+
if par['pIndVarTTC'] == 1:
|
|
305
|
+
par['pVariableNTCFrw'] = ProcessParameter(par['pVariableNTCFrw'], par['pTimeStep'])
|
|
306
|
+
par['pVariableNTCBck'] = ProcessParameter(par['pVariableNTCBck'], par['pTimeStep'])
|
|
307
|
+
if par['pIndPTDF'] == 1:
|
|
308
|
+
par['pVariablePTDF'] = ProcessParameter(par['pVariablePTDF'], par['pTimeStep'])
|
|
309
|
+
|
|
310
|
+
if par['pIndHydroTopology'] == 1:
|
|
311
|
+
par['pVariableMinVolume'] = ProcessParameter(par['pVariableMinVolume'], par['pTimeStep'])
|
|
312
|
+
par['pVariableMaxVolume'] = ProcessParameter(par['pVariableMaxVolume'], par['pTimeStep'])
|
|
313
|
+
par['pHydroInflows'] = ProcessParameter(par['pHydroInflows'], par['pTimeStep'])
|
|
314
|
+
par['pHydroOutflows'] = ProcessParameter(par['pHydroOutflows'], par['pTimeStep'])
|
|
315
|
+
|
|
316
|
+
if par['pIndHydrogen'] == 1:
|
|
317
|
+
par['pDemandH2'] = ProcessParameter(par['pDemandH2'], par['pTimeStep'])
|
|
318
|
+
|
|
319
|
+
if par['pIndHeat'] == 1:
|
|
320
|
+
par['pDemandHeat'] = ProcessParameter(par['pDemandHeat'], par['pTimeStep'])
|
|
418
321
|
|
|
419
322
|
# assign duration 0 to load levels not being considered; active load levels are at the end of every pTimeStep
|
|
420
|
-
for n in range(pTimeStep-2,-1,-1):
|
|
421
|
-
pDuration.iloc[[range(n,len(mTEPES.pp)*len(mTEPES.scc)*len(mTEPES.nn),pTimeStep)]] = 0
|
|
323
|
+
for n in range(par['pTimeStep']-2,-1,-1):
|
|
324
|
+
par['pDuration'].iloc[[range(n,len(mTEPES.pp)*len(mTEPES.scc)*len(mTEPES.nn),par['pTimeStep'])]] = 0
|
|
422
325
|
|
|
423
|
-
for psn in pDuration.index:
|
|
326
|
+
for psn in par['pDuration'].index:
|
|
424
327
|
p,sc,n = psn
|
|
425
|
-
if pPeriodWeight[p] == 0:
|
|
426
|
-
pDuration.loc[p,sc,n] = 0
|
|
427
|
-
if pScenProb[p,sc] == 0:
|
|
428
|
-
pDuration.loc[p,sc,n] = 0
|
|
328
|
+
if par['pPeriodWeight'][p] == 0:
|
|
329
|
+
par['pDuration'].loc[p,sc,n] = 0
|
|
330
|
+
if par['pScenProb'][p,sc] == 0:
|
|
331
|
+
par['pDuration'].loc[p,sc,n] = 0
|
|
429
332
|
|
|
430
333
|
#%% generation parameters
|
|
431
|
-
pGenToNode = dfGeneration ['Node' ]
|
|
432
|
-
pGenToTechnology = dfGeneration ['Technology' ]
|
|
433
|
-
pGenToExclusiveGen = dfGeneration ['MutuallyExclusive' ]
|
|
434
|
-
pIndBinUnitInvest = dfGeneration ['BinaryInvestment' ]
|
|
435
|
-
pIndBinUnitRetire = dfGeneration ['BinaryRetirement' ]
|
|
436
|
-
pIndBinUnitCommit = dfGeneration ['BinaryCommitment' ]
|
|
437
|
-
pIndBinStorInvest = dfGeneration ['StorageInvestment' ]
|
|
438
|
-
pIndOperReserve = dfGeneration ['NoOperatingReserve' ]
|
|
439
|
-
pIndOutflowIncomp = dfGeneration ['OutflowsIncompatibility' ]
|
|
440
|
-
pMustRun = dfGeneration ['MustRun' ]
|
|
441
|
-
pInertia = dfGeneration ['Inertia' ]
|
|
442
|
-
pElecGenPeriodIni = dfGeneration ['InitialPeriod' ]
|
|
443
|
-
pElecGenPeriodFin = dfGeneration ['FinalPeriod' ]
|
|
444
|
-
pAvailability = dfGeneration ['Availability' ]
|
|
445
|
-
pEFOR = dfGeneration ['EFOR' ]
|
|
446
|
-
pRatedMinPowerElec = dfGeneration ['MinimumPower' ] * 1e-3 * (1.0-dfGeneration['EFOR']) # rated minimum electric power [GW]
|
|
447
|
-
pRatedMaxPowerElec = dfGeneration ['MaximumPower' ] * 1e-3 * (1.0-dfGeneration['EFOR']) # rated maximum electric power [GW]
|
|
448
|
-
pRatedMinPowerHeat = dfGeneration ['MinimumPowerHeat' ] * 1e-3 * (1.0-dfGeneration['EFOR']) # rated minimum heat power [GW]
|
|
449
|
-
pRatedMaxPowerHeat = dfGeneration ['MaximumPowerHeat' ] * 1e-3 * (1.0-dfGeneration['EFOR']) # rated maximum heat power [GW]
|
|
450
|
-
pRatedLinearFuelCost = dfGeneration ['LinearTerm' ] * 1e-3 * dfGeneration['FuelCost'] # fuel term variable cost [MEUR/GWh]
|
|
451
|
-
pRatedConstantVarCost = dfGeneration ['ConstantTerm' ] * 1e-6 * dfGeneration['FuelCost'] # constant term variable cost [MEUR/h]
|
|
452
|
-
pLinearOMCost = dfGeneration ['OMVariableCost' ] * 1e-3
|
|
453
|
-
pOperReserveCost = dfGeneration ['OperReserveCost' ] * 1e-3
|
|
454
|
-
pStartUpCost = dfGeneration ['StartUpCost' ]
|
|
455
|
-
pShutDownCost = dfGeneration ['ShutDownCost' ]
|
|
456
|
-
pRampUp = dfGeneration ['RampUp' ] * 1e-3
|
|
457
|
-
pRampDw = dfGeneration ['RampDown' ] * 1e-3
|
|
458
|
-
pEmissionCost = dfGeneration ['CO2EmissionRate' ] * 1e-3 * pCO2Cost # CO2 emission cost [MEUR/GWh]
|
|
459
|
-
pEmissionRate = dfGeneration ['CO2EmissionRate' ]
|
|
460
|
-
pUpTime = dfGeneration ['UpTime' ]
|
|
461
|
-
pDwTime = dfGeneration ['DownTime' ]
|
|
462
|
-
pStableTime = dfGeneration ['StableTime' ]
|
|
463
|
-
pShiftTime = dfGeneration ['ShiftTime' ]
|
|
464
|
-
pGenInvestCost = dfGeneration ['FixedInvestmentCost' ] * dfGeneration['FixedChargeRate'] # generation fixed cost [MEUR]
|
|
465
|
-
pGenRetireCost = dfGeneration ['FixedRetirementCost' ] * dfGeneration['FixedChargeRate'] # generation fixed retirement cost [MEUR]
|
|
466
|
-
pRatedMinCharge = dfGeneration ['MinimumCharge' ] * 1e-3
|
|
467
|
-
pRatedMaxCharge = dfGeneration ['MaximumCharge' ] * 1e-3
|
|
468
|
-
pRatedMinStorage = dfGeneration ['MinimumStorage' ]
|
|
469
|
-
pRatedMaxStorage = dfGeneration ['MaximumStorage' ]
|
|
470
|
-
pInitialInventory = dfGeneration ['InitialStorage' ]
|
|
471
|
-
pProductionFunctionHydro = dfGeneration ['ProductionFunctionHydro' ]
|
|
472
|
-
pProductionFunctionH2 = dfGeneration ['ProductionFunctionH2' ] * 1e-3
|
|
473
|
-
pProductionFunctionHeat = dfGeneration ['ProductionFunctionHeat' ]
|
|
474
|
-
pProductionFunctionH2ToHeat = dfGeneration ['ProductionFunctionH2ToHeat'] * 1e-3
|
|
475
|
-
pEfficiency = dfGeneration ['Efficiency' ]
|
|
476
|
-
pStorageType = dfGeneration ['StorageType' ]
|
|
477
|
-
pOutflowsType = dfGeneration ['OutflowsType' ]
|
|
478
|
-
pEnergyType = dfGeneration ['EnergyType' ]
|
|
479
|
-
pRMaxReactivePower = dfGeneration ['MaximumReactivePower' ] * 1e-3
|
|
480
|
-
pGenLoInvest = dfGeneration ['InvestmentLo' ]
|
|
481
|
-
pGenUpInvest = dfGeneration ['InvestmentUp' ]
|
|
482
|
-
pGenLoRetire = dfGeneration ['RetirementLo' ]
|
|
483
|
-
pGenUpRetire = dfGeneration ['RetirementUp' ]
|
|
484
|
-
|
|
485
|
-
pRatedLinearOperCost = pRatedLinearFuelCost + pEmissionCost
|
|
486
|
-
pRatedLinearVarCost = pRatedLinearFuelCost + pLinearOMCost
|
|
487
|
-
|
|
488
|
-
if pIndHydroTopology == 1:
|
|
489
|
-
pReservoirType = dfReservoir ['StorageType' ]
|
|
490
|
-
pWaterOutfType = dfReservoir ['OutflowsType' ]
|
|
491
|
-
pRatedMinVolume = dfReservoir ['MinimumStorage' ]
|
|
492
|
-
pRatedMaxVolume = dfReservoir ['MaximumStorage' ]
|
|
493
|
-
pInitialVolume = dfReservoir ['InitialStorage' ]
|
|
494
|
-
pIndBinRsrvInvest = dfReservoir ['BinaryInvestment' ]
|
|
495
|
-
pRsrInvestCost = dfReservoir ['FixedInvestmentCost' ] * dfReservoir['FixedChargeRate'] # reservoir fixed cost [MEUR]
|
|
496
|
-
pRsrPeriodIni = dfReservoir ['InitialPeriod' ]
|
|
497
|
-
pRsrPeriodFin = dfReservoir ['FinalPeriod' ]
|
|
498
|
-
|
|
499
|
-
pNodeLat = dfNodeLocation['Latitude' ]
|
|
500
|
-
pNodeLon = dfNodeLocation['Longitude' ]
|
|
501
|
-
|
|
502
|
-
pLineType = dfNetwork ['LineType' ]
|
|
503
|
-
pLineLength = dfNetwork ['Length' ]
|
|
504
|
-
pLineVoltage = dfNetwork ['Voltage' ]
|
|
505
|
-
pElecNetPeriodIni = dfNetwork ['InitialPeriod' ]
|
|
506
|
-
pElecNetPeriodFin = dfNetwork ['FinalPeriod' ]
|
|
507
|
-
pLineLossFactor = dfNetwork ['LossFactor' ]
|
|
508
|
-
pLineR = dfNetwork ['Resistance' ]
|
|
509
|
-
pLineX = dfNetwork ['Reactance' ].sort_index()
|
|
510
|
-
pLineBsh = dfNetwork ['Susceptance' ]
|
|
511
|
-
pLineTAP = dfNetwork ['Tap' ]
|
|
512
|
-
pLineNTCFrw = dfNetwork ['TTC' ] * 1e-3 * dfNetwork['SecurityFactor' ] # net transfer capacity in forward direction [GW]
|
|
513
|
-
pLineNTCBck = dfNetwork ['TTCBck' ] * 1e-3 * dfNetwork['SecurityFactor' ] # net transfer capacity in backward direction [GW]
|
|
514
|
-
pNetFixedCost = dfNetwork ['FixedInvestmentCost' ] * dfNetwork['FixedChargeRate'] # electric network fixed cost [MEUR]
|
|
515
|
-
pIndBinLineSwitch = dfNetwork ['Switching' ]
|
|
516
|
-
pIndBinLineInvest = dfNetwork ['BinaryInvestment' ]
|
|
517
|
-
pSwitchOnTime = dfNetwork ['SwOnTime' ].astype('int')
|
|
518
|
-
pSwitchOffTime = dfNetwork ['SwOffTime' ].astype('int')
|
|
519
|
-
pAngMin = dfNetwork ['AngMin' ] * math.pi / 180
|
|
520
|
-
pAngMax = dfNetwork ['AngMax' ] * math.pi / 180
|
|
521
|
-
pNetLoInvest = dfNetwork ['InvestmentLo' ]
|
|
522
|
-
pNetUpInvest = dfNetwork ['InvestmentUp' ]
|
|
334
|
+
par['pGenToNode'] = dfs['dfGeneration'] ['Node' ] # generator location in node
|
|
335
|
+
par['pGenToTechnology'] = dfs['dfGeneration'] ['Technology' ] # generator association to technology
|
|
336
|
+
par['pGenToExclusiveGen'] = dfs['dfGeneration'] ['MutuallyExclusive' ] # mutually exclusive generator
|
|
337
|
+
par['pIndBinUnitInvest'] = dfs['dfGeneration'] ['BinaryInvestment' ] # binary unit investment decision [Yes]
|
|
338
|
+
par['pIndBinUnitRetire'] = dfs['dfGeneration'] ['BinaryRetirement' ] # binary unit retirement decision [Yes]
|
|
339
|
+
par['pIndBinUnitCommit'] = dfs['dfGeneration'] ['BinaryCommitment' ] # binary unit commitment decision [Yes]
|
|
340
|
+
par['pIndBinStorInvest'] = dfs['dfGeneration'] ['StorageInvestment' ] # storage linked to generation investment [Yes]
|
|
341
|
+
par['pIndOperReserve'] = dfs['dfGeneration'] ['NoOperatingReserve' ] # no contribution to operating reserve [Yes]
|
|
342
|
+
par['pIndOutflowIncomp'] = dfs['dfGeneration'] ['OutflowsIncompatibility' ] # outflows incompatibility with charging
|
|
343
|
+
par['pMustRun'] = dfs['dfGeneration'] ['MustRun' ] # must-run unit [Yes]
|
|
344
|
+
par['pInertia'] = dfs['dfGeneration'] ['Inertia' ] # inertia constant [s]
|
|
345
|
+
par['pElecGenPeriodIni'] = dfs['dfGeneration'] ['InitialPeriod' ] # initial period [year]
|
|
346
|
+
par['pElecGenPeriodFin'] = dfs['dfGeneration'] ['FinalPeriod' ] # final period [year]
|
|
347
|
+
par['pAvailability'] = dfs['dfGeneration'] ['Availability' ] # unit availability for adequacy [p.u.]
|
|
348
|
+
par['pEFOR'] = dfs['dfGeneration'] ['EFOR' ] # EFOR [p.u.]
|
|
349
|
+
par['pRatedMinPowerElec'] = dfs['dfGeneration'] ['MinimumPower' ] * 1e-3 * (1.0-dfs['dfGeneration']['EFOR']) # rated minimum electric power [GW]
|
|
350
|
+
par['pRatedMaxPowerElec'] = dfs['dfGeneration'] ['MaximumPower' ] * 1e-3 * (1.0-dfs['dfGeneration']['EFOR']) # rated maximum electric power [GW]
|
|
351
|
+
par['pRatedMinPowerHeat'] = dfs['dfGeneration'] ['MinimumPowerHeat' ] * 1e-3 * (1.0-dfs['dfGeneration']['EFOR']) # rated minimum heat power [GW]
|
|
352
|
+
par['pRatedMaxPowerHeat'] = dfs['dfGeneration'] ['MaximumPowerHeat' ] * 1e-3 * (1.0-dfs['dfGeneration']['EFOR']) # rated maximum heat power [GW]
|
|
353
|
+
par['pRatedLinearFuelCost'] = dfs['dfGeneration'] ['LinearTerm' ] * 1e-3 * dfs['dfGeneration']['FuelCost'] # fuel term variable cost [MEUR/GWh]
|
|
354
|
+
par['pRatedConstantVarCost'] = dfs['dfGeneration'] ['ConstantTerm' ] * 1e-6 * dfs['dfGeneration']['FuelCost'] # constant term variable cost [MEUR/h]
|
|
355
|
+
par['pLinearOMCost'] = dfs['dfGeneration'] ['OMVariableCost' ] * 1e-3 # O&M term variable cost [MEUR/GWh]
|
|
356
|
+
par['pOperReserveCost'] = dfs['dfGeneration'] ['OperReserveCost' ] * 1e-3 # operating reserve cost [MEUR/GW]
|
|
357
|
+
par['pStartUpCost'] = dfs['dfGeneration'] ['StartUpCost' ] # startup cost [MEUR]
|
|
358
|
+
par['pShutDownCost'] = dfs['dfGeneration'] ['ShutDownCost' ] # shutdown cost [MEUR]
|
|
359
|
+
par['pRampUp'] = dfs['dfGeneration'] ['RampUp' ] * 1e-3 # ramp up rate [GW/h]
|
|
360
|
+
par['pRampDw'] = dfs['dfGeneration'] ['RampDown' ] * 1e-3 # ramp down rate [GW/h]
|
|
361
|
+
par['pEmissionCost'] = dfs['dfGeneration'] ['CO2EmissionRate' ] * 1e-3 * par['pCO2Cost'] # CO2 emission cost [MEUR/GWh]
|
|
362
|
+
par['pEmissionRate'] = dfs['dfGeneration'] ['CO2EmissionRate' ] # CO2 emission rate [tCO2/MWh]
|
|
363
|
+
par['pUpTime'] = dfs['dfGeneration'] ['UpTime' ] # minimum up time [h]
|
|
364
|
+
par['pDwTime'] = dfs['dfGeneration'] ['DownTime' ] # minimum down time [h]
|
|
365
|
+
par['pStableTime'] = dfs['dfGeneration'] ['StableTime' ] # minimum stable time [h]
|
|
366
|
+
par['pShiftTime'] = dfs['dfGeneration'] ['ShiftTime' ] # maximum shift time for DSM [h]
|
|
367
|
+
par['pGenInvestCost'] = dfs['dfGeneration'] ['FixedInvestmentCost' ] * dfs['dfGeneration']['FixedChargeRate'] # generation fixed cost [MEUR]
|
|
368
|
+
par['pGenRetireCost'] = dfs['dfGeneration'] ['FixedRetirementCost' ] * dfs['dfGeneration']['FixedChargeRate'] # generation fixed retirement cost [MEUR]
|
|
369
|
+
par['pRatedMinCharge'] = dfs['dfGeneration'] ['MinimumCharge' ] * 1e-3 # rated minimum ESS charge [GW]
|
|
370
|
+
par['pRatedMaxCharge'] = dfs['dfGeneration'] ['MaximumCharge' ] * 1e-3 # rated maximum ESS charge [GW]
|
|
371
|
+
par['pRatedMinStorage'] = dfs['dfGeneration'] ['MinimumStorage' ] # rated minimum ESS storage [GWh]
|
|
372
|
+
par['pRatedMaxStorage'] = dfs['dfGeneration'] ['MaximumStorage' ] # rated maximum ESS storage [GWh]
|
|
373
|
+
par['pInitialInventory'] = dfs['dfGeneration'] ['InitialStorage' ] # initial ESS storage [GWh]
|
|
374
|
+
par['pProductionFunctionHydro'] = dfs['dfGeneration'] ['ProductionFunctionHydro' ] # production function of a hydropower plant [kWh/m3]
|
|
375
|
+
par['pProductionFunctionH2'] = dfs['dfGeneration'] ['ProductionFunctionH2' ] * 1e-3 # production function of an electrolyzer [kWh/gH2]
|
|
376
|
+
par['pProductionFunctionHeat'] = dfs['dfGeneration'] ['ProductionFunctionHeat' ] # production function of a heat pump [kWh/kWh]
|
|
377
|
+
par['pProductionFunctionH2ToHeat'] = dfs['dfGeneration'] ['ProductionFunctionH2ToHeat'] * 1e-3 # production function of a boiler using H2 [gH2/kWh]
|
|
378
|
+
par['pEfficiency'] = dfs['dfGeneration'] ['Efficiency' ] # ESS round-trip efficiency [p.u.]
|
|
379
|
+
par['pStorageType'] = dfs['dfGeneration'] ['StorageType' ] # ESS storage type
|
|
380
|
+
par['pOutflowsType'] = dfs['dfGeneration'] ['OutflowsType' ] # ESS outflows type
|
|
381
|
+
par['pEnergyType'] = dfs['dfGeneration'] ['EnergyType' ] # unit energy type
|
|
382
|
+
par['pRMaxReactivePower'] = dfs['dfGeneration'] ['MaximumReactivePower' ] * 1e-3 # rated maximum reactive power [Gvar]
|
|
383
|
+
par['pGenLoInvest'] = dfs['dfGeneration'] ['InvestmentLo' ] # Lower bound of the investment decision [p.u.]
|
|
384
|
+
par['pGenUpInvest'] = dfs['dfGeneration'] ['InvestmentUp' ] # Upper bound of the investment decision [p.u.]
|
|
385
|
+
par['pGenLoRetire'] = dfs['dfGeneration'] ['RetirementLo' ] # Lower bound of the retirement decision [p.u.]
|
|
386
|
+
par['pGenUpRetire'] = dfs['dfGeneration'] ['RetirementUp' ] # Upper bound of the retirement decision [p.u.]
|
|
387
|
+
|
|
388
|
+
par['pRatedLinearOperCost'] = par['pRatedLinearFuelCost'] + par['pEmissionCost']
|
|
389
|
+
par['pRatedLinearVarCost'] = par['pRatedLinearFuelCost'] + par['pLinearOMCost']
|
|
390
|
+
|
|
391
|
+
if par['pIndHydroTopology'] == 1:
|
|
392
|
+
par['pReservoirType'] = dfs['dfReservoir'] ['StorageType' ] # reservoir type
|
|
393
|
+
par['pWaterOutfType'] = dfs['dfReservoir'] ['OutflowsType' ] # water outflow type
|
|
394
|
+
par['pRatedMinVolume'] = dfs['dfReservoir'] ['MinimumStorage' ] # rated minimum reservoir volume [hm3]
|
|
395
|
+
par['pRatedMaxVolume'] = dfs['dfReservoir'] ['MaximumStorage' ] # rated maximum reservoir volume [hm3]
|
|
396
|
+
par['pInitialVolume'] = dfs['dfReservoir'] ['InitialStorage' ] # initial reservoir volume [hm3]
|
|
397
|
+
par['pIndBinRsrvInvest'] = dfs['dfReservoir'] ['BinaryInvestment' ] # binary reservoir investment decision [Yes]
|
|
398
|
+
par['pRsrInvestCost'] = dfs['dfReservoir'] ['FixedInvestmentCost' ] * dfs['dfReservoir']['FixedChargeRate'] # reservoir fixed cost [MEUR]
|
|
399
|
+
par['pRsrPeriodIni'] = dfs['dfReservoir'] ['InitialPeriod' ] # initial period [year]
|
|
400
|
+
par['pRsrPeriodFin'] = dfs['dfReservoir'] ['FinalPeriod' ] # final period [year]
|
|
401
|
+
|
|
402
|
+
par['pNodeLat'] = dfs['dfNodeLocation']['Latitude' ] # node latitude [º]
|
|
403
|
+
par['pNodeLon'] = dfs['dfNodeLocation']['Longitude' ] # node longitude [º]
|
|
404
|
+
|
|
405
|
+
par['pLineType'] = dfs['dfNetwork'] ['LineType' ] # electric line type
|
|
406
|
+
par['pLineLength'] = dfs['dfNetwork'] ['Length' ] # electric line length [km]
|
|
407
|
+
par['pLineVoltage'] = dfs['dfNetwork'] ['Voltage' ] # electric line voltage [kV]
|
|
408
|
+
par['pElecNetPeriodIni'] = dfs['dfNetwork'] ['InitialPeriod' ] # initial period
|
|
409
|
+
par['pElecNetPeriodFin'] = dfs['dfNetwork'] ['FinalPeriod' ] # final period
|
|
410
|
+
par['pLineLossFactor'] = dfs['dfNetwork'] ['LossFactor' ] # electric line loss factor [p.u.]
|
|
411
|
+
par['pLineR'] = dfs['dfNetwork'] ['Resistance' ] # electric line resistance [p.u.]
|
|
412
|
+
par['pLineX'] = dfs['dfNetwork'] ['Reactance' ].sort_index() # electric line reactance [p.u.]
|
|
413
|
+
par['pLineBsh'] = dfs['dfNetwork'] ['Susceptance' ] # electric line susceptance [p.u.]
|
|
414
|
+
par['pLineTAP'] = dfs['dfNetwork'] ['Tap' ] # tap changer [p.u.]
|
|
415
|
+
par['pLineNTCFrw'] = dfs['dfNetwork'] ['TTC' ] * 1e-3 * dfs['dfNetwork']['SecurityFactor' ] # net transfer capacity in forward direction [GW]
|
|
416
|
+
par['pLineNTCBck'] = dfs['dfNetwork'] ['TTCBck' ] * 1e-3 * dfs['dfNetwork']['SecurityFactor' ] # net transfer capacity in backward direction [GW]
|
|
417
|
+
par['pNetFixedCost'] = dfs['dfNetwork'] ['FixedInvestmentCost' ] * dfs['dfNetwork']['FixedChargeRate'] # electric network fixed cost [MEUR]
|
|
418
|
+
par['pIndBinLineSwitch'] = dfs['dfNetwork'] ['Switching' ] # binary electric line switching decision [Yes]
|
|
419
|
+
par['pIndBinLineInvest'] = dfs['dfNetwork'] ['BinaryInvestment' ] # binary electric line investment decision [Yes]
|
|
420
|
+
par['pSwitchOnTime'] = dfs['dfNetwork'] ['SwOnTime' ].astype('int') # minimum on time [h]
|
|
421
|
+
par['pSwitchOffTime'] = dfs['dfNetwork'] ['SwOffTime' ].astype('int') # minimum off time [h]
|
|
422
|
+
par['pAngMin'] = dfs['dfNetwork'] ['AngMin' ] * math.pi / 180 # Min phase angle difference [rad]
|
|
423
|
+
par['pAngMax'] = dfs['dfNetwork'] ['AngMax' ] * math.pi / 180 # Max phase angle difference [rad]
|
|
424
|
+
par['pNetLoInvest'] = dfs['dfNetwork'] ['InvestmentLo' ] # Lower bound of the investment decision [p.u.]
|
|
425
|
+
par['pNetUpInvest'] = dfs['dfNetwork'] ['InvestmentUp' ] # Upper bound of the investment decision [p.u.]
|
|
523
426
|
|
|
524
427
|
# replace PeriodFin = 0.0 by year 3000
|
|
525
|
-
pElecGenPeriodFin = pElecGenPeriodFin.where(pElecGenPeriodFin != 0.0, 3000 )
|
|
526
|
-
if pIndHydroTopology == 1:
|
|
527
|
-
pRsrPeriodFin = pRsrPeriodFin.where (pRsrPeriodFin != 0.0, 3000 )
|
|
528
|
-
pElecNetPeriodFin = pElecNetPeriodFin.where(pElecNetPeriodFin != 0.0, 3000 )
|
|
428
|
+
par['pElecGenPeriodFin'] = par['pElecGenPeriodFin'].where(par['pElecGenPeriodFin'] != 0.0, 3000 )
|
|
429
|
+
if par['pIndHydroTopology'] == 1:
|
|
430
|
+
par['pRsrPeriodFin'] = par['pRsrPeriodFin'].where (par['pRsrPeriodFin'] != 0.0, 3000 )
|
|
431
|
+
par['pElecNetPeriodFin'] = par['pElecNetPeriodFin'].where(par['pElecNetPeriodFin'] != 0.0, 3000 )
|
|
529
432
|
# replace pLineNTCBck = 0.0 by pLineNTCFrw
|
|
530
|
-
pLineNTCBck = pLineNTCBck.where (pLineNTCBck > 0.0, pLineNTCFrw)
|
|
433
|
+
par['pLineNTCBck'] = par['pLineNTCBck'].where (par['pLineNTCBck'] > 0.0, par['pLineNTCFrw'])
|
|
531
434
|
# replace pLineNTCFrw = 0.0 by pLineNTCBck
|
|
532
|
-
pLineNTCFrw = pLineNTCFrw.where (pLineNTCFrw > 0.0, pLineNTCBck)
|
|
435
|
+
par['pLineNTCFrw'] = par['pLineNTCFrw'].where (par['pLineNTCFrw'] > 0.0, par['pLineNTCBck'])
|
|
533
436
|
# replace pGenUpInvest = 0.0 by 1.0
|
|
534
|
-
pGenUpInvest = pGenUpInvest.where (pGenUpInvest > 0.0, 1.0
|
|
437
|
+
par['pGenUpInvest'] = par['pGenUpInvest'].where (par['pGenUpInvest'] > 0.0, 1.0 )
|
|
535
438
|
# replace pGenUpRetire = 0.0 by 1.0
|
|
536
|
-
pGenUpRetire = pGenUpRetire.where (pGenUpRetire > 0.0, 1.0
|
|
439
|
+
par['pGenUpRetire'] = par['pGenUpRetire'].where (par['pGenUpRetire'] > 0.0, 1.0 )
|
|
537
440
|
# replace pNetUpInvest = 0.0 by 1.0
|
|
538
|
-
pNetUpInvest = pNetUpInvest.where (pNetUpInvest > 0.0, 1.0
|
|
441
|
+
par['pNetUpInvest'] = par['pNetUpInvest'].where (par['pNetUpInvest'] > 0.0, 1.0 )
|
|
539
442
|
|
|
540
443
|
# minimum up- and downtime converted to an integer number of time steps
|
|
541
|
-
pSwitchOnTime = round(pSwitchOnTime /pTimeStep).astype('int')
|
|
542
|
-
pSwitchOffTime = round(pSwitchOffTime/pTimeStep).astype('int')
|
|
543
|
-
|
|
544
|
-
if pIndHydrogen == 1:
|
|
545
|
-
pH2PipeLength = dfNetworkHydrogen['Length' ]
|
|
546
|
-
pH2PipePeriodIni = dfNetworkHydrogen['InitialPeriod' ]
|
|
547
|
-
pH2PipePeriodFin = dfNetworkHydrogen['FinalPeriod' ]
|
|
548
|
-
pH2PipeNTCFrw = dfNetworkHydrogen['TTC' ] * dfNetworkHydrogen['SecurityFactor' ] # net transfer capacity in forward direction [tH2]
|
|
549
|
-
pH2PipeNTCBck = dfNetworkHydrogen['TTCBck' ] * dfNetworkHydrogen['SecurityFactor' ] # net transfer capacity in backward direction [tH2]
|
|
550
|
-
pH2PipeFixedCost = dfNetworkHydrogen['FixedInvestmentCost'] * dfNetworkHydrogen['FixedChargeRate'] # hydrogen network fixed cost [MEUR]
|
|
551
|
-
pIndBinH2PipeInvest = dfNetworkHydrogen['BinaryInvestment' ]
|
|
552
|
-
pH2PipeLoInvest = dfNetworkHydrogen['InvestmentLo' ]
|
|
553
|
-
pH2PipeUpInvest = dfNetworkHydrogen['InvestmentUp' ]
|
|
554
|
-
|
|
555
|
-
pH2PipePeriodFin = pH2PipePeriodFin.where(pH2PipePeriodFin != 0.0, 3000 )
|
|
444
|
+
par['pSwitchOnTime'] = round(par['pSwitchOnTime'] /par['pTimeStep']).astype('int')
|
|
445
|
+
par['pSwitchOffTime'] = round(par['pSwitchOffTime']/par['pTimeStep']).astype('int')
|
|
446
|
+
|
|
447
|
+
if par['pIndHydrogen'] == 1:
|
|
448
|
+
par['pH2PipeLength'] = dfs['dfNetworkHydrogen']['Length' ] # hydrogen line length [km]
|
|
449
|
+
par['pH2PipePeriodIni'] = dfs['dfNetworkHydrogen']['InitialPeriod' ] # initial period
|
|
450
|
+
par['pH2PipePeriodFin'] = dfs['dfNetworkHydrogen']['FinalPeriod' ] # final period
|
|
451
|
+
par['pH2PipeNTCFrw'] = dfs['dfNetworkHydrogen']['TTC' ] * dfs['dfNetworkHydrogen']['SecurityFactor' ] # net transfer capacity in forward direction [tH2]
|
|
452
|
+
par['pH2PipeNTCBck'] = dfs['dfNetworkHydrogen']['TTCBck' ] * dfs['dfNetworkHydrogen']['SecurityFactor' ] # net transfer capacity in backward direction [tH2]
|
|
453
|
+
par['pH2PipeFixedCost'] = dfs['dfNetworkHydrogen']['FixedInvestmentCost'] * dfs['dfNetworkHydrogen']['FixedChargeRate'] # hydrogen network fixed cost [MEUR]
|
|
454
|
+
par['pIndBinH2PipeInvest'] = dfs['dfNetworkHydrogen']['BinaryInvestment' ] # binary hydrogen pipeline investment decision [Yes]
|
|
455
|
+
par['pH2PipeLoInvest'] = dfs['dfNetworkHydrogen']['InvestmentLo' ] # Lower bound of the investment decision [p.u.]
|
|
456
|
+
par['pH2PipeUpInvest'] = dfs['dfNetworkHydrogen']['InvestmentUp' ] # Upper bound of the investment decision [p.u.]
|
|
457
|
+
|
|
458
|
+
par['pH2PipePeriodFin'] = par['pH2PipePeriodFin'].where(par['pH2PipePeriodFin'] != 0.0, 3000 )
|
|
556
459
|
# replace pH2PipeNTCBck = 0.0 by pH2PipeNTCFrw
|
|
557
|
-
pH2PipeNTCBck
|
|
460
|
+
par['pH2PipeNTCBck'] = par['pH2PipeNTCBck'].where (par['pH2PipeNTCBck'] > 0.0, par['pH2PipeNTCFrw'])
|
|
558
461
|
# replace pH2PipeNTCFrw = 0.0 by pH2PipeNTCBck
|
|
559
|
-
pH2PipeNTCFrw
|
|
462
|
+
par['pH2PipeNTCFrw'] = par['pH2PipeNTCFrw'].where (par['pH2PipeNTCFrw'] > 0.0, par['pH2PipeNTCBck'])
|
|
560
463
|
# replace pH2PipeUpInvest = 0.0 by 1.0
|
|
561
|
-
pH2PipeUpInvest
|
|
562
|
-
|
|
563
|
-
if pIndHeat == 1:
|
|
564
|
-
pHeatPipeLength = dfNetworkHeat['Length' ]
|
|
565
|
-
pHeatPipePeriodIni = dfNetworkHeat['InitialPeriod' ]
|
|
566
|
-
pHeatPipePeriodFin = dfNetworkHeat['FinalPeriod' ]
|
|
567
|
-
pHeatPipeNTCFrw = dfNetworkHeat['TTC' ] * 1e-3 * dfNetworkHeat ['SecurityFactor' ] # net transfer capacity in forward direction [GW]
|
|
568
|
-
pHeatPipeNTCBck = dfNetworkHeat['TTCBck' ] * 1e-3 * dfNetworkHeat ['SecurityFactor' ] # net transfer capacity in backward direction [GW]
|
|
569
|
-
pHeatPipeFixedCost = dfNetworkHeat['FixedInvestmentCost'] * dfNetworkHeat ['FixedChargeRate'] # heat network fixed cost [MEUR]
|
|
570
|
-
pIndBinHeatPipeInvest = dfNetworkHeat['BinaryInvestment' ]
|
|
571
|
-
pHeatPipeLoInvest = dfNetworkHeat['InvestmentLo' ]
|
|
572
|
-
pHeatPipeUpInvest = dfNetworkHeat['InvestmentUp' ]
|
|
573
|
-
|
|
574
|
-
pHeatPipePeriodFin
|
|
464
|
+
par['pH2PipeUpInvest'] = par['pH2PipeUpInvest'].where(par['pH2PipeUpInvest'] > 0.0, 1.0 )
|
|
465
|
+
|
|
466
|
+
if par['pIndHeat'] == 1:
|
|
467
|
+
par['pHeatPipeLength'] = dfs['dfNetworkHeat']['Length' ] # heat pipe length [km]
|
|
468
|
+
par['pHeatPipePeriodIni'] = dfs['dfNetworkHeat']['InitialPeriod' ] # initial period
|
|
469
|
+
par['pHeatPipePeriodFin'] = dfs['dfNetworkHeat']['FinalPeriod' ] # final period
|
|
470
|
+
par['pHeatPipeNTCFrw'] = dfs['dfNetworkHeat']['TTC' ] * 1e-3 * dfs['dfNetworkHeat'] ['SecurityFactor' ] # net transfer capacity in forward direction [GW]
|
|
471
|
+
par['pHeatPipeNTCBck'] = dfs['dfNetworkHeat']['TTCBck' ] * 1e-3 * dfs['dfNetworkHeat'] ['SecurityFactor' ] # net transfer capacity in backward direction [GW]
|
|
472
|
+
par['pHeatPipeFixedCost'] = dfs['dfNetworkHeat']['FixedInvestmentCost'] * dfs['dfNetworkHeat'] ['FixedChargeRate'] # heat network fixed cost [MEUR]
|
|
473
|
+
par['pIndBinHeatPipeInvest'] = dfs['dfNetworkHeat']['BinaryInvestment' ] # binary heat pipe investment decision [Yes]
|
|
474
|
+
par['pHeatPipeLoInvest'] = dfs['dfNetworkHeat']['InvestmentLo' ] # Lower bound of the investment decision [p.u.]
|
|
475
|
+
par['pHeatPipeUpInvest'] = dfs['dfNetworkHeat']['InvestmentUp' ] # Upper bound of the investment decision [p.u.]
|
|
476
|
+
|
|
477
|
+
par['pHeatPipePeriodFin'] = par['pHeatPipePeriodFin'].where(par['pHeatPipePeriodFin'] != 0.0, 3000 )
|
|
575
478
|
# replace pHeatPipeNTCBck = 0.0 by pHeatPipeNTCFrw
|
|
576
|
-
pHeatPipeNTCBck
|
|
479
|
+
par['pHeatPipeNTCBck'] = par['pHeatPipeNTCBck'].where (par['pHeatPipeNTCBck'] > 0.0, par['pHeatPipeNTCFrw'])
|
|
577
480
|
# replace pHeatPipeNTCFrw = 0.0 by pHeatPipeNTCBck
|
|
578
|
-
pHeatPipeNTCFrw
|
|
481
|
+
par['pHeatPipeNTCFrw'] = par['pHeatPipeNTCFrw'].where (par['pHeatPipeNTCFrw'] > 0.0, par['pHeatPipeNTCBck'])
|
|
579
482
|
# replace pHeatPipeUpInvest = 0.0 by 1.0
|
|
580
|
-
pHeatPipeUpInvest
|
|
483
|
+
par['pHeatPipeUpInvest'] = par['pHeatPipeUpInvest'].where (par['pHeatPipeUpInvest'] > 0.0, 1.0 )
|
|
484
|
+
|
|
485
|
+
#%% storing the parameters in the model
|
|
486
|
+
mTEPES.dFrame = dfs
|
|
487
|
+
mTEPES.dPar = par
|
|
581
488
|
|
|
582
489
|
ReadingDataTime = time.time() - StartTime
|
|
583
490
|
StartTime = time.time()
|
|
584
491
|
print('Reading input data ... ', round(ReadingDataTime), 's')
|
|
585
492
|
|
|
493
|
+
|
|
494
|
+
def DataConfiguration(mTEPES):
|
|
495
|
+
|
|
496
|
+
StartTime = time.time()
|
|
586
497
|
#%% Getting the branches from the electric network data
|
|
587
|
-
sBr = [(ni,nf) for (ni,nf,cc) in dfNetwork.index]
|
|
498
|
+
sBr = [(ni,nf) for (ni,nf,cc) in mTEPES.dFrame['dfNetwork'].index]
|
|
588
499
|
# Dropping duplicate keys
|
|
589
500
|
sBrList = [(ni,nf) for n,(ni,nf) in enumerate(sBr) if (ni,nf) not in sBr[:n]]
|
|
590
501
|
|
|
591
502
|
#%% defining subsets: active load levels (n,n2), thermal units (t), RES units (r), ESS units (es), candidate gen units (gc), candidate ESS units (ec), all the electric lines (la), candidate electric lines (lc), candidate DC electric lines (cd), existing DC electric lines (cd), electric lines with losses (ll), reference node (rf), and reactive generating units (gq)
|
|
592
|
-
mTEPES.p = Set(doc='periods' , initialize=[pp for pp in mTEPES.pp if pPeriodWeight [pp] > 0.0 and sum(pDuration[pp,sc,n] for sc,n in mTEPES.scc*mTEPES.nn)])
|
|
593
|
-
mTEPES.sc = Set(doc='scenarios' , initialize=[scc for scc in mTEPES.scc
|
|
594
|
-
mTEPES.ps = Set(doc='periods/scenarios' , initialize=[(p,sc) for p,sc in mTEPES.p*mTEPES.sc if pScenProb [p,sc] > 0.0 and sum(pDuration[p,sc,n ] for n in mTEPES.nn)])
|
|
595
|
-
mTEPES.st = Set(doc='stages' , initialize=[stt for stt in mTEPES.stt if pStageWeight [stt] > 0.0])
|
|
596
|
-
mTEPES.n = Set(doc='load levels' , initialize=[nn for nn in mTEPES.nn if sum(pDuration [p,sc,nn] for p,sc in mTEPES.ps) > 0])
|
|
597
|
-
mTEPES.n2 = Set(doc='load levels' , initialize=[nn for nn in mTEPES.nn if sum(pDuration [p,sc,nn] for p,sc in mTEPES.ps) > 0])
|
|
598
|
-
mTEPES.g = Set(doc='generating units' , initialize=[gg for gg in mTEPES.gg if (pRatedMaxPowerElec [gg] > 0.0 or pRatedMaxCharge[gg] > 0.0
|
|
599
|
-
mTEPES.t = Set(doc='thermal units' , initialize=[g for g in mTEPES.g if pRatedLinearOperCost[g ] > 0.0])
|
|
600
|
-
mTEPES.re = Set(doc='RES units' , initialize=[g for g in mTEPES.g if pRatedLinearOperCost[g ] == 0.0 and pRatedMaxStorage[g] == 0.0 and pProductionFunctionH2[g ] == 0.0 and pProductionFunctionHeat[g ]
|
|
601
|
-
mTEPES.es = Set(doc='ESS units' , initialize=[g for g in mTEPES.g if (pRatedMaxCharge[g ] > 0.0 or pRatedMaxStorage[g] > 0.0 or pProductionFunctionH2[g ] > 0.0 or pProductionFunctionHeat[g ]
|
|
602
|
-
mTEPES.h = Set(doc='hydro units' , initialize=[g for g in mTEPES.g
|
|
603
|
-
mTEPES.el = Set(doc='electrolyzer units' , initialize=[es for es in mTEPES.es
|
|
604
|
-
mTEPES.hp = Set(doc='heat pump & elec boiler units' , initialize=[es for es in mTEPES.es
|
|
605
|
-
mTEPES.ch = Set(doc='CHP & fuel boiler units' , initialize=[g for g in mTEPES.g if
|
|
606
|
-
mTEPES.bo = Set(doc=' fuel boiler units' , initialize=[ch for ch in mTEPES.ch if pRatedMaxPowerElec [ch] == 0.0 and pRatedMaxPowerHeat[ch] > 0.0 and pProductionFunctionHeat [ch] == 0.0])
|
|
607
|
-
mTEPES.hh = Set(doc=' hydrogen boiler units' , initialize=[bo for bo in mTEPES.bo
|
|
608
|
-
mTEPES.gc = Set(doc='candidate units' , initialize=[g for g in mTEPES.g if pGenInvestCost [g ] > 0.0])
|
|
609
|
-
mTEPES.gd = Set(doc='retirement units' , initialize=[g for g in mTEPES.g if pGenRetireCost [g ] > 0.0])
|
|
610
|
-
mTEPES.ec = Set(doc='candidate ESS units' , initialize=[es for es in mTEPES.es if pGenInvestCost [es] > 0.0])
|
|
611
|
-
mTEPES.bc = Set(doc='candidate boiler units' , initialize=[bo for bo in mTEPES.bo if pGenInvestCost [bo] > 0.0])
|
|
503
|
+
mTEPES.p = Set(doc='periods' , initialize=[pp for pp in mTEPES.pp if mTEPES.dPar['pPeriodWeight'] [pp] > 0.0 and sum(mTEPES.dPar['pDuration'][pp,sc,n] for sc,n in mTEPES.scc*mTEPES.nn)])
|
|
504
|
+
mTEPES.sc = Set(doc='scenarios' , initialize=[scc for scc in mTEPES.scc ])
|
|
505
|
+
mTEPES.ps = Set(doc='periods/scenarios' , initialize=[(p,sc) for p,sc in mTEPES.p*mTEPES.sc if mTEPES.dPar['pScenProb'] [p,sc] > 0.0 and sum(mTEPES.dPar['pDuration'][p,sc,n ] for n in mTEPES.nn)])
|
|
506
|
+
mTEPES.st = Set(doc='stages' , initialize=[stt for stt in mTEPES.stt if mTEPES.dPar['pStageWeight'] [stt] > 0.0])
|
|
507
|
+
mTEPES.n = Set(doc='load levels' , initialize=[nn for nn in mTEPES.nn if sum(mTEPES.dPar['pDuration'] [p,sc,nn] for p,sc in mTEPES.ps) > 0])
|
|
508
|
+
mTEPES.n2 = Set(doc='load levels' , initialize=[nn for nn in mTEPES.nn if sum(mTEPES.dPar['pDuration'] [p,sc,nn] for p,sc in mTEPES.ps) > 0])
|
|
509
|
+
mTEPES.g = Set(doc='generating units' , initialize=[gg for gg in mTEPES.gg if (mTEPES.dPar['pRatedMaxPowerElec'] [gg] > 0.0 or mTEPES.dPar['pRatedMaxCharge'][gg] > 0.0 or mTEPES.dPar['pRatedMaxPowerHeat'] [gg] > 0.0) and mTEPES.dPar['pElecGenPeriodIni'][gg] <= mTEPES.p.last() and mTEPES.dPar['pElecGenPeriodFin'][gg] >= mTEPES.p.first() and mTEPES.dPar['pGenToNode'].reset_index().set_index(['Generator']).isin(mTEPES.nd)['Node'][gg]]) # excludes generators with empty node
|
|
510
|
+
mTEPES.t = Set(doc='thermal units' , initialize=[g for g in mTEPES.g if mTEPES.dPar['pRatedLinearOperCost'][g ] > 0.0])
|
|
511
|
+
mTEPES.re = Set(doc='RES units' , initialize=[g for g in mTEPES.g if mTEPES.dPar['pRatedLinearOperCost'][g ] == 0.0 and mTEPES.dPar['pRatedMaxStorage'][g] == 0.0 and mTEPES.dPar['pProductionFunctionH2'][g ] == 0.0 and mTEPES.dPar['pProductionFunctionHeat'][g ] == 0.0 and mTEPES.dPar['pProductionFunctionHydro'][g ] == 0.0])
|
|
512
|
+
mTEPES.es = Set(doc='ESS units' , initialize=[g for g in mTEPES.g if (mTEPES.dPar['pRatedMaxCharge'][g ] > 0.0 or mTEPES.dPar['pRatedMaxStorage'][g] > 0.0 or mTEPES.dPar['pProductionFunctionH2'][g ] > 0.0 or mTEPES.dPar['pProductionFunctionHeat'][g ] > 0.0) and mTEPES.dPar['pProductionFunctionHydro'][g ] == 0.0])
|
|
513
|
+
mTEPES.h = Set(doc='hydro units' , initialize=[g for g in mTEPES.g if mTEPES.dPar['pProductionFunctionH2'][g ] == 0.0 and mTEPES.dPar['pProductionFunctionHeat'][g ] == 0.0 and mTEPES.dPar['pProductionFunctionHydro'][g ] > 0.0])
|
|
514
|
+
mTEPES.el = Set(doc='electrolyzer units' , initialize=[es for es in mTEPES.es if mTEPES.dPar['pProductionFunctionH2'][es] > 0.0 and mTEPES.dPar['pProductionFunctionHeat'][es] == 0.0 and mTEPES.dPar['pProductionFunctionHydro'][es] == 0.0])
|
|
515
|
+
mTEPES.hp = Set(doc='heat pump & elec boiler units' , initialize=[es for es in mTEPES.es if mTEPES.dPar['pProductionFunctionH2'][es] == 0.0 and mTEPES.dPar['pProductionFunctionHeat'][es] > 0.0 and mTEPES.dPar['pProductionFunctionHydro'][es] == 0.0])
|
|
516
|
+
mTEPES.ch = Set(doc='CHP & fuel boiler units' , initialize=[g for g in mTEPES.g if mTEPES.dPar['pRatedMaxPowerHeat'][g ] > 0.0 and mTEPES.dPar['pProductionFunctionHeat'] [g ] == 0.0])
|
|
517
|
+
mTEPES.bo = Set(doc=' fuel boiler units' , initialize=[ch for ch in mTEPES.ch if mTEPES.dPar['pRatedMaxPowerElec'] [ch] == 0.0 and mTEPES.dPar['pRatedMaxPowerHeat'][ch] > 0.0 and mTEPES.dPar['pProductionFunctionHeat'] [ch] == 0.0])
|
|
518
|
+
mTEPES.hh = Set(doc=' hydrogen boiler units' , initialize=[bo for bo in mTEPES.bo if mTEPES.dPar['pProductionFunctionH2ToHeat'][bo] > 0.0])
|
|
519
|
+
mTEPES.gc = Set(doc='candidate units' , initialize=[g for g in mTEPES.g if mTEPES.dPar['pGenInvestCost'] [g ] > 0.0])
|
|
520
|
+
mTEPES.gd = Set(doc='retirement units' , initialize=[g for g in mTEPES.g if mTEPES.dPar['pGenRetireCost'] [g ] > 0.0])
|
|
521
|
+
mTEPES.ec = Set(doc='candidate ESS units' , initialize=[es for es in mTEPES.es if mTEPES.dPar['pGenInvestCost'] [es] > 0.0])
|
|
522
|
+
mTEPES.bc = Set(doc='candidate boiler units' , initialize=[bo for bo in mTEPES.bo if mTEPES.dPar['pGenInvestCost'] [bo] > 0.0])
|
|
612
523
|
mTEPES.br = Set(doc='all input electric branches', initialize=sBrList )
|
|
613
|
-
mTEPES.ln = Set(doc='all input electric lines' , initialize=dfNetwork.index)
|
|
614
|
-
if len(mTEPES.ln) != len(dfNetwork.index):
|
|
615
|
-
raise ValueError('### Some electric lines are invalid ', len(mTEPES.ln), len(dfNetwork.index))
|
|
616
|
-
mTEPES.la = Set(doc='all real electric lines' , initialize=[ln for ln in mTEPES.ln if pLineX [ln] != 0.0 and pLineNTCFrw[ln] > 0.0 and pLineNTCBck[ln] > 0.0 and pElecNetPeriodIni[ln] <= mTEPES.p.last() and pElecNetPeriodFin[ln] >= mTEPES.p.first()])
|
|
617
|
-
mTEPES.ls = Set(doc='all real switch electric lines' , initialize=[la for la in mTEPES.la if pIndBinLineSwitch [la] ])
|
|
618
|
-
mTEPES.lc = Set(doc='candidate electric lines' , initialize=[la for la in mTEPES.la if pNetFixedCost [la] > 0.0])
|
|
619
|
-
mTEPES.cd = Set(doc='candidate DC electric lines' , initialize=[la for la in mTEPES.la if pNetFixedCost [la] > 0.0 and pLineType[la] == 'DC'])
|
|
620
|
-
mTEPES.ed = Set(doc='existing DC electric lines' , initialize=[la for la in mTEPES.la if pNetFixedCost [la] == 0.0 and pLineType[la] == 'DC'])
|
|
621
|
-
mTEPES.ll = Set(doc='loss electric lines' , initialize=[la for la in mTEPES.la if pLineLossFactor [la] > 0.0 and pIndBinNetLosses > 0 ])
|
|
622
|
-
mTEPES.rf = Set(doc='reference node' , initialize=[pReferenceNode])
|
|
623
|
-
mTEPES.gq = Set(doc='gen reactive units' , initialize=[gg for gg in mTEPES.gg if pRMaxReactivePower [gg] > 0.0 and
|
|
624
|
-
mTEPES.sq = Set(doc='synchr reactive units' , initialize=[gg for gg in mTEPES.gg if pRMaxReactivePower [gg] > 0.0 and pGenToTechnology[gg] == 'SynchronousCondenser' and pElecGenPeriodIni[gg] <= mTEPES.p.last() and pElecGenPeriodFin[gg] >= mTEPES.p.first()])
|
|
524
|
+
mTEPES.ln = Set(doc='all input electric lines' , initialize=mTEPES.dFrame['dfNetwork'].index)
|
|
525
|
+
if len(mTEPES.ln) != len(mTEPES.dFrame['dfNetwork'].index):
|
|
526
|
+
raise ValueError('### Some electric lines are invalid ', len(mTEPES.ln), len(mTEPES.dFrame['dfNetwork'].index))
|
|
527
|
+
mTEPES.la = Set(doc='all real electric lines' , initialize=[ln for ln in mTEPES.ln if mTEPES.dPar['pLineX'] [ln] != 0.0 and mTEPES.dPar['pLineNTCFrw'][ln] > 0.0 and mTEPES.dPar['pLineNTCBck'][ln] > 0.0 and mTEPES.dPar['pElecNetPeriodIni'][ln] <= mTEPES.p.last() and mTEPES.dPar['pElecNetPeriodFin'][ln] >= mTEPES.p.first()])
|
|
528
|
+
mTEPES.ls = Set(doc='all real switch electric lines' , initialize=[la for la in mTEPES.la if mTEPES.dPar['pIndBinLineSwitch'] [la] ])
|
|
529
|
+
mTEPES.lc = Set(doc='candidate electric lines' , initialize=[la for la in mTEPES.la if mTEPES.dPar['pNetFixedCost'] [la] > 0.0])
|
|
530
|
+
mTEPES.cd = Set(doc='candidate DC electric lines' , initialize=[la for la in mTEPES.la if mTEPES.dPar['pNetFixedCost'] [la] > 0.0 and mTEPES.dPar['pLineType'][la] == 'DC'])
|
|
531
|
+
mTEPES.ed = Set(doc='existing DC electric lines' , initialize=[la for la in mTEPES.la if mTEPES.dPar['pNetFixedCost'] [la] == 0.0 and mTEPES.dPar['pLineType'][la] == 'DC'])
|
|
532
|
+
mTEPES.ll = Set(doc='loss electric lines' , initialize=[la for la in mTEPES.la if mTEPES.dPar['pLineLossFactor'] [la] > 0.0 and mTEPES.dPar['pIndBinNetLosses'] > 0 ])
|
|
533
|
+
mTEPES.rf = Set(doc='reference node' , initialize=[mTEPES.dPar['pReferenceNode']])
|
|
534
|
+
mTEPES.gq = Set(doc='gen reactive units' , initialize=[gg for gg in mTEPES.gg if mTEPES.dPar['pRMaxReactivePower'] [gg] > 0.0 and mTEPES.dPar['pElecGenPeriodIni'][gg] <= mTEPES.p.last() and mTEPES.dPar['pElecGenPeriodFin'][gg] >= mTEPES.p.first()])
|
|
535
|
+
mTEPES.sq = Set(doc='synchr reactive units' , initialize=[gg for gg in mTEPES.gg if mTEPES.dPar['pRMaxReactivePower'] [gg] > 0.0 and mTEPES.dPar['pGenToTechnology'][gg] == 'SynchronousCondenser' and mTEPES.dPar['pElecGenPeriodIni'][gg] <= mTEPES.p.last() and mTEPES.dPar['pElecGenPeriodFin'][gg] >= mTEPES.p.first()])
|
|
625
536
|
mTEPES.sqc = Set(doc='synchr reactive candidate')
|
|
626
537
|
mTEPES.shc = Set(doc='shunt candidate')
|
|
627
|
-
if pIndHydroTopology == 1:
|
|
628
|
-
mTEPES.rn = Set(doc='candidate reservoirs' , initialize=[rs for rs in mTEPES.rs
|
|
538
|
+
if mTEPES.dPar['pIndHydroTopology'] == 1:
|
|
539
|
+
mTEPES.rn = Set(doc='candidate reservoirs' , initialize=[rs for rs in mTEPES.rs if mTEPES.dPar['pRsrInvestCost'] [rs] > 0.0 and mTEPES.dPar['pRsrPeriodIni'][rs] <= mTEPES.p.last() and mTEPES.dPar['pRsrPeriodFin'][rs] >= mTEPES.p.first()])
|
|
629
540
|
else:
|
|
630
541
|
mTEPES.rn = Set(doc='candidate reservoirs' , initialize=[])
|
|
631
|
-
if pIndHydrogen == 1:
|
|
632
|
-
mTEPES.pn = Set(doc='all input hydrogen pipes' , initialize=dfNetworkHydrogen.index)
|
|
633
|
-
if len(mTEPES.pn) != len(dfNetworkHydrogen.index):
|
|
634
|
-
raise ValueError('### Some hydrogen pipes are invalid ', len(mTEPES.pn), len(dfNetworkHydrogen.index))
|
|
635
|
-
mTEPES.pa = Set(doc='all real hydrogen pipes' , initialize=[pn for pn in mTEPES.pn
|
|
636
|
-
mTEPES.pc = Set(doc='candidate hydrogen pipes' , initialize=[pa for pa in mTEPES.pa
|
|
542
|
+
if mTEPES.dPar['pIndHydrogen'] == 1:
|
|
543
|
+
mTEPES.pn = Set(doc='all input hydrogen pipes' , initialize=mTEPES.dFrame['dfNetworkHydrogen'].index)
|
|
544
|
+
if len(mTEPES.pn) != len(mTEPES.dFrame['dfNetworkHydrogen'].index):
|
|
545
|
+
raise ValueError('### Some hydrogen pipes are invalid ', len(mTEPES.pn), len(mTEPES.dFrame['dfNetworkHydrogen'].index))
|
|
546
|
+
mTEPES.pa = Set(doc='all real hydrogen pipes' , initialize=[pn for pn in mTEPES.pn if mTEPES.dPar['pH2PipeNTCFrw'] [pn] > 0.0 and mTEPES.dPar['pH2PipeNTCBck'][pn] > 0.0 and mTEPES.dPar['pH2PipePeriodIni'][pn] <= mTEPES.p.last() and mTEPES.dPar['pH2PipePeriodFin'][pn] >= mTEPES.p.first()])
|
|
547
|
+
mTEPES.pc = Set(doc='candidate hydrogen pipes' , initialize=[pa for pa in mTEPES.pa if mTEPES.dPar['pH2PipeFixedCost'] [pa] > 0.0])
|
|
637
548
|
# existing hydrogen pipelines (pe)
|
|
638
549
|
mTEPES.pe = mTEPES.pa - mTEPES.pc
|
|
639
550
|
else:
|
|
@@ -641,12 +552,12 @@ def InputData(DirName, CaseName, mTEPES, pIndLogConsole):
|
|
|
641
552
|
mTEPES.pa = Set(doc='all real hydrogen pipes' , initialize=[])
|
|
642
553
|
mTEPES.pc = Set(doc='candidate hydrogen pipes' , initialize=[])
|
|
643
554
|
|
|
644
|
-
if pIndHeat == 1:
|
|
645
|
-
mTEPES.hn = Set(doc='all input heat pipes' , initialize=dfNetworkHeat.index)
|
|
646
|
-
if len(mTEPES.hn) != len(dfNetworkHeat.index):
|
|
647
|
-
raise ValueError('### Some heat pipes are invalid ', len(mTEPES.hn), len(dfNetworkHeat.index))
|
|
648
|
-
mTEPES.ha = Set(doc='all real heat pipes' , initialize=[hn for hn in mTEPES.hn if pHeatPipeNTCFrw [hn] > 0.0 and pHeatPipeNTCBck[hn] > 0.0 and pHeatPipePeriodIni[hn] <= mTEPES.p.last() and pHeatPipePeriodFin[hn] >= mTEPES.p.first()])
|
|
649
|
-
mTEPES.hc = Set(doc='candidate heat pipes' , initialize=[ha for ha in mTEPES.ha if pHeatPipeFixedCost [ha] > 0.0])
|
|
555
|
+
if mTEPES.dPar['pIndHeat'] == 1:
|
|
556
|
+
mTEPES.hn = Set(doc='all input heat pipes' , initialize=mTEPES.dFrame['dfNetworkHeat'].index)
|
|
557
|
+
if len(mTEPES.hn) != len(mTEPES.dFrame['dfNetworkHeat'].index):
|
|
558
|
+
raise ValueError('### Some heat pipes are invalid ', len(mTEPES.hn), len(mTEPES.dFrame['dfNetworkHeat'].index))
|
|
559
|
+
mTEPES.ha = Set(doc='all real heat pipes' , initialize=[hn for hn in mTEPES.hn if mTEPES.dPar['pHeatPipeNTCFrw'] [hn] > 0.0 and mTEPES.dPar['pHeatPipeNTCBck'][hn] > 0.0 and mTEPES.dPar['pHeatPipePeriodIni'][hn] <= mTEPES.p.last() and mTEPES.dPar['pHeatPipePeriodFin'][hn] >= mTEPES.p.first()])
|
|
560
|
+
mTEPES.hc = Set(doc='candidate heat pipes' , initialize=[ha for ha in mTEPES.ha if mTEPES.dPar['pHeatPipeFixedCost'] [ha] > 0.0])
|
|
650
561
|
# existing heat pipes (he)
|
|
651
562
|
mTEPES.he = mTEPES.ha - mTEPES.hc
|
|
652
563
|
else:
|
|
@@ -654,15 +565,15 @@ def InputData(DirName, CaseName, mTEPES, pIndLogConsole):
|
|
|
654
565
|
mTEPES.ha = Set(doc='all real heat pipes' , initialize=[])
|
|
655
566
|
mTEPES.hc = Set(doc='candidate heat pipes' , initialize=[])
|
|
656
567
|
|
|
657
|
-
pIndBinLinePTDF = pd.Series(index=mTEPES.la, data=0.0)
|
|
658
|
-
if pIndVarTTC == 1:
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
if pIndPTDF == 1:
|
|
568
|
+
mTEPES.dPar['pIndBinLinePTDF'] = pd.Series(index=mTEPES.la, data=0.0) # indicate if the line has a PTDF or not
|
|
569
|
+
if mTEPES.dPar['pIndVarTTC'] == 1:
|
|
570
|
+
mTEPES.dPar['pVariableNTCFrw'] = mTEPES.dPar['pVariableNTCFrw'].reindex(columns=mTEPES.la, fill_value=0.0) * mTEPES.dFrame['dfNetwork']['SecurityFactor'] # variable NTC forward direction because of the security factor
|
|
571
|
+
mTEPES.dPar['pVariableNTCBck'] = mTEPES.dPar['pVariableNTCBck'].reindex(columns=mTEPES.la, fill_value=0.0) * mTEPES.dFrame['dfNetwork']['SecurityFactor'] # variable NTC backward direction because of the security factor
|
|
572
|
+
if mTEPES.dPar['pIndPTDF'] == 1:
|
|
662
573
|
# get the level_3, level_4, and level_5 from multiindex of pVariablePTDF
|
|
663
|
-
PTDF_columns = pVariablePTDF.columns
|
|
574
|
+
PTDF_columns = mTEPES.dPar['pVariablePTDF'].columns
|
|
664
575
|
PTDF_lines = PTDF_columns.droplevel([3]).drop_duplicates()
|
|
665
|
-
pIndBinLinePTDF.loc[:] = pIndBinLinePTDF.index.isin(PTDF_lines).astype(float)
|
|
576
|
+
mTEPES.dPar['pIndBinLinePTDF'].loc[:] = mTEPES.dPar['pIndBinLinePTDF'].index.isin(PTDF_lines).astype(float)
|
|
666
577
|
|
|
667
578
|
# non-RES units, they can be committed and also contribute to the operating reserves
|
|
668
579
|
mTEPES.nr = mTEPES.g - mTEPES.re
|
|
@@ -680,14 +591,14 @@ def InputData(DirName, CaseName, mTEPES, pIndLogConsole):
|
|
|
680
591
|
mTEPES.eb = mTEPES.gc | mTEPES.bc
|
|
681
592
|
|
|
682
593
|
#%% inverse index load level to stage
|
|
683
|
-
pStageToLevel = pLevelToStage.reset_index().set_index(['Period','Scenario','Stage'])['LoadLevel']
|
|
594
|
+
mTEPES.dPar['pStageToLevel'] = mTEPES.dPar['pLevelToStage'].reset_index().set_index(['Period','Scenario','Stage'])['LoadLevel']
|
|
684
595
|
#Filter only valid indices
|
|
685
|
-
pStageToLevel = pStageToLevel.loc[pStageToLevel.index.isin([(p,s,st) for (p,s) in mTEPES.ps for st in mTEPES.st]) & pStageToLevel.isin(mTEPES.n)]
|
|
596
|
+
mTEPES.dPar['pStageToLevel'] = mTEPES.dPar['pStageToLevel'].loc[mTEPES.dPar['pStageToLevel'].index.isin([(p,s,st) for (p,s) in mTEPES.ps for st in mTEPES.st]) & mTEPES.dPar['pStageToLevel'].isin(mTEPES.n)]
|
|
686
597
|
#Reorder the elements
|
|
687
|
-
pStageToLevel = [(p,sc,st,n) for (p,sc,st),n in pStageToLevel.items()]
|
|
688
|
-
mTEPES.s2n = Set(initialize=pStageToLevel, doc='Load level to stage')
|
|
598
|
+
mTEPES.dPar['pStageToLevel'] = [(p,sc,st,n) for (p,sc,st),n in mTEPES.dPar['pStageToLevel'].items()]
|
|
599
|
+
mTEPES.s2n = Set(initialize=mTEPES.dPar['pStageToLevel'], doc='Load level to stage')
|
|
689
600
|
# all the stages must have the same duration
|
|
690
|
-
pStageDuration = pd.Series([sum(pDuration[p,sc,n] for p,sc,st2,n in mTEPES.s2n if st2 == st) for st in mTEPES.st], index=mTEPES.st)
|
|
601
|
+
mTEPES.dPar['pStageDuration'] = pd.Series([sum(mTEPES.dPar['pDuration'][p,sc,n] for p,sc,st2,n in mTEPES.s2n if st2 == st) for st in mTEPES.st], index=mTEPES.st)
|
|
691
602
|
# for st in mTEPES.st:
|
|
692
603
|
# if mTEPES.st.ord(st) > 1 and pStageDuration[st] != pStageDuration[mTEPES.st.prev(st)]:
|
|
693
604
|
# assert (0 == 1)
|
|
@@ -695,10 +606,10 @@ def InputData(DirName, CaseName, mTEPES, pIndLogConsole):
|
|
|
695
606
|
# delete all the load level belonging to stages with duration equal to zero
|
|
696
607
|
mTEPES.del_component(mTEPES.n )
|
|
697
608
|
mTEPES.del_component(mTEPES.n2)
|
|
698
|
-
mTEPES.n = Set(doc='load levels', initialize=[nn for nn in mTEPES.nn if sum(pDuration[p,sc,nn] for p,sc in mTEPES.ps) > 0])
|
|
699
|
-
mTEPES.n2 = Set(doc='load levels', initialize=[nn for nn in mTEPES.nn if sum(pDuration[p,sc,nn] for p,sc in mTEPES.ps) > 0])
|
|
609
|
+
mTEPES.n = Set(doc='load levels', initialize=[nn for nn in mTEPES.nn if sum(mTEPES.dPar['pDuration'][p,sc,nn] for p,sc in mTEPES.ps) > 0])
|
|
610
|
+
mTEPES.n2 = Set(doc='load levels', initialize=[nn for nn in mTEPES.nn if sum(mTEPES.dPar['pDuration'][p,sc,nn] for p,sc in mTEPES.ps) > 0])
|
|
700
611
|
# instrumental sets
|
|
701
|
-
def CreateInstrumentalSets(mTEPES, pIndHydroTopology, pIndHydrogen, pIndHeat) -> None:
|
|
612
|
+
def CreateInstrumentalSets(mTEPES, pIndHydroTopology, pIndHydrogen, pIndHeat, pIndPTDF) -> None:
|
|
702
613
|
'''
|
|
703
614
|
Create mTEPES instrumental sets.
|
|
704
615
|
|
|
@@ -710,7 +621,7 @@ def InputData(DirName, CaseName, mTEPES, pIndLogConsole):
|
|
|
710
621
|
Returns:
|
|
711
622
|
None: Sets are added directly to the mTEPES object.
|
|
712
623
|
'''
|
|
713
|
-
mTEPES.pg = Set(initialize = [(p, g ) for p, g in mTEPES.p *mTEPES.g if pElecGenPeriodIni[g ] <= p and pElecGenPeriodFin[g ] >= p])
|
|
624
|
+
mTEPES.pg = Set(initialize = [(p, g ) for p, g in mTEPES.p *mTEPES.g if mTEPES.dPar['pElecGenPeriodIni'][g ] <= p and mTEPES.dPar['pElecGenPeriodFin'][g ] >= p])
|
|
714
625
|
mTEPES.pgc = Set(initialize = [(p, gc ) for p, gc in mTEPES.p *mTEPES.gc if (p,gc) in mTEPES.pg])
|
|
715
626
|
mTEPES.pnr = Set(initialize = [(p, nr ) for p, nr in mTEPES.p *mTEPES.nr if (p,nr) in mTEPES.pg])
|
|
716
627
|
mTEPES.pch = Set(initialize = [(p, ch ) for p, ch in mTEPES.p *mTEPES.ch if (p,ch) in mTEPES.pg])
|
|
@@ -728,7 +639,7 @@ def InputData(DirName, CaseName, mTEPES, pIndLogConsole):
|
|
|
728
639
|
mTEPES.ph = Set(initialize = [(p, h ) for p, h in mTEPES.p *mTEPES.h if (p,h ) in mTEPES.pg])
|
|
729
640
|
mTEPES.pgd = Set(initialize = [(p, gd ) for p, gd in mTEPES.p *mTEPES.gd if (p,gd) in mTEPES.pg])
|
|
730
641
|
mTEPES.par = Set(initialize = [(p, ar ) for p, ar in mTEPES.p *mTEPES.ar ])
|
|
731
|
-
mTEPES.pla = Set(initialize = [(p, ni,nf,cc) for p, ni,nf,cc in mTEPES.p *mTEPES.la if pElecNetPeriodIni[ni,nf,cc] <= p and pElecNetPeriodFin[ni,nf,cc] >= p])
|
|
642
|
+
mTEPES.pla = Set(initialize = [(p, ni,nf,cc) for p, ni,nf,cc in mTEPES.p *mTEPES.la if mTEPES.dPar['pElecNetPeriodIni'][ni,nf,cc] <= p and mTEPES.dPar['pElecNetPeriodFin'][ni,nf,cc] >= p])
|
|
732
643
|
mTEPES.plc = Set(initialize = [(p, ni,nf,cc) for p, ni,nf,cc in mTEPES.p *mTEPES.lc if (p,ni,nf,cc) in mTEPES.pla])
|
|
733
644
|
mTEPES.pll = Set(initialize = [(p, ni,nf,cc) for p, ni,nf,cc in mTEPES.p *mTEPES.ll if (p,ni,nf,cc) in mTEPES.pla])
|
|
734
645
|
|
|
@@ -758,10 +669,10 @@ def InputData(DirName, CaseName, mTEPES, pIndLogConsole):
|
|
|
758
669
|
mTEPES.psnll = Set(initialize = [(p,sc,n,ni,nf,cc) for p,sc,n,ni,nf,cc in mTEPES.psn*mTEPES.ll if (p,ni,nf,cc) in mTEPES.pll ])
|
|
759
670
|
mTEPES.psnls = Set(initialize = [(p,sc,n,ni,nf,cc) for p,sc,n,ni,nf,cc in mTEPES.psn*mTEPES.ls if (p,ni,nf,cc) in mTEPES.pla ])
|
|
760
671
|
|
|
761
|
-
mTEPES.psnehc = Set(initialize = [(p,sc,n,eh) for p,sc,n,eh in mTEPES.psneh if pRatedMaxCharge[eh] > 0.0 ])
|
|
672
|
+
mTEPES.psnehc = Set(initialize = [(p,sc,n,eh) for p,sc,n,eh in mTEPES.psneh if mTEPES.dPar['pRatedMaxCharge'][eh] > 0.0 ])
|
|
762
673
|
|
|
763
674
|
if pIndHydroTopology == 1:
|
|
764
|
-
mTEPES.prs = Set(initialize = [(p, rs) for p, rs in mTEPES.p *mTEPES.rs if pRsrPeriodIni[rs] <= p and pRsrPeriodFin[rs] >= p])
|
|
675
|
+
mTEPES.prs = Set(initialize = [(p, rs) for p, rs in mTEPES.p *mTEPES.rs if mTEPES.dPar['pRsrPeriodIni'][rs] <= p and mTEPES.dPar['pRsrPeriodFin'][rs] >= p])
|
|
765
676
|
mTEPES.prc = Set(initialize = [(p, rc) for p, rc in mTEPES.p *mTEPES.rn if (p,rc) in mTEPES.prs])
|
|
766
677
|
mTEPES.psrs = Set(initialize = [(p,sc, rs) for p,sc, rs in mTEPES.ps *mTEPES.rs if (p,rs) in mTEPES.prs])
|
|
767
678
|
mTEPES.psnh = Set(initialize = [(p,sc,n,h ) for p,sc,n,h in mTEPES.psn*mTEPES.h if (p,h ) in mTEPES.ph ])
|
|
@@ -771,7 +682,7 @@ def InputData(DirName, CaseName, mTEPES, pIndLogConsole):
|
|
|
771
682
|
mTEPES.prc = []
|
|
772
683
|
|
|
773
684
|
if pIndHydrogen == 1:
|
|
774
|
-
mTEPES.ppa = Set(initialize = [(p, ni,nf,cc) for p, ni,nf,cc in mTEPES.p *mTEPES.pa if pH2PipePeriodIni[ni,nf,cc] <= p and pH2PipePeriodFin[ni,nf,cc] >= p])
|
|
685
|
+
mTEPES.ppa = Set(initialize = [(p, ni,nf,cc) for p, ni,nf,cc in mTEPES.p *mTEPES.pa if mTEPES.dPar['pH2PipePeriodIni'][ni,nf,cc] <= p and mTEPES.dPar['pH2PipePeriodFin'][ni,nf,cc] >= p])
|
|
775
686
|
mTEPES.ppc = Set(initialize = [(p, ni,nf,cc) for p, ni,nf,cc in mTEPES.p *mTEPES.pc if (p,ni,nf,cc) in mTEPES.ppa])
|
|
776
687
|
mTEPES.psnpn = Set(initialize = [(p,sc,n,ni,nf,cc) for p,sc,n,ni,nf,cc in mTEPES.psn*mTEPES.pn if (p,ni,nf,cc) in mTEPES.ppa])
|
|
777
688
|
mTEPES.psnpa = Set(initialize = [(p,sc,n,ni,nf,cc) for p,sc,n,ni,nf,cc in mTEPES.psn*mTEPES.pa if (p,ni,nf,cc) in mTEPES.ppa])
|
|
@@ -780,7 +691,7 @@ def InputData(DirName, CaseName, mTEPES, pIndLogConsole):
|
|
|
780
691
|
mTEPES.ppc = Set(initialize = [])
|
|
781
692
|
|
|
782
693
|
if pIndHeat == 1:
|
|
783
|
-
mTEPES.pha = Set(initialize = [(p, ni,nf,cc) for p, ni,nf,cc in mTEPES.p *mTEPES.ha if pHeatPipePeriodIni[ni,nf,cc] <= p and pHeatPipePeriodFin[ni,nf,cc] >= p])
|
|
694
|
+
mTEPES.pha = Set(initialize = [(p, ni,nf,cc) for p, ni,nf,cc in mTEPES.p *mTEPES.ha if mTEPES.dPar['pHeatPipePeriodIni'][ni,nf,cc] <= p and mTEPES.dPar['pHeatPipePeriodFin'][ni,nf,cc] >= p])
|
|
784
695
|
mTEPES.phc = Set(initialize = [(p, ni,nf,cc) for p, ni,nf,cc in mTEPES.p *mTEPES.hc if (p,ni,nf,cc) in mTEPES.pha])
|
|
785
696
|
mTEPES.psnhn = Set(initialize = [(p,sc,n,ni,nf,cc) for p,sc,n,ni,nf,cc in mTEPES.psn*mTEPES.hn if (p,ni,nf,cc) in mTEPES.pha])
|
|
786
697
|
mTEPES.psnha = Set(initialize = [(p,sc,n,ni,nf,cc) for p,sc,n,ni,nf,cc in mTEPES.psn*mTEPES.ha if (p,ni,nf,cc) in mTEPES.pha])
|
|
@@ -789,7 +700,7 @@ def InputData(DirName, CaseName, mTEPES, pIndLogConsole):
|
|
|
789
700
|
mTEPES.phc = Set(initialize = [])
|
|
790
701
|
|
|
791
702
|
if pIndPTDF == 1:
|
|
792
|
-
mTEPES.psnland = Set(initialize = [(p,sc,n,ni,nf,cc,nd) for p,sc,n,ni,nf,cc,nd in mTEPES.psnla*mTEPES.nd if (ni,nf,cc,nd) in pVariablePTDF.columns])
|
|
703
|
+
mTEPES.psnland = Set(initialize = [(p,sc,n,ni,nf,cc,nd) for p,sc,n,ni,nf,cc,nd in mTEPES.psnla*mTEPES.nd if (ni,nf,cc,nd) in mTEPES.dPar['pVariablePTDF'].columns])
|
|
793
704
|
|
|
794
705
|
# assigning a node to an area
|
|
795
706
|
mTEPES.ndar = Set(initialize = [(nd,ar) for (nd,zn,ar) in mTEPES.ndzn*mTEPES.ar if (zn,ar) in mTEPES.znar])
|
|
@@ -798,7 +709,7 @@ def InputData(DirName, CaseName, mTEPES, pIndLogConsole):
|
|
|
798
709
|
mTEPES.laar = Set(initialize = [(ni,nf,cc,ar) for ni,nf,cc,ar in mTEPES.la*mTEPES.ar if (ni,ar) in mTEPES.ndar and (nf,ar) in mTEPES.ndar])
|
|
799
710
|
|
|
800
711
|
|
|
801
|
-
CreateInstrumentalSets(mTEPES, pIndHydroTopology, pIndHydrogen, pIndHeat)
|
|
712
|
+
CreateInstrumentalSets(mTEPES, mTEPES.dPar['pIndHydroTopology'], mTEPES.dPar['pIndHydrogen'], mTEPES.dPar['pIndHeat'], mTEPES.dPar['pIndPTDF'])
|
|
802
713
|
|
|
803
714
|
# replacing string values by numerical values
|
|
804
715
|
idxDict = dict()
|
|
@@ -815,15 +726,15 @@ def InputData(DirName, CaseName, mTEPES, pIndLogConsole):
|
|
|
815
726
|
idxDict['Y' ] = 1
|
|
816
727
|
idxDict['y' ] = 1
|
|
817
728
|
|
|
818
|
-
pIndBinUnitInvest = pIndBinUnitInvest.map (idxDict)
|
|
819
|
-
pIndBinUnitRetire = pIndBinUnitRetire.map (idxDict)
|
|
820
|
-
pIndBinUnitCommit = pIndBinUnitCommit.map (idxDict)
|
|
821
|
-
pIndBinStorInvest = pIndBinStorInvest.map (idxDict)
|
|
822
|
-
pIndBinLineInvest = pIndBinLineInvest.map (idxDict)
|
|
823
|
-
pIndBinLineSwitch = pIndBinLineSwitch.map (idxDict)
|
|
824
|
-
# pIndOperReserve = pIndOperReserve.map (idxDict)
|
|
825
|
-
pIndOutflowIncomp = pIndOutflowIncomp.map (idxDict)
|
|
826
|
-
pMustRun = pMustRun.map (idxDict)
|
|
729
|
+
mTEPES.dPar['pIndBinUnitInvest'] = mTEPES.dPar['pIndBinUnitInvest'].map (idxDict)
|
|
730
|
+
mTEPES.dPar['pIndBinUnitRetire'] = mTEPES.dPar['pIndBinUnitRetire'].map (idxDict)
|
|
731
|
+
mTEPES.dPar['pIndBinUnitCommit'] = mTEPES.dPar['pIndBinUnitCommit'].map (idxDict)
|
|
732
|
+
mTEPES.dPar['pIndBinStorInvest'] = mTEPES.dPar['pIndBinStorInvest'].map (idxDict)
|
|
733
|
+
mTEPES.dPar['pIndBinLineInvest'] = mTEPES.dPar['pIndBinLineInvest'].map (idxDict)
|
|
734
|
+
mTEPES.dPar['pIndBinLineSwitch'] = mTEPES.dPar['pIndBinLineSwitch'].map (idxDict)
|
|
735
|
+
# mTEPES.dPar['pIndOperReserve'] = mTEPES.dPar['pIndOperReserve'].map (idxDict)
|
|
736
|
+
mTEPES.dPar['pIndOutflowIncomp'] = mTEPES.dPar['pIndOutflowIncomp'].map (idxDict)
|
|
737
|
+
mTEPES.dPar['pMustRun'] = mTEPES.dPar['pMustRun'].map (idxDict)
|
|
827
738
|
|
|
828
739
|
# Operating reserves can be provided while generating or while consuming
|
|
829
740
|
# So there is need for two options to decide if the unit is able to provide them
|
|
@@ -841,53 +752,53 @@ def InputData(DirName, CaseName, mTEPES, pIndLogConsole):
|
|
|
841
752
|
return pd.Series([mapped, mapped])
|
|
842
753
|
|
|
843
754
|
# Split the columns in pIndOperReserve and group them in Generation and Consumption tuples
|
|
844
|
-
pIndOperReserveGen, pIndOperReserveCon = zip(*pIndOperReserve.map(split_and_map))
|
|
755
|
+
mTEPES.dPar['pIndOperReserveGen'], mTEPES.dPar['pIndOperReserveCon'] = zip(*mTEPES.dPar['pIndOperReserve'].map(split_and_map))
|
|
845
756
|
|
|
846
|
-
pIndOperReserveGen = pd.Series(pIndOperReserveGen, index=pIndOperReserve.index)
|
|
847
|
-
pIndOperReserveCon = pd.Series(pIndOperReserveCon, index=pIndOperReserve.index)
|
|
757
|
+
mTEPES.dPar['pIndOperReserveGen'] = pd.Series(mTEPES.dPar['pIndOperReserveGen'], index=mTEPES.dPar['pIndOperReserve'].index)
|
|
758
|
+
mTEPES.dPar['pIndOperReserveCon'] = pd.Series(mTEPES.dPar['pIndOperReserveCon'], index=mTEPES.dPar['pIndOperReserve'].index)
|
|
848
759
|
|
|
849
|
-
if pIndHydroTopology == 1:
|
|
850
|
-
pIndBinRsrvInvest = pIndBinRsrvInvest.map (idxDict)
|
|
760
|
+
if mTEPES.dPar['pIndHydroTopology'] == 1:
|
|
761
|
+
mTEPES.dPar['pIndBinRsrvInvest'] = mTEPES.dPar['pIndBinRsrvInvest'].map (idxDict)
|
|
851
762
|
|
|
852
|
-
if pIndHydrogen == 1:
|
|
853
|
-
pIndBinH2PipeInvest = pIndBinH2PipeInvest.map (idxDict)
|
|
763
|
+
if mTEPES.dPar['pIndHydrogen'] == 1:
|
|
764
|
+
mTEPES.dPar['pIndBinH2PipeInvest'] = mTEPES.dPar['pIndBinH2PipeInvest'].map (idxDict)
|
|
854
765
|
|
|
855
|
-
if pIndHeat == 1:
|
|
856
|
-
pIndBinHeatPipeInvest = pIndBinHeatPipeInvest.map(idxDict)
|
|
766
|
+
if mTEPES.dPar['pIndHeat'] == 1:
|
|
767
|
+
mTEPES.dPar['pIndBinHeatPipeInvest'] = mTEPES.dPar['pIndBinHeatPipeInvest'].map(idxDict)
|
|
857
768
|
|
|
858
769
|
# define AC existing lines non-switchable lines
|
|
859
|
-
mTEPES.lea = Set(doc='AC existing lines and non-switchable lines', initialize=[le for le in mTEPES.le if pIndBinLineSwitch[le] == 0
|
|
770
|
+
mTEPES.lea = Set(doc='AC existing lines and non-switchable lines', initialize=[le for le in mTEPES.le if mTEPES.dPar['pIndBinLineSwitch'][le] == 0 and not mTEPES.dPar['pLineType'][le] == 'DC'])
|
|
860
771
|
# define AC candidate lines and switchable lines
|
|
861
|
-
mTEPES.lca = Set(doc='AC candidate lines and switchable lines', initialize=[la for la in mTEPES.la if (pIndBinLineSwitch[la] == 1 or pNetFixedCost[la] > 0.0) and not pLineType[la] == 'DC'])
|
|
772
|
+
mTEPES.lca = Set(doc='AC candidate lines and switchable lines', initialize=[la for la in mTEPES.la if (mTEPES.dPar['pIndBinLineSwitch'][la] == 1 or mTEPES.dPar['pNetFixedCost'][la] > 0.0) and not mTEPES.dPar['pLineType'][la] == 'DC'])
|
|
862
773
|
|
|
863
774
|
mTEPES.laa = mTEPES.lea | mTEPES.lca
|
|
864
775
|
|
|
865
776
|
# define DC existing lines non-switchable lines
|
|
866
|
-
mTEPES.led = Set(doc='DC existing lines and non-switchable lines', initialize=[le for le in mTEPES.le if pIndBinLineSwitch[le] == 0
|
|
777
|
+
mTEPES.led = Set(doc='DC existing lines and non-switchable lines', initialize=[le for le in mTEPES.le if mTEPES.dPar['pIndBinLineSwitch'][le] == 0 and mTEPES.dPar['pLineType'][le] == 'DC'])
|
|
867
778
|
# define DC candidate lines and switchable lines
|
|
868
|
-
mTEPES.lcd = Set(doc='DC candidate lines and switchable lines', initialize=[la for la in mTEPES.la if (pIndBinLineSwitch[la] == 1 or pNetFixedCost[la] > 0.0) and pLineType[la] == 'DC'])
|
|
779
|
+
mTEPES.lcd = Set(doc='DC candidate lines and switchable lines', initialize=[la for la in mTEPES.la if (mTEPES.dPar['pIndBinLineSwitch'][la] == 1 or mTEPES.dPar['pNetFixedCost'][la] > 0.0) and mTEPES.dPar['pLineType'][la] == 'DC'])
|
|
869
780
|
|
|
870
781
|
mTEPES.lad = mTEPES.led | mTEPES.lcd
|
|
871
782
|
|
|
872
783
|
# line type
|
|
873
|
-
pLineType = pLineType.reset_index().set_index(['InitialNode', 'FinalNode', 'Circuit', 'LineType'])
|
|
784
|
+
mTEPES.dPar['pLineType'] = mTEPES.dPar['pLineType'].reset_index().set_index(['InitialNode', 'FinalNode', 'Circuit', 'LineType'])
|
|
874
785
|
|
|
875
|
-
mTEPES.pLineType = Set(initialize=pLineType.index, doc='line type')
|
|
786
|
+
mTEPES.pLineType = Set(initialize=mTEPES.dPar['pLineType'].index, doc='line type')
|
|
876
787
|
|
|
877
|
-
if
|
|
878
|
-
pDiscountedWeight = pd.Series([
|
|
788
|
+
if mTEPES.dPar['pAnnualDiscountRate'] == 0.0:
|
|
789
|
+
mTEPES.dPar['pDiscountedWeight'] = pd.Series([ mTEPES.dPar['pPeriodWeight'][p] for p in mTEPES.p], index=mTEPES.p)
|
|
879
790
|
else:
|
|
880
|
-
pDiscountedWeight = pd.Series([((1.0+
|
|
791
|
+
mTEPES.dPar['pDiscountedWeight'] = pd.Series([((1.0+mTEPES.dPar['pAnnualDiscountRate'])**mTEPES.dPar['pPeriodWeight'][p]-1.0) / (mTEPES.dPar['pAnnualDiscountRate']*(1.0+mTEPES.dPar['pAnnualDiscountRate'])**(mTEPES.dPar['pPeriodWeight'][p]-1+p-mTEPES.dPar['pEconomicBaseYear'])) for p in mTEPES.p], index=mTEPES.p)
|
|
881
792
|
|
|
882
793
|
mTEPES.pLoadLevelWeight = Param(mTEPES.psn, initialize=0.0, within=NonNegativeReals, doc='Load level weight', mutable=True)
|
|
883
794
|
for p,sc,st,n in mTEPES.s2n:
|
|
884
|
-
mTEPES.pLoadLevelWeight[p,sc,n] = pStageWeight[st]
|
|
795
|
+
mTEPES.pLoadLevelWeight[p,sc,n] = mTEPES.dPar['pStageWeight'][st]
|
|
885
796
|
|
|
886
797
|
#%% inverse index node to generator
|
|
887
|
-
pNodeToGen = pGenToNode.reset_index().set_index('Node').set_axis(['Generator'], axis=1)[['Generator']]
|
|
888
|
-
pNodeToGen = pNodeToGen.loc[pNodeToGen['Generator'].isin(mTEPES.g)].reset_index().set_index(['Node', 'Generator'])
|
|
798
|
+
mTEPES.dPar['pNodeToGen'] = mTEPES.dPar['pGenToNode'].reset_index().set_index('Node').set_axis(['Generator'], axis=1)[['Generator']]
|
|
799
|
+
mTEPES.dPar['pNodeToGen'] = mTEPES.dPar['pNodeToGen'].loc[mTEPES.dPar['pNodeToGen']['Generator'].isin(mTEPES.g)].reset_index().set_index(['Node', 'Generator'])
|
|
889
800
|
|
|
890
|
-
mTEPES.n2g = Set(initialize=pNodeToGen.index, doc='node to generator')
|
|
801
|
+
mTEPES.n2g = Set(initialize=mTEPES.dPar['pNodeToGen'].index, doc='node to generator')
|
|
891
802
|
|
|
892
803
|
mTEPES.z2g = Set(doc='zone to generator', initialize=[(zn,g) for (nd,g,zn ) in mTEPES.n2g*mTEPES.zn if (nd,zn) in mTEPES.ndzn ])
|
|
893
804
|
mTEPES.a2g = Set(doc='area to generator', initialize=[(ar,g) for (nd,g,zn,ar ) in mTEPES.n2g*mTEPES.znar if (nd,zn) in mTEPES.ndzn ])
|
|
@@ -896,10 +807,10 @@ def InputData(DirName, CaseName, mTEPES, pIndLogConsole):
|
|
|
896
807
|
# mTEPES.z2g = Set(initialize = [(zn,g) for zn,g in mTEPES.zn*mTEPES.g if (zn,g) in pZone2Gen])
|
|
897
808
|
|
|
898
809
|
#%% inverse index generator to technology
|
|
899
|
-
pTechnologyToGen = pGenToTechnology.reset_index().set_index('Technology').set_axis(['Generator'], axis=1)[['Generator']]
|
|
900
|
-
pTechnologyToGen = pTechnologyToGen.loc[pTechnologyToGen['Generator'].isin(mTEPES.g)].reset_index().set_index(['Technology', 'Generator'])
|
|
810
|
+
mTEPES.dPar['pTechnologyToGen'] = mTEPES.dPar['pGenToTechnology'].reset_index().set_index('Technology').set_axis(['Generator'], axis=1)[['Generator']]
|
|
811
|
+
mTEPES.dPar['pTechnologyToGen'] = mTEPES.dPar['pTechnologyToGen'].loc[mTEPES.dPar['pTechnologyToGen']['Generator'].isin(mTEPES.g)].reset_index().set_index(['Technology', 'Generator'])
|
|
901
812
|
|
|
902
|
-
mTEPES.t2g = Set(initialize=pTechnologyToGen.index, doc='technology to generator')
|
|
813
|
+
mTEPES.t2g = Set(initialize=mTEPES.dPar['pTechnologyToGen'].index, doc='technology to generator')
|
|
903
814
|
|
|
904
815
|
# ESS and RES technologies
|
|
905
816
|
def Create_ESS_RES_Sets(mTEPES) -> None:
|
|
@@ -927,7 +838,7 @@ def InputData(DirName, CaseName, mTEPES, pIndLogConsole):
|
|
|
927
838
|
# Create mutually exclusive groups
|
|
928
839
|
# Store in a group-generator dictionary all the relevant data
|
|
929
840
|
group_dict = {}
|
|
930
|
-
for generator, groups in pGenToExclusiveGen.items():
|
|
841
|
+
for generator, groups in mTEPES.dPar['pGenToExclusiveGen'].items():
|
|
931
842
|
if groups != 0.0:
|
|
932
843
|
for group in str(groups).split('|'):
|
|
933
844
|
group_dict.setdefault(group, []).append(generator)
|
|
@@ -962,43 +873,43 @@ def InputData(DirName, CaseName, mTEPES, pIndLogConsole):
|
|
|
962
873
|
mTEPES.ExclusiveGeneratorsHourly = Set(initialize=sorted(sum(group_dict_hourly.values(), [])))
|
|
963
874
|
|
|
964
875
|
# minimum and maximum variable power, charge, and storage capacity
|
|
965
|
-
pMinPowerElec = pVariableMinPowerElec.replace(0.0, pRatedMinPowerElec)
|
|
966
|
-
pMaxPowerElec = pVariableMaxPowerElec.replace(0.0, pRatedMaxPowerElec)
|
|
967
|
-
pMinCharge = pVariableMinCharge.replace (0.0, pRatedMinCharge )
|
|
968
|
-
pMaxCharge = pVariableMaxCharge.replace (0.0, pRatedMaxCharge )
|
|
969
|
-
pMinStorage = pVariableMinStorage.replace (0.0, pRatedMinStorage )
|
|
970
|
-
pMaxStorage = pVariableMaxStorage.replace (0.0, pRatedMaxStorage )
|
|
971
|
-
if pIndHydroTopology == 1:
|
|
972
|
-
pMinVolume = pVariableMinVolume.replace (0.0, pRatedMinVolume )
|
|
973
|
-
pMaxVolume = pVariableMaxVolume.replace (0.0, pRatedMaxVolume )
|
|
974
|
-
|
|
975
|
-
pMinPowerElec = pMinPowerElec.where(pMinPowerElec > 0.0, 0.0)
|
|
976
|
-
pMaxPowerElec = pMaxPowerElec.where(pMaxPowerElec > 0.0, 0.0)
|
|
977
|
-
pMinCharge = pMinCharge.where (pMinCharge > 0.0, 0.0)
|
|
978
|
-
pMaxCharge = pMaxCharge.where (pMaxCharge > 0.0, 0.0)
|
|
979
|
-
pMinStorage = pMinStorage.where (pMinStorage > 0.0, 0.0)
|
|
980
|
-
pMaxStorage = pMaxStorage.where (pMaxStorage > 0.0, 0.0)
|
|
981
|
-
if pIndHydroTopology == 1:
|
|
982
|
-
pMinVolume = pMinVolume.where (pMinVolume > 0.0, 0.0)
|
|
983
|
-
pMaxVolume = pMaxVolume.where (pMaxVolume > 0.0, 0.0)
|
|
876
|
+
mTEPES.dPar['pMinPowerElec'] = mTEPES.dPar['pVariableMinPowerElec'].replace(0.0, mTEPES.dPar['pRatedMinPowerElec'])
|
|
877
|
+
mTEPES.dPar['pMaxPowerElec'] = mTEPES.dPar['pVariableMaxPowerElec'].replace(0.0, mTEPES.dPar['pRatedMaxPowerElec'])
|
|
878
|
+
mTEPES.dPar['pMinCharge'] = mTEPES.dPar['pVariableMinCharge'].replace (0.0, mTEPES.dPar['pRatedMinCharge'] )
|
|
879
|
+
mTEPES.dPar['pMaxCharge'] = mTEPES.dPar['pVariableMaxCharge'].replace (0.0, mTEPES.dPar['pRatedMaxCharge'] )
|
|
880
|
+
mTEPES.dPar['pMinStorage'] = mTEPES.dPar['pVariableMinStorage'].replace (0.0, mTEPES.dPar['pRatedMinStorage'] )
|
|
881
|
+
mTEPES.dPar['pMaxStorage'] = mTEPES.dPar['pVariableMaxStorage'].replace (0.0, mTEPES.dPar['pRatedMaxStorage'] )
|
|
882
|
+
if mTEPES.dPar['pIndHydroTopology'] == 1:
|
|
883
|
+
mTEPES.dPar['pMinVolume'] = mTEPES.dPar['pVariableMinVolume'].replace (0.0, mTEPES.dPar['pRatedMinVolume'] )
|
|
884
|
+
mTEPES.dPar['pMaxVolume'] = mTEPES.dPar['pVariableMaxVolume'].replace (0.0, mTEPES.dPar['pRatedMaxVolume'] )
|
|
885
|
+
|
|
886
|
+
mTEPES.dPar['pMinPowerElec'] = mTEPES.dPar['pMinPowerElec'].where(mTEPES.dPar['pMinPowerElec'] > 0.0, 0.0)
|
|
887
|
+
mTEPES.dPar['pMaxPowerElec'] = mTEPES.dPar['pMaxPowerElec'].where(mTEPES.dPar['pMaxPowerElec'] > 0.0, 0.0)
|
|
888
|
+
mTEPES.dPar['pMinCharge'] = mTEPES.dPar['pMinCharge'].where (mTEPES.dPar['pMinCharge'] > 0.0, 0.0)
|
|
889
|
+
mTEPES.dPar['pMaxCharge'] = mTEPES.dPar['pMaxCharge'].where (mTEPES.dPar['pMaxCharge'] > 0.0, 0.0)
|
|
890
|
+
mTEPES.dPar['pMinStorage'] = mTEPES.dPar['pMinStorage'].where (mTEPES.dPar['pMinStorage'] > 0.0, 0.0)
|
|
891
|
+
mTEPES.dPar['pMaxStorage'] = mTEPES.dPar['pMaxStorage'].where (mTEPES.dPar['pMaxStorage'] > 0.0, 0.0)
|
|
892
|
+
if mTEPES.dPar['pIndHydroTopology'] == 1:
|
|
893
|
+
mTEPES.dPar['pMinVolume'] = mTEPES.dPar['pMinVolume'].where (mTEPES.dPar['pMinVolume'] > 0.0, 0.0)
|
|
894
|
+
mTEPES.dPar['pMaxVolume'] = mTEPES.dPar['pMaxVolume'].where (mTEPES.dPar['pMaxVolume'] > 0.0, 0.0)
|
|
984
895
|
|
|
985
896
|
# fuel term and constant term variable cost
|
|
986
|
-
pVariableFuelCost = pVariableFuelCost.replace(0.0, dfGeneration['FuelCost'])
|
|
987
|
-
pLinearVarCost = dfGeneration['LinearTerm' ] * 1e-3 * pVariableFuelCost + dfGeneration['OMVariableCost'] * 1e-3
|
|
988
|
-
pConstantVarCost = dfGeneration['ConstantTerm'] * 1e-6 * pVariableFuelCost
|
|
989
|
-
pLinearVarCost = pLinearVarCost.reindex (sorted(pLinearVarCost.columns ), axis=1)
|
|
990
|
-
pConstantVarCost = pConstantVarCost.reindex(sorted(pConstantVarCost.columns), axis=1)
|
|
897
|
+
mTEPES.dPar['pVariableFuelCost'] = mTEPES.dPar ['pVariableFuelCost'].replace(0.0, mTEPES.dFrame['dfGeneration']['FuelCost'])
|
|
898
|
+
mTEPES.dPar['pLinearVarCost'] = mTEPES.dFrame['dfGeneration']['LinearTerm' ] * 1e-3 * mTEPES.dPar['pVariableFuelCost'] + mTEPES.dFrame['dfGeneration']['OMVariableCost'] * 1e-3
|
|
899
|
+
mTEPES.dPar['pConstantVarCost'] = mTEPES.dFrame['dfGeneration']['ConstantTerm'] * 1e-6 * mTEPES.dPar['pVariableFuelCost']
|
|
900
|
+
mTEPES.dPar['pLinearVarCost'] = mTEPES.dPar ['pLinearVarCost'].reindex (sorted(mTEPES.dPar['pLinearVarCost'].columns ), axis=1)
|
|
901
|
+
mTEPES.dPar['pConstantVarCost'] = mTEPES.dPar ['pConstantVarCost'].reindex(sorted(mTEPES.dPar['pConstantVarCost'].columns), axis=1)
|
|
991
902
|
|
|
992
903
|
# variable emission cost [M€/GWh]
|
|
993
|
-
pVariableEmissionCost = pVariableEmissionCost.replace(0.0, pCO2Cost) #[€/tCO2]
|
|
994
|
-
pEmissionVarCost = pEmissionRate * 1e-3 * pVariableEmissionCost #[M€/GWh] = [tCO2/MWh] * 1e-3 * [€/tCO2]
|
|
995
|
-
pEmissionVarCost = pEmissionVarCost.reindex(sorted(pEmissionVarCost.columns), axis=1)
|
|
904
|
+
mTEPES.dPar['pVariableEmissionCost'] = mTEPES.dPar['pVariableEmissionCost'].replace(0.0, mTEPES.dPar['pCO2Cost']) #[€/tCO2]
|
|
905
|
+
mTEPES.dPar['pEmissionVarCost'] = mTEPES.dPar['pEmissionRate'] * 1e-3 * mTEPES.dPar['pVariableEmissionCost'] #[M€/GWh] = [tCO2/MWh] * 1e-3 * [€/tCO2]
|
|
906
|
+
mTEPES.dPar['pEmissionVarCost'] = mTEPES.dPar['pEmissionVarCost'].reindex(sorted(mTEPES.dPar['pEmissionVarCost'].columns), axis=1)
|
|
996
907
|
|
|
997
908
|
# minimum up- and downtime and maximum shift time converted to an integer number of time steps
|
|
998
|
-
pUpTime = round(pUpTime /pTimeStep).astype('int')
|
|
999
|
-
pDwTime = round(pDwTime /pTimeStep).astype('int')
|
|
1000
|
-
pStableTime = round(pStableTime/pTimeStep).astype('int')
|
|
1001
|
-
pShiftTime = round(pShiftTime /pTimeStep).astype('int')
|
|
909
|
+
mTEPES.dPar['pUpTime'] = round(mTEPES.dPar['pUpTime'] /mTEPES.dPar['pTimeStep']).astype('int')
|
|
910
|
+
mTEPES.dPar['pDwTime'] = round(mTEPES.dPar['pDwTime'] /mTEPES.dPar['pTimeStep']).astype('int')
|
|
911
|
+
mTEPES.dPar['pStableTime'] = round(mTEPES.dPar['pStableTime']/mTEPES.dPar['pTimeStep']).astype('int')
|
|
912
|
+
mTEPES.dPar['pShiftTime'] = round(mTEPES.dPar['pShiftTime'] /mTEPES.dPar['pTimeStep']).astype('int')
|
|
1002
913
|
|
|
1003
914
|
# %% definition of the time-steps leap to observe the stored energy at an ESS
|
|
1004
915
|
idxCycle = dict()
|
|
@@ -1006,149 +917,150 @@ def InputData(DirName, CaseName, mTEPES, pIndLogConsole):
|
|
|
1006
917
|
idxCycle[0.0 ] = 1
|
|
1007
918
|
idxCycle['Hourly' ] = 1
|
|
1008
919
|
idxCycle['Daily' ] = 1
|
|
1009
|
-
idxCycle['Weekly' ] = round( 24/pTimeStep)
|
|
1010
|
-
idxCycle['Monthly'] = round( 168/pTimeStep)
|
|
1011
|
-
idxCycle['Yearly' ] = round( 672/pTimeStep)
|
|
920
|
+
idxCycle['Weekly' ] = round( 24/mTEPES.dPar['pTimeStep'])
|
|
921
|
+
idxCycle['Monthly'] = round( 168/mTEPES.dPar['pTimeStep'])
|
|
922
|
+
idxCycle['Yearly' ] = round( 672/mTEPES.dPar['pTimeStep'])
|
|
1012
923
|
|
|
1013
924
|
idxOutflows = dict()
|
|
1014
925
|
idxOutflows[0 ] = 1
|
|
1015
926
|
idxOutflows[0.0 ] = 1
|
|
1016
927
|
idxOutflows['Hourly' ] = 1
|
|
1017
|
-
idxOutflows['Daily' ] = round( 24/pTimeStep)
|
|
1018
|
-
idxOutflows['Weekly' ] = round( 168/pTimeStep)
|
|
1019
|
-
idxOutflows['Monthly'] = round( 672/pTimeStep)
|
|
1020
|
-
idxOutflows['Yearly' ] = round(8736/pTimeStep)
|
|
928
|
+
idxOutflows['Daily' ] = round( 24/mTEPES.dPar['pTimeStep'])
|
|
929
|
+
idxOutflows['Weekly' ] = round( 168/mTEPES.dPar['pTimeStep'])
|
|
930
|
+
idxOutflows['Monthly'] = round( 672/mTEPES.dPar['pTimeStep'])
|
|
931
|
+
idxOutflows['Yearly' ] = round(8736/mTEPES.dPar['pTimeStep'])
|
|
1021
932
|
|
|
1022
933
|
idxEnergy = dict()
|
|
1023
934
|
idxEnergy[0 ] = 1
|
|
1024
935
|
idxEnergy[0.0 ] = 1
|
|
1025
936
|
idxEnergy['Hourly' ] = 1
|
|
1026
|
-
idxEnergy['Daily' ] = round( 24/pTimeStep)
|
|
1027
|
-
idxEnergy['Weekly' ] = round( 168/pTimeStep)
|
|
1028
|
-
idxEnergy['Monthly'] = round( 672/pTimeStep)
|
|
1029
|
-
idxEnergy['Yearly' ] = round(8736/pTimeStep)
|
|
937
|
+
idxEnergy['Daily' ] = round( 24/mTEPES.dPar['pTimeStep'])
|
|
938
|
+
idxEnergy['Weekly' ] = round( 168/mTEPES.dPar['pTimeStep'])
|
|
939
|
+
idxEnergy['Monthly'] = round( 672/mTEPES.dPar['pTimeStep'])
|
|
940
|
+
idxEnergy['Yearly' ] = round(8736/mTEPES.dPar['pTimeStep'])
|
|
1030
941
|
|
|
1031
|
-
pStorageTimeStep = pStorageType.map (idxCycle
|
|
1032
|
-
pOutflowsTimeStep = pOutflowsType.map(idxOutflows).where(pEnergyOutflows.sum()
|
|
1033
|
-
pEnergyTimeStep = pEnergyType.map (idxEnergy ).where(pVariableMinEnergy.sum() + pVariableMaxEnergy.sum() > 0.0, other = 1).astype('int')
|
|
942
|
+
mTEPES.dPar['pStorageTimeStep'] = mTEPES.dPar['pStorageType'].map (idxCycle ).astype('int')
|
|
943
|
+
mTEPES.dPar['pOutflowsTimeStep'] = mTEPES.dPar['pOutflowsType'].map(idxOutflows).where(mTEPES.dPar['pEnergyOutflows'].sum() > 0.0, other = 1).astype('int')
|
|
944
|
+
mTEPES.dPar['pEnergyTimeStep'] = mTEPES.dPar['pEnergyType'].map (idxEnergy ).where(mTEPES.dPar['pVariableMinEnergy'].sum() + mTEPES.dPar['pVariableMaxEnergy'].sum() > 0.0, other = 1).astype('int')
|
|
1034
945
|
|
|
1035
|
-
pStorageTimeStep = pd.concat([pStorageTimeStep, pOutflowsTimeStep, pEnergyTimeStep], axis=1).min(axis=1)
|
|
946
|
+
mTEPES.dPar['pStorageTimeStep'] = pd.concat([mTEPES.dPar['pStorageTimeStep'], mTEPES.dPar['pOutflowsTimeStep'], mTEPES.dPar['pEnergyTimeStep']], axis=1).min(axis=1)
|
|
1036
947
|
# cycle time step can't exceed the stage duration
|
|
1037
|
-
pStorageTimeStep = pStorageTimeStep.where(pStorageTimeStep <= pStageDuration.min(), pStageDuration.min())
|
|
948
|
+
mTEPES.dPar['pStorageTimeStep'] = mTEPES.dPar['pStorageTimeStep'].where(mTEPES.dPar['pStorageTimeStep'] <= mTEPES.dPar['pStageDuration'].min(), mTEPES.dPar['pStageDuration'].min())
|
|
1038
949
|
|
|
1039
|
-
if pIndHydroTopology == 1:
|
|
950
|
+
if mTEPES.dPar['pIndHydroTopology'] == 1:
|
|
1040
951
|
# %% definition of the time-steps leap to observe the stored energy at a reservoir
|
|
1041
952
|
idxCycleRsr = dict()
|
|
1042
953
|
idxCycleRsr[0 ] = 1
|
|
1043
954
|
idxCycleRsr[0.0 ] = 1
|
|
1044
955
|
idxCycleRsr['Hourly' ] = 1
|
|
1045
956
|
idxCycleRsr['Daily' ] = 1
|
|
1046
|
-
idxCycleRsr['Weekly' ] = round( 24/pTimeStep)
|
|
1047
|
-
idxCycleRsr['Monthly'] = round( 168/pTimeStep)
|
|
1048
|
-
idxCycleRsr['Yearly' ] = round( 672/pTimeStep)
|
|
957
|
+
idxCycleRsr['Weekly' ] = round( 24/mTEPES.dPar['pTimeStep'])
|
|
958
|
+
idxCycleRsr['Monthly'] = round( 168/mTEPES.dPar['pTimeStep'])
|
|
959
|
+
idxCycleRsr['Yearly' ] = round( 672/mTEPES.dPar['pTimeStep'])
|
|
1049
960
|
|
|
1050
961
|
idxWaterOut = dict()
|
|
1051
962
|
idxWaterOut[0 ] = 1
|
|
1052
963
|
idxWaterOut[0.0 ] = 1
|
|
1053
964
|
idxWaterOut['Hourly' ] = 1
|
|
1054
|
-
idxWaterOut['Daily' ] = round( 24/pTimeStep)
|
|
1055
|
-
idxWaterOut['Weekly' ] = round( 168/pTimeStep)
|
|
1056
|
-
idxWaterOut['Monthly'] = round( 672/pTimeStep)
|
|
1057
|
-
idxWaterOut['Yearly' ] = round(8736/pTimeStep)
|
|
965
|
+
idxWaterOut['Daily' ] = round( 24/mTEPES.dPar['pTimeStep'])
|
|
966
|
+
idxWaterOut['Weekly' ] = round( 168/mTEPES.dPar['pTimeStep'])
|
|
967
|
+
idxWaterOut['Monthly'] = round( 672/mTEPES.dPar['pTimeStep'])
|
|
968
|
+
idxWaterOut['Yearly' ] = round(8736/mTEPES.dPar['pTimeStep'])
|
|
1058
969
|
|
|
1059
|
-
pCycleRsrTimeStep = pReservoirType.map(idxCycleRsr).astype('int')
|
|
1060
|
-
pWaterOutTimeStep = pWaterOutfType.map(idxWaterOut).astype('int')
|
|
970
|
+
mTEPES.dPar['pCycleRsrTimeStep'] = mTEPES.dPar['pReservoirType'].map(idxCycleRsr).astype('int')
|
|
971
|
+
mTEPES.dPar['pWaterOutTimeStep'] = mTEPES.dPar['pWaterOutfType'].map(idxWaterOut).astype('int')
|
|
1061
972
|
|
|
1062
|
-
pReservoirTimeStep = pd.concat([pCycleRsrTimeStep, pWaterOutTimeStep], axis=1).min(axis=1)
|
|
973
|
+
mTEPES.dPar['pReservoirTimeStep'] = pd.concat([mTEPES.dPar['pCycleRsrTimeStep'], mTEPES.dPar['pWaterOutTimeStep']], axis=1).min(axis=1)
|
|
1063
974
|
# cycle water step can't exceed the stage duration
|
|
1064
|
-
pReservoirTimeStep = pReservoirTimeStep.where(pReservoirTimeStep <= pStageDuration.min(), pStageDuration.min())
|
|
975
|
+
mTEPES.dPar['pReservoirTimeStep'] = mTEPES.dPar['pReservoirTimeStep'].where(mTEPES.dPar['pReservoirTimeStep'] <= mTEPES.dPar['pStageDuration'].min(), mTEPES.dPar['pStageDuration'].min())
|
|
1065
976
|
|
|
1066
977
|
# initial inventory must be between minimum and maximum
|
|
1067
|
-
pInitialInventory = pInitialInventory.where(pInitialInventory > pRatedMinStorage, pRatedMinStorage)
|
|
1068
|
-
pInitialInventory = pInitialInventory.where(pInitialInventory < pRatedMaxStorage, pRatedMaxStorage)
|
|
1069
|
-
if pIndHydroTopology == 1:
|
|
1070
|
-
pInitialVolume = pInitialVolume.where (pInitialVolume > pRatedMinVolume, pRatedMinVolume )
|
|
1071
|
-
pInitialVolume = pInitialVolume.where (pInitialVolume < pRatedMaxVolume, pRatedMaxVolume )
|
|
978
|
+
mTEPES.dPar['pInitialInventory'] = mTEPES.dPar['pInitialInventory'].where(mTEPES.dPar['pInitialInventory'] > mTEPES.dPar['pRatedMinStorage'], mTEPES.dPar['pRatedMinStorage'])
|
|
979
|
+
mTEPES.dPar['pInitialInventory'] = mTEPES.dPar['pInitialInventory'].where(mTEPES.dPar['pInitialInventory'] < mTEPES.dPar['pRatedMaxStorage'], mTEPES.dPar['pRatedMaxStorage'])
|
|
980
|
+
if mTEPES.dPar['pIndHydroTopology'] == 1:
|
|
981
|
+
mTEPES.dPar['pInitialVolume'] = mTEPES.dPar['pInitialVolume'].where (mTEPES.dPar['pInitialVolume'] > mTEPES.dPar['pRatedMinVolume'], mTEPES.dPar['pRatedMinVolume'] )
|
|
982
|
+
mTEPES.dPar['pInitialVolume'] = mTEPES.dPar['pInitialVolume'].where (mTEPES.dPar['pInitialVolume'] < mTEPES.dPar['pRatedMaxVolume'], mTEPES.dPar['pRatedMaxVolume'] )
|
|
1072
983
|
|
|
1073
984
|
# initial inventory of the candidate storage units equal to its maximum capacity if the storage capacity is linked to the investment decision
|
|
1074
|
-
pInitialInventory.update(pd.Series([pInitialInventory[ec] if pIndBinStorInvest[ec] == 0 else pRatedMaxStorage[ec] for ec in mTEPES.ec], index=mTEPES.ec, dtype='float64'))
|
|
985
|
+
mTEPES.dPar['pInitialInventory'].update(pd.Series([mTEPES.dPar['pInitialInventory'][ec] if mTEPES.dPar['pIndBinStorInvest'][ec] == 0 else mTEPES.dPar['pRatedMaxStorage'][ec] for ec in mTEPES.ec], index=mTEPES.ec, dtype='float64'))
|
|
1075
986
|
|
|
1076
987
|
# parameter that allows the initial inventory to change with load level
|
|
1077
|
-
pIniInventory = pd.DataFrame([pInitialInventory]*len(mTEPES.psn), index=mTEPES.psn, columns=mTEPES.es)
|
|
1078
|
-
if pIndHydroTopology == 1:
|
|
1079
|
-
pIniVolume = pd.DataFrame([pInitialVolume ]*len(mTEPES.psn), index=mTEPES.psn, columns=mTEPES.rs)
|
|
988
|
+
mTEPES.dPar['pIniInventory'] = pd.DataFrame([mTEPES.dPar['pInitialInventory']]*len(mTEPES.psn), index=mTEPES.psn, columns=mTEPES.es)
|
|
989
|
+
if mTEPES.dPar['pIndHydroTopology'] == 1:
|
|
990
|
+
mTEPES.dPar['pIniVolume'] = pd.DataFrame([mTEPES.dPar['pInitialVolume'] ]*len(mTEPES.psn), index=mTEPES.psn, columns=mTEPES.rs)
|
|
1080
991
|
|
|
1081
992
|
# initial inventory must be between minimum and maximum
|
|
1082
993
|
for p,sc,n,es in mTEPES.psnes:
|
|
1083
|
-
if (p,sc,st,n) in mTEPES.s2n and mTEPES.n.ord(n) == pStorageTimeStep[es]:
|
|
1084
|
-
if pIniInventory[es][p,sc,n] < pMinStorage[es][p,sc,n]:
|
|
1085
|
-
pIniInventory[es][p,sc,n] = pMinStorage[es][p,sc,n]
|
|
994
|
+
if (p,sc,st,n) in mTEPES.s2n and mTEPES.n.ord(n) == mTEPES.dPar['pStorageTimeStep'][es]:
|
|
995
|
+
if mTEPES.dPar['pIniInventory'][es].loc[p,sc,n] < mTEPES.dPar['pMinStorage'][es].loc[p,sc,n]:
|
|
996
|
+
mTEPES.dPar['pIniInventory'][es].loc[p,sc,n] = mTEPES.dPar['pMinStorage'][es].loc[p,sc,n]
|
|
1086
997
|
print('### Initial inventory lower than minimum storage ', p, sc, st, es)
|
|
1087
|
-
if pIniInventory[es][p,sc,n] > pMaxStorage[es][p,sc,n]:
|
|
1088
|
-
pIniInventory[es][p,sc,n] = pMaxStorage[es][p,sc,n]
|
|
998
|
+
if mTEPES.dPar['pIniInventory'][es].loc[p,sc,n] > mTEPES.dPar['pMaxStorage'][es].loc[p,sc,n]:
|
|
999
|
+
mTEPES.dPar['pIniInventory'][es].loc[p,sc,n] = mTEPES.dPar['pMaxStorage'][es].loc[p,sc,n]
|
|
1089
1000
|
print('### Initial inventory greater than maximum storage ', p, sc, st, es)
|
|
1090
|
-
if pIndHydroTopology == 1:
|
|
1001
|
+
if mTEPES.dPar['pIndHydroTopology'] == 1:
|
|
1091
1002
|
for p,sc,n,rs in mTEPES.psnrs:
|
|
1092
|
-
if (p,sc,st,n) in mTEPES.s2n and mTEPES.n.ord(n) == pReservoirTimeStep[rs]:
|
|
1093
|
-
if pIniVolume[rs][p,sc,n] < pMinVolume[rs][p,sc,n]:
|
|
1094
|
-
pIniVolume[rs][p,sc,n] = pMinVolume[rs][p,sc,n]
|
|
1003
|
+
if (p,sc,st,n) in mTEPES.s2n and mTEPES.n.ord(n) == mTEPES.dPar['pReservoirTimeStep'][rs]:
|
|
1004
|
+
if mTEPES.dPar['pIniVolume'][rs].loc[p,sc,n] < mTEPES.dPar['pMinVolume'][rs].loc[p,sc,n]:
|
|
1005
|
+
mTEPES.dPar['pIniVolume'][rs].loc[p,sc,n] = mTEPES.dPar['pMinVolume'][rs].loc[p,sc,n]
|
|
1095
1006
|
print('### Initial volume lower than minimum volume ', p, sc, st, rs)
|
|
1096
|
-
if pIniVolume[rs][p,sc,n] > pMaxVolume[rs][p,sc,n]:
|
|
1097
|
-
pIniVolume[rs][p,sc,n] = pMaxVolume[rs][p,sc,n]
|
|
1007
|
+
if mTEPES.dPar['pIniVolume'][rs].loc[p,sc,n] > mTEPES.dPar['pMaxVolume'][rs].loc[p,sc,n]:
|
|
1008
|
+
mTEPES.dPar['pIniVolume'][rs].loc[p,sc,n] = mTEPES.dPar['pMaxVolume'][rs].loc[p,sc,n]
|
|
1098
1009
|
print('### Initial volume greater than maximum volume ', p, sc, st, rs)
|
|
1099
1010
|
|
|
1100
1011
|
# drop load levels with duration 0
|
|
1101
|
-
pDuration = pDuration.loc [mTEPES.psn ]
|
|
1102
|
-
pDemandElec = pDemandElec.loc [mTEPES.psn ]
|
|
1103
|
-
pSystemInertia = pSystemInertia.loc [mTEPES.psnar]
|
|
1104
|
-
pOperReserveUp = pOperReserveUp.loc [mTEPES.psnar]
|
|
1105
|
-
pOperReserveDw = pOperReserveDw.loc [mTEPES.psnar]
|
|
1106
|
-
pMinPowerElec = pMinPowerElec.loc [mTEPES.psn ]
|
|
1107
|
-
pMaxPowerElec = pMaxPowerElec.loc [mTEPES.psn ]
|
|
1108
|
-
pMinCharge = pMinCharge.loc [mTEPES.psn ]
|
|
1109
|
-
pMaxCharge = pMaxCharge.loc [mTEPES.psn ]
|
|
1110
|
-
pEnergyInflows = pEnergyInflows.loc [mTEPES.psn ]
|
|
1111
|
-
pEnergyOutflows = pEnergyOutflows.loc [mTEPES.psn ]
|
|
1112
|
-
pIniInventory = pIniInventory.loc [mTEPES.psn ]
|
|
1113
|
-
pMinStorage = pMinStorage.loc [mTEPES.psn ]
|
|
1114
|
-
pMaxStorage = pMaxStorage.loc [mTEPES.psn ]
|
|
1115
|
-
pVariableMaxEnergy = pVariableMaxEnergy.loc [mTEPES.psn ]
|
|
1116
|
-
pVariableMinEnergy = pVariableMinEnergy.loc [mTEPES.psn ]
|
|
1117
|
-
pLinearVarCost = pLinearVarCost.loc [mTEPES.psn ]
|
|
1118
|
-
pConstantVarCost = pConstantVarCost.loc [mTEPES.psn ]
|
|
1119
|
-
pEmissionVarCost = pEmissionVarCost.loc [mTEPES.psn ]
|
|
1120
|
-
|
|
1121
|
-
pRatedLinearOperCost = pRatedLinearFuelCost.loc [mTEPES.g ]
|
|
1122
|
-
pRatedLinearVarCost = pRatedLinearFuelCost.loc [mTEPES.g ]
|
|
1012
|
+
mTEPES.dPar['pDuration'] = mTEPES.dPar['pDuration'].loc [mTEPES.psn ]
|
|
1013
|
+
mTEPES.dPar['pDemandElec'] = mTEPES.dPar['pDemandElec'].loc [mTEPES.psn ]
|
|
1014
|
+
mTEPES.dPar['pSystemInertia'] = mTEPES.dPar['pSystemInertia'].loc [mTEPES.psnar]
|
|
1015
|
+
mTEPES.dPar['pOperReserveUp'] = mTEPES.dPar['pOperReserveUp'].loc [mTEPES.psnar]
|
|
1016
|
+
mTEPES.dPar['pOperReserveDw'] = mTEPES.dPar['pOperReserveDw'].loc [mTEPES.psnar]
|
|
1017
|
+
mTEPES.dPar['pMinPowerElec'] = mTEPES.dPar['pMinPowerElec'].loc [mTEPES.psn ]
|
|
1018
|
+
mTEPES.dPar['pMaxPowerElec'] = mTEPES.dPar['pMaxPowerElec'].loc [mTEPES.psn ]
|
|
1019
|
+
mTEPES.dPar['pMinCharge'] = mTEPES.dPar['pMinCharge'].loc [mTEPES.psn ]
|
|
1020
|
+
mTEPES.dPar['pMaxCharge'] = mTEPES.dPar['pMaxCharge'].loc [mTEPES.psn ]
|
|
1021
|
+
mTEPES.dPar['pEnergyInflows'] = mTEPES.dPar['pEnergyInflows'].loc [mTEPES.psn ]
|
|
1022
|
+
mTEPES.dPar['pEnergyOutflows'] = mTEPES.dPar['pEnergyOutflows'].loc [mTEPES.psn ]
|
|
1023
|
+
mTEPES.dPar['pIniInventory'] = mTEPES.dPar['pIniInventory'].loc [mTEPES.psn ]
|
|
1024
|
+
mTEPES.dPar['pMinStorage'] = mTEPES.dPar['pMinStorage'].loc [mTEPES.psn ]
|
|
1025
|
+
mTEPES.dPar['pMaxStorage'] = mTEPES.dPar['pMaxStorage'].loc [mTEPES.psn ]
|
|
1026
|
+
mTEPES.dPar['pVariableMaxEnergy'] = mTEPES.dPar['pVariableMaxEnergy'].loc [mTEPES.psn ]
|
|
1027
|
+
mTEPES.dPar['pVariableMinEnergy'] = mTEPES.dPar['pVariableMinEnergy'].loc [mTEPES.psn ]
|
|
1028
|
+
mTEPES.dPar['pLinearVarCost'] = mTEPES.dPar['pLinearVarCost'].loc [mTEPES.psn ]
|
|
1029
|
+
mTEPES.dPar['pConstantVarCost'] = mTEPES.dPar['pConstantVarCost'].loc [mTEPES.psn ]
|
|
1030
|
+
mTEPES.dPar['pEmissionVarCost'] = mTEPES.dPar['pEmissionVarCost'].loc [mTEPES.psn ]
|
|
1031
|
+
|
|
1032
|
+
mTEPES.dPar['pRatedLinearOperCost'] = mTEPES.dPar['pRatedLinearFuelCost'].loc [mTEPES.g ]
|
|
1033
|
+
mTEPES.dPar['pRatedLinearVarCost'] = mTEPES.dPar['pRatedLinearFuelCost'].loc [mTEPES.g ]
|
|
1123
1034
|
|
|
1124
1035
|
# drop generators not es
|
|
1125
|
-
pEfficiency = pEfficiency.loc [mTEPES.eh ]
|
|
1126
|
-
pStorageTimeStep = pStorageTimeStep.loc [mTEPES.es ]
|
|
1127
|
-
pOutflowsTimeStep = pOutflowsTimeStep.loc [mTEPES.es ]
|
|
1128
|
-
pStorageType = pStorageType.loc [mTEPES.es ]
|
|
1129
|
-
|
|
1130
|
-
if pIndHydroTopology == 1:
|
|
1131
|
-
pHydroInflows = pHydroInflows.loc [mTEPES.psn ]
|
|
1132
|
-
pHydroOutflows = pHydroOutflows.loc [mTEPES.psn ]
|
|
1133
|
-
pIniVolume = pIniVolume.loc [mTEPES.psn ]
|
|
1134
|
-
pMinVolume = pMinVolume.loc [mTEPES.psn ]
|
|
1135
|
-
pMaxVolume = pMaxVolume.loc [mTEPES.psn ]
|
|
1136
|
-
if pIndHydrogen == 1:
|
|
1137
|
-
pDemandH2 = pDemandH2.loc [mTEPES.psn ]
|
|
1138
|
-
pDemandH2Abs = pDemandH2.where (pDemandH2 > 0.0, 0.0)
|
|
1139
|
-
if pIndHeat == 1:
|
|
1140
|
-
pDemandHeat = pDemandHeat.loc [mTEPES.psn ]
|
|
1141
|
-
pDemandHeatAbs = pDemandHeat.where(pDemandHeat > 0.0, 0.0)
|
|
1142
|
-
|
|
1143
|
-
if
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1036
|
+
mTEPES.dPar['pEfficiency'] = mTEPES.dPar['pEfficiency'].loc [mTEPES.eh ]
|
|
1037
|
+
mTEPES.dPar['pStorageTimeStep'] = mTEPES.dPar['pStorageTimeStep'].loc [mTEPES.es ]
|
|
1038
|
+
mTEPES.dPar['pOutflowsTimeStep'] = mTEPES.dPar['pOutflowsTimeStep'].loc [mTEPES.es ]
|
|
1039
|
+
mTEPES.dPar['pStorageType'] = mTEPES.dPar['pStorageType'].loc [mTEPES.es ]
|
|
1040
|
+
|
|
1041
|
+
if mTEPES.dPar['pIndHydroTopology'] == 1:
|
|
1042
|
+
mTEPES.dPar['pHydroInflows'] = mTEPES.dPar['pHydroInflows'].loc [mTEPES.psn ]
|
|
1043
|
+
mTEPES.dPar['pHydroOutflows'] = mTEPES.dPar['pHydroOutflows'].loc [mTEPES.psn ]
|
|
1044
|
+
mTEPES.dPar['pIniVolume'] = mTEPES.dPar['pIniVolume'].loc [mTEPES.psn ]
|
|
1045
|
+
mTEPES.dPar['pMinVolume'] = mTEPES.dPar['pMinVolume'].loc [mTEPES.psn ]
|
|
1046
|
+
mTEPES.dPar['pMaxVolume'] = mTEPES.dPar['pMaxVolume'].loc [mTEPES.psn ]
|
|
1047
|
+
if mTEPES.dPar['pIndHydrogen'] == 1:
|
|
1048
|
+
mTEPES.dPar['pDemandH2'] = mTEPES.dPar['pDemandH2'].loc [mTEPES.psn ]
|
|
1049
|
+
mTEPES.dPar['pDemandH2Abs'] = mTEPES.dPar['pDemandH2'].where (mTEPES.dPar['pDemandH2'] > 0.0, 0.0)
|
|
1050
|
+
if mTEPES.dPar['pIndHeat'] == 1:
|
|
1051
|
+
mTEPES.dPar['pDemandHeat'] = mTEPES.dPar['pDemandHeat'].loc [mTEPES.psn ]
|
|
1052
|
+
mTEPES.dPar['pDemandHeatAbs'] = mTEPES.dPar['pDemandHeat'].where(mTEPES.dPar['pDemandHeat'] > 0.0, 0.0)
|
|
1053
|
+
|
|
1054
|
+
if mTEPES.dPar['pIndVarTTC'] == 1:
|
|
1055
|
+
mTEPES.dPar['pVariableNTCFrw'] = mTEPES.dPar['pVariableNTCFrw'].loc [mTEPES.psn]
|
|
1056
|
+
mTEPES.dPar['pVariableNTCBck'] = mTEPES.dPar['pVariableNTCBck'].loc [mTEPES.psn]
|
|
1057
|
+
if mTEPES.dPar['pIndPTDF'] == 1:
|
|
1058
|
+
mTEPES.dPar['pVariablePTDF'] = mTEPES.dPar['pVariablePTDF'].loc [mTEPES.psn]
|
|
1147
1059
|
|
|
1148
1060
|
# separate positive and negative demands to avoid converting negative values to 0
|
|
1149
|
-
pDemandElecPos = pDemandElec.where(pDemandElec >= 0.0, 0.0)
|
|
1150
|
-
pDemandElecNeg = pDemandElec.where(pDemandElec < 0.0, 0.0)
|
|
1151
|
-
pDemandElecAbs = pDemandElec.where(pDemandElec > 0.0, 0.0)
|
|
1061
|
+
mTEPES.dPar['pDemandElecPos'] = mTEPES.dPar['pDemandElec'].where(mTEPES.dPar['pDemandElec'] >= 0.0, 0.0)
|
|
1062
|
+
mTEPES.dPar['pDemandElecNeg'] = mTEPES.dPar['pDemandElec'].where(mTEPES.dPar['pDemandElec'] < 0.0, 0.0)
|
|
1063
|
+
# mTEPES.dPar['pDemandElecAbs'] = mTEPES.dPar['pDemandElec'].where(mTEPES.dPar['pDemandElec'] > 0.0, 0.0)
|
|
1152
1064
|
|
|
1153
1065
|
# generators to area (g2a) (e2a) (n2a)
|
|
1154
1066
|
g2a = defaultdict(list)
|
|
@@ -1174,242 +1086,244 @@ def InputData(DirName, CaseName, mTEPES, pIndLogConsole):
|
|
|
1174
1086
|
d2a[ar].append(nd)
|
|
1175
1087
|
|
|
1176
1088
|
# small values are converted to 0
|
|
1177
|
-
pDemandElecPeak = pd.Series([0.0 for p,ar in mTEPES.par], index=mTEPES.par)
|
|
1178
|
-
pDemandHeatPeak = pd.Series([0.0 for p,ar in mTEPES.par], index=mTEPES.par)
|
|
1089
|
+
mTEPES.dPar['pDemandElecPeak'] = pd.Series([0.0 for p,ar in mTEPES.par], index=mTEPES.par)
|
|
1090
|
+
mTEPES.dPar['pDemandHeatPeak'] = pd.Series([0.0 for p,ar in mTEPES.par], index=mTEPES.par)
|
|
1179
1091
|
for p,ar in mTEPES.par:
|
|
1180
1092
|
# values < 1e-5 times the maximum demand for each area (an area is related to operating reserves procurement, i.e., country) are converted to 0
|
|
1181
|
-
pDemandElecPeak[p,ar] = pDemandElec.loc[p,:,:][[nd for nd in d2a[ar]]].sum(axis=1).max()
|
|
1182
|
-
pEpsilonElec = pDemandElecPeak[p,ar]*1e-5
|
|
1093
|
+
mTEPES.dPar['pDemandElecPeak'][p,ar] = mTEPES.dPar['pDemandElec'].loc[p,:,:][[nd for nd in d2a[ar]]].sum(axis=1).max()
|
|
1094
|
+
mTEPES.dPar['pEpsilonElec'] = mTEPES.dPar['pDemandElecPeak'][p,ar]*1e-5
|
|
1183
1095
|
|
|
1184
1096
|
# these parameters are in GW
|
|
1185
|
-
pDemandElecPos [pDemandElecPos [[nd for nd in d2a[ar]]] < pEpsilonElec] = 0.0
|
|
1186
|
-
pDemandElecNeg [pDemandElecNeg [[nd for nd in d2a[ar]]] > -pEpsilonElec] = 0.0
|
|
1187
|
-
pSystemInertia [pSystemInertia [[ ar ]] < pEpsilonElec] = 0.0
|
|
1188
|
-
pOperReserveUp [pOperReserveUp [[ ar ]] < pEpsilonElec] = 0.0
|
|
1189
|
-
pOperReserveDw [pOperReserveDw [[ ar ]] < pEpsilonElec] = 0.0
|
|
1097
|
+
mTEPES.dPar['pDemandElecPos'] [mTEPES.dPar['pDemandElecPos'] [[nd for nd in d2a[ar]]] < mTEPES.dPar['pEpsilonElec']] = 0.0
|
|
1098
|
+
mTEPES.dPar['pDemandElecNeg'] [mTEPES.dPar['pDemandElecNeg'] [[nd for nd in d2a[ar]]] > -mTEPES.dPar['pEpsilonElec']] = 0.0
|
|
1099
|
+
mTEPES.dPar['pSystemInertia'] [mTEPES.dPar['pSystemInertia'] [[ ar ]] < mTEPES.dPar['pEpsilonElec']] = 0.0
|
|
1100
|
+
mTEPES.dPar['pOperReserveUp'] [mTEPES.dPar['pOperReserveUp'] [[ ar ]] < mTEPES.dPar['pEpsilonElec']] = 0.0
|
|
1101
|
+
mTEPES.dPar['pOperReserveDw'] [mTEPES.dPar['pOperReserveDw'] [[ ar ]] < mTEPES.dPar['pEpsilonElec']] = 0.0
|
|
1190
1102
|
|
|
1191
1103
|
if g2a[ar]:
|
|
1192
|
-
pMinPowerElec [pMinPowerElec [[g for g in g2a[ar]]] < pEpsilonElec] = 0.0
|
|
1193
|
-
pMaxPowerElec [pMaxPowerElec [[g for g in g2a[ar]]] < pEpsilonElec] = 0.0
|
|
1194
|
-
pMinCharge [pMinCharge [[es for es in e2a[ar]]] < pEpsilonElec] = 0.0
|
|
1195
|
-
pMaxCharge [pMaxCharge [[eh for eh in g2a[ar]]] < pEpsilonElec] = 0.0
|
|
1196
|
-
pEnergyInflows [pEnergyInflows [[es for es in e2a[ar]]] < pEpsilonElec] = 0.0
|
|
1197
|
-
pEnergyOutflows[pEnergyOutflows[[es for es in e2a[ar]]] < pEpsilonElec] = 0.0
|
|
1104
|
+
mTEPES.dPar['pMinPowerElec'] [mTEPES.dPar['pMinPowerElec'] [[g for g in g2a[ar]]] < mTEPES.dPar['pEpsilonElec']] = 0.0
|
|
1105
|
+
mTEPES.dPar['pMaxPowerElec'] [mTEPES.dPar['pMaxPowerElec'] [[g for g in g2a[ar]]] < mTEPES.dPar['pEpsilonElec']] = 0.0
|
|
1106
|
+
mTEPES.dPar['pMinCharge'] [mTEPES.dPar['pMinCharge'] [[es for es in e2a[ar]]] < mTEPES.dPar['pEpsilonElec']] = 0.0
|
|
1107
|
+
mTEPES.dPar['pMaxCharge'] [mTEPES.dPar['pMaxCharge'] [[eh for eh in g2a[ar]]] < mTEPES.dPar['pEpsilonElec']] = 0.0
|
|
1108
|
+
mTEPES.dPar['pEnergyInflows'] [mTEPES.dPar['pEnergyInflows'] [[es for es in e2a[ar]]] < mTEPES.dPar['pEpsilonElec']] = 0.0
|
|
1109
|
+
mTEPES.dPar['pEnergyOutflows'][mTEPES.dPar['pEnergyOutflows'][[es for es in e2a[ar]]] < mTEPES.dPar['pEpsilonElec']] = 0.0
|
|
1198
1110
|
# these parameters are in GWh
|
|
1199
|
-
pMinStorage [pMinStorage [[es for es in e2a[ar]]] < pEpsilonElec] = 0.0
|
|
1200
|
-
pMaxStorage [pMaxStorage [[es for es in e2a[ar]]] < pEpsilonElec] = 0.0
|
|
1201
|
-
pIniInventory [pIniInventory [[es for es in e2a[ar]]] < pEpsilonElec] = 0.0
|
|
1111
|
+
mTEPES.dPar['pMinStorage'] [mTEPES.dPar['pMinStorage'] [[es for es in e2a[ar]]] < mTEPES.dPar['pEpsilonElec']] = 0.0
|
|
1112
|
+
mTEPES.dPar['pMaxStorage'] [mTEPES.dPar['pMaxStorage'] [[es for es in e2a[ar]]] < mTEPES.dPar['pEpsilonElec']] = 0.0
|
|
1113
|
+
mTEPES.dPar['pIniInventory'] [mTEPES.dPar['pIniInventory'] [[es for es in e2a[ar]]] < mTEPES.dPar['pEpsilonElec']] = 0.0
|
|
1202
1114
|
|
|
1203
|
-
if pIndHydroTopology == 1:
|
|
1204
|
-
pMinVolume [pMinVolume [[rs for rs in r2a[ar]]] < pEpsilonElec] = 0.0
|
|
1205
|
-
pMaxVolume [pMaxVolume [[rs for rs in r2a[ar]]] < pEpsilonElec] = 0.0
|
|
1206
|
-
pHydroInflows [pHydroInflows [[rs for rs in r2a[ar]]] < pEpsilonElec] = 0.0
|
|
1207
|
-
pHydroOutflows[pHydroOutflows[[rs for rs in r2a[ar]]] < pEpsilonElec] = 0.0
|
|
1115
|
+
if mTEPES.dPar['pIndHydroTopology'] == 1:
|
|
1116
|
+
mTEPES.dPar['pMinVolume'] [mTEPES.dPar['pMinVolume'] [[rs for rs in r2a[ar]]] < mTEPES.dPar['pEpsilonElec']] = 0.0
|
|
1117
|
+
mTEPES.dPar['pMaxVolume'] [mTEPES.dPar['pMaxVolume'] [[rs for rs in r2a[ar]]] < mTEPES.dPar['pEpsilonElec']] = 0.0
|
|
1118
|
+
mTEPES.dPar['pHydroInflows'] [mTEPES.dPar['pHydroInflows'] [[rs for rs in r2a[ar]]] < mTEPES.dPar['pEpsilonElec']] = 0.0
|
|
1119
|
+
mTEPES.dPar['pHydroOutflows'][mTEPES.dPar['pHydroOutflows'][[rs for rs in r2a[ar]]] < mTEPES.dPar['pEpsilonElec']] = 0.0
|
|
1208
1120
|
|
|
1209
1121
|
# pInitialInventory.update(pd.Series([0.0 for es in e2a[ar] if pInitialInventory[es] < pEpsilonElec], index=[es for es in e2a[ar] if pInitialInventory[es] < pEpsilonElec], dtype='float64'))
|
|
1210
1122
|
|
|
1211
1123
|
# merging positive and negative values of the demand
|
|
1212
|
-
pDemandElec = pDemandElecPos.where(pDemandElecNeg
|
|
1124
|
+
mTEPES.dPar['pDemandElec'] = mTEPES.dPar['pDemandElecPos'].where(mTEPES.dPar['pDemandElecNeg'] == 0.0, mTEPES.dPar['pDemandElecNeg'])
|
|
1213
1125
|
|
|
1214
1126
|
# Increase Maximum to reach minimum
|
|
1215
|
-
# pMaxPowerElec = pMaxPowerElec.where(pMaxPowerElec >= pMinPowerElec, pMinPowerElec)
|
|
1216
|
-
# pMaxCharge = pMaxCharge.where (pMaxCharge >= pMinCharge, pMinCharge )
|
|
1127
|
+
# mTEPES.dPar['pMaxPowerElec'] = mTEPES.dPar['pMaxPowerElec'].where(mTEPES.dPar['pMaxPowerElec'] >= mTEPES.dPar['pMinPowerElec'], mTEPES.dPar['pMinPowerElec'])
|
|
1128
|
+
# mTEPES.dPar['pMaxCharge'] = mTEPES.dPar['pMaxCharge'].where (mTEPES.dPar['pMaxCharge'] >= mTEPES.dPar['pMinCharge'], mTEPES.dPar['pMinCharge'] )
|
|
1217
1129
|
|
|
1218
1130
|
# Decrease Minimum to reach maximum
|
|
1219
|
-
pMinPowerElec = pMinPowerElec.where(pMinPowerElec <= pMaxPowerElec, pMaxPowerElec)
|
|
1220
|
-
pMinCharge = pMinCharge.where (pMinCharge <= pMaxCharge, pMaxCharge )
|
|
1131
|
+
mTEPES.dPar['pMinPowerElec'] = mTEPES.dPar['pMinPowerElec'].where(mTEPES.dPar['pMinPowerElec'] <= mTEPES.dPar['pMaxPowerElec'], mTEPES.dPar['pMaxPowerElec'])
|
|
1132
|
+
mTEPES.dPar['pMinCharge'] = mTEPES.dPar['pMinCharge'].where (mTEPES.dPar['pMinCharge'] <= mTEPES.dPar['pMaxCharge'], mTEPES.dPar['pMaxCharge'] )
|
|
1221
1133
|
|
|
1222
|
-
#
|
|
1223
|
-
pMaxPower2ndBlock = pMaxPowerElec - pMinPowerElec
|
|
1224
|
-
pMaxCharge2ndBlock = pMaxCharge - pMinCharge
|
|
1134
|
+
# calculate 2nd Blocks
|
|
1135
|
+
mTEPES.dPar['pMaxPower2ndBlock'] = mTEPES.dPar['pMaxPowerElec'] - mTEPES.dPar['pMinPowerElec']
|
|
1136
|
+
mTEPES.dPar['pMaxCharge2ndBlock'] = mTEPES.dPar['pMaxCharge'] - mTEPES.dPar['pMinCharge']
|
|
1225
1137
|
|
|
1226
|
-
pMaxCapacity = pMaxPowerElec.where(pMaxPowerElec > pMaxCharge, pMaxCharge)
|
|
1138
|
+
mTEPES.dPar['pMaxCapacity'] = mTEPES.dPar['pMaxPowerElec'].where(mTEPES.dPar['pMaxPowerElec'] > mTEPES.dPar['pMaxCharge'], mTEPES.dPar['pMaxCharge'])
|
|
1227
1139
|
|
|
1228
1140
|
if g2a[ar]:
|
|
1229
|
-
pMaxPower2ndBlock [pMaxPower2ndBlock [[g for g in g2a[ar]]] < pEpsilonElec] = 0.0
|
|
1230
|
-
pMaxCharge2ndBlock[pMaxCharge2ndBlock[[g for g in g2a[ar]]] < pEpsilonElec] = 0.0
|
|
1141
|
+
mTEPES.dPar['pMaxPower2ndBlock'] [mTEPES.dPar['pMaxPower2ndBlock'] [[g for g in g2a[ar]]] < mTEPES.dPar['pEpsilonElec']] = 0.0
|
|
1142
|
+
mTEPES.dPar['pMaxCharge2ndBlock'][mTEPES.dPar['pMaxCharge2ndBlock'][[g for g in g2a[ar]]] < mTEPES.dPar['pEpsilonElec']] = 0.0
|
|
1231
1143
|
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
pLineNTCMax = pLineNTCFrw.where(pLineNTCFrw > pLineNTCBck, pLineNTCBck)
|
|
1144
|
+
mTEPES.dPar['pLineNTCFrw'][mTEPES.dPar['pLineNTCFrw'] < mTEPES.dPar['pEpsilonElec']] = 0
|
|
1145
|
+
mTEPES.dPar['pLineNTCBck'][mTEPES.dPar['pLineNTCBck'] < mTEPES.dPar['pEpsilonElec']] = 0
|
|
1146
|
+
mTEPES.dPar['pLineNTCMax'] = mTEPES.dPar['pLineNTCFrw'].where(mTEPES.dPar['pLineNTCFrw'] > mTEPES.dPar['pLineNTCBck'], mTEPES.dPar['pLineNTCBck'])
|
|
1235
1147
|
|
|
1236
|
-
if pIndHydrogen == 1:
|
|
1237
|
-
pDemandH2[pDemandH2[[nd for nd in d2a[ar]]] < pEpsilonElec] = 0.0
|
|
1238
|
-
|
|
1239
|
-
|
|
1148
|
+
if mTEPES.dPar['pIndHydrogen'] == 1:
|
|
1149
|
+
mTEPES.dPar['pDemandH2'][mTEPES.dPar['pDemandH2'][[nd for nd in d2a[ar]]] < mTEPES.dPar['pEpsilonElec']] = 0.0
|
|
1150
|
+
mTEPES.dPar['pH2PipeNTCFrw'][mTEPES.dPar['pH2PipeNTCFrw'] < mTEPES.dPar['pEpsilonElec']] = 0
|
|
1151
|
+
mTEPES.dPar['pH2PipeNTCBck'][mTEPES.dPar['pH2PipeNTCBck'] < mTEPES.dPar['pEpsilonElec']] = 0
|
|
1240
1152
|
|
|
1241
|
-
if pIndHeat == 1:
|
|
1242
|
-
pDemandHeatPeak[p,ar] = pDemandHeat.loc[p,:,:][[nd for nd in d2a[ar]]].sum(axis=1).max()
|
|
1243
|
-
pEpsilonHeat = pDemandHeatPeak[p,ar]*1e-5
|
|
1244
|
-
pDemandHeat [pDemandHeat [[nd for nd in d2a[ar]]] < pEpsilonHeat] = 0.0
|
|
1245
|
-
|
|
1246
|
-
|
|
1153
|
+
if mTEPES.dPar['pIndHeat'] == 1:
|
|
1154
|
+
mTEPES.dPar['pDemandHeatPeak'][p,ar] = mTEPES.dPar['pDemandHeat'].loc[p,:,:][[nd for nd in d2a[ar]]].sum(axis=1).max()
|
|
1155
|
+
mTEPES.dPar['pEpsilonHeat'] = mTEPES.dPar['pDemandHeatPeak'][p,ar]*1e-5
|
|
1156
|
+
mTEPES.dPar['pDemandHeat'] [mTEPES.dPar['pDemandHeat'] [[nd for nd in d2a[ar]]] < mTEPES.dPar['pEpsilonHeat']] = 0.0
|
|
1157
|
+
mTEPES.dPar['pHeatPipeNTCFrw'][mTEPES.dPar['pHeatPipeNTCFrw'] < mTEPES.dPar['pEpsilonElec']] = 0
|
|
1158
|
+
mTEPES.dPar['pHeatPipeNTCBck'][mTEPES.dPar['pHeatPipeNTCBck'] < mTEPES.dPar['pEpsilonElec']] = 0
|
|
1247
1159
|
|
|
1248
1160
|
# drop generators not g or es or eh or ch
|
|
1249
|
-
pMinPowerElec = pMinPowerElec.loc [:,mTEPES.g ]
|
|
1250
|
-
pMaxPowerElec = pMaxPowerElec.loc [:,mTEPES.g ]
|
|
1251
|
-
pMinCharge = pMinCharge.loc [:,mTEPES.eh]
|
|
1252
|
-
pMaxCharge = pMaxCharge.loc [:,mTEPES.eh]
|
|
1253
|
-
pMaxPower2ndBlock = pMaxPower2ndBlock.loc [:,mTEPES.g ]
|
|
1254
|
-
pMaxCharge2ndBlock = pMaxCharge2ndBlock.loc[:,mTEPES.eh]
|
|
1255
|
-
pMaxCapacity = pMaxCapacity.loc [:,mTEPES.eh]
|
|
1256
|
-
pEnergyInflows = pEnergyInflows.loc [:,mTEPES.es]
|
|
1257
|
-
pEnergyOutflows = pEnergyOutflows.loc [:,mTEPES.es]
|
|
1258
|
-
pIniInventory = pIniInventory.loc [:,mTEPES.es]
|
|
1259
|
-
pMinStorage = pMinStorage.loc [:,mTEPES.es]
|
|
1260
|
-
pMaxStorage = pMaxStorage.loc [:,mTEPES.es]
|
|
1261
|
-
pVariableMaxEnergy = pVariableMaxEnergy.loc[:,mTEPES.g ]
|
|
1262
|
-
pVariableMinEnergy = pVariableMinEnergy.loc[:,mTEPES.g ]
|
|
1263
|
-
pLinearVarCost = pLinearVarCost.loc [:,mTEPES.g ]
|
|
1264
|
-
pConstantVarCost = pConstantVarCost.loc [:,mTEPES.g ]
|
|
1265
|
-
pEmissionVarCost = pEmissionVarCost.loc [:,mTEPES.g ]
|
|
1161
|
+
mTEPES.dPar['pMinPowerElec'] = mTEPES.dPar['pMinPowerElec'].loc [:,mTEPES.g ]
|
|
1162
|
+
mTEPES.dPar['pMaxPowerElec'] = mTEPES.dPar['pMaxPowerElec'].loc [:,mTEPES.g ]
|
|
1163
|
+
mTEPES.dPar['pMinCharge'] = mTEPES.dPar['pMinCharge'].loc [:,mTEPES.eh]
|
|
1164
|
+
mTEPES.dPar['pMaxCharge'] = mTEPES.dPar['pMaxCharge'].loc [:,mTEPES.eh]
|
|
1165
|
+
mTEPES.dPar['pMaxPower2ndBlock'] = mTEPES.dPar['pMaxPower2ndBlock'].loc [:,mTEPES.g ]
|
|
1166
|
+
mTEPES.dPar['pMaxCharge2ndBlock'] = mTEPES.dPar['pMaxCharge2ndBlock'].loc[:,mTEPES.eh]
|
|
1167
|
+
mTEPES.dPar['pMaxCapacity'] = mTEPES.dPar['pMaxCapacity'].loc [:,mTEPES.eh]
|
|
1168
|
+
mTEPES.dPar['pEnergyInflows'] = mTEPES.dPar['pEnergyInflows'].loc [:,mTEPES.es]
|
|
1169
|
+
mTEPES.dPar['pEnergyOutflows'] = mTEPES.dPar['pEnergyOutflows'].loc [:,mTEPES.es]
|
|
1170
|
+
mTEPES.dPar['pIniInventory'] = mTEPES.dPar['pIniInventory'].loc [:,mTEPES.es]
|
|
1171
|
+
mTEPES.dPar['pMinStorage'] = mTEPES.dPar['pMinStorage'].loc [:,mTEPES.es]
|
|
1172
|
+
mTEPES.dPar['pMaxStorage'] = mTEPES.dPar['pMaxStorage'].loc [:,mTEPES.es]
|
|
1173
|
+
mTEPES.dPar['pVariableMaxEnergy'] = mTEPES.dPar['pVariableMaxEnergy'].loc[:,mTEPES.g ]
|
|
1174
|
+
mTEPES.dPar['pVariableMinEnergy'] = mTEPES.dPar['pVariableMinEnergy'].loc[:,mTEPES.g ]
|
|
1175
|
+
mTEPES.dPar['pLinearVarCost'] = mTEPES.dPar['pLinearVarCost'].loc [:,mTEPES.g ]
|
|
1176
|
+
mTEPES.dPar['pConstantVarCost'] = mTEPES.dPar['pConstantVarCost'].loc [:,mTEPES.g ]
|
|
1177
|
+
mTEPES.dPar['pEmissionVarCost'] = mTEPES.dPar['pEmissionVarCost'].loc [:,mTEPES.g ]
|
|
1266
1178
|
|
|
1267
1179
|
# replace < 0.0 by 0.0
|
|
1268
|
-
pEpsilon = 1e-6
|
|
1269
|
-
pMaxPower2ndBlock = pMaxPower2ndBlock.where (pMaxPower2ndBlock > pEpsilon, 0.0)
|
|
1270
|
-
pMaxCharge2ndBlock = pMaxCharge2ndBlock.where(pMaxCharge2ndBlock > pEpsilon, 0.0)
|
|
1180
|
+
mTEPES.dPar['pEpsilon'] = 1e-6
|
|
1181
|
+
mTEPES.dPar['pMaxPower2ndBlock'] = mTEPES.dPar['pMaxPower2ndBlock'].where (mTEPES.dPar['pMaxPower2ndBlock'] > mTEPES.dPar['pEpsilon'], 0.0)
|
|
1182
|
+
mTEPES.dPar['pMaxCharge2ndBlock'] = mTEPES.dPar['pMaxCharge2ndBlock'].where(mTEPES.dPar['pMaxCharge2ndBlock'] > mTEPES.dPar['pEpsilon'], 0.0)
|
|
1271
1183
|
|
|
1272
1184
|
# computation of the power-to-heat ratio of the CHP units
|
|
1273
1185
|
# heat ratio of boiler units is fixed to 1.0
|
|
1274
|
-
pPower2HeatRatio = pd.Series([1.0 if ch in mTEPES.bo else (pRatedMaxPowerElec[ch]-pRatedMinPowerElec[ch])/(pRatedMaxPowerHeat[ch]-pRatedMinPowerHeat[ch]) for ch in mTEPES.ch], index=mTEPES.ch)
|
|
1275
|
-
pMinPowerHeat = pd.DataFrame([[pMinPowerElec [ch][p,sc,n]/pPower2HeatRatio[ch] for ch in mTEPES.ch] for p,sc,n in mTEPES.psn], index=mTEPES.psn, columns=mTEPES.ch)
|
|
1276
|
-
pMaxPowerHeat = pd.DataFrame([[pMaxPowerElec [ch][p,sc,n]/pPower2HeatRatio[ch] for ch in mTEPES.ch] for p,sc,n in mTEPES.psn], index=mTEPES.psn, columns=mTEPES.ch)
|
|
1277
|
-
pMinPowerHeat.update(pd.DataFrame([[pRatedMinPowerHeat[bo]
|
|
1278
|
-
pMaxPowerHeat.update(pd.DataFrame([[pRatedMaxPowerHeat[bo]
|
|
1279
|
-
pMaxPowerHeat.update(pd.DataFrame([[pMaxCharge[hp][p,sc,n]/pProductionFunctionHeat[hp] for hp in mTEPES.hp] for p,sc,n in mTEPES.psn], index=mTEPES.psn, columns=mTEPES.hp))
|
|
1186
|
+
mTEPES.dPar['pPower2HeatRatio'] = pd.Series([1.0 if ch in mTEPES.bo else (mTEPES.dPar['pRatedMaxPowerElec'][ch]-mTEPES.dPar['pRatedMinPowerElec'][ch])/(mTEPES.dPar['pRatedMaxPowerHeat'][ch]-mTEPES.dPar['pRatedMinPowerHeat'][ch]) for ch in mTEPES.ch], index=mTEPES.ch)
|
|
1187
|
+
mTEPES.dPar['pMinPowerHeat'] = pd.DataFrame([[mTEPES.dPar['pMinPowerElec'] [ch][p,sc,n]/mTEPES.dPar['pPower2HeatRatio'][ch] for ch in mTEPES.ch] for p,sc,n in mTEPES.psn], index=mTEPES.psn, columns=mTEPES.ch)
|
|
1188
|
+
mTEPES.dPar['pMaxPowerHeat'] = pd.DataFrame([[mTEPES.dPar['pMaxPowerElec'] [ch][p,sc,n]/mTEPES.dPar['pPower2HeatRatio'][ch] for ch in mTEPES.ch] for p,sc,n in mTEPES.psn], index=mTEPES.psn, columns=mTEPES.ch)
|
|
1189
|
+
mTEPES.dPar['pMinPowerHeat'].update(pd.DataFrame([[mTEPES.dPar['pRatedMinPowerHeat'][bo] for bo in mTEPES.bo] for p,sc,n in mTEPES.psn], index=mTEPES.psn, columns=mTEPES.bo))
|
|
1190
|
+
mTEPES.dPar['pMaxPowerHeat'].update(pd.DataFrame([[mTEPES.dPar['pRatedMaxPowerHeat'][bo] for bo in mTEPES.bo] for p,sc,n in mTEPES.psn], index=mTEPES.psn, columns=mTEPES.bo))
|
|
1191
|
+
mTEPES.dPar['pMaxPowerHeat'].update(pd.DataFrame([[mTEPES.dPar['pMaxCharge'][hp][p,sc,n]/mTEPES.dPar['pProductionFunctionHeat'][hp] for hp in mTEPES.hp] for p,sc,n in mTEPES.psn], index=mTEPES.psn, columns=mTEPES.hp))
|
|
1280
1192
|
|
|
1281
1193
|
# drop values not par, p, or ps
|
|
1282
|
-
pReserveMargin = pReserveMargin.loc [mTEPES.par]
|
|
1283
|
-
pEmission = pEmission.loc [mTEPES.par]
|
|
1284
|
-
pRESEnergy = pRESEnergy.loc [mTEPES.par]
|
|
1285
|
-
pDemandElecPeak = pDemandElecPeak.loc[mTEPES.par]
|
|
1286
|
-
pDemandHeatPeak = pDemandHeatPeak.loc[mTEPES.par]
|
|
1287
|
-
pPeriodWeight = pPeriodWeight.loc [mTEPES.p ]
|
|
1288
|
-
pScenProb = pScenProb.loc [mTEPES.ps ]
|
|
1194
|
+
mTEPES.dPar['pReserveMargin'] = mTEPES.dPar['pReserveMargin'].loc [mTEPES.par]
|
|
1195
|
+
mTEPES.dPar['pEmission'] = mTEPES.dPar['pEmission'].loc [mTEPES.par]
|
|
1196
|
+
mTEPES.dPar['pRESEnergy'] = mTEPES.dPar['pRESEnergy'].loc [mTEPES.par]
|
|
1197
|
+
mTEPES.dPar['pDemandElecPeak'] = mTEPES.dPar['pDemandElecPeak'].loc[mTEPES.par]
|
|
1198
|
+
mTEPES.dPar['pDemandHeatPeak'] = mTEPES.dPar['pDemandHeatPeak'].loc[mTEPES.par]
|
|
1199
|
+
mTEPES.dPar['pPeriodWeight'] = mTEPES.dPar['pPeriodWeight'].loc [mTEPES.p ]
|
|
1200
|
+
mTEPES.dPar['pScenProb'] = mTEPES.dPar['pScenProb'].loc [mTEPES.ps ]
|
|
1289
1201
|
|
|
1290
1202
|
# drop generators not gc or gd
|
|
1291
|
-
pGenInvestCost = pGenInvestCost.loc [mTEPES.eb]
|
|
1292
|
-
pGenRetireCost = pGenRetireCost.loc [mTEPES.gd]
|
|
1293
|
-
pIndBinUnitInvest = pIndBinUnitInvest.loc[mTEPES.eb]
|
|
1294
|
-
pIndBinUnitRetire = pIndBinUnitRetire.loc[mTEPES.gd]
|
|
1295
|
-
pGenLoInvest = pGenLoInvest.loc [mTEPES.eb]
|
|
1296
|
-
pGenLoRetire = pGenLoRetire.loc [mTEPES.gd]
|
|
1297
|
-
pGenUpInvest = pGenUpInvest.loc [mTEPES.eb]
|
|
1298
|
-
pGenUpRetire = pGenUpRetire.loc [mTEPES.gd]
|
|
1203
|
+
mTEPES.dPar['pGenInvestCost'] = mTEPES.dPar['pGenInvestCost'].loc [mTEPES.eb]
|
|
1204
|
+
mTEPES.dPar['pGenRetireCost'] = mTEPES.dPar['pGenRetireCost'].loc [mTEPES.gd]
|
|
1205
|
+
mTEPES.dPar['pIndBinUnitInvest'] = mTEPES.dPar['pIndBinUnitInvest'].loc[mTEPES.eb]
|
|
1206
|
+
mTEPES.dPar['pIndBinUnitRetire'] = mTEPES.dPar['pIndBinUnitRetire'].loc[mTEPES.gd]
|
|
1207
|
+
mTEPES.dPar['pGenLoInvest'] = mTEPES.dPar['pGenLoInvest'].loc [mTEPES.eb]
|
|
1208
|
+
mTEPES.dPar['pGenLoRetire'] = mTEPES.dPar['pGenLoRetire'].loc [mTEPES.gd]
|
|
1209
|
+
mTEPES.dPar['pGenUpInvest'] = mTEPES.dPar['pGenUpInvest'].loc [mTEPES.eb]
|
|
1210
|
+
mTEPES.dPar['pGenUpRetire'] = mTEPES.dPar['pGenUpRetire'].loc [mTEPES.gd]
|
|
1299
1211
|
|
|
1300
1212
|
# drop generators not nr or ec
|
|
1301
|
-
pStartUpCost = pStartUpCost.loc [mTEPES.nr]
|
|
1302
|
-
pShutDownCost = pShutDownCost.loc [mTEPES.nr]
|
|
1303
|
-
pIndBinUnitCommit = pIndBinUnitCommit.loc[mTEPES.nr]
|
|
1304
|
-
pIndBinStorInvest = pIndBinStorInvest.loc[mTEPES.ec]
|
|
1213
|
+
mTEPES.dPar['pStartUpCost'] = mTEPES.dPar['pStartUpCost'].loc [mTEPES.nr]
|
|
1214
|
+
mTEPES.dPar['pShutDownCost'] = mTEPES.dPar['pShutDownCost'].loc [mTEPES.nr]
|
|
1215
|
+
mTEPES.dPar['pIndBinUnitCommit'] = mTEPES.dPar['pIndBinUnitCommit'].loc[mTEPES.nr]
|
|
1216
|
+
mTEPES.dPar['pIndBinStorInvest'] = mTEPES.dPar['pIndBinStorInvest'].loc[mTEPES.ec]
|
|
1305
1217
|
|
|
1306
1218
|
# drop lines not la
|
|
1307
|
-
pLineR = pLineR.loc [mTEPES.la]
|
|
1308
|
-
pLineX = pLineX.loc [mTEPES.la]
|
|
1309
|
-
pLineBsh = pLineBsh.loc [mTEPES.la]
|
|
1310
|
-
pLineTAP = pLineTAP.loc [mTEPES.la]
|
|
1311
|
-
pLineLength = pLineLength.loc [mTEPES.la]
|
|
1312
|
-
pElecNetPeriodIni = pElecNetPeriodIni.loc[mTEPES.la]
|
|
1313
|
-
pElecNetPeriodFin = pElecNetPeriodFin.loc[mTEPES.la]
|
|
1314
|
-
pLineVoltage = pLineVoltage.loc [mTEPES.la]
|
|
1315
|
-
pLineNTCFrw = pLineNTCFrw.loc [mTEPES.la]
|
|
1316
|
-
pLineNTCBck = pLineNTCBck.loc [mTEPES.la]
|
|
1317
|
-
pLineNTCMax = pLineNTCMax.loc [mTEPES.la]
|
|
1318
|
-
# pSwOnTime = pSwOnTime.loc [mTEPES.la]
|
|
1319
|
-
# pSwOffTime = pSwOffTime.loc [mTEPES.la]
|
|
1320
|
-
pIndBinLineInvest = pIndBinLineInvest.loc[mTEPES.la]
|
|
1321
|
-
pIndBinLineSwitch = pIndBinLineSwitch.loc[mTEPES.la]
|
|
1322
|
-
pAngMin = pAngMin.loc [mTEPES.la]
|
|
1323
|
-
pAngMax = pAngMax.loc [mTEPES.la]
|
|
1219
|
+
mTEPES.dPar['pLineR'] = mTEPES.dPar['pLineR'].loc [mTEPES.la]
|
|
1220
|
+
mTEPES.dPar['pLineX'] = mTEPES.dPar['pLineX'].loc [mTEPES.la]
|
|
1221
|
+
mTEPES.dPar['pLineBsh'] = mTEPES.dPar['pLineBsh'].loc [mTEPES.la]
|
|
1222
|
+
mTEPES.dPar['pLineTAP'] = mTEPES.dPar['pLineTAP'].loc [mTEPES.la]
|
|
1223
|
+
mTEPES.dPar['pLineLength'] = mTEPES.dPar['pLineLength'].loc [mTEPES.la]
|
|
1224
|
+
mTEPES.dPar['pElecNetPeriodIni'] = mTEPES.dPar['pElecNetPeriodIni'].loc[mTEPES.la]
|
|
1225
|
+
mTEPES.dPar['pElecNetPeriodFin'] = mTEPES.dPar['pElecNetPeriodFin'].loc[mTEPES.la]
|
|
1226
|
+
mTEPES.dPar['pLineVoltage'] = mTEPES.dPar['pLineVoltage'].loc [mTEPES.la]
|
|
1227
|
+
mTEPES.dPar['pLineNTCFrw'] = mTEPES.dPar['pLineNTCFrw'].loc [mTEPES.la]
|
|
1228
|
+
mTEPES.dPar['pLineNTCBck'] = mTEPES.dPar['pLineNTCBck'].loc [mTEPES.la]
|
|
1229
|
+
mTEPES.dPar['pLineNTCMax'] = mTEPES.dPar['pLineNTCMax'].loc [mTEPES.la]
|
|
1230
|
+
# mTEPES.dPar['pSwOnTime'] = mTEPES.dPar['pSwOnTime'].loc [mTEPES.la]
|
|
1231
|
+
# mTEPES.dPar['pSwOffTime'] = mTEPES.dPar['pSwOffTime'].loc [mTEPES.la]
|
|
1232
|
+
mTEPES.dPar['pIndBinLineInvest'] = mTEPES.dPar['pIndBinLineInvest'].loc[mTEPES.la]
|
|
1233
|
+
mTEPES.dPar['pIndBinLineSwitch'] = mTEPES.dPar['pIndBinLineSwitch'].loc[mTEPES.la]
|
|
1234
|
+
mTEPES.dPar['pAngMin'] = mTEPES.dPar['pAngMin'].loc [mTEPES.la]
|
|
1235
|
+
mTEPES.dPar['pAngMax'] = mTEPES.dPar['pAngMax'].loc [mTEPES.la]
|
|
1324
1236
|
|
|
1325
1237
|
# drop lines not lc or ll
|
|
1326
|
-
pNetFixedCost = pNetFixedCost.loc [mTEPES.lc]
|
|
1327
|
-
pNetLoInvest = pNetLoInvest.loc [mTEPES.lc]
|
|
1328
|
-
pNetUpInvest = pNetUpInvest.loc [mTEPES.lc]
|
|
1329
|
-
pLineLossFactor = pLineLossFactor.loc [mTEPES.ll]
|
|
1330
|
-
|
|
1331
|
-
pMaxNTCFrw = pd.DataFrame([[pLineNTCFrw[la] for la in mTEPES.la] for p,sc,n in mTEPES.psn], index=mTEPES.psn, columns=mTEPES.la)
|
|
1332
|
-
pMaxNTCBck = pd.DataFrame([[pLineNTCBck[la] for la in mTEPES.la] for p,sc,n in mTEPES.psn], index=mTEPES.psn, columns=mTEPES.la)
|
|
1333
|
-
if pIndVarTTC == 1:
|
|
1334
|
-
pMaxNTCFrw =
|
|
1335
|
-
pMaxNTCBck =
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1238
|
+
mTEPES.dPar['pNetFixedCost'] = mTEPES.dPar['pNetFixedCost'].loc [mTEPES.lc]
|
|
1239
|
+
mTEPES.dPar['pNetLoInvest'] = mTEPES.dPar['pNetLoInvest'].loc [mTEPES.lc]
|
|
1240
|
+
mTEPES.dPar['pNetUpInvest'] = mTEPES.dPar['pNetUpInvest'].loc [mTEPES.lc]
|
|
1241
|
+
mTEPES.dPar['pLineLossFactor'] = mTEPES.dPar['pLineLossFactor'].loc [mTEPES.ll]
|
|
1242
|
+
|
|
1243
|
+
mTEPES.dPar['pMaxNTCFrw'] = pd.DataFrame([[mTEPES.dPar['pLineNTCFrw'][la] for la in mTEPES.la] for p,sc,n in mTEPES.psn], index=mTEPES.psn, columns=mTEPES.la)
|
|
1244
|
+
mTEPES.dPar['pMaxNTCBck'] = pd.DataFrame([[mTEPES.dPar['pLineNTCBck'][la] for la in mTEPES.la] for p,sc,n in mTEPES.psn], index=mTEPES.psn, columns=mTEPES.la)
|
|
1245
|
+
if mTEPES.dPar['pIndVarTTC'] == 1:
|
|
1246
|
+
mTEPES.dPar['pMaxNTCFrw'] = mTEPES.dPar['pVariableNTCFrw'].replace(0.0, mTEPES.dPar['pLineNTCFrw'])
|
|
1247
|
+
mTEPES.dPar['pMaxNTCBck'] = mTEPES.dPar['pVariableNTCBck'].replace(0.0, mTEPES.dPar['pLineNTCBck'])
|
|
1248
|
+
mTEPES.dPar['pMaxNTCFrw'] [mTEPES.dPar['pMaxNTCFrw'] < mTEPES.dPar['pEpsilonElec']] = 0.0
|
|
1249
|
+
mTEPES.dPar['pMaxNTCBck'] [mTEPES.dPar['pMaxNTCBck'] < mTEPES.dPar['pEpsilonElec']] = 0.0
|
|
1250
|
+
mTEPES.dPar['pMaxNTCMax'] = mTEPES.dPar['pMaxNTCFrw'].where(mTEPES.dPar['pMaxNTCFrw'] > mTEPES.dPar['pMaxNTCBck'], mTEPES.dPar['pMaxNTCBck'])
|
|
1251
|
+
|
|
1252
|
+
mTEPES.dPar['pMaxNTCBck'] = mTEPES.dPar['pMaxNTCBck'].loc [:,mTEPES.la]
|
|
1253
|
+
mTEPES.dPar['pMaxNTCFrw'] = mTEPES.dPar['pMaxNTCFrw'].loc [:,mTEPES.la]
|
|
1254
|
+
mTEPES.dPar['pMaxNTCMax'] = mTEPES.dPar['pMaxNTCFrw'].loc [:,mTEPES.la]
|
|
1255
|
+
|
|
1256
|
+
if mTEPES.dPar['pIndHydroTopology'] == 1:
|
|
1343
1257
|
# drop generators not h
|
|
1344
|
-
pProductionFunctionHydro = pProductionFunctionHydro.loc[mTEPES.h ]
|
|
1258
|
+
mTEPES.dPar['pProductionFunctionHydro'] = mTEPES.dPar['pProductionFunctionHydro'].loc[mTEPES.h ]
|
|
1345
1259
|
# drop reservoirs not rn
|
|
1346
|
-
pIndBinRsrvInvest = pIndBinRsrvInvest.loc [mTEPES.rn]
|
|
1347
|
-
pRsrInvestCost = pRsrInvestCost.loc [mTEPES.rn]
|
|
1260
|
+
mTEPES.dPar['pIndBinRsrvInvest'] = mTEPES.dPar['pIndBinRsrvInvest'].loc [mTEPES.rn]
|
|
1261
|
+
mTEPES.dPar['pRsrInvestCost'] = mTEPES.dPar['pRsrInvestCost'].loc [mTEPES.rn]
|
|
1348
1262
|
# maximum outflows depending on the downstream hydropower unit
|
|
1349
|
-
pMaxOutflows = pd.DataFrame([[sum(pMaxPowerElec[h][p,sc,n]/pProductionFunctionHydro[h] for h in mTEPES.h if (rs,h) in mTEPES.r2h) for rs in mTEPES.rs] for p,sc,n in mTEPES.psn], index=mTEPES.psn, columns=mTEPES.rs)
|
|
1263
|
+
mTEPES.dPar['pMaxOutflows'] = pd.DataFrame([[sum(mTEPES.dPar['pMaxPowerElec'][h][p,sc,n]/mTEPES.dPar['pProductionFunctionHydro'][h] for h in mTEPES.h if (rs,h) in mTEPES.r2h) for rs in mTEPES.rs] for p,sc,n in mTEPES.psn], index=mTEPES.psn, columns=mTEPES.rs)
|
|
1350
1264
|
|
|
1351
|
-
if pIndHydrogen == 1:
|
|
1265
|
+
if mTEPES.dPar['pIndHydrogen'] == 1:
|
|
1352
1266
|
# drop generators not el
|
|
1353
|
-
pProductionFunctionH2 = pProductionFunctionH2.loc[mTEPES.el]
|
|
1267
|
+
mTEPES.dPar['pProductionFunctionH2'] = mTEPES.dPar['pProductionFunctionH2'].loc[mTEPES.el]
|
|
1354
1268
|
# drop pipelines not pc
|
|
1355
|
-
pH2PipeFixedCost = pH2PipeFixedCost.loc [mTEPES.pc]
|
|
1356
|
-
pH2PipeLoInvest = pH2PipeLoInvest.loc [mTEPES.pc]
|
|
1357
|
-
pH2PipeUpInvest = pH2PipeUpInvest.loc [mTEPES.pc]
|
|
1269
|
+
mTEPES.dPar['pH2PipeFixedCost'] = mTEPES.dPar['pH2PipeFixedCost'].loc [mTEPES.pc]
|
|
1270
|
+
mTEPES.dPar['pH2PipeLoInvest'] = mTEPES.dPar['pH2PipeLoInvest'].loc [mTEPES.pc]
|
|
1271
|
+
mTEPES.dPar['pH2PipeUpInvest'] = mTEPES.dPar['pH2PipeUpInvest'].loc [mTEPES.pc]
|
|
1358
1272
|
|
|
1359
|
-
if pIndHeat == 1:
|
|
1360
|
-
pReserveMarginHeat = pReserveMarginHeat.loc [mTEPES.par]
|
|
1273
|
+
if mTEPES.dPar['pIndHeat'] == 1:
|
|
1274
|
+
mTEPES.dPar['pReserveMarginHeat'] = mTEPES.dPar['pReserveMarginHeat'].loc [mTEPES.par]
|
|
1361
1275
|
# drop generators not hp
|
|
1362
|
-
pProductionFunctionHeat = pProductionFunctionHeat.loc [mTEPES.hp]
|
|
1276
|
+
mTEPES.dPar['pProductionFunctionHeat'] = mTEPES.dPar['pProductionFunctionHeat'].loc [mTEPES.hp]
|
|
1363
1277
|
# drop generators not hh
|
|
1364
|
-
pProductionFunctionH2ToHeat = pProductionFunctionH2ToHeat.loc[mTEPES.hh]
|
|
1278
|
+
mTEPES.dPar['pProductionFunctionH2ToHeat'] = mTEPES.dPar['pProductionFunctionH2ToHeat'].loc[mTEPES.hh]
|
|
1365
1279
|
# drop heat pipes not hc
|
|
1366
|
-
pHeatPipeFixedCost = pHeatPipeFixedCost.loc [mTEPES.hc]
|
|
1367
|
-
pHeatPipeLoInvest = pHeatPipeLoInvest.loc [mTEPES.hc]
|
|
1368
|
-
pHeatPipeUpInvest = pHeatPipeUpInvest.loc [mTEPES.hc]
|
|
1280
|
+
mTEPES.dPar['pHeatPipeFixedCost'] = mTEPES.dPar['pHeatPipeFixedCost'].loc [mTEPES.hc]
|
|
1281
|
+
mTEPES.dPar['pHeatPipeLoInvest'] = mTEPES.dPar['pHeatPipeLoInvest'].loc [mTEPES.hc]
|
|
1282
|
+
mTEPES.dPar['pHeatPipeUpInvest'] = mTEPES.dPar['pHeatPipeUpInvest'].loc [mTEPES.hc]
|
|
1369
1283
|
|
|
1370
1284
|
# replace very small costs by 0
|
|
1371
|
-
pEpsilon = 1e-5 # this value in EUR/GWh is lower than the O&M variable cost of any technology, independent of the area
|
|
1285
|
+
mTEPES.dPar['pEpsilon'] = 1e-5 # this value in EUR/GWh is lower than the O&M variable cost of any technology, independent of the area
|
|
1372
1286
|
|
|
1373
|
-
pLinearVarCost [pLinearVarCost [[g for g in mTEPES.g]] < pEpsilon] = 0.0
|
|
1374
|
-
pConstantVarCost[pConstantVarCost[[g for g in mTEPES.g]] < pEpsilon] = 0.0
|
|
1375
|
-
pEmissionVarCost[pEmissionVarCost[[g for g in mTEPES.g]] < pEpsilon] = 0.0
|
|
1287
|
+
mTEPES.dPar['pLinearVarCost'] [mTEPES.dPar['pLinearVarCost'] [[g for g in mTEPES.g]] < mTEPES.dPar['pEpsilon']] = 0.0
|
|
1288
|
+
mTEPES.dPar['pConstantVarCost'][mTEPES.dPar['pConstantVarCost'][[g for g in mTEPES.g]] < mTEPES.dPar['pEpsilon']] = 0.0
|
|
1289
|
+
mTEPES.dPar['pEmissionVarCost'][mTEPES.dPar['pEmissionVarCost'][[g for g in mTEPES.g]] < mTEPES.dPar['pEpsilon']] = 0.0
|
|
1376
1290
|
|
|
1377
|
-
pRatedLinearVarCost.update (pd.Series([0.0 for g in mTEPES.g if pRatedLinearVarCost [g ] < pEpsilon], index=[g for g in mTEPES.g if pRatedLinearVarCost [g ] < pEpsilon]))
|
|
1378
|
-
pRatedConstantVarCost.update(pd.Series([0.0 for g in mTEPES.g if pRatedConstantVarCost[g ] < pEpsilon], index=[g for g in mTEPES.g if pRatedConstantVarCost[g ] < pEpsilon]))
|
|
1379
|
-
pLinearOMCost.update (pd.Series([0.0 for g in mTEPES.g if pLinearOMCost [g ] < pEpsilon], index=[g for g in mTEPES.g if pLinearOMCost [g ] < pEpsilon]))
|
|
1380
|
-
pOperReserveCost.update (pd.Series([0.0 for g in mTEPES.g if pOperReserveCost [g ] < pEpsilon], index=[g for g in mTEPES.g if pOperReserveCost [g ] < pEpsilon]))
|
|
1381
|
-
# pEmissionCost.update (pd.Series([0.0 for g in mTEPES.g if abs(pEmissionCost [g ]) < pEpsilon], index=[g for g in mTEPES.g if abs(pEmissionCost [g ]) < pEpsilon]))
|
|
1382
|
-
pStartUpCost.update (pd.Series([0.0 for nr in mTEPES.nr if pStartUpCost [nr] < pEpsilon], index=[nr for nr in mTEPES.nr if pStartUpCost [nr] < pEpsilon]))
|
|
1383
|
-
pShutDownCost.update (pd.Series([0.0 for nr in mTEPES.nr if pShutDownCost [nr] < pEpsilon], index=[nr for nr in mTEPES.nr if pShutDownCost [nr] < pEpsilon]))
|
|
1291
|
+
mTEPES.dPar['pRatedLinearVarCost'].update (pd.Series([0.0 for g in mTEPES.g if mTEPES.dPar['pRatedLinearVarCost'] [g ] < mTEPES.dPar['pEpsilon']], index=[g for g in mTEPES.g if mTEPES.dPar['pRatedLinearVarCost'] [g ] < mTEPES.dPar['pEpsilon']]))
|
|
1292
|
+
mTEPES.dPar['pRatedConstantVarCost'].update(pd.Series([0.0 for g in mTEPES.g if mTEPES.dPar['pRatedConstantVarCost'][g ] < mTEPES.dPar['pEpsilon']], index=[g for g in mTEPES.g if mTEPES.dPar['pRatedConstantVarCost'][g ] < mTEPES.dPar['pEpsilon']]))
|
|
1293
|
+
mTEPES.dPar['pLinearOMCost'].update (pd.Series([0.0 for g in mTEPES.g if mTEPES.dPar['pLinearOMCost'] [g ] < mTEPES.dPar['pEpsilon']], index=[g for g in mTEPES.g if mTEPES.dPar['pLinearOMCost'] [g ] < mTEPES.dPar['pEpsilon']]))
|
|
1294
|
+
mTEPES.dPar['pOperReserveCost'].update (pd.Series([0.0 for g in mTEPES.g if mTEPES.dPar['pOperReserveCost'] [g ] < mTEPES.dPar['pEpsilon']], index=[g for g in mTEPES.g if mTEPES.dPar['pOperReserveCost'] [g ] < mTEPES.dPar['pEpsilon']]))
|
|
1295
|
+
# mTEPES.dPar['pEmissionCost'].update (pd.Series([0.0 for g in mTEPES.g if abs(mTEPES.dPar['pEmissionCost'] [g ]) < mTEPES.dPar['pEpsilon']], index=[g for g in mTEPES.g if abs(mTEPES.dPar['pEmissionCost'] [g ]) < mTEPES.dPar['pEpsilon']]))
|
|
1296
|
+
mTEPES.dPar['pStartUpCost'].update (pd.Series([0.0 for nr in mTEPES.nr if mTEPES.dPar['pStartUpCost'] [nr] < mTEPES.dPar['pEpsilon']], index=[nr for nr in mTEPES.nr if mTEPES.dPar['pStartUpCost'] [nr] < mTEPES.dPar['pEpsilon']]))
|
|
1297
|
+
mTEPES.dPar['pShutDownCost'].update (pd.Series([0.0 for nr in mTEPES.nr if mTEPES.dPar['pShutDownCost'] [nr] < mTEPES.dPar['pEpsilon']], index=[nr for nr in mTEPES.nr if mTEPES.dPar['pShutDownCost'] [nr] < mTEPES.dPar['pEpsilon']]))
|
|
1384
1298
|
|
|
1385
1299
|
# this rated linear variable cost is going to be used to order the generating units
|
|
1386
1300
|
# we include a small term to avoid a stochastic behavior due to equal values
|
|
1387
1301
|
for g in mTEPES.g:
|
|
1388
|
-
pRatedLinearVarCost[g] += 1e-3*pEpsilon*mTEPES.g.ord(g)
|
|
1302
|
+
mTEPES.dPar['pRatedLinearVarCost'][g] += 1e-3*mTEPES.dPar['pEpsilon']*mTEPES.g.ord(g)
|
|
1389
1303
|
|
|
1390
1304
|
# BigM maximum flow to be used in the Kirchhoff's 2nd law disjunctive constraint
|
|
1391
|
-
pBigMFlowBck = pLineNTCBck*0.0
|
|
1392
|
-
pBigMFlowFrw = pLineNTCFrw*0.0
|
|
1305
|
+
mTEPES.dPar['pBigMFlowBck'] = mTEPES.dPar['pLineNTCBck']*0.0
|
|
1306
|
+
mTEPES.dPar['pBigMFlowFrw'] = mTEPES.dPar['pLineNTCFrw']*0.0
|
|
1393
1307
|
for lea in mTEPES.lea:
|
|
1394
|
-
pBigMFlowBck.loc[lea] = pLineNTCBck[lea]
|
|
1395
|
-
pBigMFlowFrw.loc[lea] = pLineNTCFrw[lea]
|
|
1308
|
+
mTEPES.dPar['pBigMFlowBck'].loc[lea] = mTEPES.dPar['pLineNTCBck'][lea]
|
|
1309
|
+
mTEPES.dPar['pBigMFlowFrw'].loc[lea] = mTEPES.dPar['pLineNTCFrw'][lea]
|
|
1396
1310
|
for lca in mTEPES.lca:
|
|
1397
|
-
pBigMFlowBck.loc[lca] = pLineNTCBck[lca]*1.5
|
|
1398
|
-
pBigMFlowFrw.loc[lca] = pLineNTCFrw[lca]*1.5
|
|
1311
|
+
mTEPES.dPar['pBigMFlowBck'].loc[lca] = mTEPES.dPar['pLineNTCBck'][lca]*1.5
|
|
1312
|
+
mTEPES.dPar['pBigMFlowFrw'].loc[lca] = mTEPES.dPar['pLineNTCFrw'][lca]*1.5
|
|
1399
1313
|
for led in mTEPES.led:
|
|
1400
|
-
pBigMFlowBck.loc[led] = pLineNTCBck[led]
|
|
1401
|
-
pBigMFlowFrw.loc[led] = pLineNTCFrw[led]
|
|
1314
|
+
mTEPES.dPar['pBigMFlowBck'].loc[led] = mTEPES.dPar['pLineNTCBck'][led]
|
|
1315
|
+
mTEPES.dPar['pBigMFlowFrw'].loc[led] = mTEPES.dPar['pLineNTCFrw'][led]
|
|
1402
1316
|
for lcd in mTEPES.lcd:
|
|
1403
|
-
pBigMFlowBck.loc[lcd] = pLineNTCBck[lcd]*1.5
|
|
1404
|
-
pBigMFlowFrw.loc[lcd] = pLineNTCFrw[lcd]*1.5
|
|
1317
|
+
mTEPES.dPar['pBigMFlowBck'].loc[lcd] = mTEPES.dPar['pLineNTCBck'][lcd]*1.5
|
|
1318
|
+
mTEPES.dPar['pBigMFlowFrw'].loc[lcd] = mTEPES.dPar['pLineNTCFrw'][lcd]*1.5
|
|
1405
1319
|
|
|
1406
1320
|
# if BigM are 0.0 then converted to 1.0 to avoid division by 0.0
|
|
1407
|
-
pBigMFlowBck = pBigMFlowBck.where(pBigMFlowBck != 0.0, 1.0)
|
|
1408
|
-
pBigMFlowFrw = pBigMFlowFrw.where(pBigMFlowFrw != 0.0, 1.0)
|
|
1321
|
+
mTEPES.dPar['pBigMFlowBck'] = mTEPES.dPar['pBigMFlowBck'].where(mTEPES.dPar['pBigMFlowBck'] != 0.0, 1.0)
|
|
1322
|
+
mTEPES.dPar['pBigMFlowFrw'] = mTEPES.dPar['pBigMFlowFrw'].where(mTEPES.dPar['pBigMFlowFrw'] != 0.0, 1.0)
|
|
1409
1323
|
|
|
1410
1324
|
# maximum voltage angle
|
|
1411
|
-
pMaxTheta = pDemandElec*0.0 + math.pi/2
|
|
1412
|
-
pMaxTheta = pMaxTheta.loc[mTEPES.psn]
|
|
1325
|
+
mTEPES.dPar['pMaxTheta'] = mTEPES.dPar['pDemandElec']*0.0 + math.pi/2
|
|
1326
|
+
mTEPES.dPar['pMaxTheta'] = mTEPES.dPar['pMaxTheta'].loc[mTEPES.psn]
|
|
1413
1327
|
|
|
1414
1328
|
# this option avoids a warning in the following assignments
|
|
1415
1329
|
pd.options.mode.chained_assignment = None
|
|
@@ -1419,200 +1333,201 @@ def InputData(DirName, CaseName, mTEPES, pIndLogConsole):
|
|
|
1419
1333
|
df = df[df.index.isin(set)]
|
|
1420
1334
|
return df
|
|
1421
1335
|
|
|
1422
|
-
pMinPowerElec = filter_rows(pMinPowerElec , mTEPES.psng )
|
|
1423
|
-
pMaxPowerElec = filter_rows(pMaxPowerElec , mTEPES.psng )
|
|
1424
|
-
pMinCharge = filter_rows(pMinCharge , mTEPES.psneh)
|
|
1425
|
-
pMaxCharge = filter_rows(pMaxCharge , mTEPES.psneh)
|
|
1426
|
-
pMaxCapacity = filter_rows(pMaxCapacity , mTEPES.psneh)
|
|
1427
|
-
pMaxPower2ndBlock = filter_rows(pMaxPower2ndBlock , mTEPES.psng )
|
|
1428
|
-
pMaxCharge2ndBlock = filter_rows(pMaxCharge2ndBlock, mTEPES.psneh)
|
|
1429
|
-
pEnergyInflows = filter_rows(pEnergyInflows , mTEPES.psnes)
|
|
1430
|
-
pEnergyOutflows = filter_rows(pEnergyOutflows , mTEPES.psnes)
|
|
1431
|
-
pMinStorage = filter_rows(pMinStorage , mTEPES.psnes)
|
|
1432
|
-
pMaxStorage = filter_rows(pMaxStorage , mTEPES.psnes)
|
|
1433
|
-
pVariableMaxEnergy = filter_rows(pVariableMaxEnergy, mTEPES.psng )
|
|
1434
|
-
pVariableMinEnergy = filter_rows(pVariableMinEnergy, mTEPES.psng )
|
|
1435
|
-
pLinearVarCost = filter_rows(pLinearVarCost , mTEPES.psng )
|
|
1436
|
-
pConstantVarCost = filter_rows(pConstantVarCost , mTEPES.psng )
|
|
1437
|
-
pEmissionVarCost = filter_rows(pEmissionVarCost , mTEPES.psng )
|
|
1438
|
-
pIniInventory = filter_rows(pIniInventory , mTEPES.psnes)
|
|
1439
|
-
|
|
1440
|
-
pDemandElec = filter_rows(pDemandElec , mTEPES.psnnd)
|
|
1441
|
-
|
|
1442
|
-
pSystemInertia = filter_rows(pSystemInertia , mTEPES.psnar)
|
|
1443
|
-
pOperReserveUp = filter_rows(pOperReserveUp , mTEPES.psnar)
|
|
1444
|
-
pOperReserveDw = filter_rows(pOperReserveDw , mTEPES.psnar)
|
|
1445
|
-
|
|
1446
|
-
pMaxNTCBck = filter_rows(pMaxNTCBck , mTEPES.psnla)
|
|
1447
|
-
pMaxNTCFrw = filter_rows(pMaxNTCFrw , mTEPES.psnla)
|
|
1448
|
-
pMaxNTCMax = filter_rows(pMaxNTCMax , mTEPES.psnla)
|
|
1449
|
-
|
|
1450
|
-
if pIndPTDF == 1:
|
|
1451
|
-
pPTDF = pVariablePTDF.stack(level=list(range(pVariablePTDF.columns.nlevels)), future_stack=True)
|
|
1452
|
-
pPTDF.index.set_names(['Period', 'Scenario', 'LoadLevel', 'InitialNode', 'FinalNode', 'Circuit', 'Node'], inplace=True)
|
|
1336
|
+
mTEPES.dPar['pMinPowerElec'] = filter_rows(mTEPES.dPar['pMinPowerElec'] , mTEPES.psng )
|
|
1337
|
+
mTEPES.dPar['pMaxPowerElec'] = filter_rows(mTEPES.dPar['pMaxPowerElec'] , mTEPES.psng )
|
|
1338
|
+
mTEPES.dPar['pMinCharge'] = filter_rows(mTEPES.dPar['pMinCharge'] , mTEPES.psneh)
|
|
1339
|
+
mTEPES.dPar['pMaxCharge'] = filter_rows(mTEPES.dPar['pMaxCharge'] , mTEPES.psneh)
|
|
1340
|
+
mTEPES.dPar['pMaxCapacity'] = filter_rows(mTEPES.dPar['pMaxCapacity'] , mTEPES.psneh)
|
|
1341
|
+
mTEPES.dPar['pMaxPower2ndBlock'] = filter_rows(mTEPES.dPar['pMaxPower2ndBlock'] , mTEPES.psng )
|
|
1342
|
+
mTEPES.dPar['pMaxCharge2ndBlock'] = filter_rows(mTEPES.dPar['pMaxCharge2ndBlock'], mTEPES.psneh)
|
|
1343
|
+
mTEPES.dPar['pEnergyInflows'] = filter_rows(mTEPES.dPar['pEnergyInflows'] , mTEPES.psnes)
|
|
1344
|
+
mTEPES.dPar['pEnergyOutflows'] = filter_rows(mTEPES.dPar['pEnergyOutflows'] , mTEPES.psnes)
|
|
1345
|
+
mTEPES.dPar['pMinStorage'] = filter_rows(mTEPES.dPar['pMinStorage'] , mTEPES.psnes)
|
|
1346
|
+
mTEPES.dPar['pMaxStorage'] = filter_rows(mTEPES.dPar['pMaxStorage'] , mTEPES.psnes)
|
|
1347
|
+
mTEPES.dPar['pVariableMaxEnergy'] = filter_rows(mTEPES.dPar['pVariableMaxEnergy'], mTEPES.psng )
|
|
1348
|
+
mTEPES.dPar['pVariableMinEnergy'] = filter_rows(mTEPES.dPar['pVariableMinEnergy'], mTEPES.psng )
|
|
1349
|
+
mTEPES.dPar['pLinearVarCost'] = filter_rows(mTEPES.dPar['pLinearVarCost'] , mTEPES.psng )
|
|
1350
|
+
mTEPES.dPar['pConstantVarCost'] = filter_rows(mTEPES.dPar['pConstantVarCost'] , mTEPES.psng )
|
|
1351
|
+
mTEPES.dPar['pEmissionVarCost'] = filter_rows(mTEPES.dPar['pEmissionVarCost'] , mTEPES.psng )
|
|
1352
|
+
mTEPES.dPar['pIniInventory'] = filter_rows(mTEPES.dPar['pIniInventory'] , mTEPES.psnes)
|
|
1353
|
+
|
|
1354
|
+
mTEPES.dPar['pDemandElec'] = filter_rows(mTEPES.dPar['pDemandElec'] , mTEPES.psnnd)
|
|
1355
|
+
mTEPES.dPar['pDemandElecPos'] = filter_rows(mTEPES.dPar['pDemandElecPos'] , mTEPES.psnnd)
|
|
1356
|
+
mTEPES.dPar['pSystemInertia'] = filter_rows(mTEPES.dPar['pSystemInertia'] , mTEPES.psnar)
|
|
1357
|
+
mTEPES.dPar['pOperReserveUp'] = filter_rows(mTEPES.dPar['pOperReserveUp'] , mTEPES.psnar)
|
|
1358
|
+
mTEPES.dPar['pOperReserveDw'] = filter_rows(mTEPES.dPar['pOperReserveDw'] , mTEPES.psnar)
|
|
1359
|
+
|
|
1360
|
+
mTEPES.dPar['pMaxNTCBck'] = filter_rows(mTEPES.dPar['pMaxNTCBck'] , mTEPES.psnla)
|
|
1361
|
+
mTEPES.dPar['pMaxNTCFrw'] = filter_rows(mTEPES.dPar['pMaxNTCFrw'] , mTEPES.psnla)
|
|
1362
|
+
mTEPES.dPar['pMaxNTCMax'] = filter_rows(mTEPES.dPar['pMaxNTCMax'] , mTEPES.psnla)
|
|
1363
|
+
|
|
1364
|
+
if mTEPES.dPar['pIndPTDF'] == 1:
|
|
1365
|
+
mTEPES.dPar['pPTDF'] = mTEPES.dPar['pVariablePTDF'].stack(level=list(range(mTEPES.dPar['pVariablePTDF'].columns.nlevels)), future_stack=True)
|
|
1366
|
+
mTEPES.dPar['pPTDF'].index.set_names(['Period', 'Scenario', 'LoadLevel', 'InitialNode', 'FinalNode', 'Circuit', 'Node'], inplace=True)
|
|
1453
1367
|
# filter rows to keep the same as mTEPES.psnland
|
|
1454
|
-
pPTDF = pPTDF[pPTDF.index.isin(mTEPES.psnland)]
|
|
1368
|
+
mTEPES.dPar['pPTDF'] = mTEPES.dPar['pPTDF'][mTEPES.dPar['pPTDF'].index.isin(mTEPES.psnland)]
|
|
1455
1369
|
|
|
1456
1370
|
# %% parameters
|
|
1457
|
-
mTEPES.pIndBinGenInvest = Param(initialize=pIndBinGenInvest , within=NonNegativeIntegers, doc='Indicator of binary generation investment decisions', mutable=True)
|
|
1458
|
-
mTEPES.pIndBinGenRetire = Param(initialize=
|
|
1459
|
-
mTEPES.pIndBinRsrInvest = Param(initialize=pIndBinRsrInvest , within=NonNegativeIntegers, doc='Indicator of binary reservoir investment decisions', mutable=True)
|
|
1460
|
-
mTEPES.pIndBinNetElecInvest = Param(initialize=
|
|
1461
|
-
mTEPES.pIndBinNetH2Invest = Param(initialize=pIndBinNetH2Invest , within=NonNegativeIntegers, doc='Indicator of binary hydrogen network investment decisions', mutable=True)
|
|
1462
|
-
mTEPES.pIndBinNetHeatInvest = Param(initialize=pIndBinNetHeatInvest, within=NonNegativeIntegers, doc='Indicator of binary heat network investment decisions', mutable=True)
|
|
1463
|
-
mTEPES.pIndBinGenOperat = Param(initialize=pIndBinGenOperat , within=Binary, doc='Indicator of binary generation operation decisions', mutable=True)
|
|
1464
|
-
mTEPES.pIndBinSingleNode = Param(initialize=pIndBinSingleNode , within=Binary, doc='Indicator of single node within a electric network case', mutable=True)
|
|
1465
|
-
mTEPES.pIndBinGenRamps = Param(initialize=pIndBinGenRamps , within=Binary, doc='Indicator of using or not the ramp constraints', mutable=True)
|
|
1466
|
-
mTEPES.pIndBinGenMinTime = Param(initialize=pIndBinGenMinTime , within=Binary, doc='Indicator of using or not the min up/dw time constraints', mutable=True)
|
|
1467
|
-
mTEPES.pIndBinLineCommit = Param(initialize=pIndBinLineCommit , within=Binary, doc='Indicator of binary electric network switching decisions', mutable=True)
|
|
1468
|
-
mTEPES.pIndBinNetLosses = Param(initialize=pIndBinNetLosses , within=Binary, doc='Indicator of binary electric network ohmic losses', mutable=True)
|
|
1469
|
-
mTEPES.pIndHydroTopology = Param(initialize=pIndHydroTopology , within=Binary, doc='Indicator of reservoir and hydropower topology' )
|
|
1470
|
-
mTEPES.pIndHydrogen = Param(initialize=pIndHydrogen , within=Binary, doc='Indicator of hydrogen demand and pipeline network' )
|
|
1471
|
-
mTEPES.pIndHeat = Param(initialize=pIndHeat , within=Binary, doc='Indicator of heat demand and pipe network' )
|
|
1472
|
-
mTEPES.
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
mTEPES.
|
|
1476
|
-
mTEPES.
|
|
1477
|
-
mTEPES.
|
|
1478
|
-
mTEPES.
|
|
1479
|
-
mTEPES.
|
|
1480
|
-
mTEPES.
|
|
1481
|
-
mTEPES.
|
|
1482
|
-
mTEPES.
|
|
1483
|
-
mTEPES.
|
|
1484
|
-
mTEPES.
|
|
1485
|
-
mTEPES.
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
mTEPES.
|
|
1489
|
-
mTEPES.
|
|
1490
|
-
mTEPES.
|
|
1491
|
-
mTEPES.
|
|
1492
|
-
mTEPES.
|
|
1493
|
-
mTEPES.
|
|
1494
|
-
mTEPES.
|
|
1495
|
-
mTEPES.
|
|
1496
|
-
mTEPES.
|
|
1497
|
-
mTEPES.
|
|
1498
|
-
mTEPES.
|
|
1499
|
-
mTEPES.
|
|
1500
|
-
mTEPES.
|
|
1501
|
-
mTEPES.
|
|
1502
|
-
mTEPES.
|
|
1503
|
-
mTEPES.
|
|
1504
|
-
mTEPES.
|
|
1505
|
-
mTEPES.
|
|
1506
|
-
mTEPES.
|
|
1507
|
-
mTEPES.
|
|
1508
|
-
mTEPES.
|
|
1509
|
-
mTEPES.
|
|
1510
|
-
mTEPES.
|
|
1511
|
-
mTEPES.
|
|
1512
|
-
mTEPES.
|
|
1513
|
-
mTEPES.
|
|
1514
|
-
mTEPES.
|
|
1515
|
-
mTEPES.
|
|
1516
|
-
mTEPES.
|
|
1517
|
-
mTEPES.
|
|
1518
|
-
mTEPES.
|
|
1519
|
-
mTEPES.
|
|
1520
|
-
mTEPES.
|
|
1521
|
-
mTEPES.
|
|
1522
|
-
mTEPES.
|
|
1523
|
-
mTEPES.
|
|
1524
|
-
mTEPES.
|
|
1525
|
-
mTEPES.
|
|
1526
|
-
mTEPES.
|
|
1527
|
-
mTEPES.
|
|
1528
|
-
mTEPES.
|
|
1529
|
-
mTEPES.
|
|
1530
|
-
mTEPES.
|
|
1531
|
-
mTEPES.
|
|
1532
|
-
mTEPES.
|
|
1533
|
-
mTEPES.
|
|
1534
|
-
mTEPES.
|
|
1535
|
-
mTEPES.
|
|
1536
|
-
mTEPES.
|
|
1537
|
-
mTEPES.
|
|
1538
|
-
mTEPES.
|
|
1539
|
-
mTEPES.
|
|
1540
|
-
mTEPES.
|
|
1541
|
-
mTEPES.
|
|
1542
|
-
mTEPES.
|
|
1543
|
-
mTEPES.
|
|
1544
|
-
mTEPES.
|
|
1545
|
-
mTEPES.
|
|
1546
|
-
mTEPES.
|
|
1547
|
-
mTEPES.
|
|
1548
|
-
mTEPES.
|
|
1549
|
-
mTEPES.
|
|
1550
|
-
mTEPES.
|
|
1551
|
-
mTEPES.
|
|
1552
|
-
mTEPES.
|
|
1553
|
-
mTEPES.
|
|
1554
|
-
mTEPES.
|
|
1555
|
-
mTEPES.
|
|
1556
|
-
mTEPES.
|
|
1557
|
-
mTEPES.
|
|
1558
|
-
mTEPES.
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
mTEPES.
|
|
1569
|
-
mTEPES.
|
|
1570
|
-
mTEPES.
|
|
1571
|
-
mTEPES.
|
|
1572
|
-
mTEPES.
|
|
1573
|
-
mTEPES.
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
mTEPES.
|
|
1588
|
-
mTEPES.
|
|
1589
|
-
mTEPES.
|
|
1590
|
-
mTEPES.
|
|
1591
|
-
mTEPES.
|
|
1592
|
-
mTEPES.
|
|
1593
|
-
mTEPES.
|
|
1594
|
-
mTEPES.
|
|
1595
|
-
mTEPES.
|
|
1596
|
-
mTEPES.
|
|
1597
|
-
mTEPES.
|
|
1598
|
-
mTEPES.
|
|
1599
|
-
mTEPES.
|
|
1600
|
-
mTEPES.
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
mTEPES.
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
mTEPES.
|
|
1615
|
-
mTEPES.
|
|
1371
|
+
mTEPES.pIndBinGenInvest = Param(initialize=mTEPES.dPar['pIndBinGenInvest'] , within=NonNegativeIntegers, doc='Indicator of binary generation investment decisions', mutable=True)
|
|
1372
|
+
mTEPES.pIndBinGenRetire = Param(initialize=mTEPES.dPar['pIndBinGenRetirement'], within=NonNegativeIntegers, doc='Indicator of binary generation retirement decisions', mutable=True)
|
|
1373
|
+
mTEPES.pIndBinRsrInvest = Param(initialize=mTEPES.dPar['pIndBinRsrInvest'] , within=NonNegativeIntegers, doc='Indicator of binary reservoir investment decisions', mutable=True)
|
|
1374
|
+
mTEPES.pIndBinNetElecInvest = Param(initialize=mTEPES.dPar['pIndBinNetInvest'] , within=NonNegativeIntegers, doc='Indicator of binary electric network investment decisions', mutable=True)
|
|
1375
|
+
mTEPES.pIndBinNetH2Invest = Param(initialize=mTEPES.dPar['pIndBinNetH2Invest'] , within=NonNegativeIntegers, doc='Indicator of binary hydrogen network investment decisions', mutable=True)
|
|
1376
|
+
mTEPES.pIndBinNetHeatInvest = Param(initialize=mTEPES.dPar['pIndBinNetHeatInvest'], within=NonNegativeIntegers, doc='Indicator of binary heat network investment decisions', mutable=True)
|
|
1377
|
+
mTEPES.pIndBinGenOperat = Param(initialize=mTEPES.dPar['pIndBinGenOperat'] , within=Binary, doc='Indicator of binary generation operation decisions', mutable=True)
|
|
1378
|
+
mTEPES.pIndBinSingleNode = Param(initialize=mTEPES.dPar['pIndBinSingleNode'] , within=Binary, doc='Indicator of single node within a electric network case', mutable=True)
|
|
1379
|
+
mTEPES.pIndBinGenRamps = Param(initialize=mTEPES.dPar['pIndBinGenRamps'] , within=Binary, doc='Indicator of using or not the ramp constraints', mutable=True)
|
|
1380
|
+
mTEPES.pIndBinGenMinTime = Param(initialize=mTEPES.dPar['pIndBinGenMinTime'] , within=Binary, doc='Indicator of using or not the min up/dw time constraints', mutable=True)
|
|
1381
|
+
mTEPES.pIndBinLineCommit = Param(initialize=mTEPES.dPar['pIndBinLineCommit'] , within=Binary, doc='Indicator of binary electric network switching decisions', mutable=True)
|
|
1382
|
+
mTEPES.pIndBinNetLosses = Param(initialize=mTEPES.dPar['pIndBinNetLosses'] , within=Binary, doc='Indicator of binary electric network ohmic losses', mutable=True)
|
|
1383
|
+
mTEPES.pIndHydroTopology = Param(initialize=mTEPES.dPar['pIndHydroTopology'] , within=Binary, doc='Indicator of reservoir and hydropower topology' )
|
|
1384
|
+
mTEPES.pIndHydrogen = Param(initialize=mTEPES.dPar['pIndHydrogen'] , within=Binary, doc='Indicator of hydrogen demand and pipeline network' )
|
|
1385
|
+
mTEPES.pIndHeat = Param(initialize=mTEPES.dPar['pIndHeat'] , within=Binary, doc='Indicator of heat demand and pipe network' )
|
|
1386
|
+
mTEPES.pIndVarTTC = Param(initialize=mTEPES.dPar['pIndVarTTC'] , within=Binary, doc='Indicator of using or not variable TTC' )
|
|
1387
|
+
mTEPES.pIndPTDF = Param(initialize=mTEPES.dPar['pIndPTDF'] , within=Binary, doc='Indicator of using or not the Flow-based method' )
|
|
1388
|
+
|
|
1389
|
+
mTEPES.pENSCost = Param(initialize=mTEPES.dPar['pENSCost'] , within=NonNegativeReals, doc='ENS cost' )
|
|
1390
|
+
mTEPES.pH2NSCost = Param(initialize=mTEPES.dPar['pHNSCost'] , within=NonNegativeReals, doc='HNS cost' )
|
|
1391
|
+
mTEPES.pHeatNSCost = Param(initialize=mTEPES.dPar['pHTNSCost'] , within=NonNegativeReals, doc='HTNS cost' )
|
|
1392
|
+
mTEPES.pCO2Cost = Param(initialize=mTEPES.dPar['pCO2Cost'] , within=NonNegativeReals, doc='CO2 emission cost' )
|
|
1393
|
+
mTEPES.pAnnualDiscRate = Param(initialize=mTEPES.dPar['pAnnualDiscountRate'] , within=UnitInterval, doc='Annual discount rate' )
|
|
1394
|
+
mTEPES.pUpReserveActivation = Param(initialize=mTEPES.dPar['pUpReserveActivation'], within=UnitInterval, doc='Proportion of upward reserve activation' )
|
|
1395
|
+
mTEPES.pDwReserveActivation = Param(initialize=mTEPES.dPar['pDwReserveActivation'], within=UnitInterval, doc='Proportion of downward reserve activation' )
|
|
1396
|
+
mTEPES.pMinRatioDwUp = Param(initialize=mTEPES.dPar['pMinRatioDwUp'] , within=UnitInterval, doc='Minimum ratio downward to upward operating reserves')
|
|
1397
|
+
mTEPES.pMaxRatioDwUp = Param(initialize=mTEPES.dPar['pMaxRatioDwUp'] , within=UnitInterval, doc='Maximum ratio downward to upward operating reserves')
|
|
1398
|
+
mTEPES.pSBase = Param(initialize=mTEPES.dPar['pSBase'] , within=PositiveReals, doc='Base power' )
|
|
1399
|
+
mTEPES.pTimeStep = Param(initialize=mTEPES.dPar['pTimeStep'] , within=PositiveIntegers, doc='Unitary time step' )
|
|
1400
|
+
mTEPES.pEconomicBaseYear = Param(initialize=mTEPES.dPar['pEconomicBaseYear'] , within=PositiveIntegers, doc='Base year' )
|
|
1401
|
+
|
|
1402
|
+
mTEPES.pReserveMargin = Param(mTEPES.par, initialize=mTEPES.dPar['pReserveMargin'].to_dict() , within=NonNegativeReals, doc='Adequacy reserve margin' )
|
|
1403
|
+
mTEPES.pEmission = Param(mTEPES.par, initialize=mTEPES.dPar['pEmission'].to_dict() , within=NonNegativeReals, doc='Maximum CO2 emission' )
|
|
1404
|
+
mTEPES.pRESEnergy = Param(mTEPES.par, initialize=mTEPES.dPar['pRESEnergy'].to_dict() , within=NonNegativeReals, doc='Minimum RES energy' )
|
|
1405
|
+
mTEPES.pDemandElecPeak = Param(mTEPES.par, initialize=mTEPES.dPar['pDemandElecPeak'].to_dict() , within=NonNegativeReals, doc='Peak electric demand' )
|
|
1406
|
+
mTEPES.pDemandElec = Param(mTEPES.psnnd, initialize=mTEPES.dPar['pDemandElec'].to_dict() , within= Reals, doc='Electric demand' )
|
|
1407
|
+
mTEPES.pDemandElecPos = Param(mTEPES.psnnd, initialize=mTEPES.dPar['pDemandElecPos'].to_dict() , within=NonNegativeReals, doc='Electric demand positive' )
|
|
1408
|
+
mTEPES.pPeriodWeight = Param(mTEPES.p, initialize=mTEPES.dPar['pPeriodWeight'].to_dict() , within=NonNegativeReals, doc='Period weight', mutable=True)
|
|
1409
|
+
mTEPES.pDiscountedWeight = Param(mTEPES.p, initialize=mTEPES.dPar['pDiscountedWeight'].to_dict() , within=NonNegativeReals, doc='Discount factor' )
|
|
1410
|
+
mTEPES.pScenProb = Param(mTEPES.psc, initialize=mTEPES.dPar['pScenProb'].to_dict() , within=UnitInterval , doc='Probability', mutable=True)
|
|
1411
|
+
mTEPES.pStageWeight = Param(mTEPES.stt, initialize=mTEPES.dPar['pStageWeight'].to_dict() , within=NonNegativeReals, doc='Stage weight' )
|
|
1412
|
+
mTEPES.pDuration = Param(mTEPES.psn, initialize=mTEPES.dPar['pDuration'].to_dict() , within=NonNegativeIntegers, doc='Duration', mutable=True)
|
|
1413
|
+
mTEPES.pNodeLon = Param(mTEPES.nd, initialize=mTEPES.dPar['pNodeLon'].to_dict() , doc='Longitude' )
|
|
1414
|
+
mTEPES.pNodeLat = Param(mTEPES.nd, initialize=mTEPES.dPar['pNodeLat'].to_dict() , doc='Latitude' )
|
|
1415
|
+
mTEPES.pSystemInertia = Param(mTEPES.psnar, initialize=mTEPES.dPar['pSystemInertia'].to_dict() , within=NonNegativeReals, doc='System inertia' )
|
|
1416
|
+
mTEPES.pOperReserveUp = Param(mTEPES.psnar, initialize=mTEPES.dPar['pOperReserveUp'].to_dict() , within=NonNegativeReals, doc='Upward operating reserve' )
|
|
1417
|
+
mTEPES.pOperReserveDw = Param(mTEPES.psnar, initialize=mTEPES.dPar['pOperReserveDw'].to_dict() , within=NonNegativeReals, doc='Downward operating reserve' )
|
|
1418
|
+
mTEPES.pMinPowerElec = Param(mTEPES.psng , initialize=mTEPES.dPar['pMinPowerElec'].to_dict() , within=NonNegativeReals, doc='Minimum electric power' )
|
|
1419
|
+
mTEPES.pMaxPowerElec = Param(mTEPES.psng , initialize=mTEPES.dPar['pMaxPowerElec'].to_dict() , within=NonNegativeReals, doc='Maximum electric power' )
|
|
1420
|
+
mTEPES.pMinCharge = Param(mTEPES.psneh, initialize=mTEPES.dPar['pMinCharge'].to_dict() , within=NonNegativeReals, doc='Minimum charge' )
|
|
1421
|
+
mTEPES.pMaxCharge = Param(mTEPES.psneh, initialize=mTEPES.dPar['pMaxCharge'].to_dict() , within=NonNegativeReals, doc='Maximum charge' )
|
|
1422
|
+
mTEPES.pMaxCapacity = Param(mTEPES.psneh, initialize=mTEPES.dPar['pMaxCapacity'].to_dict() , within=NonNegativeReals, doc='Maximum capacity' )
|
|
1423
|
+
mTEPES.pMaxPower2ndBlock = Param(mTEPES.psng , initialize=mTEPES.dPar['pMaxPower2ndBlock'].to_dict() , within=NonNegativeReals, doc='Second block power' )
|
|
1424
|
+
mTEPES.pMaxCharge2ndBlock = Param(mTEPES.psneh, initialize=mTEPES.dPar['pMaxCharge2ndBlock'].to_dict() , within=NonNegativeReals, doc='Second block charge' )
|
|
1425
|
+
mTEPES.pEnergyInflows = Param(mTEPES.psnes, initialize=mTEPES.dPar['pEnergyInflows'].to_dict() , within=NonNegativeReals, doc='Energy inflows', mutable=True)
|
|
1426
|
+
mTEPES.pEnergyOutflows = Param(mTEPES.psnes, initialize=mTEPES.dPar['pEnergyOutflows'].to_dict() , within=NonNegativeReals, doc='Energy outflows', mutable=True)
|
|
1427
|
+
mTEPES.pMinStorage = Param(mTEPES.psnes, initialize=mTEPES.dPar['pMinStorage'].to_dict() , within=NonNegativeReals, doc='ESS Minimum storage capacity' )
|
|
1428
|
+
mTEPES.pMaxStorage = Param(mTEPES.psnes, initialize=mTEPES.dPar['pMaxStorage'].to_dict() , within=NonNegativeReals, doc='ESS Maximum storage capacity' )
|
|
1429
|
+
mTEPES.pMinEnergy = Param(mTEPES.psng , initialize=mTEPES.dPar['pVariableMinEnergy'].to_dict() , within=NonNegativeReals, doc='Unit minimum energy demand' )
|
|
1430
|
+
mTEPES.pMaxEnergy = Param(mTEPES.psng , initialize=mTEPES.dPar['pVariableMaxEnergy'].to_dict() , within=NonNegativeReals, doc='Unit maximum energy demand' )
|
|
1431
|
+
mTEPES.pRatedMaxPowerElec = Param(mTEPES.gg, initialize=mTEPES.dPar['pRatedMaxPowerElec'].to_dict() , within=NonNegativeReals, doc='Rated maximum power' )
|
|
1432
|
+
mTEPES.pRatedMaxCharge = Param(mTEPES.gg, initialize=mTEPES.dPar['pRatedMaxCharge'].to_dict() , within=NonNegativeReals, doc='Rated maximum charge' )
|
|
1433
|
+
mTEPES.pMustRun = Param(mTEPES.gg, initialize=mTEPES.dPar['pMustRun'].to_dict() , within=Binary , doc='must-run unit' )
|
|
1434
|
+
mTEPES.pInertia = Param(mTEPES.gg, initialize=mTEPES.dPar['pInertia'].to_dict() , within=NonNegativeReals, doc='unit inertia constant' )
|
|
1435
|
+
mTEPES.pElecGenPeriodIni = Param(mTEPES.gg, initialize=mTEPES.dPar['pElecGenPeriodIni'].to_dict() , within=PositiveIntegers, doc='installation year', )
|
|
1436
|
+
mTEPES.pElecGenPeriodFin = Param(mTEPES.gg, initialize=mTEPES.dPar['pElecGenPeriodFin'].to_dict() , within=PositiveIntegers, doc='retirement year', )
|
|
1437
|
+
mTEPES.pAvailability = Param(mTEPES.gg, initialize=mTEPES.dPar['pAvailability'].to_dict() , within=UnitInterval , doc='unit availability', mutable=True)
|
|
1438
|
+
mTEPES.pEFOR = Param(mTEPES.gg, initialize=mTEPES.dPar['pEFOR'].to_dict() , within=UnitInterval , doc='EFOR' )
|
|
1439
|
+
mTEPES.pRatedLinearVarCost = Param(mTEPES.gg, initialize=mTEPES.dPar['pRatedLinearVarCost'].to_dict() , within=NonNegativeReals, doc='Linear variable cost' )
|
|
1440
|
+
mTEPES.pRatedConstantVarCost = Param(mTEPES.gg, initialize=mTEPES.dPar['pRatedConstantVarCost'].to_dict() , within=NonNegativeReals, doc='Constant variable cost' )
|
|
1441
|
+
mTEPES.pLinearVarCost = Param(mTEPES.psng , initialize=mTEPES.dPar['pLinearVarCost'].to_dict() , within=NonNegativeReals, doc='Linear variable cost' )
|
|
1442
|
+
mTEPES.pConstantVarCost = Param(mTEPES.psng , initialize=mTEPES.dPar['pConstantVarCost'].to_dict() , within=NonNegativeReals, doc='Constant variable cost' )
|
|
1443
|
+
mTEPES.pLinearOMCost = Param(mTEPES.gg, initialize=mTEPES.dPar['pLinearOMCost'].to_dict() , within=NonNegativeReals, doc='Linear O&M cost' )
|
|
1444
|
+
mTEPES.pOperReserveCost = Param(mTEPES.gg, initialize=mTEPES.dPar['pOperReserveCost'].to_dict() , within=NonNegativeReals, doc='Operating reserve cost' )
|
|
1445
|
+
mTEPES.pEmissionVarCost = Param(mTEPES.psng , initialize=mTEPES.dPar['pEmissionVarCost'].to_dict() , within=Reals , doc='CO2 Emission cost' )
|
|
1446
|
+
mTEPES.pEmissionRate = Param(mTEPES.gg, initialize=mTEPES.dPar['pEmissionRate'].to_dict() , within=Reals , doc='CO2 Emission rate' )
|
|
1447
|
+
mTEPES.pStartUpCost = Param(mTEPES.nr, initialize=mTEPES.dPar['pStartUpCost'].to_dict() , within=NonNegativeReals, doc='Startup cost' )
|
|
1448
|
+
mTEPES.pShutDownCost = Param(mTEPES.nr, initialize=mTEPES.dPar['pShutDownCost'].to_dict() , within=NonNegativeReals, doc='Shutdown cost' )
|
|
1449
|
+
mTEPES.pRampUp = Param(mTEPES.gg, initialize=mTEPES.dPar['pRampUp'].to_dict() , within=NonNegativeReals, doc='Ramp up rate' )
|
|
1450
|
+
mTEPES.pRampDw = Param(mTEPES.gg, initialize=mTEPES.dPar['pRampDw'].to_dict() , within=NonNegativeReals, doc='Ramp down rate' )
|
|
1451
|
+
mTEPES.pUpTime = Param(mTEPES.gg, initialize=mTEPES.dPar['pUpTime'].to_dict() , within=NonNegativeIntegers, doc='Up time' )
|
|
1452
|
+
mTEPES.pDwTime = Param(mTEPES.gg, initialize=mTEPES.dPar['pDwTime'].to_dict() , within=NonNegativeIntegers, doc='Down time' )
|
|
1453
|
+
mTEPES.pStableTime = Param(mTEPES.gg, initialize=mTEPES.dPar['pStableTime'].to_dict() , within=NonNegativeIntegers, doc='Stable time' )
|
|
1454
|
+
mTEPES.pShiftTime = Param(mTEPES.gg, initialize=mTEPES.dPar['pShiftTime'].to_dict() , within=NonNegativeIntegers, doc='Shift time' )
|
|
1455
|
+
mTEPES.pGenInvestCost = Param(mTEPES.eb, initialize=mTEPES.dPar['pGenInvestCost'].to_dict() , within=NonNegativeReals, doc='Generation fixed cost' )
|
|
1456
|
+
mTEPES.pGenRetireCost = Param(mTEPES.gd, initialize=mTEPES.dPar['pGenRetireCost'].to_dict() , within=Reals , doc='Generation fixed retire cost' )
|
|
1457
|
+
mTEPES.pIndBinUnitInvest = Param(mTEPES.eb, initialize=mTEPES.dPar['pIndBinUnitInvest'].to_dict() , within=Binary , doc='Binary investment decision' )
|
|
1458
|
+
mTEPES.pIndBinUnitRetire = Param(mTEPES.gd, initialize=mTEPES.dPar['pIndBinUnitRetire'].to_dict() , within=Binary , doc='Binary retirement decision' )
|
|
1459
|
+
mTEPES.pIndBinUnitCommit = Param(mTEPES.nr, initialize=mTEPES.dPar['pIndBinUnitCommit'].to_dict() , within=Binary , doc='Binary commitment decision' )
|
|
1460
|
+
mTEPES.pIndBinStorInvest = Param(mTEPES.ec, initialize=mTEPES.dPar['pIndBinStorInvest'].to_dict() , within=Binary , doc='Storage linked to generation investment' )
|
|
1461
|
+
mTEPES.pIndOperReserveGen = Param(mTEPES.gg, initialize=mTEPES.dPar['pIndOperReserveGen'].to_dict() , within=Binary , doc='Indicator of operating reserve when generating power')
|
|
1462
|
+
mTEPES.pIndOperReserveCon = Param(mTEPES.gg, initialize=mTEPES.dPar['pIndOperReserveCon'].to_dict() , within=Binary , doc='Indicator of operating reserve when consuming power' )
|
|
1463
|
+
mTEPES.pIndOutflowIncomp = Param(mTEPES.gg, initialize=mTEPES.dPar['pIndOutflowIncomp'].to_dict() , within=Binary , doc='Indicator of outflow incompatibility with charging' )
|
|
1464
|
+
mTEPES.pEfficiency = Param(mTEPES.eh, initialize=mTEPES.dPar['pEfficiency'].to_dict() , within=UnitInterval , doc='Round-trip efficiency' )
|
|
1465
|
+
mTEPES.pStorageTimeStep = Param(mTEPES.es, initialize=mTEPES.dPar['pStorageTimeStep'].to_dict() , within=PositiveIntegers, doc='ESS Storage cycle' )
|
|
1466
|
+
mTEPES.pOutflowsTimeStep = Param(mTEPES.es, initialize=mTEPES.dPar['pOutflowsTimeStep'].to_dict() , within=PositiveIntegers, doc='ESS Outflows cycle' )
|
|
1467
|
+
mTEPES.pEnergyTimeStep = Param(mTEPES.gg, initialize=mTEPES.dPar['pEnergyTimeStep'].to_dict() , within=PositiveIntegers, doc='Unit energy cycle' )
|
|
1468
|
+
mTEPES.pIniInventory = Param(mTEPES.psnes, initialize=mTEPES.dPar['pIniInventory'].to_dict() , within=NonNegativeReals, doc='ESS Initial storage', mutable=True)
|
|
1469
|
+
mTEPES.pStorageType = Param(mTEPES.es, initialize=mTEPES.dPar['pStorageType'].to_dict() , within=Any , doc='ESS Storage type' )
|
|
1470
|
+
mTEPES.pGenLoInvest = Param(mTEPES.eb, initialize=mTEPES.dPar['pGenLoInvest'].to_dict() , within=NonNegativeReals, doc='Lower bound of the investment decision', mutable=True)
|
|
1471
|
+
mTEPES.pGenUpInvest = Param(mTEPES.eb, initialize=mTEPES.dPar['pGenUpInvest'].to_dict() , within=NonNegativeReals, doc='Upper bound of the investment decision', mutable=True)
|
|
1472
|
+
mTEPES.pGenLoRetire = Param(mTEPES.gd, initialize=mTEPES.dPar['pGenLoRetire'].to_dict() , within=NonNegativeReals, doc='Lower bound of the retirement decision', mutable=True)
|
|
1473
|
+
mTEPES.pGenUpRetire = Param(mTEPES.gd, initialize=mTEPES.dPar['pGenUpRetire'].to_dict() , within=NonNegativeReals, doc='Upper bound of the retirement decision', mutable=True)
|
|
1474
|
+
|
|
1475
|
+
if mTEPES.dPar['pIndHydrogen'] == 1:
|
|
1476
|
+
mTEPES.pProductionFunctionH2 = Param(mTEPES.el, initialize=mTEPES.dPar['pProductionFunctionH2'].to_dict(), within=NonNegativeReals, doc='Production function of an electrolyzer plant')
|
|
1477
|
+
|
|
1478
|
+
if mTEPES.dPar['pIndHeat'] == 1:
|
|
1479
|
+
mTEPES.dPar['pMinPowerHeat'] = filter_rows(mTEPES.dPar['pMinPowerHeat'], mTEPES.psnch)
|
|
1480
|
+
mTEPES.dPar['pMaxPowerHeat'] = filter_rows(mTEPES.dPar['pMaxPowerHeat'], mTEPES.psnch)
|
|
1481
|
+
|
|
1482
|
+
mTEPES.pReserveMarginHeat = Param(mTEPES.par, initialize=mTEPES.dPar['pReserveMarginHeat'].to_dict() , within=NonNegativeReals, doc='Adequacy reserve margin' )
|
|
1483
|
+
mTEPES.pRatedMaxPowerHeat = Param(mTEPES.gg, initialize=mTEPES.dPar['pRatedMaxPowerHeat'].to_dict() , within=NonNegativeReals, doc='Rated maximum heat' )
|
|
1484
|
+
mTEPES.pMinPowerHeat = Param(mTEPES.psnch, initialize=mTEPES.dPar['pMinPowerHeat'].to_dict() , within=NonNegativeReals, doc='Minimum heat power' )
|
|
1485
|
+
mTEPES.pMaxPowerHeat = Param(mTEPES.psnch, initialize=mTEPES.dPar['pMaxPowerHeat'].to_dict() , within=NonNegativeReals, doc='Maximum heat power' )
|
|
1486
|
+
mTEPES.pPower2HeatRatio = Param(mTEPES.ch, initialize=mTEPES.dPar['pPower2HeatRatio'].to_dict() , within=NonNegativeReals, doc='Power to heat ratio' )
|
|
1487
|
+
mTEPES.pProductionFunctionHeat = Param(mTEPES.hp, initialize=mTEPES.dPar['pProductionFunctionHeat'].to_dict() , within=NonNegativeReals, doc='Production function of an CHP plant' )
|
|
1488
|
+
mTEPES.pProductionFunctionH2ToHeat = Param(mTEPES.hh, initialize=mTEPES.dPar['pProductionFunctionH2ToHeat'].to_dict(), within=NonNegativeReals, doc='Production function of an boiler using H2')
|
|
1489
|
+
|
|
1490
|
+
if mTEPES.dPar['pIndPTDF'] == 1:
|
|
1491
|
+
mTEPES.pPTDF = Param(mTEPES.psnland, initialize=mTEPES.dPar['pPTDF'].to_dict() , within=Reals , doc='Power transfer distribution factor' )
|
|
1492
|
+
|
|
1493
|
+
if mTEPES.dPar['pIndHydroTopology'] == 1:
|
|
1494
|
+
mTEPES.dPar['pHydroInflows'] = filter_rows(mTEPES.dPar['pHydroInflows'] , mTEPES.psnrs)
|
|
1495
|
+
mTEPES.dPar['pHydroOutflows'] = filter_rows(mTEPES.dPar['pHydroOutflows'], mTEPES.psnrs)
|
|
1496
|
+
mTEPES.dPar['pMaxOutflows'] = filter_rows(mTEPES.dPar['pMaxOutflows'] , mTEPES.psnrs)
|
|
1497
|
+
mTEPES.dPar['pMinVolume'] = filter_rows(mTEPES.dPar['pMinVolume'] , mTEPES.psnrs)
|
|
1498
|
+
mTEPES.dPar['pMaxVolume'] = filter_rows(mTEPES.dPar['pMaxVolume'] , mTEPES.psnrs)
|
|
1499
|
+
mTEPES.dPar['pIniVolume'] = filter_rows(mTEPES.dPar['pIniVolume'] , mTEPES.psnrs)
|
|
1500
|
+
|
|
1501
|
+
mTEPES.pProductionFunctionHydro = Param(mTEPES.h , initialize=mTEPES.dPar['pProductionFunctionHydro'].to_dict(), within=NonNegativeReals, doc='Production function of a hydro power plant' )
|
|
1502
|
+
mTEPES.pHydroInflows = Param(mTEPES.psnrs, initialize=mTEPES.dPar['pHydroInflows'].to_dict() , within=NonNegativeReals, doc='Hydro inflows', mutable=True)
|
|
1503
|
+
mTEPES.pHydroOutflows = Param(mTEPES.psnrs, initialize=mTEPES.dPar['pHydroOutflows'].to_dict() , within=NonNegativeReals, doc='Hydro outflows', mutable=True)
|
|
1504
|
+
mTEPES.pMaxOutflows = Param(mTEPES.psnrs, initialize=mTEPES.dPar['pMaxOutflows'].to_dict() , within=NonNegativeReals, doc='Maximum hydro outflows', )
|
|
1505
|
+
mTEPES.pMinVolume = Param(mTEPES.psnrs, initialize=mTEPES.dPar['pMinVolume'].to_dict() , within=NonNegativeReals, doc='Minimum reservoir volume capacity' )
|
|
1506
|
+
mTEPES.pMaxVolume = Param(mTEPES.psnrs, initialize=mTEPES.dPar['pMaxVolume'].to_dict() , within=NonNegativeReals, doc='Maximum reservoir volume capacity' )
|
|
1507
|
+
mTEPES.pIndBinRsrvInvest = Param(mTEPES.rn, initialize=mTEPES.dPar['pIndBinRsrvInvest'].to_dict() , within=Binary , doc='Binary reservoir investment decision' )
|
|
1508
|
+
mTEPES.pRsrInvestCost = Param(mTEPES.rn, initialize=mTEPES.dPar['pRsrInvestCost'].to_dict() , within=NonNegativeReals, doc='Reservoir fixed cost' )
|
|
1509
|
+
mTEPES.pRsrPeriodIni = Param(mTEPES.rs, initialize=mTEPES.dPar['pRsrPeriodIni'].to_dict() , within=PositiveIntegers, doc='Installation year', )
|
|
1510
|
+
mTEPES.pRsrPeriodFin = Param(mTEPES.rs, initialize=mTEPES.dPar['pRsrPeriodFin'].to_dict() , within=PositiveIntegers, doc='Retirement year', )
|
|
1511
|
+
mTEPES.pReservoirTimeStep = Param(mTEPES.rs, initialize=mTEPES.dPar['pReservoirTimeStep'].to_dict() , within=PositiveIntegers, doc='Reservoir volume cycle' )
|
|
1512
|
+
mTEPES.pWaterOutTimeStep = Param(mTEPES.rs, initialize=mTEPES.dPar['pWaterOutTimeStep'].to_dict() , within=PositiveIntegers, doc='Reservoir outflows cycle' )
|
|
1513
|
+
mTEPES.pIniVolume = Param(mTEPES.psnrs, initialize=mTEPES.dPar['pIniVolume'].to_dict() , within=NonNegativeReals, doc='Reservoir initial volume', mutable=True)
|
|
1514
|
+
mTEPES.pInitialVolume = Param(mTEPES.rs, initialize=mTEPES.dPar['pInitialVolume'].to_dict() , within=NonNegativeReals, doc='Reservoir initial volume without load levels')
|
|
1515
|
+
mTEPES.pReservoirType = Param(mTEPES.rs, initialize=mTEPES.dPar['pReservoirType'].to_dict() , within=Any , doc='Reservoir volume type' )
|
|
1516
|
+
|
|
1517
|
+
if mTEPES.dPar['pIndHydrogen'] == 1:
|
|
1518
|
+
mTEPES.dPar['pDemandH2'] = filter_rows(mTEPES.dPar['pDemandH2'] ,mTEPES.psnnd)
|
|
1519
|
+
mTEPES.dPar['pDemandH2Abs'] = filter_rows(mTEPES.dPar['pDemandH2Abs'],mTEPES.psnnd)
|
|
1520
|
+
|
|
1521
|
+
mTEPES.pDemandH2 = Param(mTEPES.psnnd, initialize=mTEPES.dPar['pDemandH2'].to_dict() , within=NonNegativeReals, doc='Hydrogen demand per hour')
|
|
1522
|
+
mTEPES.pDemandH2Abs = Param(mTEPES.psnnd, initialize=mTEPES.dPar['pDemandH2Abs'].to_dict(), within=NonNegativeReals, doc='Hydrogen demand' )
|
|
1523
|
+
|
|
1524
|
+
if mTEPES.dPar['pIndHeat'] == 1:
|
|
1525
|
+
mTEPES.dPar['pDemandHeat'] = filter_rows(mTEPES.dPar['pDemandHeat'] , mTEPES.psnnd)
|
|
1526
|
+
mTEPES.dPar['pDemandHeatAbs'] = filter_rows(mTEPES.dPar['pDemandHeatAbs'] , mTEPES.psnnd)
|
|
1527
|
+
|
|
1528
|
+
mTEPES.pDemandHeatPeak = Param(mTEPES.par, initialize=mTEPES.dPar['pDemandHeatPeak'].to_dict(), within=NonNegativeReals, doc='Peak heat demand' )
|
|
1529
|
+
mTEPES.pDemandHeat = Param(mTEPES.psnnd, initialize=mTEPES.dPar['pDemandHeat'].to_dict() , within=NonNegativeReals, doc='Heat demand per hour' )
|
|
1530
|
+
mTEPES.pDemandHeatAbs = Param(mTEPES.psnnd, initialize=mTEPES.dPar['pDemandHeatAbs'].to_dict(), within=NonNegativeReals, doc='Heat demand' )
|
|
1616
1531
|
|
|
1617
1532
|
mTEPES.pLoadLevelDuration = Param(mTEPES.psn, initialize=0 , within=NonNegativeIntegers, doc='Load level duration', mutable=True)
|
|
1618
1533
|
for p,sc,n in mTEPES.psn:
|
|
@@ -1623,65 +1538,65 @@ def InputData(DirName, CaseName, mTEPES, pIndLogConsole):
|
|
|
1623
1538
|
# periods and scenarios are going to be solved together with their weight and probability
|
|
1624
1539
|
mTEPES.pPeriodProb[p,sc] = mTEPES.pPeriodWeight[p] * mTEPES.pScenProb[p,sc]
|
|
1625
1540
|
|
|
1626
|
-
pMaxTheta = filter_rows(pMaxTheta, mTEPES.psnnd)
|
|
1627
|
-
|
|
1628
|
-
mTEPES.pLineLossFactor = Param(mTEPES.ll, initialize=pLineLossFactor.to_dict() , within= Reals, doc='Loss factor' )
|
|
1629
|
-
mTEPES.pLineR = Param(mTEPES.la, initialize=pLineR.to_dict() , within=NonNegativeReals, doc='Resistance' )
|
|
1630
|
-
mTEPES.pLineX = Param(mTEPES.la, initialize=pLineX.to_dict() , within= Reals, doc='Reactance' )
|
|
1631
|
-
mTEPES.pLineBsh = Param(mTEPES.la, initialize=pLineBsh.to_dict() , within=NonNegativeReals, doc='Susceptance', mutable=True)
|
|
1632
|
-
mTEPES.pLineTAP = Param(mTEPES.la, initialize=pLineTAP.to_dict() , within=NonNegativeReals, doc='Tap changer', mutable=True)
|
|
1633
|
-
mTEPES.pLineLength = Param(mTEPES.la, initialize=pLineLength.to_dict() , within=NonNegativeReals, doc='Length', mutable=True)
|
|
1634
|
-
mTEPES.pElecNetPeriodIni = Param(mTEPES.la, initialize=pElecNetPeriodIni.to_dict(), within=PositiveIntegers, doc='Installation period' )
|
|
1635
|
-
mTEPES.pElecNetPeriodFin = Param(mTEPES.la, initialize=pElecNetPeriodFin.to_dict(), within=PositiveIntegers, doc='Retirement period' )
|
|
1636
|
-
mTEPES.pLineVoltage = Param(mTEPES.la, initialize=pLineVoltage.to_dict() , within=NonNegativeReals, doc='Voltage' )
|
|
1637
|
-
mTEPES.pLineNTCFrw = Param(mTEPES.la, initialize=pLineNTCFrw.to_dict() , within=NonNegativeReals, doc='Electric line NTC forward' )
|
|
1638
|
-
mTEPES.pLineNTCBck = Param(mTEPES.la, initialize=pLineNTCBck.to_dict() , within=NonNegativeReals, doc='Electric line NTC backward' )
|
|
1639
|
-
mTEPES.pLineNTCMax = Param(mTEPES.la, initialize=pLineNTCMax.to_dict() , within=NonNegativeReals, doc='Electric line NTC' )
|
|
1640
|
-
mTEPES.pNetFixedCost = Param(mTEPES.lc, initialize=pNetFixedCost.to_dict() , within=NonNegativeReals, doc='Electric line fixed cost' )
|
|
1641
|
-
mTEPES.pIndBinLineInvest = Param(mTEPES.la, initialize=pIndBinLineInvest.to_dict(), within=Binary , doc='Binary electric line investment decision' )
|
|
1642
|
-
mTEPES.pIndBinLineSwitch = Param(mTEPES.la, initialize=pIndBinLineSwitch.to_dict(), within=Binary , doc='Binary electric line switching decision' )
|
|
1643
|
-
# mTEPES.pSwOnTime = Param(mTEPES.la, initialize=pSwitchOnTime.to_dict() , within=NonNegativeIntegers, doc='Minimum switching on time' )
|
|
1644
|
-
# mTEPES.pSwOffTime = Param(mTEPES.la, initialize=pSwitchOffTime.to_dict() , within=NonNegativeIntegers, doc='Minimum switching off time' )
|
|
1645
|
-
mTEPES.pBigMFlowBck = Param(mTEPES.la, initialize=pBigMFlowBck.to_dict() , within=NonNegativeReals, doc='Maximum backward capacity', mutable=True)
|
|
1646
|
-
mTEPES.pBigMFlowFrw = Param(mTEPES.la, initialize=pBigMFlowFrw.to_dict() , within=NonNegativeReals, doc='Maximum forward capacity', mutable=True)
|
|
1647
|
-
mTEPES.pMaxTheta = Param(mTEPES.psnnd, initialize=pMaxTheta.to_dict() , within=NonNegativeReals, doc='Maximum voltage angle', mutable=True)
|
|
1648
|
-
mTEPES.pAngMin = Param(mTEPES.la, initialize=pAngMin.to_dict() , within= Reals, doc='Minimum phase angle difference', mutable=True)
|
|
1649
|
-
mTEPES.pAngMax = Param(mTEPES.la, initialize=pAngMax.to_dict() , within= Reals, doc='Maximum phase angle difference', mutable=True)
|
|
1650
|
-
mTEPES.pNetLoInvest = Param(mTEPES.lc, initialize=pNetLoInvest.to_dict() , within=NonNegativeReals, doc='Lower bound of the electric line investment decision', mutable=True)
|
|
1651
|
-
mTEPES.pNetUpInvest = Param(mTEPES.lc, initialize=pNetUpInvest.to_dict() , within=NonNegativeReals, doc='Upper bound of the electric line investment decision', mutable=True)
|
|
1652
|
-
mTEPES.pIndBinLinePTDF = Param(mTEPES.la, initialize=pIndBinLinePTDF.to_dict() , within=Binary , doc='Binary indicator of line with' )
|
|
1653
|
-
mTEPES.pMaxNTCFrw = Param(mTEPES.psnla, initialize=pMaxNTCFrw.to_dict() , within= Reals, doc='Maximum NTC forward capacity' )
|
|
1654
|
-
mTEPES.pMaxNTCBck = Param(mTEPES.psnla, initialize=pMaxNTCBck.to_dict() , within= Reals, doc='Maximum NTC backward capacity' )
|
|
1655
|
-
mTEPES.pMaxNTCMax = Param(mTEPES.psnla, initialize=pMaxNTCMax.to_dict() , within= Reals, doc='Maximum NTC capacity' )
|
|
1656
|
-
|
|
1657
|
-
if pIndHydrogen == 1:
|
|
1658
|
-
mTEPES.pH2PipeLength = Param(mTEPES.pn, initialize=pH2PipeLength.to_dict() , within=NonNegativeReals, doc='Hydrogen pipeline length', mutable=True)
|
|
1659
|
-
mTEPES.pH2PipePeriodIni = Param(mTEPES.pn, initialize=pH2PipePeriodIni.to_dict() , within=PositiveIntegers, doc='Installation period' )
|
|
1660
|
-
mTEPES.pH2PipePeriodFin = Param(mTEPES.pn, initialize=pH2PipePeriodFin.to_dict() , within=PositiveIntegers, doc='Retirement period' )
|
|
1661
|
-
mTEPES.pH2PipeNTCFrw = Param(mTEPES.pn, initialize=pH2PipeNTCFrw.to_dict() , within=NonNegativeReals, doc='Hydrogen pipeline NTC forward' )
|
|
1662
|
-
mTEPES.pH2PipeNTCBck = Param(mTEPES.pn, initialize=pH2PipeNTCBck.to_dict() , within=NonNegativeReals, doc='Hydrogen pipeline NTC backward' )
|
|
1663
|
-
mTEPES.pH2PipeFixedCost = Param(mTEPES.pc, initialize=pH2PipeFixedCost.to_dict() , within=NonNegativeReals, doc='Hydrogen pipeline fixed cost' )
|
|
1664
|
-
mTEPES.pIndBinH2PipeInvest = Param(mTEPES.pn, initialize=pIndBinH2PipeInvest.to_dict(), within=Binary , doc='Binary pipeline investment decision' )
|
|
1665
|
-
mTEPES.pH2PipeLoInvest = Param(mTEPES.pc, initialize=pH2PipeLoInvest.to_dict() , within=NonNegativeReals, doc='Lower bound of the pipeline investment decision', mutable=True)
|
|
1666
|
-
mTEPES.pH2PipeUpInvest = Param(mTEPES.pc, initialize=pH2PipeUpInvest.to_dict() , within=NonNegativeReals, doc='Upper bound of the pipeline investment decision', mutable=True)
|
|
1667
|
-
|
|
1668
|
-
if pIndHeat == 1:
|
|
1669
|
-
mTEPES.pHeatPipeLength = Param(mTEPES.hn, initialize=pHeatPipeLength.to_dict() , within=NonNegativeReals, doc='Heat pipe length', mutable=True)
|
|
1670
|
-
mTEPES.pHeatPipePeriodIni = Param(mTEPES.hn, initialize=pHeatPipePeriodIni.to_dict() , within=PositiveIntegers, doc='Installation period' )
|
|
1671
|
-
mTEPES.pHeatPipePeriodFin = Param(mTEPES.hn, initialize=pHeatPipePeriodFin.to_dict() , within=PositiveIntegers, doc='Retirement period' )
|
|
1672
|
-
mTEPES.pHeatPipeNTCFrw = Param(mTEPES.hn, initialize=pHeatPipeNTCFrw.to_dict() , within=NonNegativeReals, doc='Heat pipe NTC forward' )
|
|
1673
|
-
mTEPES.pHeatPipeNTCBck = Param(mTEPES.hn, initialize=pHeatPipeNTCBck.to_dict() , within=NonNegativeReals, doc='Heat pipe NTC backward' )
|
|
1674
|
-
mTEPES.pHeatPipeFixedCost = Param(mTEPES.hc, initialize=pHeatPipeFixedCost.to_dict() , within=NonNegativeReals, doc='Heat pipe fixed cost' )
|
|
1675
|
-
mTEPES.pIndBinHeatPipeInvest = Param(mTEPES.hn, initialize=pIndBinHeatPipeInvest.to_dict(), within=Binary , doc='Binary heat pipe investment decision' )
|
|
1676
|
-
mTEPES.pHeatPipeLoInvest = Param(mTEPES.hc, initialize=pHeatPipeLoInvest.to_dict() , within=NonNegativeReals, doc='Lower bound of the heat pipe investment decision', mutable=True)
|
|
1677
|
-
mTEPES.pHeatPipeUpInvest = Param(mTEPES.hc, initialize=pHeatPipeUpInvest.to_dict() , within=NonNegativeReals, doc='Upper bound of the heat pipe investment decision', mutable=True)
|
|
1541
|
+
mTEPES.dPar['pMaxTheta'] = filter_rows(mTEPES.dPar['pMaxTheta'], mTEPES.psnnd)
|
|
1542
|
+
|
|
1543
|
+
mTEPES.pLineLossFactor = Param(mTEPES.ll, initialize=mTEPES.dPar['pLineLossFactor'].to_dict() , within= Reals, doc='Loss factor' )
|
|
1544
|
+
mTEPES.pLineR = Param(mTEPES.la, initialize=mTEPES.dPar['pLineR'].to_dict() , within=NonNegativeReals, doc='Resistance' )
|
|
1545
|
+
mTEPES.pLineX = Param(mTEPES.la, initialize=mTEPES.dPar['pLineX'].to_dict() , within= Reals, doc='Reactance' )
|
|
1546
|
+
mTEPES.pLineBsh = Param(mTEPES.la, initialize=mTEPES.dPar['pLineBsh'].to_dict() , within=NonNegativeReals, doc='Susceptance', mutable=True)
|
|
1547
|
+
mTEPES.pLineTAP = Param(mTEPES.la, initialize=mTEPES.dPar['pLineTAP'].to_dict() , within=NonNegativeReals, doc='Tap changer', mutable=True)
|
|
1548
|
+
mTEPES.pLineLength = Param(mTEPES.la, initialize=mTEPES.dPar['pLineLength'].to_dict() , within=NonNegativeReals, doc='Length', mutable=True)
|
|
1549
|
+
mTEPES.pElecNetPeriodIni = Param(mTEPES.la, initialize=mTEPES.dPar['pElecNetPeriodIni'].to_dict(), within=PositiveIntegers, doc='Installation period' )
|
|
1550
|
+
mTEPES.pElecNetPeriodFin = Param(mTEPES.la, initialize=mTEPES.dPar['pElecNetPeriodFin'].to_dict(), within=PositiveIntegers, doc='Retirement period' )
|
|
1551
|
+
mTEPES.pLineVoltage = Param(mTEPES.la, initialize=mTEPES.dPar['pLineVoltage'].to_dict() , within=NonNegativeReals, doc='Voltage' )
|
|
1552
|
+
mTEPES.pLineNTCFrw = Param(mTEPES.la, initialize=mTEPES.dPar['pLineNTCFrw'].to_dict() , within=NonNegativeReals, doc='Electric line NTC forward' )
|
|
1553
|
+
mTEPES.pLineNTCBck = Param(mTEPES.la, initialize=mTEPES.dPar['pLineNTCBck'].to_dict() , within=NonNegativeReals, doc='Electric line NTC backward' )
|
|
1554
|
+
mTEPES.pLineNTCMax = Param(mTEPES.la, initialize=mTEPES.dPar['pLineNTCMax'].to_dict() , within=NonNegativeReals, doc='Electric line NTC' )
|
|
1555
|
+
mTEPES.pNetFixedCost = Param(mTEPES.lc, initialize=mTEPES.dPar['pNetFixedCost'].to_dict() , within=NonNegativeReals, doc='Electric line fixed cost' )
|
|
1556
|
+
mTEPES.pIndBinLineInvest = Param(mTEPES.la, initialize=mTEPES.dPar['pIndBinLineInvest'].to_dict(), within=Binary , doc='Binary electric line investment decision' )
|
|
1557
|
+
mTEPES.pIndBinLineSwitch = Param(mTEPES.la, initialize=mTEPES.dPar['pIndBinLineSwitch'].to_dict(), within=Binary , doc='Binary electric line switching decision' )
|
|
1558
|
+
# mTEPES.pSwOnTime = Param(mTEPES.la, initialize=mTEPES.dPar['pSwitchOnTime'].to_dict() , within=NonNegativeIntegers, doc='Minimum switching on time' )
|
|
1559
|
+
# mTEPES.pSwOffTime = Param(mTEPES.la, initialize=mTEPES.dPar['pSwitchOffTime'].to_dict() , within=NonNegativeIntegers, doc='Minimum switching off time' )
|
|
1560
|
+
mTEPES.pBigMFlowBck = Param(mTEPES.la, initialize=mTEPES.dPar['pBigMFlowBck'].to_dict() , within=NonNegativeReals, doc='Maximum backward capacity', mutable=True)
|
|
1561
|
+
mTEPES.pBigMFlowFrw = Param(mTEPES.la, initialize=mTEPES.dPar['pBigMFlowFrw'].to_dict() , within=NonNegativeReals, doc='Maximum forward capacity', mutable=True)
|
|
1562
|
+
mTEPES.pMaxTheta = Param(mTEPES.psnnd, initialize=mTEPES.dPar['pMaxTheta'].to_dict() , within=NonNegativeReals, doc='Maximum voltage angle', mutable=True)
|
|
1563
|
+
mTEPES.pAngMin = Param(mTEPES.la, initialize=mTEPES.dPar['pAngMin'].to_dict() , within= Reals, doc='Minimum phase angle difference', mutable=True)
|
|
1564
|
+
mTEPES.pAngMax = Param(mTEPES.la, initialize=mTEPES.dPar['pAngMax'].to_dict() , within= Reals, doc='Maximum phase angle difference', mutable=True)
|
|
1565
|
+
mTEPES.pNetLoInvest = Param(mTEPES.lc, initialize=mTEPES.dPar['pNetLoInvest'].to_dict() , within=NonNegativeReals, doc='Lower bound of the electric line investment decision', mutable=True)
|
|
1566
|
+
mTEPES.pNetUpInvest = Param(mTEPES.lc, initialize=mTEPES.dPar['pNetUpInvest'].to_dict() , within=NonNegativeReals, doc='Upper bound of the electric line investment decision', mutable=True)
|
|
1567
|
+
mTEPES.pIndBinLinePTDF = Param(mTEPES.la, initialize=mTEPES.dPar['pIndBinLinePTDF'].to_dict() , within=Binary , doc='Binary indicator of line with' )
|
|
1568
|
+
mTEPES.pMaxNTCFrw = Param(mTEPES.psnla, initialize=mTEPES.dPar['pMaxNTCFrw'].to_dict() , within= Reals, doc='Maximum NTC forward capacity' )
|
|
1569
|
+
mTEPES.pMaxNTCBck = Param(mTEPES.psnla, initialize=mTEPES.dPar['pMaxNTCBck'].to_dict() , within= Reals, doc='Maximum NTC backward capacity' )
|
|
1570
|
+
mTEPES.pMaxNTCMax = Param(mTEPES.psnla, initialize=mTEPES.dPar['pMaxNTCMax'].to_dict() , within= Reals, doc='Maximum NTC capacity' )
|
|
1571
|
+
|
|
1572
|
+
if mTEPES.dPar['pIndHydrogen'] == 1:
|
|
1573
|
+
mTEPES.pH2PipeLength = Param(mTEPES.pn, initialize=mTEPES.dPar['pH2PipeLength'].to_dict() , within=NonNegativeReals, doc='Hydrogen pipeline length', mutable=True)
|
|
1574
|
+
mTEPES.pH2PipePeriodIni = Param(mTEPES.pn, initialize=mTEPES.dPar['pH2PipePeriodIni'].to_dict() , within=PositiveIntegers, doc='Installation period' )
|
|
1575
|
+
mTEPES.pH2PipePeriodFin = Param(mTEPES.pn, initialize=mTEPES.dPar['pH2PipePeriodFin'].to_dict() , within=PositiveIntegers, doc='Retirement period' )
|
|
1576
|
+
mTEPES.pH2PipeNTCFrw = Param(mTEPES.pn, initialize=mTEPES.dPar['pH2PipeNTCFrw'].to_dict() , within=NonNegativeReals, doc='Hydrogen pipeline NTC forward' )
|
|
1577
|
+
mTEPES.pH2PipeNTCBck = Param(mTEPES.pn, initialize=mTEPES.dPar['pH2PipeNTCBck'].to_dict() , within=NonNegativeReals, doc='Hydrogen pipeline NTC backward' )
|
|
1578
|
+
mTEPES.pH2PipeFixedCost = Param(mTEPES.pc, initialize=mTEPES.dPar['pH2PipeFixedCost'].to_dict() , within=NonNegativeReals, doc='Hydrogen pipeline fixed cost' )
|
|
1579
|
+
mTEPES.pIndBinH2PipeInvest = Param(mTEPES.pn, initialize=mTEPES.dPar['pIndBinH2PipeInvest'].to_dict(), within=Binary , doc='Binary pipeline investment decision' )
|
|
1580
|
+
mTEPES.pH2PipeLoInvest = Param(mTEPES.pc, initialize=mTEPES.dPar['pH2PipeLoInvest'].to_dict() , within=NonNegativeReals, doc='Lower bound of the pipeline investment decision', mutable=True)
|
|
1581
|
+
mTEPES.pH2PipeUpInvest = Param(mTEPES.pc, initialize=mTEPES.dPar['pH2PipeUpInvest'].to_dict() , within=NonNegativeReals, doc='Upper bound of the pipeline investment decision', mutable=True)
|
|
1582
|
+
|
|
1583
|
+
if mTEPES.dPar['pIndHeat'] == 1:
|
|
1584
|
+
mTEPES.pHeatPipeLength = Param(mTEPES.hn, initialize=mTEPES.dPar['pHeatPipeLength'].to_dict() , within=NonNegativeReals, doc='Heat pipe length', mutable=True)
|
|
1585
|
+
mTEPES.pHeatPipePeriodIni = Param(mTEPES.hn, initialize=mTEPES.dPar['pHeatPipePeriodIni'].to_dict() , within=PositiveIntegers, doc='Installation period' )
|
|
1586
|
+
mTEPES.pHeatPipePeriodFin = Param(mTEPES.hn, initialize=mTEPES.dPar['pHeatPipePeriodFin'].to_dict() , within=PositiveIntegers, doc='Retirement period' )
|
|
1587
|
+
mTEPES.pHeatPipeNTCFrw = Param(mTEPES.hn, initialize=mTEPES.dPar['pHeatPipeNTCFrw'].to_dict() , within=NonNegativeReals, doc='Heat pipe NTC forward' )
|
|
1588
|
+
mTEPES.pHeatPipeNTCBck = Param(mTEPES.hn, initialize=mTEPES.dPar['pHeatPipeNTCBck'].to_dict() , within=NonNegativeReals, doc='Heat pipe NTC backward' )
|
|
1589
|
+
mTEPES.pHeatPipeFixedCost = Param(mTEPES.hc, initialize=mTEPES.dPar['pHeatPipeFixedCost'].to_dict() , within=NonNegativeReals, doc='Heat pipe fixed cost' )
|
|
1590
|
+
mTEPES.pIndBinHeatPipeInvest = Param(mTEPES.hn, initialize=mTEPES.dPar['pIndBinHeatPipeInvest'].to_dict(), within=Binary , doc='Binary heat pipe investment decision' )
|
|
1591
|
+
mTEPES.pHeatPipeLoInvest = Param(mTEPES.hc, initialize=mTEPES.dPar['pHeatPipeLoInvest'].to_dict() , within=NonNegativeReals, doc='Lower bound of the heat pipe investment decision', mutable=True)
|
|
1592
|
+
mTEPES.pHeatPipeUpInvest = Param(mTEPES.hc, initialize=mTEPES.dPar['pHeatPipeUpInvest'].to_dict() , within=NonNegativeReals, doc='Upper bound of the heat pipe investment decision', mutable=True)
|
|
1678
1593
|
|
|
1679
1594
|
# load levels multiple of cycles for each ESS/generator
|
|
1680
1595
|
mTEPES.nesc = [(n,es) for n,es in mTEPES.n*mTEPES.es if mTEPES.n.ord(n) % mTEPES.pStorageTimeStep [es] == 0]
|
|
1681
1596
|
mTEPES.necc = [(n,ec) for n,ec in mTEPES.n*mTEPES.ec if mTEPES.n.ord(n) % mTEPES.pStorageTimeStep [ec] == 0]
|
|
1682
1597
|
mTEPES.neso = [(n,es) for n,es in mTEPES.n*mTEPES.es if mTEPES.n.ord(n) % mTEPES.pOutflowsTimeStep[es] == 0]
|
|
1683
1598
|
mTEPES.ngen = [(n,g ) for n,g in mTEPES.n*mTEPES.g if mTEPES.n.ord(n) % mTEPES.pEnergyTimeStep [g ] == 0]
|
|
1684
|
-
if pIndHydroTopology == 1:
|
|
1599
|
+
if mTEPES.dPar['pIndHydroTopology'] == 1:
|
|
1685
1600
|
mTEPES.nhc = [(n,h ) for n,h in mTEPES.n*mTEPES.h if mTEPES.n.ord(n) % sum(mTEPES.pReservoirTimeStep[rs] for rs in mTEPES.rs if (rs,h) in mTEPES.r2h) == 0]
|
|
1686
1601
|
if sum(1 for h,rs in mTEPES.p2r):
|
|
1687
1602
|
mTEPES.np2c = [(n,h ) for n,h in mTEPES.n*mTEPES.h if sum(1 for rs in mTEPES.rs if (h,rs) in mTEPES.p2r) and mTEPES.n.ord(n) % sum(mTEPES.pReservoirTimeStep[rs] for rs in mTEPES.rs if (h,rs) in mTEPES.p2r) == 0]
|
|
@@ -1697,7 +1612,7 @@ def InputData(DirName, CaseName, mTEPES, pIndLogConsole):
|
|
|
1697
1612
|
|
|
1698
1613
|
# ESS with outflows
|
|
1699
1614
|
mTEPES.eo = [(p,sc,es) for p,sc,es in mTEPES.pses if sum(mTEPES.pEnergyOutflows[p,sc,n2,es]() for n2 in mTEPES.n2 if (p,sc,n2) in mTEPES.psn)]
|
|
1700
|
-
if pIndHydroTopology == 1:
|
|
1615
|
+
if mTEPES.dPar['pIndHydroTopology'] == 1:
|
|
1701
1616
|
# reservoirs with outflows
|
|
1702
1617
|
mTEPES.ro = [(p,sc,rs) for p,sc,rs in mTEPES.psrs if sum(mTEPES.pHydroOutflows [p,sc,n2,rs]() for n2 in mTEPES.n2 if (p,sc,n2) in mTEPES.psn)]
|
|
1703
1618
|
# generators with min/max energy
|
|
@@ -1714,30 +1629,30 @@ def InputData(DirName, CaseName, mTEPES, pIndLogConsole):
|
|
|
1714
1629
|
if mTEPES.pLineLength[ni,nf,cc]() == 0.0:
|
|
1715
1630
|
mTEPES.pLineLength[ni,nf,cc] = 1.1 * 6371 * 2 * math.asin(math.sqrt(math.pow(math.sin((mTEPES.pNodeLat[nf]-mTEPES.pNodeLat[ni])*math.pi/180/2),2) + math.cos(mTEPES.pNodeLat[ni]*math.pi/180)*math.cos(mTEPES.pNodeLat[nf]*math.pi/180)*math.pow(math.sin((mTEPES.pNodeLon[nf]-mTEPES.pNodeLon[ni])*math.pi/180/2),2)))
|
|
1716
1631
|
|
|
1717
|
-
if pIndHydrogen == 1:
|
|
1632
|
+
if mTEPES.dPar['pIndHydrogen'] == 1:
|
|
1718
1633
|
# if line length = 0 changed to geographical distance with an additional 10%
|
|
1719
1634
|
for ni,nf,cc in mTEPES.pa:
|
|
1720
1635
|
if mTEPES.pH2PipeLength[ni,nf,cc]() == 0.0:
|
|
1721
1636
|
mTEPES.pH2PipeLength[ni,nf,cc] = 1.1 * 6371 * 2 * math.asin(math.sqrt(math.pow(math.sin((mTEPES.pNodeLat[nf]-mTEPES.pNodeLat[ni])*math.pi/180/2),2) + math.cos(mTEPES.pNodeLat[ni]*math.pi/180)*math.cos(mTEPES.pNodeLat[nf]*math.pi/180)*math.pow(math.sin((mTEPES.pNodeLon[nf]-mTEPES.pNodeLon[ni])*math.pi/180/2),2)))
|
|
1722
1637
|
|
|
1723
|
-
if pIndHeat == 1:
|
|
1638
|
+
if mTEPES.dPar['pIndHeat'] == 1:
|
|
1724
1639
|
# if line length = 0 changed to geographical distance with an additional 10%
|
|
1725
1640
|
for ni,nf,cc in mTEPES.pa:
|
|
1726
1641
|
if mTEPES.pHeatPipeLength[ni,nf,cc]() == 0.0:
|
|
1727
1642
|
mTEPES.pHeatPipeLength[ni,nf,cc] = 1.1 * 6371 * 2 * math.asin(math.sqrt(math.pow(math.sin((mTEPES.pNodeLat[nf]-mTEPES.pNodeLat[ni])*math.pi/180/2),2) + math.cos(mTEPES.pNodeLat[ni]*math.pi/180)*math.cos(mTEPES.pNodeLat[nf]*math.pi/180)*math.pow(math.sin((mTEPES.pNodeLon[nf]-mTEPES.pNodeLon[ni])*math.pi/180/2),2)))
|
|
1728
1643
|
|
|
1729
1644
|
# initialize generation output, unit commitment and line switching
|
|
1730
|
-
pInitialOutput = pd.DataFrame([[0.0]*len(mTEPES.g )]*len(mTEPES.psn), index=mTEPES.psn, columns=mTEPES.g )
|
|
1731
|
-
pInitialUC = pd.DataFrame([[0 ]*len(mTEPES.g )]*len(mTEPES.psn), index=mTEPES.psn, columns=mTEPES.g )
|
|
1732
|
-
pInitialSwitch = pd.DataFrame([[0 ]*len(mTEPES.la)]*len(mTEPES.psn), index=mTEPES.psn, columns=mTEPES.la)
|
|
1645
|
+
mTEPES.dPar['pInitialOutput'] = pd.DataFrame([[0.0]*len(mTEPES.g )]*len(mTEPES.psn), index=mTEPES.psn, columns=mTEPES.g )
|
|
1646
|
+
mTEPES.dPar['pInitialUC'] = pd.DataFrame([[0 ]*len(mTEPES.g )]*len(mTEPES.psn), index=mTEPES.psn, columns=mTEPES.g )
|
|
1647
|
+
mTEPES.dPar['pInitialSwitch'] = pd.DataFrame([[0 ]*len(mTEPES.la)]*len(mTEPES.psn), index=mTEPES.psn, columns=mTEPES.la)
|
|
1733
1648
|
|
|
1734
|
-
pInitialOutput = filter_rows(pInitialOutput, mTEPES.psng )
|
|
1735
|
-
pInitialUC = filter_rows(pInitialUC , mTEPES.psng )
|
|
1736
|
-
pInitialSwitch = filter_rows(pInitialSwitch, mTEPES.psnla)
|
|
1649
|
+
mTEPES.dPar['pInitialOutput'] = filter_rows(mTEPES.dPar['pInitialOutput'], mTEPES.psng )
|
|
1650
|
+
mTEPES.dPar['pInitialUC'] = filter_rows(mTEPES.dPar['pInitialUC'] , mTEPES.psng )
|
|
1651
|
+
mTEPES.dPar['pInitialSwitch'] = filter_rows(mTEPES.dPar['pInitialSwitch'], mTEPES.psnla)
|
|
1737
1652
|
|
|
1738
|
-
mTEPES.pInitialOutput = Param(mTEPES.psng , initialize=pInitialOutput.to_dict(), within=NonNegativeReals, doc='unit initial output', mutable=True)
|
|
1739
|
-
mTEPES.pInitialUC = Param(mTEPES.psng , initialize=pInitialUC.to_dict() , within=Binary, doc='unit initial commitment', mutable=True)
|
|
1740
|
-
mTEPES.pInitialSwitch = Param(mTEPES.psnla, initialize=pInitialSwitch.to_dict(), within=Binary, doc='line initial switching', mutable=True)
|
|
1653
|
+
mTEPES.pInitialOutput = Param(mTEPES.psng , initialize=mTEPES.dPar['pInitialOutput'].to_dict(), within=NonNegativeReals, doc='unit initial output', mutable=True)
|
|
1654
|
+
mTEPES.pInitialUC = Param(mTEPES.psng , initialize=mTEPES.dPar['pInitialUC'].to_dict() , within=Binary, doc='unit initial commitment', mutable=True)
|
|
1655
|
+
mTEPES.pInitialSwitch = Param(mTEPES.psnla, initialize=mTEPES.dPar['pInitialSwitch'].to_dict(), within=Binary, doc='line initial switching', mutable=True)
|
|
1741
1656
|
|
|
1742
1657
|
SettingUpDataTime = time.time() - StartTime
|
|
1743
1658
|
print('Setting up input data ... ', round(SettingUpDataTime), 's')
|
|
@@ -1877,7 +1792,6 @@ def SettingUpVariables(OptModel, mTEPES):
|
|
|
1877
1792
|
if mTEPES.pIndHydroTopology == 1:
|
|
1878
1793
|
OptModel.vCommitmentCons = Var(mTEPES.psnh, within=Binary, doc='consumption commitment of the unit {0,1}')
|
|
1879
1794
|
|
|
1880
|
-
|
|
1881
1795
|
if mTEPES.pIndBinLineCommit() == 0:
|
|
1882
1796
|
OptModel.vLineCommit = Var(mTEPES.psnla, within=UnitInterval, doc='line switching of the electric line [0,1]')
|
|
1883
1797
|
else:
|
|
@@ -1922,7 +1836,7 @@ def SettingUpVariables(OptModel, mTEPES):
|
|
|
1922
1836
|
[OptModel.vCharge2ndBlock[p,sc,n,eh].setub(mTEPES.pMaxCharge2ndBlock[p,sc,n,eh] ) for p,sc,n,eh in mTEPES.psneh]
|
|
1923
1837
|
[OptModel.vESSReserveUp [p,sc,n,eh].setub(mTEPES.pMaxCharge2ndBlock[p,sc,n,eh] ) for p,sc,n,eh in mTEPES.psneh]
|
|
1924
1838
|
[OptModel.vESSReserveDown[p,sc,n,eh].setub(mTEPES.pMaxCharge2ndBlock[p,sc,n,eh] ) for p,sc,n,eh in mTEPES.psneh]
|
|
1925
|
-
[OptModel.vENS [p,sc,n,nd].setub(mTEPES.
|
|
1839
|
+
[OptModel.vENS [p,sc,n,nd].setub(mTEPES.pDemandElecPos [p,sc,n,nd] ) for p,sc,n,nd in mTEPES.psnnd]
|
|
1926
1840
|
|
|
1927
1841
|
if mTEPES.pIndHydroTopology == 1:
|
|
1928
1842
|
[OptModel.vHydroInflows [p,sc,n,rc].setub(mTEPES.pHydroInflows[p,sc,n,rc]()) for p,sc,n,rc in mTEPES.psnrc]
|
|
@@ -2022,7 +1936,7 @@ def SettingUpVariables(OptModel, mTEPES):
|
|
|
2022
1936
|
|
|
2023
1937
|
return nFixedBinaries
|
|
2024
1938
|
|
|
2025
|
-
#
|
|
1939
|
+
# call the relaxing variables function and add its output to nFixedVariables
|
|
2026
1940
|
nFixedBinaries = RelaxBinaryInvestmentConditions(mTEPES, mTEPES)
|
|
2027
1941
|
nFixedVariables += nFixedBinaries
|
|
2028
1942
|
|
|
@@ -2040,6 +1954,7 @@ def SettingUpVariables(OptModel, mTEPES):
|
|
|
2040
1954
|
Returns:
|
|
2041
1955
|
int: The number of line commitment variables fixed
|
|
2042
1956
|
'''
|
|
1957
|
+
|
|
2043
1958
|
nFixedVariables = 0
|
|
2044
1959
|
# existing lines are always committed if no switching decision is modeled
|
|
2045
1960
|
[OptModel.vLineCommit[p,sc,n,ni,nf,cc].fix(1) for p,sc,n,ni,nf,cc in mTEPES.psnle if mTEPES.pIndBinLineSwitch[ni,nf,cc] == 0]
|
|
@@ -2055,6 +1970,11 @@ def SettingUpVariables(OptModel, mTEPES):
|
|
|
2055
1970
|
OptModel.vFlowElec = Var(mTEPES.psnla, within=Reals, doc='electric flow [GW]')
|
|
2056
1971
|
OptModel.vTheta = Var(mTEPES.psnnd, within=Reals, doc='voltage angle [rad]')
|
|
2057
1972
|
|
|
1973
|
+
if mTEPES.pIndVarTTC == 1:
|
|
1974
|
+
# lines with TTC and TTCBck = 0 are disconnected and the flow is fixed to 0
|
|
1975
|
+
[OptModel.vFlowElec[p,sc,n,ni,nf,cc].fix(0.0) for p,sc,n,ni,nf,cc in mTEPES.psnla if mTEPES.pMaxNTCFrw[p,sc,n,ni,nf,cc] == 0.0 and mTEPES.pMaxNTCBck[p,sc,n,ni,nf,cc] == 0.0]
|
|
1976
|
+
nFixedVariables += sum( 1 for p,sc,n,ni,nf,cc in mTEPES.psnla if mTEPES.pMaxNTCFrw[p,sc,n,ni,nf,cc] == 0.0 and mTEPES.pMaxNTCBck[p,sc,n,ni,nf,cc] == 0.0)
|
|
1977
|
+
|
|
2058
1978
|
if mTEPES.pIndPTDF == 1:
|
|
2059
1979
|
OptModel.vNetPosition = Var(mTEPES.psnnd, within=Reals, doc='net position in node [GW]')
|
|
2060
1980
|
|
|
@@ -2331,7 +2251,7 @@ def SettingUpVariables(OptModel, mTEPES):
|
|
|
2331
2251
|
|
|
2332
2252
|
# fixing the ENS in nodes with no demand
|
|
2333
2253
|
for p,sc,n,nd in mTEPES.psnnd:
|
|
2334
|
-
if mTEPES.pDemandElec[p,sc,n,nd]
|
|
2254
|
+
if mTEPES.pDemandElec[p,sc,n,nd] <= 0.0:
|
|
2335
2255
|
OptModel.vENS [p,sc,n,nd].fix(0.0)
|
|
2336
2256
|
nFixedVariables += 1
|
|
2337
2257
|
|
|
@@ -2657,7 +2577,65 @@ def SettingUpVariables(OptModel, mTEPES):
|
|
|
2657
2577
|
|
|
2658
2578
|
DetectInfeasibilities(mTEPES)
|
|
2659
2579
|
|
|
2660
|
-
mTEPES.nFixedVariables
|
|
2580
|
+
mTEPES.nFixedVariables = Param(initialize=round(nFixedVariables), within=NonNegativeIntegers, doc='Number of fixed variables')
|
|
2581
|
+
|
|
2582
|
+
mTEPES.IndependentPeriods = Param( domain=Boolean, initialize=False, mutable=True)
|
|
2583
|
+
mTEPES.IndependentStages = Param(mTEPES.pp, domain=Boolean, initialize=False, mutable=True)
|
|
2584
|
+
mTEPES.IndependentStages2 = Param( domain=Boolean, initialize=False, mutable=True)
|
|
2585
|
+
mTEPES.Parallel = Param( domain=Boolean, initialize=False, mutable=True)
|
|
2586
|
+
mTEPES.Parallel = True
|
|
2587
|
+
if ( (len(mTEPES.gc) == 0 or mTEPES.pIndBinGenInvest() == 2) # No candidates
|
|
2588
|
+
and (len(mTEPES.gd) == 0 or mTEPES.pIndBinGenRetire() == 2) # No retirements
|
|
2589
|
+
and (len(mTEPES.lc) == 0 or mTEPES.pIndBinNetElecInvest() == 2)): # No line candidates
|
|
2590
|
+
# Periods and scenarios are independent each other
|
|
2591
|
+
ScIndep = True
|
|
2592
|
+
mTEPES.IndependentPeriods = True
|
|
2593
|
+
for p in mTEPES.p:
|
|
2594
|
+
if ( (min([mTEPES.pEmission[p, ar] for ar in mTEPES.ar]) == math.inf or sum(mTEPES.pEmissionRate[nr] for nr in mTEPES.nr) == 0) # No emissions
|
|
2595
|
+
and (max([mTEPES.pRESEnergy[p, ar] for ar in mTEPES.ar]) == 0)): # No minimum RES requirements
|
|
2596
|
+
# Stages are independent from each other
|
|
2597
|
+
StIndep = True
|
|
2598
|
+
mTEPES.IndependentStages[p] = True
|
|
2599
|
+
if all(mTEPES.IndependentStages[p]() for p in mTEPES.pp):
|
|
2600
|
+
mTEPES.IndependentStages2 = True
|
|
2601
|
+
|
|
2602
|
+
mTEPES.Period = Block(mTEPES.p)
|
|
2603
|
+
for p in mTEPES.Period:
|
|
2604
|
+
Period = mTEPES.Period[p]
|
|
2605
|
+
#TODO: Filter in some way that scenarios may not belong to periods
|
|
2606
|
+
# period2scenario = [stt for pp, scc, stt, nn in mTEPES.s2n if scc == sc and pp == p]
|
|
2607
|
+
Period.Scenario = Block(mTEPES.sc)
|
|
2608
|
+
Period.n = Set(doc='load levels', initialize=[nn for pp, scc, stt, nn in mTEPES.s2n if pp == p])
|
|
2609
|
+
for sc in Period.Scenario:
|
|
2610
|
+
Scenario = Period.Scenario[sc]
|
|
2611
|
+
Scenario.Stage = Block(Set(initialize=[stt for pp,scc,stt, nn in mTEPES.s2n if scc == sc and pp == p]))
|
|
2612
|
+
Scenario.n = Set(doc='load levels', initialize=[nn for pp, scc, stt, nn in mTEPES.s2n if scc == sc and pp == p])
|
|
2613
|
+
|
|
2614
|
+
# iterative model formulation for each stage of a year
|
|
2615
|
+
for st in Scenario.Stage:
|
|
2616
|
+
Stage = Scenario.Stage[st]
|
|
2617
|
+
Stage.n = Set(doc='load levels', initialize=[nn for pp, scc, stt, nn in mTEPES.s2n if stt == st and scc == sc and pp == p])
|
|
2618
|
+
Stage.n2 = Set(doc='load levels', initialize=[nn for pp, scc, stt, nn in mTEPES.s2n if stt == st and scc == sc and pp == p])
|
|
2619
|
+
|
|
2620
|
+
# load levels multiple of cycles for each ESS/generator
|
|
2621
|
+
Stage.nesc = [(n, es) for n, es in Stage.n * mTEPES.es if Stage.n.ord(n) % mTEPES.pStorageTimeStep[es] == 0]
|
|
2622
|
+
Stage.necc = [(n, ec) for n, ec in Stage.n * mTEPES.ec if Stage.n.ord(n) % mTEPES.pStorageTimeStep[ec] == 0]
|
|
2623
|
+
Stage.neso = [(n, es) for n, es in Stage.n * mTEPES.es if Stage.n.ord(n) % mTEPES.pOutflowsTimeStep[es] == 0]
|
|
2624
|
+
Stage.ngen = [(n, g ) for n, g in Stage.n * mTEPES.g if Stage.n.ord(n) % mTEPES.pEnergyTimeStep[g] == 0]
|
|
2625
|
+
|
|
2626
|
+
if mTEPES.pIndHydroTopology == 1:
|
|
2627
|
+
Stage.nhc = [(n,h ) for n,h in Stage.n*mTEPES.h if Stage.n.ord(n) % sum(mTEPES.pReservoirTimeStep[rs] for rs in mTEPES.rs if (rs,h) in mTEPES.r2h) == 0]
|
|
2628
|
+
if sum(1 for h,rs in mTEPES.p2r):
|
|
2629
|
+
Stage.np2c = [(n,h ) for n,h in Stage.n*mTEPES.h if sum(1 for rs in mTEPES.rs if (h,rs) in mTEPES.p2r) and Stage.n.ord(n) % sum(mTEPES.pReservoirTimeStep[rs] for rs in mTEPES.rs if (h,rs) in mTEPES.p2r) == 0]
|
|
2630
|
+
else:
|
|
2631
|
+
Stage.np2c = []
|
|
2632
|
+
if sum(1 for rs,h in mTEPES.r2p):
|
|
2633
|
+
Stage.npc = [(n,h ) for n,h in mTEPES.n*mTEPES.h if sum(1 for rs in mTEPES.rs if (rs,h) in mTEPES.r2p) and mTEPES.n.ord(n) % sum(mTEPES.pReservoirTimeStep[rs] for rs in mTEPES.rs if (rs,h) in mTEPES.r2p) == 0]
|
|
2634
|
+
else:
|
|
2635
|
+
Stage.npc = []
|
|
2636
|
+
Stage.nrsc = [(n,rs) for n,rs in Stage.n*mTEPES.rs if mTEPES.n.ord(n) % mTEPES.pReservoirTimeStep[rs] == 0]
|
|
2637
|
+
Stage.nrcc = [(n,rs) for n,rs in Stage.n*mTEPES.rn if mTEPES.n.ord(n) % mTEPES.pReservoirTimeStep[rs] == 0]
|
|
2638
|
+
Stage.nrso = [(n,rs) for n,rs in Stage.n*mTEPES.rs if mTEPES.n.ord(n) % mTEPES.pWaterOutTimeStep [rs] == 0]
|
|
2661
2639
|
|
|
2662
2640
|
SettingUpVariablesTime = time.time() - StartTime
|
|
2663
2641
|
print('Setting up variables ... ', round(SettingUpVariablesTime), 's')
|