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.
@@ -1,5 +1,5 @@
1
1
  """
2
- Open Generation, Storage, and Transmission Operation and Expansion Planning Model with RES and ESS (openTEPES) - June 20, 2025
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
- #%% reading data from CSV
20
- dfOption = pd.read_csv(f'{_path}/oT_Data_Option_' f'{CaseName}.csv', header=0 )
21
- dfParameter = pd.read_csv(f'{_path}/oT_Data_Parameter_' f'{CaseName}.csv', header=0 )
22
- dfPeriod = pd.read_csv(f'{_path}/oT_Data_Period_' f'{CaseName}.csv', header=0, index_col=[0 ])
23
- dfScenario = pd.read_csv(f'{_path}/oT_Data_Scenario_' f'{CaseName}.csv', header=0, index_col=[0,1 ])
24
- dfStage = pd.read_csv(f'{_path}/oT_Data_Stage_' f'{CaseName}.csv', header=0, index_col=[0 ])
25
- dfDuration = pd.read_csv(f'{_path}/oT_Data_Duration_' f'{CaseName}.csv', header=0, index_col=[0,1,2])
26
- dfReserveMargin = pd.read_csv(f'{_path}/oT_Data_ReserveMargin_' f'{CaseName}.csv', header=0, index_col=[0,1 ])
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
- try:
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
- try:
75
- dfDemandHydrogen = pd.read_csv(f'{_path}/oT_Data_DemandHydrogen_' f'{CaseName}.csv', header=0, index_col=[0,1,2])
76
- dfNetworkHydrogen = pd.read_csv(f'{_path}/oT_Data_NetworkHydrogen_' f'{CaseName}.csv', header=0, index_col=[0,1,2])
77
- pIndHydrogen = 1
78
- except:
79
- pIndHydrogen = 0
80
- print('**** No hydrogen energy carrier')
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
- try:
83
- dfDemandHeat = pd.read_csv(f'{_path}/oT_Data_DemandHeat_' f'{CaseName}.csv', header=0, index_col=[0,1,2])
84
- dfReserveMarginHeat = pd.read_csv(f'{_path}/oT_Data_ReserveMarginHeat_' f'{CaseName}.csv', header=0, index_col=[0,1 ])
85
- dfNetworkHeat = pd.read_csv(f'{_path}/oT_Data_NetworkHeat_' f'{CaseName}.csv', header=0, index_col=[0,1,2])
86
- pIndHeat = 1
87
- except:
88
- pIndHeat = 0
89
- print('**** No heat energy carrier')
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
- dfOption.fillna (0 , inplace=True)
93
- dfParameter.fillna (0.0, inplace=True)
94
- dfPeriod.fillna (0.0, inplace=True)
95
- dfScenario.fillna (0.0, inplace=True)
96
- dfStage.fillna (0.0, inplace=True)
97
- dfDuration.fillna (0 , inplace=True)
98
- dfReserveMargin.fillna (0.0, inplace=True)
99
- dfEmission.fillna (math.inf , inplace=True)
100
- dfRESEnergy.fillna (0.0, inplace=True)
101
- dfDemand.fillna (0.0, inplace=True)
102
- dfInertia.fillna (0.0, inplace=True)
103
- dfUpOperatingReserve.fillna (0.0, inplace=True)
104
- dfDwOperatingReserve.fillna (0.0, inplace=True)
105
- dfGeneration.fillna ({"Efficiency":1.0}, inplace=True)
106
- dfGeneration.fillna (0.0, inplace=True)
107
- dfVariableMinPower.fillna (0.0, inplace=True)
108
- dfVariableMaxPower.fillna (0.0, inplace=True)
109
- dfVariableMinCharge.fillna (0.0, inplace=True)
110
- dfVariableMaxCharge.fillna (0.0, inplace=True)
111
- dfVariableMinStorage.fillna (0.0, inplace=True)
112
- dfVariableMaxStorage.fillna (0.0, inplace=True)
113
- dfVariableMinEnergy.fillna (0.0, inplace=True)
114
- dfVariableMaxEnergy.fillna (0.0, inplace=True)
115
- dfVariableFuelCost.fillna (0.0, inplace=True)
116
- dfVariableEmissionCost.fillna (0.0, inplace=True)
117
- dfEnergyInflows.fillna (0.0, inplace=True)
118
- dfEnergyOutflows.fillna (0.0, inplace=True)
119
- dfNodeLocation.fillna (0.0, inplace=True)
120
- dfNetwork.fillna (0.0, inplace=True)
121
-
122
- if pIndVarTTC == 1:
123
- dfVariableTTCFrw.fillna (0.0, inplace=True)
124
- dfVariableTTCBck.fillna (0.0, inplace=True)
125
- if pIndPTDF == 1:
126
- dfVariablePTDF.fillna (0.0, inplace=True)
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 pIndHydroTopology == 1:
169
- dfVariableMinVolume = dfVariableMinVolume.where (dfVariableMinVolume > 0.0, 0.0)
170
- dfVariableMaxVolume = dfVariableMaxVolume.where (dfVariableMaxVolume > 0.0, 0.0)
171
- dfHydroInflows = dfHydroInflows.where (dfHydroInflows > 0.0, 0.0)
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
- if pIndLogConsole == 1:
176
- print('Reserve margin electricity \n', dfReserveMargin.describe (), '\n')
177
- print('Maximum CO2 emission \n', dfEmission.describe (), '\n')
178
- print('Minimum RES energy \n', dfRESEnergy.describe (), '\n')
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
- #%% parameters
302
- pIndBinGenInvest = dfOption ['IndBinGenInvest' ].iloc[0].astype('int') # Indicator of binary generation expansion decisions, 0 continuous - 1 binary - 2 no investment variables
303
- pIndBinGenRetire = dfOption ['IndBinGenRetirement'].iloc[0].astype('int') # Indicator of binary generation retirement decisions,0 continuous - 1 binary - 2 no retirement variables
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
- pVariableTTCFrw = ProcessParameter(pVariableTTCFrw, pTimeStep)
403
- pVariableTTCBck = ProcessParameter(pVariableTTCBck, pTimeStep)
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' ] # generator location in node
432
- pGenToTechnology = dfGeneration ['Technology' ] # generator association to technology
433
- pGenToExclusiveGen = dfGeneration ['MutuallyExclusive' ] # mutually exclusive generator
434
- pIndBinUnitInvest = dfGeneration ['BinaryInvestment' ] # binary unit investment decision [Yes]
435
- pIndBinUnitRetire = dfGeneration ['BinaryRetirement' ] # binary unit retirement decision [Yes]
436
- pIndBinUnitCommit = dfGeneration ['BinaryCommitment' ] # binary unit commitment decision [Yes]
437
- pIndBinStorInvest = dfGeneration ['StorageInvestment' ] # storage linked to generation investment [Yes]
438
- pIndOperReserve = dfGeneration ['NoOperatingReserve' ] # no contribution to operating reserve [Yes]
439
- pIndOutflowIncomp = dfGeneration ['OutflowsIncompatibility' ] # outflows incompatibility with charging
440
- pMustRun = dfGeneration ['MustRun' ] # must-run unit [Yes]
441
- pInertia = dfGeneration ['Inertia' ] # inertia constant [s]
442
- pElecGenPeriodIni = dfGeneration ['InitialPeriod' ] # initial period [year]
443
- pElecGenPeriodFin = dfGeneration ['FinalPeriod' ] # final period [year]
444
- pAvailability = dfGeneration ['Availability' ] # unit availability for adequacy [p.u.]
445
- pEFOR = dfGeneration ['EFOR' ] # EFOR [p.u.]
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 # O&M term variable cost [MEUR/GWh]
453
- pOperReserveCost = dfGeneration ['OperReserveCost' ] * 1e-3 # operating reserve cost [MEUR/GW]
454
- pStartUpCost = dfGeneration ['StartUpCost' ] # startup cost [MEUR]
455
- pShutDownCost = dfGeneration ['ShutDownCost' ] # shutdown cost [MEUR]
456
- pRampUp = dfGeneration ['RampUp' ] * 1e-3 # ramp up rate [GW/h]
457
- pRampDw = dfGeneration ['RampDown' ] * 1e-3 # ramp down rate [GW/h]
458
- pEmissionCost = dfGeneration ['CO2EmissionRate' ] * 1e-3 * pCO2Cost # CO2 emission cost [MEUR/GWh]
459
- pEmissionRate = dfGeneration ['CO2EmissionRate' ] # CO2 emission rate [tCO2/MWh]
460
- pUpTime = dfGeneration ['UpTime' ] # minimum up time [h]
461
- pDwTime = dfGeneration ['DownTime' ] # minimum down time [h]
462
- pStableTime = dfGeneration ['StableTime' ] # minimum stable time [h]
463
- pShiftTime = dfGeneration ['ShiftTime' ] # maximum shift time for DSM [h]
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 # rated minimum ESS charge [GW]
467
- pRatedMaxCharge = dfGeneration ['MaximumCharge' ] * 1e-3 # rated maximum ESS charge [GW]
468
- pRatedMinStorage = dfGeneration ['MinimumStorage' ] # rated minimum ESS storage [GWh]
469
- pRatedMaxStorage = dfGeneration ['MaximumStorage' ] # rated maximum ESS storage [GWh]
470
- pInitialInventory = dfGeneration ['InitialStorage' ] # initial ESS storage [GWh]
471
- pProductionFunctionHydro = dfGeneration ['ProductionFunctionHydro' ] # production function of a hydropower plant [kWh/m3]
472
- pProductionFunctionH2 = dfGeneration ['ProductionFunctionH2' ] * 1e-3 # production function of an electrolyzer [kWh/gH2]
473
- pProductionFunctionHeat = dfGeneration ['ProductionFunctionHeat' ] # production function of a heat pump [kWh/kWh]
474
- pProductionFunctionH2ToHeat = dfGeneration ['ProductionFunctionH2ToHeat'] * 1e-3 # production function of a boiler using H2 [gH2/kWh]
475
- pEfficiency = dfGeneration ['Efficiency' ] # ESS round-trip efficiency [p.u.]
476
- pStorageType = dfGeneration ['StorageType' ] # ESS storage type
477
- pOutflowsType = dfGeneration ['OutflowsType' ] # ESS outflows type
478
- pEnergyType = dfGeneration ['EnergyType' ] # unit energy type
479
- pRMaxReactivePower = dfGeneration ['MaximumReactivePower' ] * 1e-3 # rated maximum reactive power [Gvar]
480
- pGenLoInvest = dfGeneration ['InvestmentLo' ] # Lower bound of the investment decision [p.u.]
481
- pGenUpInvest = dfGeneration ['InvestmentUp' ] # Upper bound of the investment decision [p.u.]
482
- pGenLoRetire = dfGeneration ['RetirementLo' ] # Lower bound of the retirement decision [p.u.]
483
- pGenUpRetire = dfGeneration ['RetirementUp' ] # Upper bound of the retirement decision [p.u.]
484
-
485
- pRatedLinearOperCost = pRatedLinearFuelCost + pEmissionCost
486
- pRatedLinearVarCost = pRatedLinearFuelCost + pLinearOMCost
487
-
488
- if pIndHydroTopology == 1:
489
- pReservoirType = dfReservoir ['StorageType' ] # reservoir type
490
- pWaterOutfType = dfReservoir ['OutflowsType' ] # water outflow type
491
- pRatedMinVolume = dfReservoir ['MinimumStorage' ] # rated minimum reservoir volume [hm3]
492
- pRatedMaxVolume = dfReservoir ['MaximumStorage' ] # rated maximum reservoir volume [hm3]
493
- pInitialVolume = dfReservoir ['InitialStorage' ] # initial reservoir volume [hm3]
494
- pIndBinRsrvInvest = dfReservoir ['BinaryInvestment' ] # binary reservoir investment decision [Yes]
495
- pRsrInvestCost = dfReservoir ['FixedInvestmentCost' ] * dfReservoir['FixedChargeRate'] # reservoir fixed cost [MEUR]
496
- pRsrPeriodIni = dfReservoir ['InitialPeriod' ] # initial period [year]
497
- pRsrPeriodFin = dfReservoir ['FinalPeriod' ] # final period [year]
498
-
499
- pNodeLat = dfNodeLocation['Latitude' ] # node latitude [º]
500
- pNodeLon = dfNodeLocation['Longitude' ] # node longitude [º]
501
-
502
- pLineType = dfNetwork ['LineType' ] # electric line type
503
- pLineLength = dfNetwork ['Length' ] # electric line length [km]
504
- pLineVoltage = dfNetwork ['Voltage' ] # electric line voltage [kV]
505
- pElecNetPeriodIni = dfNetwork ['InitialPeriod' ] # initial period
506
- pElecNetPeriodFin = dfNetwork ['FinalPeriod' ] # final period
507
- pLineLossFactor = dfNetwork ['LossFactor' ] # electric line loss factor [p.u.]
508
- pLineR = dfNetwork ['Resistance' ] # electric line resistance [p.u.]
509
- pLineX = dfNetwork ['Reactance' ].sort_index() # electric line reactance [p.u.]
510
- pLineBsh = dfNetwork ['Susceptance' ] # electric line susceptance [p.u.]
511
- pLineTAP = dfNetwork ['Tap' ] # tap changer [p.u.]
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' ] # binary electric line switching decision [Yes]
516
- pIndBinLineInvest = dfNetwork ['BinaryInvestment' ] # binary electric line investment decision [Yes]
517
- pSwitchOnTime = dfNetwork ['SwOnTime' ].astype('int') # minimum on time [h]
518
- pSwitchOffTime = dfNetwork ['SwOffTime' ].astype('int') # minimum off time [h]
519
- pAngMin = dfNetwork ['AngMin' ] * math.pi / 180 # Min phase angle difference [rad]
520
- pAngMax = dfNetwork ['AngMax' ] * math.pi / 180 # Max phase angle difference [rad]
521
- pNetLoInvest = dfNetwork ['InvestmentLo' ] # Lower bound of the investment decision [p.u.]
522
- pNetUpInvest = dfNetwork ['InvestmentUp' ] # Upper bound of the investment decision [p.u.]
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' ] # hydrogen line length [km]
546
- pH2PipePeriodIni = dfNetworkHydrogen['InitialPeriod' ] # initial period
547
- pH2PipePeriodFin = dfNetworkHydrogen['FinalPeriod' ] # final period
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' ] # binary hydrogen pipeline investment decision [Yes]
552
- pH2PipeLoInvest = dfNetworkHydrogen['InvestmentLo' ] # Lower bound of the investment decision [p.u.]
553
- pH2PipeUpInvest = dfNetworkHydrogen['InvestmentUp' ] # Upper bound of the investment decision [p.u.]
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 = pH2PipeNTCBck.where (pH2PipeNTCBck > 0.0, pH2PipeNTCFrw)
460
+ par['pH2PipeNTCBck'] = par['pH2PipeNTCBck'].where (par['pH2PipeNTCBck'] > 0.0, par['pH2PipeNTCFrw'])
558
461
  # replace pH2PipeNTCFrw = 0.0 by pH2PipeNTCBck
559
- pH2PipeNTCFrw = pH2PipeNTCFrw.where (pH2PipeNTCFrw > 0.0, pH2PipeNTCBck)
462
+ par['pH2PipeNTCFrw'] = par['pH2PipeNTCFrw'].where (par['pH2PipeNTCFrw'] > 0.0, par['pH2PipeNTCBck'])
560
463
  # replace pH2PipeUpInvest = 0.0 by 1.0
561
- pH2PipeUpInvest = pH2PipeUpInvest.where(pH2PipeUpInvest > 0.0, 1.0 )
562
-
563
- if pIndHeat == 1:
564
- pHeatPipeLength = dfNetworkHeat['Length' ] # heat pipe length [km]
565
- pHeatPipePeriodIni = dfNetworkHeat['InitialPeriod' ] # initial period
566
- pHeatPipePeriodFin = dfNetworkHeat['FinalPeriod' ] # final period
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' ] # binary heat pipe investment decision [Yes]
571
- pHeatPipeLoInvest = dfNetworkHeat['InvestmentLo' ] # Lower bound of the investment decision [p.u.]
572
- pHeatPipeUpInvest = dfNetworkHeat['InvestmentUp' ] # Upper bound of the investment decision [p.u.]
573
-
574
- pHeatPipePeriodFin = pHeatPipePeriodFin.where(pHeatPipePeriodFin != 0.0, 3000 )
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 = pHeatPipeNTCBck.where (pHeatPipeNTCBck > 0.0, pHeatPipeNTCFrw)
479
+ par['pHeatPipeNTCBck'] = par['pHeatPipeNTCBck'].where (par['pHeatPipeNTCBck'] > 0.0, par['pHeatPipeNTCFrw'])
577
480
  # replace pHeatPipeNTCFrw = 0.0 by pHeatPipeNTCBck
578
- pHeatPipeNTCFrw = pHeatPipeNTCFrw.where (pHeatPipeNTCFrw > 0.0, pHeatPipeNTCBck)
481
+ par['pHeatPipeNTCFrw'] = par['pHeatPipeNTCFrw'].where (par['pHeatPipeNTCFrw'] > 0.0, par['pHeatPipeNTCBck'])
579
482
  # replace pHeatPipeUpInvest = 0.0 by 1.0
580
- pHeatPipeUpInvest = pHeatPipeUpInvest.where(pHeatPipeUpInvest > 0.0, 1.0 )
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 or pRatedMaxPowerHeat [gg] > 0.0) and pElecGenPeriodIni[gg] <= mTEPES.p.last() and pElecGenPeriodFin[gg] >= mTEPES.p.first() and pGenToNode.reset_index().set_index(['Generator']).isin(mTEPES.nd)['Node'][gg]]) # excludes generators with empty node
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 ] == 0.0 and pProductionFunctionHydro[g ] == 0.0])
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 ] > 0.0) and pProductionFunctionHydro[g ] == 0.0])
602
- mTEPES.h = Set(doc='hydro units' , initialize=[g for g in mTEPES.g if pProductionFunctionH2[g ] == 0.0 and pProductionFunctionHeat[g ] == 0.0 and pProductionFunctionHydro[g ] > 0.0])
603
- mTEPES.el = Set(doc='electrolyzer units' , initialize=[es for es in mTEPES.es if pProductionFunctionH2[es] > 0.0 and pProductionFunctionHeat[es] == 0.0 and pProductionFunctionHydro[es] == 0.0])
604
- mTEPES.hp = Set(doc='heat pump & elec boiler units' , initialize=[es for es in mTEPES.es if pProductionFunctionH2[es] == 0.0 and pProductionFunctionHeat[es] > 0.0 and pProductionFunctionHydro[es] == 0.0])
605
- mTEPES.ch = Set(doc='CHP & fuel boiler units' , initialize=[g for g in mTEPES.g if pRatedMaxPowerHeat[g ] > 0.0 and pProductionFunctionHeat [g ] == 0.0])
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 if pProductionFunctionH2ToHeat[bo] > 0.0])
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 pElecGenPeriodIni[gg] <= mTEPES.p.last() and pElecGenPeriodFin[gg] >= mTEPES.p.first()])
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 if pRsrInvestCost [rs] > 0.0 and pRsrPeriodIni[rs] <= mTEPES.p.last() and pRsrPeriodFin[rs] >= mTEPES.p.first()])
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 if pH2PipeNTCFrw [pn] > 0.0 and pH2PipeNTCBck[pn] > 0.0 and pH2PipePeriodIni[pn] <= mTEPES.p.last() and pH2PipePeriodFin[pn] >= mTEPES.p.first()])
636
- mTEPES.pc = Set(doc='candidate hydrogen pipes' , initialize=[pa for pa in mTEPES.pa if pH2PipeFixedCost [pa] > 0.0])
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) # indicate if the line has a PTDF or not
658
- if pIndVarTTC == 1:
659
- pVariableTTCFrw = pVariableTTCFrw.reindex(columns=mTEPES.la, fill_value=0.0) # variable TTC forward direction
660
- pVariableTTCBck = pVariableTTCBck.reindex(columns=mTEPES.la, fill_value=0.0) # variable TTC backward direction
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 and not pLineType[le] == 'DC'])
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 and pLineType[le] == 'DC'])
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 pAnnualDiscRate == 0.0:
878
- pDiscountedWeight = pd.Series([ pPeriodWeight[p] for p in mTEPES.p], index=mTEPES.p)
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+pAnnualDiscRate)**pPeriodWeight[p]-1.0) / (pAnnualDiscRate*(1.0+pAnnualDiscRate)**(pPeriodWeight[p]-1+p-pEconomicBaseYear)) for p in mTEPES.p], index=mTEPES.p)
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 ).astype('int')
1032
- pOutflowsTimeStep = pOutflowsType.map(idxOutflows).where(pEnergyOutflows.sum() > 0.0, other = 1).astype('int')
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 pIndPTDF == 1:
1144
- pVariableTTCFrw = pVariableTTCFrw.loc [mTEPES.psn]
1145
- pVariableTTCBck = pVariableTTCBck.loc [mTEPES.psn]
1146
- pVariablePTDF = pVariablePTDF.loc [mTEPES.psn]
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 >= 0.0, 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
- #Calculate 2nd Blocks
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
- pLineNTCFrw.update(pd.Series([0.0 for la in mTEPES.la if pLineNTCFrw[la] < pEpsilonElec], index=[la for la in mTEPES.la if pLineNTCFrw[la] < pEpsilonElec], dtype='float64'))
1233
- pLineNTCBck.update(pd.Series([0.0 for la in mTEPES.la if pLineNTCBck[la] < pEpsilonElec], index=[la for la in mTEPES.la if pLineNTCBck[la] < pEpsilonElec], dtype='float64'))
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
- pH2PipeNTCFrw.update(pd.Series([0.0 for pa in mTEPES.pa if pH2PipeNTCFrw[pa] < pEpsilonElec], index=[pa for pa in mTEPES.pa if pH2PipeNTCFrw[pa] < pEpsilonElec], dtype='float64'))
1239
- pH2PipeNTCBck.update(pd.Series([0.0 for pa in mTEPES.pa if pH2PipeNTCBck[pa] < pEpsilonElec], index=[pa for pa in mTEPES.pa if pH2PipeNTCBck[pa] < pEpsilonElec], dtype='float64'))
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
- pHeatPipeNTCFrw.update(pd.Series([0.0 for ha in mTEPES.ha if pHeatPipeNTCFrw[ha] < pEpsilonHeat], index=[ha for ha in mTEPES.ha if pHeatPipeNTCFrw[ha] < pEpsilonHeat], dtype='float64'))
1246
- pHeatPipeNTCBck.update(pd.Series([0.0 for ha in mTEPES.ha if pHeatPipeNTCBck[ha] < pEpsilonHeat], index=[ha for ha in mTEPES.ha if pHeatPipeNTCBck[ha] < pEpsilonHeat], dtype='float64'))
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] for bo in mTEPES.bo] for p,sc,n in mTEPES.psn], index=mTEPES.psn, columns=mTEPES.bo))
1278
- pMaxPowerHeat.update(pd.DataFrame([[pRatedMaxPowerHeat[bo] for bo in mTEPES.bo] for p,sc,n in mTEPES.psn], index=mTEPES.psn, columns=mTEPES.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 = pVariableTTCFrw.replace(0.0, pLineNTCFrw / dfNetwork['SecurityFactor']) * dfNetwork['SecurityFactor'].loc[dfNetwork.index.isin(set(mTEPES.la))]
1335
- pMaxNTCBck = pVariableTTCBck.replace(0.0, pLineNTCBck / dfNetwork['SecurityFactor']) * dfNetwork['SecurityFactor'].loc[dfNetwork.index.isin(set(mTEPES.la))]
1336
- pMaxNTCMax = pMaxNTCFrw.where(pMaxNTCFrw > pMaxNTCBck, pMaxNTCBck)
1337
-
1338
- pMaxNTCBck = pMaxNTCBck.loc [:,mTEPES.la]
1339
- pMaxNTCFrw = pMaxNTCFrw.loc [:,mTEPES.la]
1340
- pMaxNTCMax = pMaxNTCFrw.loc [:,mTEPES.la]
1341
-
1342
- if pIndHydroTopology == 1:
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
- pDemandElecAbs = filter_rows(pDemandElecAbs , mTEPES.psnnd)
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=pIndBinGenRetire , within=NonNegativeIntegers, doc='Indicator of binary generation retirement decisions', mutable=True)
1459
- mTEPES.pIndBinRsrInvest = Param(initialize=pIndBinRsrInvest , within=NonNegativeIntegers, doc='Indicator of binary reservoir investment decisions', mutable=True)
1460
- mTEPES.pIndBinNetElecInvest = Param(initialize=pIndBinNetElecInvest, within=NonNegativeIntegers, doc='Indicator of binary electric network investment decisions', mutable=True)
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.pIndPTDF = Param(initialize=pIndPTDF , within=Binary, doc='Indicator of using or not the Flow-based method' )
1473
-
1474
- mTEPES.pENSCost = Param(initialize=pENSCost , within=NonNegativeReals, doc='ENS cost' )
1475
- mTEPES.pH2NSCost = Param(initialize=pH2NSCost , within=NonNegativeReals, doc='HNS cost' )
1476
- mTEPES.pHeatNSCost = Param(initialize=pHeatNSCost , within=NonNegativeReals, doc='HTNS cost' )
1477
- mTEPES.pCO2Cost = Param(initialize=pCO2Cost , within=NonNegativeReals, doc='CO2 emission cost' )
1478
- mTEPES.pAnnualDiscRate = Param(initialize=pAnnualDiscRate , within=UnitInterval, doc='Annual discount rate' )
1479
- mTEPES.pUpReserveActivation = Param(initialize=pUpReserveActivation, within=UnitInterval, doc='Proportion of upward reserve activation' )
1480
- mTEPES.pDwReserveActivation = Param(initialize=pDwReserveActivation, within=UnitInterval, doc='Proportion of downward reserve activation' )
1481
- mTEPES.pMinRatioDwUp = Param(initialize=pMinRatioDwUp , within=UnitInterval, doc='Minimum ratio downward to upward operating reserves')
1482
- mTEPES.pMaxRatioDwUp = Param(initialize=pMaxRatioDwUp , within=UnitInterval, doc='Maximum ratio downward to upward operating reserves')
1483
- mTEPES.pSBase = Param(initialize=pSBase , within=PositiveReals, doc='Base power' )
1484
- mTEPES.pTimeStep = Param(initialize=pTimeStep , within=PositiveIntegers, doc='Unitary time step' )
1485
- mTEPES.pEconomicBaseYear = Param(initialize=pEconomicBaseYear , within=PositiveIntegers, doc='Base year' )
1486
-
1487
- mTEPES.pReserveMargin = Param(mTEPES.par, initialize=pReserveMargin.to_dict() , within=NonNegativeReals, doc='Adequacy reserve margin' )
1488
- mTEPES.pEmission = Param(mTEPES.par, initialize=pEmission.to_dict() , within=NonNegativeReals, doc='Maximum CO2 emission' )
1489
- mTEPES.pRESEnergy = Param(mTEPES.par, initialize=pRESEnergy.to_dict() , within=NonNegativeReals, doc='Minimum RES energy' )
1490
- mTEPES.pDemandElecPeak = Param(mTEPES.par, initialize=pDemandElecPeak.to_dict() , within=NonNegativeReals, doc='Peak electric demand' )
1491
- mTEPES.pDemandElec = Param(mTEPES.psnnd, initialize=pDemandElec.to_dict() , within= Reals, doc='Electric demand' )
1492
- mTEPES.pDemandElecAbs = Param(mTEPES.psnnd, initialize=pDemandElecAbs.to_dict() , within=NonNegativeReals, doc='Electric demand' )
1493
- mTEPES.pPeriodWeight = Param(mTEPES.p, initialize=pPeriodWeight.to_dict() , within=NonNegativeReals, doc='Period weight', mutable=True)
1494
- mTEPES.pDiscountedWeight = Param(mTEPES.p, initialize=pDiscountedWeight.to_dict() , within=NonNegativeReals, doc='Discount factor' )
1495
- mTEPES.pScenProb = Param(mTEPES.psc, initialize=pScenProb.to_dict() , within=UnitInterval , doc='Probability', mutable=True)
1496
- mTEPES.pStageWeight = Param(mTEPES.stt, initialize=pStageWeight.to_dict() , within=NonNegativeReals, doc='Stage weight' )
1497
- mTEPES.pDuration = Param(mTEPES.psn, initialize=pDuration.to_dict() , within=NonNegativeIntegers, doc='Duration', mutable=True)
1498
- mTEPES.pNodeLon = Param(mTEPES.nd, initialize=pNodeLon.to_dict() , doc='Longitude' )
1499
- mTEPES.pNodeLat = Param(mTEPES.nd, initialize=pNodeLat.to_dict() , doc='Latitude' )
1500
- mTEPES.pSystemInertia = Param(mTEPES.psnar, initialize=pSystemInertia.to_dict() , within=NonNegativeReals, doc='System inertia' )
1501
- mTEPES.pOperReserveUp = Param(mTEPES.psnar, initialize=pOperReserveUp.to_dict() , within=NonNegativeReals, doc='Upward operating reserve' )
1502
- mTEPES.pOperReserveDw = Param(mTEPES.psnar, initialize=pOperReserveDw.to_dict() , within=NonNegativeReals, doc='Downward operating reserve' )
1503
- mTEPES.pMinPowerElec = Param(mTEPES.psng , initialize=pMinPowerElec.to_dict() , within=NonNegativeReals, doc='Minimum electric power' )
1504
- mTEPES.pMaxPowerElec = Param(mTEPES.psng , initialize=pMaxPowerElec.to_dict() , within=NonNegativeReals, doc='Maximum electric power' )
1505
- mTEPES.pMinCharge = Param(mTEPES.psneh, initialize=pMinCharge.to_dict() , within=NonNegativeReals, doc='Minimum charge' )
1506
- mTEPES.pMaxCharge = Param(mTEPES.psneh, initialize=pMaxCharge.to_dict() , within=NonNegativeReals, doc='Maximum charge' )
1507
- mTEPES.pMaxCapacity = Param(mTEPES.psneh, initialize=pMaxCapacity.to_dict() , within=NonNegativeReals, doc='Maximum capacity' )
1508
- mTEPES.pMaxPower2ndBlock = Param(mTEPES.psng , initialize=pMaxPower2ndBlock.to_dict() , within=NonNegativeReals, doc='Second block power' )
1509
- mTEPES.pMaxCharge2ndBlock = Param(mTEPES.psneh, initialize=pMaxCharge2ndBlock.to_dict() , within=NonNegativeReals, doc='Second block charge' )
1510
- mTEPES.pEnergyInflows = Param(mTEPES.psnes, initialize=pEnergyInflows.to_dict() , within=NonNegativeReals, doc='Energy inflows', mutable=True)
1511
- mTEPES.pEnergyOutflows = Param(mTEPES.psnes, initialize=pEnergyOutflows.to_dict() , within=NonNegativeReals, doc='Energy outflows', mutable=True)
1512
- mTEPES.pMinStorage = Param(mTEPES.psnes, initialize=pMinStorage.to_dict() , within=NonNegativeReals, doc='ESS Minimum storage capacity' )
1513
- mTEPES.pMaxStorage = Param(mTEPES.psnes, initialize=pMaxStorage.to_dict() , within=NonNegativeReals, doc='ESS Maximum storage capacity' )
1514
- mTEPES.pMinEnergy = Param(mTEPES.psng , initialize=pVariableMinEnergy.to_dict() , within=NonNegativeReals, doc='Unit minimum energy demand' )
1515
- mTEPES.pMaxEnergy = Param(mTEPES.psng , initialize=pVariableMaxEnergy.to_dict() , within=NonNegativeReals, doc='Unit maximum energy demand' )
1516
- mTEPES.pRatedMaxPowerElec = Param(mTEPES.gg, initialize=pRatedMaxPowerElec.to_dict() , within=NonNegativeReals, doc='Rated maximum power' )
1517
- mTEPES.pRatedMaxCharge = Param(mTEPES.gg, initialize=pRatedMaxCharge.to_dict() , within=NonNegativeReals, doc='Rated maximum charge' )
1518
- mTEPES.pMustRun = Param(mTEPES.gg, initialize=pMustRun.to_dict() , within=Binary , doc='must-run unit' )
1519
- mTEPES.pInertia = Param(mTEPES.gg, initialize=pInertia.to_dict() , within=NonNegativeReals, doc='unit inertia constant' )
1520
- mTEPES.pElecGenPeriodIni = Param(mTEPES.gg, initialize=pElecGenPeriodIni.to_dict() , within=PositiveIntegers, doc='installation year', )
1521
- mTEPES.pElecGenPeriodFin = Param(mTEPES.gg, initialize=pElecGenPeriodFin.to_dict() , within=PositiveIntegers, doc='retirement year', )
1522
- mTEPES.pAvailability = Param(mTEPES.gg, initialize=pAvailability.to_dict() , within=UnitInterval , doc='unit availability', mutable=True)
1523
- mTEPES.pEFOR = Param(mTEPES.gg, initialize=pEFOR.to_dict() , within=UnitInterval , doc='EFOR' )
1524
- mTEPES.pRatedLinearVarCost = Param(mTEPES.gg, initialize=pRatedLinearVarCost.to_dict() , within=NonNegativeReals, doc='Linear variable cost' )
1525
- mTEPES.pRatedConstantVarCost = Param(mTEPES.gg, initialize=pRatedConstantVarCost.to_dict() , within=NonNegativeReals, doc='Constant variable cost' )
1526
- mTEPES.pLinearVarCost = Param(mTEPES.psng , initialize=pLinearVarCost.to_dict() , within=NonNegativeReals, doc='Linear variable cost' )
1527
- mTEPES.pConstantVarCost = Param(mTEPES.psng , initialize=pConstantVarCost.to_dict() , within=NonNegativeReals, doc='Constant variable cost' )
1528
- mTEPES.pLinearOMCost = Param(mTEPES.gg, initialize=pLinearOMCost.to_dict() , within=NonNegativeReals, doc='Linear O&M cost' )
1529
- mTEPES.pOperReserveCost = Param(mTEPES.gg, initialize=pOperReserveCost.to_dict() , within=NonNegativeReals, doc='Operating reserve cost' )
1530
- mTEPES.pEmissionVarCost = Param(mTEPES.psng , initialize=pEmissionVarCost.to_dict() , within=Reals , doc='CO2 Emission cost' )
1531
- mTEPES.pEmissionRate = Param(mTEPES.gg, initialize=pEmissionRate.to_dict() , within=Reals , doc='CO2 Emission rate' )
1532
- mTEPES.pStartUpCost = Param(mTEPES.nr, initialize=pStartUpCost.to_dict() , within=NonNegativeReals, doc='Startup cost' )
1533
- mTEPES.pShutDownCost = Param(mTEPES.nr, initialize=pShutDownCost.to_dict() , within=NonNegativeReals, doc='Shutdown cost' )
1534
- mTEPES.pRampUp = Param(mTEPES.gg, initialize=pRampUp.to_dict() , within=NonNegativeReals, doc='Ramp up rate' )
1535
- mTEPES.pRampDw = Param(mTEPES.gg, initialize=pRampDw.to_dict() , within=NonNegativeReals, doc='Ramp down rate' )
1536
- mTEPES.pUpTime = Param(mTEPES.gg, initialize=pUpTime.to_dict() , within=NonNegativeIntegers, doc='Up time' )
1537
- mTEPES.pDwTime = Param(mTEPES.gg, initialize=pDwTime.to_dict() , within=NonNegativeIntegers, doc='Down time' )
1538
- mTEPES.pStableTime = Param(mTEPES.gg, initialize=pStableTime.to_dict() , within=NonNegativeIntegers, doc='Stable time' )
1539
- mTEPES.pShiftTime = Param(mTEPES.gg, initialize=pShiftTime.to_dict() , within=NonNegativeIntegers, doc='Shift time' )
1540
- mTEPES.pGenInvestCost = Param(mTEPES.eb, initialize=pGenInvestCost.to_dict() , within=NonNegativeReals, doc='Generation fixed cost' )
1541
- mTEPES.pGenRetireCost = Param(mTEPES.gd, initialize=pGenRetireCost.to_dict() , within=Reals , doc='Generation fixed retire cost' )
1542
- mTEPES.pIndBinUnitInvest = Param(mTEPES.eb, initialize=pIndBinUnitInvest.to_dict() , within=Binary , doc='Binary investment decision' )
1543
- mTEPES.pIndBinUnitRetire = Param(mTEPES.gd, initialize=pIndBinUnitRetire.to_dict() , within=Binary , doc='Binary retirement decision' )
1544
- mTEPES.pIndBinUnitCommit = Param(mTEPES.nr, initialize=pIndBinUnitCommit.to_dict() , within=Binary , doc='Binary commitment decision' )
1545
- mTEPES.pIndBinStorInvest = Param(mTEPES.ec, initialize=pIndBinStorInvest.to_dict() , within=Binary , doc='Storage linked to generation investment' )
1546
- mTEPES.pIndOperReserveGen = Param(mTEPES.gg, initialize=pIndOperReserveGen.to_dict() , within=Binary , doc='Indicator of operating reserve when generating power')
1547
- mTEPES.pIndOperReserveCon = Param(mTEPES.gg, initialize=pIndOperReserveCon.to_dict() , within=Binary , doc='Indicator of operating reserve when consuming power' )
1548
- mTEPES.pIndOutflowIncomp = Param(mTEPES.gg, initialize=pIndOutflowIncomp.to_dict() , within=Binary , doc='Indicator of outflow incompatibility with charging' )
1549
- mTEPES.pEfficiency = Param(mTEPES.eh, initialize=pEfficiency.to_dict() , within=UnitInterval , doc='Round-trip efficiency' )
1550
- mTEPES.pStorageTimeStep = Param(mTEPES.es, initialize=pStorageTimeStep.to_dict() , within=PositiveIntegers, doc='ESS Storage cycle' )
1551
- mTEPES.pOutflowsTimeStep = Param(mTEPES.es, initialize=pOutflowsTimeStep.to_dict() , within=PositiveIntegers, doc='ESS Outflows cycle' )
1552
- mTEPES.pEnergyTimeStep = Param(mTEPES.gg, initialize=pEnergyTimeStep.to_dict() , within=PositiveIntegers, doc='Unit energy cycle' )
1553
- mTEPES.pIniInventory = Param(mTEPES.psnes, initialize=pIniInventory.to_dict() , within=NonNegativeReals, doc='ESS Initial storage', mutable=True)
1554
- mTEPES.pStorageType = Param(mTEPES.es, initialize=pStorageType.to_dict() , within=Any , doc='ESS Storage type' )
1555
- mTEPES.pGenLoInvest = Param(mTEPES.eb, initialize=pGenLoInvest.to_dict() , within=NonNegativeReals, doc='Lower bound of the investment decision', mutable=True)
1556
- mTEPES.pGenUpInvest = Param(mTEPES.eb, initialize=pGenUpInvest.to_dict() , within=NonNegativeReals, doc='Upper bound of the investment decision', mutable=True)
1557
- mTEPES.pGenLoRetire = Param(mTEPES.gd, initialize=pGenLoRetire.to_dict() , within=NonNegativeReals, doc='Lower bound of the retirement decision', mutable=True)
1558
- mTEPES.pGenUpRetire = Param(mTEPES.gd, initialize=pGenUpRetire.to_dict() , within=NonNegativeReals, doc='Upper bound of the retirement decision', mutable=True)
1559
-
1560
- if pIndHydrogen == 1:
1561
- mTEPES.pProductionFunctionH2 = Param(mTEPES.el, initialize=pProductionFunctionH2.to_dict(), within=NonNegativeReals, doc='Production function of an electrolyzer plant')
1562
-
1563
- if pIndHeat == 1:
1564
- pMinPowerHeat = filter_rows(pMinPowerHeat, mTEPES.psnch)
1565
- pMaxPowerHeat = filter_rows(pMaxPowerHeat, mTEPES.psnch)
1566
-
1567
- mTEPES.pReserveMarginHeat = Param(mTEPES.par, initialize=pReserveMarginHeat.to_dict() , within=NonNegativeReals, doc='Adequacy reserve margin' )
1568
- mTEPES.pRatedMaxPowerHeat = Param(mTEPES.gg, initialize=pRatedMaxPowerHeat.to_dict() , within=NonNegativeReals, doc='Rated maximum heat' )
1569
- mTEPES.pMinPowerHeat = Param(mTEPES.psnch, initialize=pMinPowerHeat.to_dict() , within=NonNegativeReals, doc='Minimum heat power' )
1570
- mTEPES.pMaxPowerHeat = Param(mTEPES.psnch, initialize=pMaxPowerHeat.to_dict() , within=NonNegativeReals, doc='Maximum heat power' )
1571
- mTEPES.pPower2HeatRatio = Param(mTEPES.ch, initialize=pPower2HeatRatio.to_dict() , within=NonNegativeReals, doc='Power to heat ratio' )
1572
- mTEPES.pProductionFunctionHeat = Param(mTEPES.hp, initialize=pProductionFunctionHeat.to_dict() , within=NonNegativeReals, doc='Production function of an CHP plant' )
1573
- mTEPES.pProductionFunctionH2ToHeat = Param(mTEPES.hh, initialize=pProductionFunctionH2ToHeat.to_dict(), within=NonNegativeReals, doc='Production function of an boiler using H2')
1574
-
1575
- if pIndPTDF == 1:
1576
- mTEPES.pPTDF = Param(mTEPES.psnland, initialize=pPTDF.to_dict() , within=Reals , doc='Power transfer distribution factor' )
1577
-
1578
- if pIndHydroTopology == 1:
1579
- pHydroInflows = filter_rows(pHydroInflows , mTEPES.psnrs)
1580
- pHydroOutflows = filter_rows(pHydroOutflows, mTEPES.psnrs)
1581
- pMaxOutflows = filter_rows(pMaxOutflows , mTEPES.psnrs)
1582
- pMinVolume = filter_rows(pMinVolume , mTEPES.psnrs)
1583
- pMaxVolume = filter_rows(pMaxVolume , mTEPES.psnrs)
1584
- pIniVolume = filter_rows(pIniVolume , mTEPES.psnrs)
1585
-
1586
- mTEPES.pProductionFunctionHydro = Param(mTEPES.h , initialize=pProductionFunctionHydro.to_dict(), within=NonNegativeReals, doc='Production function of a hydro power plant' )
1587
- mTEPES.pHydroInflows = Param(mTEPES.psnrs, initialize=pHydroInflows.to_dict() , within=NonNegativeReals, doc='Hydro inflows', mutable=True)
1588
- mTEPES.pHydroOutflows = Param(mTEPES.psnrs, initialize=pHydroOutflows.to_dict() , within=NonNegativeReals, doc='Hydro outflows', mutable=True)
1589
- mTEPES.pMaxOutflows = Param(mTEPES.psnrs, initialize=pMaxOutflows.to_dict() , within=NonNegativeReals, doc='Maximum hydro outflows', )
1590
- mTEPES.pMinVolume = Param(mTEPES.psnrs, initialize=pMinVolume.to_dict() , within=NonNegativeReals, doc='Minimum reservoir volume capacity' )
1591
- mTEPES.pMaxVolume = Param(mTEPES.psnrs, initialize=pMaxVolume.to_dict() , within=NonNegativeReals, doc='Maximum reservoir volume capacity' )
1592
- mTEPES.pIndBinRsrvInvest = Param(mTEPES.rn, initialize=pIndBinRsrvInvest.to_dict() , within=Binary , doc='Binary reservoir investment decision' )
1593
- mTEPES.pRsrInvestCost = Param(mTEPES.rn, initialize=pRsrInvestCost.to_dict() , within=NonNegativeReals, doc='Reservoir fixed cost' )
1594
- mTEPES.pRsrPeriodIni = Param(mTEPES.rs, initialize=pRsrPeriodIni.to_dict() , within=PositiveIntegers, doc='Installation year', )
1595
- mTEPES.pRsrPeriodFin = Param(mTEPES.rs, initialize=pRsrPeriodFin.to_dict() , within=PositiveIntegers, doc='Retirement year', )
1596
- mTEPES.pReservoirTimeStep = Param(mTEPES.rs, initialize=pReservoirTimeStep.to_dict() , within=PositiveIntegers, doc='Reservoir volume cycle' )
1597
- mTEPES.pWaterOutTimeStep = Param(mTEPES.rs, initialize=pWaterOutTimeStep.to_dict() , within=PositiveIntegers, doc='Reservoir outflows cycle' )
1598
- mTEPES.pIniVolume = Param(mTEPES.psnrs, initialize=pIniVolume.to_dict() , within=NonNegativeReals, doc='Reservoir initial volume', mutable=True)
1599
- mTEPES.pInitialVolume = Param(mTEPES.rs, initialize=pInitialVolume.to_dict() , within=NonNegativeReals, doc='Reservoir initial volume without load levels')
1600
- mTEPES.pReservoirType = Param(mTEPES.rs, initialize=pReservoirType.to_dict() , within=Any , doc='Reservoir volume type' )
1601
-
1602
- if pIndHydrogen == 1:
1603
- pDemandH2 = filter_rows(pDemandH2 ,mTEPES.psnnd)
1604
- pDemandH2Abs = filter_rows(pDemandH2Abs,mTEPES.psnnd)
1605
-
1606
- mTEPES.pDemandH2 = Param(mTEPES.psnnd, initialize=pDemandH2.to_dict() , within=NonNegativeReals, doc='Hydrogen demand per hour')
1607
- mTEPES.pDemandH2Abs = Param(mTEPES.psnnd, initialize=pDemandH2Abs.to_dict(), within=NonNegativeReals, doc='Hydrogen demand' )
1608
-
1609
- if pIndHeat == 1:
1610
- pDemandHeat = filter_rows(pDemandHeat , mTEPES.psnnd)
1611
- pDemandHeatAbs = filter_rows(pDemandHeatAbs , mTEPES.psnnd)
1612
-
1613
- mTEPES.pDemandHeatPeak = Param(mTEPES.par, initialize=pDemandHeatPeak.to_dict(), within=NonNegativeReals, doc='Peak heat demand' )
1614
- mTEPES.pDemandHeat = Param(mTEPES.psnnd, initialize=pDemandHeat.to_dict() , within=NonNegativeReals, doc='Heat demand per hour' )
1615
- mTEPES.pDemandHeatAbs = Param(mTEPES.psnnd, initialize=pDemandHeatAbs.to_dict(), within=NonNegativeReals, doc='Heat demand' )
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.pDemandElecAbs [p,sc,n,nd] ) for p,sc,n,nd in mTEPES.psnnd]
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
- #Call the relaxing variables function and add its output to nFixedVariables
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] == 0.0:
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 = Param(initialize=round(nFixedVariables), within=NonNegativeIntegers, doc='Number of fixed variables')
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')