-
Notifications
You must be signed in to change notification settings - Fork 0
/
EOLES_RES_EPR.gms
335 lines (326 loc) · 16.7 KB
/
EOLES_RES_EPR.gms
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
$OnText
French power sector financial modelling for only renewable energies as supply technologies (Offshore and Onshore wind, PV, Hydroelectricity and biogas)
and Battery and PHS (pumped hydro storage) as storage technologies,including primary and secondary reserve requirements for meteo and electricity consumption data of 2016;
Offshore and onshore wind power, Solar power and biogas capacities as well as battery storage and hydrogen (P2G) storage capacity are chosen endogenousely, while hydroelectricity lake and run-of-river and Phumped hydro storage capacities are chosen exogenousely.
Existing capacities by December 2017 are also entered as lower bound of each capacity, and investment cost for existing capacities has been considered zero.
Linear optimisation using one-hour time step with respect to Investment Cost.
By Behrang SHIRIZADEH - December 2018
$Offtext
*-------------------------------------------------------------------------------
* Defining the sets
*-------------------------------------------------------------------------------
sets h /0*8759/
first(h) 'first hour'
last(h) 'last hour'
m 'month' /1*12/
tec 'technology' /offshore, onshore, pv, river, lake, biogas, gas, nuclear, phs, battery, methanation/
gen(tec) 'power plants' /offshore, onshore, pv, river, lake, biogas, gas, nuclear/
vre(tec) 'variable tecs' /offshore, onshore, pv, river/
ncomb(tec) 'non-combustible generation' /offshore, onshore, pv, river, lake, nuclear, phs, battery/
str(tec) 'storage technologies' /phs, battery, methanation/
frr(tec) 'technologies for upward FRR' /lake, phs, battery,gas,nuclear/
;
first(h) = ord(h)=1;
last(h) = ord(h)=card(h);
*-------------------------------------------------------------------------------
* Inputs
*-------------------------------------------------------------------------------
$Offlisting
parameter month(h) 'Production profiles of VRE'
/
$ondelim
$include inputs/month.csv
$offdelim
/;
parameter load_factor(vre,h) 'Production profiles of VRE'
/
$ondelim
$include inputs/vre_profiles2006r.csv
$offdelim
/;
parameter demand(h) 'demand profile in each hour in GW'
/
$ondelim
$include inputs/demand2035_RTE.csv
$offdelim
/;
Parameter lake_inflows(m) 'monthly lake inflows in GWh'
/
$ondelim
$include inputs/lake2006.csv
$offdelim
/ ;
parameter epsilon(vre) 'additional FRR requirement for variable renewable energies because of forecast errors'
/
$ondelim
$include inputs/reserve_requirements.csv
$offdelim
/ ;
parameter capa_ex(tec) 'existing capacities of the technologies by December 2017 in GW'
/
$ondelim
$include inputs/existing_capasr.csv
$offdelim
/ ;
parameter capa_max(vre) 'maximum capacities of the technologies in GW'
/
$ondelim
$include inputs/max_capas.csv
$offdelim
/ ;
parameter capex(tec) 'annualized power capex cost in M€/GW/year'
/
$ondelim
$include inputs/annuities2035.csv
$offdelim
/ ;
parameter capex_en(str) 'annualized energy capex cost of storage technologies in M€/GWh/year'
/
$ondelim
$include inputs/str_annuities.csv
$offdelim
/ ;
parameter fOM(tec) 'annualized fixed operation and maintenance costs M€/GW/year'
/
$ondelim
$include inputs/fO&M2035.csv
$offdelim
/ ;
Parameter vOM(tec) 'Variable operation and maintenance costs in M€/GWh'
/
$ondelim
$include inputs/vO&M2035.csv
$offdelim
/ ;
parameter fixed_costs(tec) 'yearly fixed cost of each tec in M€/GW/year' ;
fixed_costs(tec) = capex(tec) + fOM(tec);
*For WACC = 4.5% the line below:
parameter s_capex(str) 'charging related annuity of storage in M€/GW/year' /PHS 0, battery 0, methanation 134.1993182/;
*For WACC = 8%, the line below:
*parameter s_capex(str) 'charging related annuity of storage in M€/GW/year' /PHS 0, battery 0, methanation 181.479171/;
parameter s_opex(str) 'charging related fOM of storage in M€/GW/year' /PHS 0, battery 0, methanation 87.75/;
parameter eta_in(str) 'charging efifciency of storage technologies' /PHS 0.95, battery 0.9, methanation 0.59/;
parameter eta_out(str) 'discharging efficiency of storage technolgoies' /PHS 0.9, battery 0.95, methanation 0.45/;
scalar eta_ocgt 'efficiency of OCGT power plants' /0.45/;
scalar cf_nuc 'maximum capacity factor of nuclear power plants' /0.90/;
scalar ramp_rate 'maximum ramp up/down rate for nuclear power plant' /0.50/;
scalar pump_capa 'pumping capacity in GW' /9.3/;
scalar max_phs 'maximum volume of energy can be stored in PHS reservoir in TWh' /0.18/;
scalar max_biogas 'maxium energy can be generated by biogas in TWh' /15/;
scalar load_uncertainty 'uncertainty coefficient for hourly demand' /0.01/;
scalar delta 'load variation factor' /0.1/;
*-------------------------------------------------------------------------------
* Model
*-------------------------------------------------------------------------------
variables GENE(tec,h) 'hourly energy generation in TWh'
CAPA(tec) 'overal yearly installed capacity in GW'
STORAGE(str,h) 'hourly electricity input of battery storage GW'
S(str) 'charging power capacity of each storage technology'
STORED(str,h) 'energy stored in each storage technology in GWh'
CAPACITY(str) 'energy volume of storage technologies in GWh'
RSV(frr,h) 'required upward frequency restoration reserve in GW'
COST 'final investment cost in b€' ;
positive variables GENE(tec,h),CAPA(tec),STORAGE(str,h), S(str),STORED(str,h),CAPACITY(str),RSV(frr,h);
equations gene_vre 'variables renewable profiles generation'
gene_capa 'capacity and genration relation for technologies'
combustion 'the relationship of combustible technologies'
capa_frr 'capacity needed for the secondary reserve requirements'
storing 'the definition of stored energy in the storage options'
storage_const 'storage in the first hour is equal to the storage in the last hour'
lake_res 'constraint on water for lake reservoirs'
stored_cap 'maximum energy that is stored in storage units'
storage_capa1 'the capacity with hourly charging relationship of storage'
storage_capa2 'storage power limit'
biogas_const 'maximum energy can be produced by biogas'
nuc_cf 'the yearly capacity factor of nuclear power plants should not pass 80%'
nuc_up 'Nuclear power plant upward flexibility flexibility'
nuc_down 'Nuclear power plant downward flexibility flexibility'
reserves 'FRR requirement'
adequacy 'supply/demand relation'
obj 'the final objective function which is COST';
gene_vre(vre,h).. GENE(vre,h) =e= CAPA(vre)*load_factor(vre,h);
gene_capa(tec,h).. CAPA(tec) =g= GENE(tec,h);
combustion(h).. GENE('gas',h) =e= GENE('methanation',h) + GENE('biogas',h) ;
capa_frr(frr,h).. CAPA(frr) =g= GENE(frr,h) + RSV(frr,h);
storing(h,h+1,str).. STORED(str,h+1) =e= STORED(str,h) + STORAGE(str,h)*eta_in(str) - GENE(str,h)/eta_out(str);
storage_const(str,first,last).. STORED(str,first) =e= STORED(str,last) + STORAGE(str,last)*eta_in(str) - GENE(str,last)/eta_out(str);
lake_res(m).. lake_inflows(m) =g= sum(h$(month(h) = ord(m)),GENE('lake',h))/1000;
stored_cap(str,h).. STORED(str,h) =l= CAPACITY(str);
storage_capa1(str,h).. S(str) =g= STORAGE(str,h);
storage_capa2(str).. S(str) =l= CAPA(str);
biogas_const.. sum(h,GENE('biogas',h)) =l= max_biogas*1000;
nuc_cf.. sum(h,GENE('nuclear',h)) =l= CAPA('nuclear')*cf_nuc*8760;
nuc_up(h,h+1).. GENE('nuclear',h+1) + RSV('nuclear',h+1) =l= GENE('nuclear',h) + ramp_rate*(CAPA('nuclear')-GENE('nuclear',h)) ;
nuc_down(h,h+1).. GENE('nuclear',h+1) =g= GENE('nuclear',h)*(1 - ramp_rate) ;
reserves(h).. sum(frr, RSV(frr,h)) =e= sum(vre,epsilon(vre)*CAPA(vre))+ demand(h)*load_uncertainty*(1+delta);
adequacy(h).. sum(ncomb,GENE(ncomb,h))+GENE('gas',h) =g= demand(h) + sum(str,STORAGE(str,h));
obj.. COST =e= (sum(tec,(CAPA(tec)-capa_ex(tec))*capex(tec))+ sum(str,CAPACITY(str)*capex_en(str))+sum(tec,(CAPA(tec)*fOM(tec)))+ sum(str,S(str)*(s_capex(str)+s_opex(str))) + sum((tec,h),GENE(tec,h)*vOM(tec)))/1000;
*-------------------------------------------------------------------------------
* Initial and fixed values
*-------------------------------------------------------------------------------
CAPA.fx('phs') = pump_capa;
CAPA.fx('river')= capa_ex('river');
CAPA.fx('lake') = 12.855;
S.fx('phs') = pump_capa;
CAPACITY.fx('phs') = max_phs*1000;
CAPA.up('offshore') = capa_max('offshore');
CAPA.up('onshore') = capa_max('onshore');
CAPA.up('pv') = capa_max('pv');
*CAPA.fx('nuclear') = 0;
*-------------------------------------------------------------------------------
* Model options
*-------------------------------------------------------------------------------
model EOLES_RES_EPR /all/;
*-------------------------------------------------------------------------------
option solvelink=0;
option RESLIM = 1000000;
option lp=CPLEX;
option Savepoint=1;
option solveopt = replace;
option limcol = 0;
option limrow = 0;
option SOLPRINT = OFF;
*-------------------------------------------------------------------------------
* Solve statement
*-------------------------------------------------------------------------------
$If exist EOLES_RES_EPR_p.gdx execute_loadpoint 'EOLES_RES_EPR_p';
Solve EOLES_RES_EPR using lp minimizing COST;
*-------------------------------------------------------------------------------
* Display statement
*-------------------------------------------------------------------------------
parameter sumdemand 'the whole demand per year in TWh';
sumdemand = sum(h,demand(h))/1000;
parameter gene_tec(tec) 'Overall yearly energy generated by the technology in TWh';
gene_tec(tec) = sum(h,GENE.l(tec,h))/1000;
parameter sumgene 'the whole generation per year in TWh';
sumgene = sum((gen,h),GENE.l(gen,h))/1000 - gene_tec('gas');
Parameter lcoe(gen);
lcoe(gen) = (CAPA.l(gen)*(fOM(gen)+capex(gen))+ gene_tec(gen)*vOM(gen)*1000)/gene_tec(gen);
parameter lcoe_sys1;
lcoe_sys1 = cost.l*1000/sumgene;
parameter lcoe_sys2;
lcoe_sys2 = cost.l*1000/sumdemand;
parameter lcos(str);
lcos(str) = (CAPA.l(str)*(fOM(str)+capex(str))+ gene_tec(str)*vOM(str) + S.l(str)*(s_capex(str)+s_opex(str))+ CAPACITY.l(str)*capex_en(str))/gene_tec(str);
parameter cf(gen) 'load factor of generation technologies';
cf(gen) = gene_tec(gen)*1000/(8760*CAPA.l(gen));
parameter str_loss 'yearly storage related loss in % of power production';
str_loss = (sum((str,h),STORAGE.l(str,h))-sum(str,gene_tec(str)*1000))/(sumgene*10);
parameter lc 'load curtailment of the network';
lc = ((sumgene - sumdemand)*100/sumgene) - str_loss;
parameter spot_price(h) 'marginal cost' ;
spot_price(h) = 1000000*adequacy.m(h);
parameter marginal_cost 'average value over the year of spot price in €/MWh';
marginal_cost = sum(h,spot_price(h))/8760;
parameter gas_price(h) 'hourly gas price';
gas_price(h) = -1000000*combustion.m(h);
*-------------------------------------------------------------------------------
display cost.l;
display capa.l;
display sumdemand;
display sumgene;
display gene_tec;
display lcoe;
display lcoe_sys1;
display lcoe_sys2;
display lcos;
display CAPACITY.l;
display cf;
display lc;
display str_loss;
display marginal_cost;
display S.l;
*-------------------------------------------------------------------------------
* Output
*-------------------------------------------------------------------------------
$Ontext
two main output files;
The .txt file just to have a summary and general idea of the key numbers
The .csv file to have a fine output with hourly data for final data processing and analysis
$Offtext
*-------------------------------------------------------------------------------
file results /'outputs/Results.txt'/ ;
*the .txt file
put results;
put ' the main results ' //
//
'I)Overall investment cost is' cost.l 'b€' //
//
'II)the Renewable capacity ' //
'Offshore 'CAPA.l('offshore')' GW'//
'onsore 'CAPA.l('onshore')' GW' //
'PV 'CAPA.l('PV')' GW'//
'run of river 'CAPA.l('river') 'GW' //
'lake 'CAPA.l('lake') 'GW' //
'biogas 'CAPA.l('biogas')' GW'//
'OCGT 'CAPA.l('gas')' GW'//
'nuclear 'CAPA.l('nuclear') ' GW'//
'Battery 'CAPA.l('battery')' GW'//
'PHS 'CAPA.l('phs')' GW'//
'methanation 'CAPA.l('methanation')' GW'//
//
//
'III)Needed storage volume and storage charging power' //
'Battery Storage 'CAPACITY.l('battery')' GWh' //
'PHS Storage 'CAPACITY.l('phs')' GWh'//
'methane storage 'CAPACITY.l('methanation')' GWh'//
'Battery Storage 'S.l('battery')' GW' //
'PHS Storage 'S.l('phs')' GW'//
'methane storage 'S.l('methanation')' GW'//
//
'V)Overall yearly energy generation of each technology'//
'Offshore 'gene_tec('offshore')' TWh'//
'onsore 'gene_tec('onshore')' TWh' //
'PV 'gene_tec('PV')' TWh'//
'run of river 'gene_tec('river') 'TWh' //
'lake 'gene_tec('lake') 'TWh' //
'biogas 'gene_tec('biogas')' TWh'//
'OCGT 'gene_tec('gas')' TWh'//
'nuclear 'gene_tec('nuclear') ' TWh'//
'battery 'gene_tec('battery')' TWh'//
'phs 'gene_tec('phs')' TWh'//
'Methanation 'gene_tec('methanation')'TWh'//
//
'VI)more details'//
'LCOE for Offshore ' lcoe('offshore')' €/MWh'//
'LCOE for Onshore ' lcoe('onshore')' €/MWh'//
'LCOE for PV ' lcoe('pv')' €/MWh'//
'LCOE for Run-of-river ' lcoe('river')' €/MWh'//
'LCOE for Lake ' lcoe('lake')' €/MWh'//
'LCOE for Biogas ' lcoe('biogas')' €/MWh'//
'LCOE for OCGT ' lcoe('gas')' €/MWh'//
'LCOE for Nuclear power ' lcoe('nuclear')' €/MWh'//
'LCOS for battery ' lcos('battery')' €/MWh'//
'LCOS for pumped storage ' lcos('phs')' €/MWh'//
'LCOS for methanation ' lcos('methanation')' €/MWh'//
//
'Load Curtailment' lc '% and the storage loss ' str_loss '%'//
//
'LCOE of the system is 'lcoe_sys1' €/MWh or 'lcoe_sys2' €/MWh '//
//
'Average spot price of the system is ' marginal_cost' €/MWh'//
//
'capacity factors '//
'Offshore 'cf('offshore')//
'onsore 'cf('onshore')//
'PV 'cf('pv') //
'run of river 'cf('river') //
'lake 'cf('lake') //
'OCGT 'cf('gas')//
'Nuclear power 'cf('nuclear')//
//
;
*-------------------------------------------------------------------------------
file hourly_generation /'outputs/Results.csv' / ;
*the .csv file
parameter nSTORAGE(str,h);
nSTORAGE(str,h) = 0 - STORAGE.l(str,h);
put hourly_generation;
hourly_generation.pc=5;
put 'hour'; loop(tec, put tec.tl;) put 'demand' , 'Pump' , 'ElecStr' , 'CH4', 'elec_price','gas_price'/ ;
loop (h,
put h.tl; loop(tec, put GENE.l(tec,h);) put demand(h), nSTORAGE('PHS',h), nSTORAGE('battery',h), nSTORAGE('methanation',h), spot_price(h),gas_price(h)/
;);
*-------------------------------------------------------------------------------
* The End :D
*-------------------------------------------------------------------------------