4b_outputInvariant.gms 29.9 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$ontext
This file is part of Backbone.

Backbone is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Backbone is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with Backbone.  If not, see <http://www.gnu.org/licenses/>.
$offtext

18
* =============================================================================
19
* --- Time Step Dependent Results ---------------------------------------------
20
* =============================================================================
21

22
23
// Need to loop over the model dimension, as this file is no longer contained in the modelSolves loop...
loop(m,
24

Topi Rasku's avatar
Topi Rasku committed
25
26
27
* --- Realized Individual Costs ----------------------------------------------

    // Variable O&M costs
28
    r_gnuVOMCost(gnu(grid, node, unit), ft_realizedNoReset(f,t))$[ord(t) > mSettings(m, 't_start') + mSettings(m, 't_initializationPeriod')]
Topi Rasku's avatar
Topi Rasku committed
29
30
        = 1e-6 // Scaling to MEUR
            * p_stepLengthNoReset(m, f, t)
31
            * abs(r_gen(grid, node, unit, f, t))
32
            * p_gnu(grid, node, unit, 'vomCosts');
Topi Rasku's avatar
Topi Rasku committed
33
34

    // Fuel and emission costs during normal operation
35
    r_uFuelEmissionCost(commodity, unit_commodity(unit), ft_realizedNoReset(f,t))${ un_commodity(unit, commodity) and [ord(t) > mSettings(m, 't_start') + mSettings(m, 't_initializationPeriod')]}
Topi Rasku's avatar
Topi Rasku committed
36
37
        = 1e-6 // Scaling to MEUR
            * p_stepLengthNoReset(m, f, t)
38
            * r_fuelUse(commodity, unit, f, t)
39
40
            * [ + p_price(commodity, 'price')$p_price(commodity, 'useConstant')
                + ts_price(commodity, t)$p_price(commodity, 'useTimeSeries')
Topi Rasku's avatar
Topi Rasku committed
41
                // Emission costs
42
43
                + sum(emission, p_unitEmissionCost(unit, commodity, emission))
              ];
Topi Rasku's avatar
Topi Rasku committed
44
45

    // Unit startup costs
46
    r_uStartupCost(unit, ft_realizedNoReset(f,t))${sum(starttype, unitStarttype(unit, starttype)) and [ord(t) > mSettings(m, 't_start') + mSettings(m, 't_initializationPeriod')]}
Topi Rasku's avatar
Topi Rasku committed
47
48
49
        = 1e-6 // Scaling to MEUR
            * sum(unitStarttype(unit, starttype),
                + r_startup(unit, starttype, f, t)
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
                    * [
                        + p_uStartup(unit, starttype, 'cost') // CUR/start-up
                        // Start-up fuel and emission costs
                        + sum(nu(node,unit)$p_unStartup(unit, node, starttype),
                            + p_unStartup(unit, node, starttype) // MWh/start-up
                              * [
                                  + p_price(node, 'price')$p_price(node, 'useConstant') // CUR/MWh
                                  + ts_price(node, t)$p_price(node, 'useTimeseries') // CUR/MWh
                                ] // END * p_uStartup
                          ) // END sum(node)
                        + sum((nu(node, unit), emission)$p_unitEmissionCost(unit, node, emission),
                            + p_unStartup(unit, node, starttype) // MWh/start-up
                              * p_unitEmissionCost(unit, node, emission) // CUR/MWh
                          ) // END sum(nu, emission)
                      ] // END * r_startup
65
              ); // END sum(starttype)
Topi Rasku's avatar
Topi Rasku committed
66
67

    // Node state slack costs
68
    r_gnStateSlackCost(gn_stateSlack(grid, node), ft_realizedNoReset(f,t))$[ord(t) > mSettings(m, 't_start') + mSettings(m, 't_initializationPeriod')]
Topi Rasku's avatar
Topi Rasku committed
69
70
71
72
73
74
75
76
        = 1e-6 // Scaling to MEUR
            * p_stepLengthNoReset(m, f, t)
            * sum(slack${ p_gnBoundaryPropertiesForStates(grid, node, slack, 'slackCost') },
                + r_stateSlack(grid, node, slack, f, t)
                    * p_gnBoundaryPropertiesForStates(grid, node, slack, 'slackCost')
                ); // END sum(slack)

    // Storage Value Change
77
    r_gnStorageValueChange(gn_state(grid, node))${ active(m, 'storageValue') }
Topi Rasku's avatar
Topi Rasku committed
78
79
80
        = 1e-6
            * [
                + sum(ft_realizedNoReset(f,t)${ ord(t) = mSettings(m, 't_end') + 1 },
81
                    + [
Topi Rasku's avatar
Topi Rasku committed
82
                        + p_storageValue(grid, node)${ not p_gn(grid, node, 'storageValueUseTimeSeries') }
83
84
                        + ts_storageValue(grid, node, f, t)${ p_gn(grid, node, 'storageValueUseTimeSeries') }
                      ]
Topi Rasku's avatar
Topi Rasku committed
85
86
                        * r_state(grid, node, f, t)
                    ) // END sum(ft_realizedNoReset)
87
                - sum(ft_realizedNoReset(f,t)${ ord(t) = mSettings(m, 't_start') + mSettings(m, 't_initializationPeriod') }, // INITIAL v_state NOW INCLUDED IN THE RESULTS
88
                    + [
Topi Rasku's avatar
Topi Rasku committed
89
                        + p_storageValue(grid, node)${ not p_gn(grid, node, 'storageValueUseTimeSeries') }
90
91
                        + ts_storageValue(grid, node, f, t)${ p_gn(grid, node, 'storageValueUseTimeSeries') }
                      ]
Topi Rasku's avatar
Topi Rasku committed
92
93
94
95
                        * r_state(grid, node, f, t)
                    ) // END sum(ft_realizedNoReset)
                ]; // END * 1e-6

96
* --- Total Cost Components (discounted) --------------------------------------
Topi Rasku's avatar
Topi Rasku committed
97
98
99

    // Total VOM costs
    r_gnuTotalVOMCost(gnu_output(grid, node, unit))
100
        = sum(ft_realizedNoReset(f,t)$[ord(t) > mSettings(m, 't_start') + mSettings(m, 't_initializationPeriod')],
Topi Rasku's avatar
Topi Rasku committed
101
            + r_gnuVOMCost(grid, node, unit, f, t)
102
                * sum(msft_realizedNoReset(m, s, f, t), p_msProbability(m, s) * p_msWeight(m, s) * p_s_discountFactor(s))
Topi Rasku's avatar
Topi Rasku committed
103
104
105
            );

    // Total fuel & emission costs
106
    r_uTotalFuelEmissionCost(commodity, unit)$un_commodity(unit, commodity)
107
        = sum(ft_realizedNoReset(f,t)$[ord(t) > mSettings(m, 't_start') + mSettings(m, 't_initializationPeriod')],
108
            + r_uFuelEmissionCost(commodity, unit, f, t)
109
                * sum(msft_realizedNoReset(m, s, f, t), p_msProbability(m, s) * p_msWeight(m, s) * p_s_discountFactor(s))
Topi Rasku's avatar
Topi Rasku committed
110
111
112
113
            );

    // Total unit startup costs
    r_uTotalStartupCost(unit)${ sum(starttype, unitStarttype(unit, starttype)) }
114
        = sum(ft_realizedNoReset(f,t)$[ord(t) > mSettings(m, 't_start') + mSettings(m, 't_initializationPeriod')],
Topi Rasku's avatar
Topi Rasku committed
115
            + r_uStartupCost(unit, f, t)
116
                * sum(msft_realizedNoReset(m, s, f, t), p_msProbability(m, s) * p_msWeight(m, s) * p_s_discountFactor(s))
Topi Rasku's avatar
Topi Rasku committed
117
118
119
120
            );

    // Total state variable slack costs
    r_gnTotalStateSlackCost(gn_stateSlack(grid, node))
121
        = sum(ft_realizedNoReset(f,t)$[ord(t) > mSettings(m, 't_start') + mSettings(m, 't_initializationPeriod')],
Topi Rasku's avatar
Topi Rasku committed
122
            + r_gnStateSlackCost(grid, node, f, t)
123
                * sum(msft_realizedNoReset(m, s, f, t), p_msProbability(m, s) * p_msWeight(m, s) * p_s_discountFactor(s))
Topi Rasku's avatar
Topi Rasku committed
124
125
            );

Niina Helistö's avatar
Niina Helistö committed
126
127
128
    // Fixed O&M costs
    r_gnuFOMCost(gnu(grid, node, unit))
        = 1e-6 // Scaling to MEUR
129
130
            * sum(ms(m, s)${ sum(msft_realizedNoReset(m, s, f, t_), 1) }, // consider ms only if it has active msft_realizedNoReset
                + [
131
                    + p_gnu(grid, node, unit, 'capacity')$sum(msft_realizedNoReset(m, s, f, t_), uft(unit, f, t_)) // Not in v_obj; only units active in msft_realizedNoReset
132
                    + r_invest(unit)$sum(msft_realizedNoReset(m, s, f, t_), uft(unit, f, t_)) // only units active in msft_realizedNoReset
133
                        * p_gnu(grid, node, unit, 'unitSize')
134
135
                    ]
                    * p_msAnnuityWeight(m, s) // Sample weighting to calculate annual costs
136
                    * p_s_discountFactor(s) // Discount costs
137
                ) // END * sum(ms)
Niina Helistö's avatar
Niina Helistö committed
138
139
140
141
142
            * p_gnu(grid, node, unit, 'fomCosts');

    // Unit investment costs
    r_gnuUnitInvestmentCost(gnu(grid, node, unit))
        = 1e-6 // Scaling to MEUR
143
            * sum(ms(m, s)${ sum(msft_realizedNoReset(m, s, f, t_), 1) }, // consider ms only if it has active msft_realizedNoReset
144
                + r_invest(unit)$sum(msft_realizedNoReset(m, s, f, t_), uft(unit, f, t_)) // only units active in msft_realizedNoReset
145
                    * p_msAnnuityWeight(m, s) // Sample weighting to calculate annual costs
146
                    * p_s_discountFactor(s) // Discount costs
147
                ) // END * sum(ms)
148
            * p_gnu(grid, node, unit, 'unitSize')
Niina Helistö's avatar
Niina Helistö committed
149
150
151
152
            * p_gnu(grid, node, unit, 'invCosts')
            * p_gnu(grid, node, unit, 'annuity');

    // Transfer link investment costs
153
    r_gnnLinkInvestmentCost(gn2n_directional(grid, from_node, to_node)) // gn2n_directional only, as in q_obj
Niina Helistö's avatar
Niina Helistö committed
154
        = 1e-6 // Scaling to MEUR
155
156
157
158
159
            * sum(ms(m, s)${ sum(msft_realizedNoReset(m, s, f, t_), 1) }, // consider ms only if it has active msft_realizedNoReset
                + sum(t_invest(t)${ord(t) <= msEnd(m, s)}, // only if investment was made before or during the sample
                    + r_investTransfer(grid, from_node, to_node, t)
                    )
                    * p_msAnnuityWeight(m, s) // Sample weighting to calculate annual costs
160
                    * p_s_discountFactor(s) // Discount costs
161
                ) // END * sum(ms)
Niina Helistö's avatar
Niina Helistö committed
162
163
164
165
166
167
168
            * [
                + p_gnn(grid, from_node, to_node, 'invCost')
                    * p_gnn(grid, from_node, to_node, 'annuity')
                + p_gnn(grid, to_node, from_node, 'invCost')
                    * p_gnn(grid, to_node, from_node, 'annuity')
                ]; // END * r_investTransfer;

169
170
* --- Realized Nodal System Costs ---------------------------------------------

Niina Helistö's avatar
Niina Helistö committed
171
    // Total realized gn operating costs
172
    r_gnRealizedOperatingCost(gn(grid, node), ft_realizedNoReset(f, t))$[ord(t) > mSettings(m, 't_start') + mSettings(m, 't_initializationPeriod')]
173
174
175
176
177
178
        = + sum(gnu(grid, node, unit),
              // VOM costs
              + r_gnuVOMCost(grid, node, unit, f, t)
            )
          // Allocate fuel and startup costs on energy basis, but for output nodes only
          + sum(unit$gnu(grid, node, unit),
179
180
181
182
183
184
              + [
                  + abs{r_gen(grid, node, unit, f, t)}  // abs is due to potential negative outputs like energy from a cooling unit. It's the energy contribution that matters, not direction.
                      / sum(gnu_output(grid_output, node_output, unit),
                          + abs{r_gen(grid_output, node_output, unit, f, t)}
                        ) // END sum(gnu_output)
                ]$(gnu_output(grid, node, unit) and abs{r_gen(grid, node, unit, f, t)} > eps)
185
186
187
188
189
190
191
192
                *
                {
                  + sum(un_commodity(unit, commodity), r_uFuelEmissionCost(commodity, unit, f, t))
                  + r_uStartupCost(unit, f, t)
                }
            )
          // Node state slack costs
          + r_gnStateSlackCost(grid, node, f, t);
193
194
195
196

* --- Realized Nodal Energy Consumption ---------------------------------------
// !!! NOTE !!! This is a bit of an approximation at the moment !!!!!!!!!!!!!!!

197
    r_gnConsumption(gn(grid, node), ft_realizedNoReset(f, t))$[ord(t) > mSettings(m, 't_start') + mSettings(m, 't_initializationPeriod')]
198
199
200
201
202
203
204
205
        = p_stepLengthNoReset(m, f, t)
            * [
                + min(ts_influx(grid, node, f, t), 0) // Not necessarily a good idea, as ts_influx contains energy gains as well...
                + sum(gnu_input(grid, node, unit),
                    + r_gen(grid, node, unit, f, t)
                    ) // END sum(gnu_input)
                ];

206
207
208
* --- Total Energy Generation -------------------------------------------------

    // Total energy generation
209
    r_gnuTotalGen(gnu_output(grid, node, unit))
210
        = sum(ft_realizedNoReset(f, t)$[ord(t) > mSettings(m, 't_start') + mSettings(m, 't_initializationPeriod')],
211
212
            + r_gen(grid, node, unit, f, t)
                * p_stepLengthNoReset(m, f, t)
213
                * sum(msft_realizedNoReset(m, s, f, t), p_msProbability(m, s) * p_msWeight(m, s))
214
            ); // END sum(ft_realizedNoReset)
215

216
217
218
219
220
221
222
223
224
    r_gen_gnUnittype(gn(grid, node), unittype)$sum(unit$unitUnittype(unit, unittype), 1)
      = sum(gnu(grid,node,unit)$unitUnittype(unit, unittype),
            sum(ft_realizedNoReset(f, t)$[ord(t) > mSettings(m, 't_start') + mSettings(m, 't_initializationPeriod')],
              + r_gen(grid, node, unit, f, t)
                  * p_stepLengthNoReset(m, f, t)
                  * sum(msft_realizedNoReset(m, s, f, t), p_msProbability(m, s) * p_msWeight(m, s))
            ) // END sum(ft_realizedNoReset)
        );

225
    // Energy generation by fuels
226
227
228
    r_genFuel(gn(grid, node), commodity, ft_realizedNoReset(f, t))$[    sum(gnu_input(grid_, node_, unit)$gnu_output(grid, node, unit), r_gen(grid_, node_, unit, f, t))
                                                                    and ord(t) > mSettings(m, 't_start') + mSettings(m, 't_initializationPeriod')]
        = sum(gnu_output(grid, node, unit)$sum(gnu_input(grid_, commodity, unit), 1),
229
            + r_gen(grid, node, unit, f, t)
230
231
232
233
234
235
236
237
238
          );
// The calculation with multiple inputs needs to be fixed below (right share for different commodities - now units with multiple input commodities will get the same amount allocated which will then be too big
//          * sum((grid_, unit)$gnu_output(grid, node, unit),
//                r_gen(grid_, commodity, unit, f, t))
//                  / sum(gnu_input(grid__, node_, unit), r_gen(grid__, node_, unit, f, t));

    r_genFuel(gn(grid, node), flow, ft_realizedNoReset(f, t))$flowNode(flow, node)
        = sum(gnu_output(grid, node, unit)$flowUnit(flow, unit),
            + r_gen(grid, node, unit, f, t));
239

Juha Kiviluoma's avatar
Juha Kiviluoma committed
240
    // Energy generation by fuels
241
242
243
244
    r_genUnittype(gn(grid, node), unittype, ft_realizedNoReset(f,t))
        ${  sum(unit,gnu_output(grid, node, unit))
            and [ord(t) > mSettings(m, 't_start') + mSettings(m, 't_initializationPeriod')]
            }
Juha Kiviluoma's avatar
Juha Kiviluoma committed
245
        = sum(unit${unitUnittype(unit, unittype) and gnu_output(grid, node, unit)},
246
            + r_gen(grid, node, unit, f, t)
Juha Kiviluoma's avatar
Juha Kiviluoma committed
247
248
            ); // END sum(unit)

249
    // Total generation on each node by fuels
250
    r_gnTotalGenFuel(gn(grid, node), commodity)
251
        = sum(ft_realizedNoReset(f, t)$[ord(t) > mSettings(m, 't_start') + mSettings(m, 't_initializationPeriod')],
252
            + r_genFuel(grid, node, commodity, f, t)
253
                * p_stepLengthNoReset(m, f, t)
254
                * sum(msft_realizedNoReset(m, s, f, t), p_msProbability(m, s) * p_msWeight(m, s))
255
            ); // END sum(ft_realizedNoReset)
256

257
258
    // Total dummy generation/consumption
    r_gnTotalqGen(inc_dec, gn(grid, node))
259
        = sum(ft_realizedNoReset(f,t)$[ord(t) > mSettings(m, 't_start') + mSettings(m, 't_initializationPeriod')],
260
261
            + r_qGen(inc_dec, grid, node, f, t)
                * p_stepLengthNoReset(m, f, t)
262
                * sum(msft_realizedNoReset(m, s, f, t), p_msProbability(m, s) * p_msWeight(m, s))
263
264
            ); // END sum(ft_realizedNoReset)

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
* --- Emission Results --------------------------------------------------------

    // Emissions of units (only for commodities, not including startup fuels)
    r_emissions(commodity, emission, unit, ft_realizedNoReset(f,t))$ {un_commodity(unit, commodity) and [ord(t) > mSettings(m, 't_start') + mSettings(m, 't_initializationPeriod')]}
        =   + p_stepLengthNoReset(m, f, t)
            * r_fuelUse(commodity, unit, f, t)
            * p_nEmission(commodity, emission)
            / 1e3 // NOTE!!! Conversion to t/MWh from kg/MWh in data
    ;


    // Emission sums
    r_nuTotalEmissions (commodity, unit, emission)
        = sum(ft_realizedNoReset(f, t)$[ord(t) > mSettings(m, 't_start') + mSettings(m, 't_initializationPeriod')],
            + r_emissions(commodity, emission, unit, f, t)
                 * sum(msft_realizedNoReset(m, s, f, t), p_msProbability(m, s) * p_msWeight(m, s))
            )
    ;

    r_nTotalEmissions(commodity, emission)
        = sum(unit, r_nuTotalEmissions (commodity, unit, emission))
    ;

    r_uTotalEmissions(unit, emission)
        = sum(commodity, r_nuTotalEmissions (commodity, unit, emission))
    ;

    r_totalEmissions (emission)
        = sum(commodity, r_nTotalEmissions(commodity, emission))
    ;

296
* --- Total Unit Online Results -----------------------------------------------
297

298
299
    // Total sub-unit-hours for units over the simulation
    r_uTotalOnline(unit)
300
        = sum(ft_realizedNoReset(f, t)$[ord(t) > mSettings(m, 't_start') + mSettings(m, 't_initializationPeriod')],
301
            + r_online(unit, f, t)
302
                * p_stepLengthNoReset(m, f, t)
303
                * sum(msft_realizedNoReset(m, s, f, t), p_msProbability(m, s) * p_msWeight(m, s))
304
            ); // END sum(ft_realizedNoReset)
305

306
    // Approximate utilization rates for gnus over the simulation
307
    r_gnuUtilizationRate(gnu_output(grid, node, unit))${ r_gnuTotalGen(grid, node, unit)
308
                                                         and ( p_gnu(grid, node, unit, 'capacity')
309
                                                               or r_invest(unit)
310
311
                                                               )
                                                         }
312
313
        = r_gnuTotalGen(grid, node, unit)
            / [
314
                + (p_gnu(grid, node, unit, 'capacity') + r_invest(unit)*p_gnu(grid, node, unit, 'unitSize'))
315
                    * (mSettings(m, 't_end') - (mSettings(m, 't_start') + mSettings(m, 't_initializationPeriod')) + 1)
316
                    * mSettings(m, 'stepLengthInHours')
317
318
319
320
                ]; // END division

* --- Total Reserve Provision -------------------------------------------------

321
    // Total reserve provisions over the simulation
322
    r_gnuTotalReserve(gnuRescapable(restype, up_down, grid, node, unit))
323
        = sum(ft_realizedNoReset(f, t)$[ord(t) > mSettings(m, 't_start') + mSettings(m, 't_initializationPeriod')],
324
            + r_reserve(restype, up_down, grid, node, unit, f, t)
325
                * p_stepLengthNoReset(m, f, t)
326
                * sum(msft_realizedNoReset(m, s, f, t), p_msProbability(m, s) * p_msWeight(m, s))
327
328
            ); // END sum(ft_realizedNoReset)

329
    // Total dummy reserve provisions over the simulation
330
    r_groupTotalqResDemand(restypeDirectionGroup(restype, up_down, group))
331
        = sum(ft_realizedNoReset(f, t)$[ord(t) > mSettings(m, 't_start') + mSettings(m, 't_initializationPeriod')],
332
            + r_qResDemand(restype, up_down, group, f, t)
333
                * p_stepLengthNoReset(m, f, t)
334
                * sum(msft_realizedNoReset(m, s, f, t), p_msProbability(m, s) * p_msWeight(m, s))
335
336
            ); // END sum(ft_realizedNoReset)

337
338
339
340
* --- Total Transfer and Spill ------------------------------------------------

    // Total transfer of energy between nodes
    r_gnnTotalTransfer(gn2n(grid, from_node, to_node))
341
        = sum(ft_realizedNoReset(f, t)$[ord(t) > mSettings(m, 't_start') + mSettings(m, 't_initializationPeriod')],
342
            + r_transfer(grid, from_node, to_node, f, t)
343
                * p_stepLengthNoReset(m, f, t)
344
                * sum(msft_realizedNoReset(m, s, f, t), p_msProbability(m, s) * p_msWeight(m, s))
345
346
            ); // END sum(ft_realizedNoReset)

347
348
    // Total energy spill from nodes
    r_gnTotalSpill(grid, node_spill(node))
349
        = sum(ft_realizedNoReset(f, t)$[ord(t) > mSettings(m, 't_start') + mSettings(m, 't_initializationPeriod')],
350
351
            + r_spill(grid, node, f, t)
                * p_stepLengthNoReset(m, f, t)
352
                * sum(msft_realizedNoReset(m, s, f, t), p_msProbability(m, s) * p_msWeight(m, s))
353
            ); // END sum(ft_realizedNoReset)
354

355
356
357
358
* =============================================================================
* --- Futher Time Step Independent Results ------------------------------------
* =============================================================================

359
* --- Scaling Marginal Values to EUR/MWh from MEUR/MWh ------------------------
360
361

// Energy balance
362
r_balanceMarginal(gn(grid, node), ft_realizedNoReset(f, t))$[ord(t) > mSettings(m, 't_start') + mSettings(m, 't_initializationPeriod')]
363
364
365
    = 1e6 * r_balanceMarginal(grid, node, f, t);

// Reserve balance
366
367
r_resDemandMarginal(restypeDirectionGroup(restype, up_down, group), ft_realizedNoReset(f, t))$[ord(t) > mSettings(m, 't_start') + mSettings(m, 't_initializationPeriod')]
    = 1e6 * r_resDemandMarginal(restype, up_down, group, f, t);
368

369
370
* --- Total Generation Results ------------------------------------------------

371
372
// Total generation in gn
r_gnTotalGen(gn(grid, node))
373
374
    = sum(gnu_output(grid, node, unit), r_gnuTotalGen(grid, node, unit));

375
376
377
// Total generation in g
r_gTotalGen(grid)
    = sum(gn(grid, node), r_gnTotalGen(grid, node));
378

379
// Total generation gnu/gn shares
380
r_gnuTotalGenShare(gnu_output(grid, node, unit))${ r_gnTotalGen(grid, node) > 0 }
381
382
383
384
    = r_gnuTotalGen(grid, node, unit)
        / r_gnTotalGen(grid, node);

// Total generation gn/g shares
385
r_gnTotalGenShare(gn(grid, node))${ r_gTotalGen(grid) > 0 }
386
387
388
    = r_gnTotalGen(grid, node)
        / r_gTotalGen(grid);

389
390
391
392
393
394
* --- Total Dummy Generation Results ------------------------------------------

// Total dummy generaion in g
r_gTotalqGen(inc_dec, grid)
    = sum(gn(grid, node), r_gnTotalqGen(inc_dec, grid, node));

395
396
* --- Total Energy Consumption Results ----------------------------------------

397
398
// Total consumption on each gn over the simulation
r_gnTotalConsumption(gn(grid, node))
399
    = sum(ft_realizedNoReset(f, t)$[ord(t) > mSettings(m, 't_start') + mSettings(m, 't_initializationPeriod')],
Niina Helistö's avatar
Niina Helistö committed
400
        + r_gnConsumption(grid, node, f ,t)
401
            * sum(msft_realizedNoReset(m, s, f, t), p_msProbability(m, s) * p_msWeight(m, s))
Niina Helistö's avatar
Niina Helistö committed
402
        );
403

404
405
406
// Total consumption in each grid over the simulation
r_gTotalConsumption(grid)
    = sum(gn(grid, node), r_gnTotalConsumption(grid, node));
407

408
// Total consumption gn/g share
409
r_gnTotalConsumptionShare(gn(grid, node))${ r_gTotalConsumption(grid) > 0 }
410
411
412
413
414
    = r_gnTotalConsumption(grid, node)
        / r_gTotalConsumption(grid);

* --- Total Fuel Consumption Results ------------------------------------------

415
// Total fuel consumption in grids over the simulation
416
417
r_gTotalGenFuel(grid, commodity)
    = sum(gn(grid, node), r_gnTotalGenFuel(grid, node, commodity));
418

419
// Total fuel consumption over the simulation
420
421
r_totalGenFuel(commodity)
    = sum(gn(grid, node), r_gnTotalGenFuel(grid, node, commodity));
422

423
// Total fuel consumption gn/g shares
424
425
r_gnTotalGenFuelShare(gn(grid, node), commodity)${ r_gnTotalGen(grid, node) }
    = r_gnTotalGenFuel(grid, node, commodity)
426
        / r_gnTotalGen(grid, node);
427
428
429

* --- Total Spilled Energy Results --------------------------------------------

430
431
432
// Total spilled energy in each grid over the simulation
r_gTotalSpill(grid)
    = sum(gn(grid, node_spill(node)), r_gnTotalSpill(grid, node));
433

434
// Total spilled energy gn/g share
435
r_gnTotalSpillShare(gn(grid, node_spill))${ r_gTotalSpill(grid) > 0 }
436
437
438
    = r_gnTotalSpill(grid, node_spill)
        / r_gTotalSpill(grid);

439
* --- Total Costs Results (discounted) ----------------------------------------
440

Niina Helistö's avatar
Niina Helistö committed
441
442
// Total realized operating costs on each gn over the simulation
r_gnTotalRealizedOperatingCost(gn(grid, node))
443
    = sum(ft_realizedNoReset(f, t)$[ord(t) > mSettings(m, 't_start') + mSettings(m, 't_initializationPeriod')],
Niina Helistö's avatar
Niina Helistö committed
444
        + r_gnRealizedOperatingCost(grid, node, f ,t)
445
            * sum(msft_realizedNoReset(m, s, f, t), p_msProbability(m, s) * p_msWeight(m, s) * p_s_discountFactor(s))
Niina Helistö's avatar
Niina Helistö committed
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
        );

// Total realized net operating costs on each gn over the simulation
r_gnTotalRealizedNetOperatingCost(gn(grid, node))
    = r_gnTotalRealizedOperatingCost(grid, node) - r_gnStorageValueChange(grid, node);

// Total realized operating costs on each grid over the simulation
r_gTotalRealizedOperatingCost(grid)
    = sum(gn(grid, node), r_gnTotalRealizedOperatingCost(grid, node));

// Total realized net operating costs on each grid over the simulation
r_gTotalRealizedNetOperatingCost(grid)
    = sum(gn(grid, node), r_gnTotalRealizedNetOperatingCost(grid, node));

// Total realized operating costs gn/g share
461
r_gnTotalRealizedOperatingCostShare(gn(grid, node))${ r_gTotalRealizedOperatingCost(grid) > 0 }
Niina Helistö's avatar
Niina Helistö committed
462
463
464
465
466
467
468
469
470
471
472
    = r_gnTotalRealizedOperatingCost(grid, node)
        / r_gTotalRealizedOperatingCost(grid);

// Total realized operating costs over the simulation
r_totalRealizedOperatingCost
    = sum(gn(grid, node), r_gnTotalRealizedOperatingCost(grid, node));

// Total realized net operating costs over the simulation
r_totalRealizedNetOperatingCost
    = sum(gn(grid, node), r_gnTotalRealizedNetOperatingCost(grid, node));

473
474
// Total realized costs on each gn over the simulation
r_gnTotalRealizedCost(gn(grid, node))
Niina Helistö's avatar
Niina Helistö committed
475
476
477
478
479
480
481
    = r_gnTotalRealizedOperatingCost(grid, node)
        + sum(gnu(grid, node, unit),
            + r_gnuFOMCost(grid, node, unit)
            + r_gnuUnitInvestmentCost(grid, node, unit)
            )
        + sum(gn2n_directional(grid, from_node, node),
            + r_gnnLinkInvestmentCost(grid, from_node, node)
482
                / 2 // Half of the link costs are allocated to the receiving end
Niina Helistö's avatar
Niina Helistö committed
483
484
485
            )
        + sum(gn2n_directional(grid, node, to_node),
            + r_gnnLinkInvestmentCost(grid, node, to_node)
486
                / 2 // Half of the link costs are allocated to the sending end
Niina Helistö's avatar
Niina Helistö committed
487
            );
488

489
490
491
492
// Total realized net costs on each gn over the simulation
r_gnTotalRealizedNetCost(gn(grid, node))
    = r_gnTotalRealizedCost(grid, node) - r_gnStorageValueChange(grid, node);

493
494
495
// Total realized costs on each grid over the simulation
r_gTotalRealizedCost(grid)
    = sum(gn(grid, node), r_gnTotalRealizedCost(grid, node));
496

497
498
499
500
// Total realized net costs on each grid over the simulation
r_gTotalRealizedNetCost(grid)
    = sum(gn(grid, node), r_gnTotalRealizedNetCost(grid, node));

501
// Total realized costs gn/g share
502
r_gnTotalRealizedCostShare(gn(grid, node))${ r_gTotalRealizedCost(grid) > 0 }
503
504
505
    = r_gnTotalRealizedCost(grid, node)
        / r_gTotalRealizedCost(grid);

506
507
// Total realized costs over the simulation
r_totalRealizedCost
508
    = sum(gn(grid, node), r_gnTotalRealizedCost(grid, node));
509

Niina Helistö's avatar
Niina Helistö committed
510
// Total realized net operating costs over the simulation
511
512
513
r_totalRealizedNetCost
    = sum(gn(grid, node), r_gnTotalRealizedNetCost(grid, node));

514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
// Total realized fixed costs on each gn over the simulation
r_gnTotalRealizedFixedCost(gn(grid, node))
    = r_gnTotalRealizedCost(grid, node)
        - r_gnTotalRealizedOperatingCost(grid, node);

// Total realized fixed costs on each grid over the simulation
r_gTotalRealizedFixedCost(grid)
    = r_gTotalRealizedCost(grid)
        - r_gTotalRealizedOperatingCost(grid);

// Total realized fixed costs gn/g share
r_gnTotalRealizedFixedCostShare(gn(grid, node))${ r_gTotalRealizedFixedCost(grid) > 0 }
    = r_gnTotalRealizedFixedCost(grid, node)
        / r_gTotalRealizedFixedCost(grid);

// Total realized fixed costs over the simulation
r_totalRealizedFixedCost
    = r_totalRealizedCost
        - r_totalRealizedOperatingCost;

534
535
536
* --- Reserve Provision Overlap Results ---------------------------------------

// Calculate the overlapping reserve provisions
537
538
539
540
r_reserve2Reserve(gnuRescapable(restype, up_down, grid, node, unit), restype_, ft_realizedNoReset(f, t))
    ${ p_gnuRes2Res(grid, node, unit, restype, up_down, restype_) }
    = r_reserve(restype, up_down, grid, node, unit, f, t)
        * p_gnuRes2Res(grid, node, unit, restype, up_down, restype_);
541

542
543
* --- Total Reserve Provision Results -----------------------------------------

544
545
546
547
548
// Total reserve provision in groups over the simulation
r_groupTotalReserve(restypeDirectionGroup(restype, up_down, group))
    = sum(gnuRescapable(restype, up_down, grid, node, unit)${gnGroup(grid, node, group)},
        + r_gnuTotalReserve(restype, up_down, grid, node, unit)
    ); // END sum(gnuRescapable)
549

550
551
552
553
r_gnuTotalReserveShare(gnuRescapable(restype, up_down, grid, node, unit))
    ${ sum(gnGroup(grid, node, group), r_groupTotalReserve(restype, up_down, group)) > 0 }
    = r_gnuTotalReserve(restype, up_down, grid, node, unit)
        / sum(gnGroup(grid, node, group), r_groupTotalReserve(restype, up_down, group));
554
555
556

* --- Total Unit Online State Results -----------------------------------------

557
// Total unit online hours per sub-unit over the simulation
558
r_uTotalOnlinePerUnit(unit)${ p_unit(unit, 'unitCount') > 0 }
559
560
561
    = r_uTotalOnline(unit)
        / p_unit(unit, 'unitCount');

562
563
// Total sub-unit startups over the simulation
r_uTotalStartup(unit, starttype)
564
    = sum(ft_realizedNoReset(f, t)$[ord(t) > mSettings(m, 't_start') + mSettings(m, 't_initializationPeriod')],
565
        + r_startup(unit, starttype, f, t)
566
            * sum(msft_realizedNoReset(m, s, f, t), p_msProbability(m, s) * p_msWeight(m, s))
567
568
569
570
        ); // END sum(ft_realizedNoReset)

// Total sub-unit shutdowns over the simulation
r_uTotalShutdown(unit)
571
    = sum(ft_realizedNoReset(f, t)$[ord(t) > mSettings(m, 't_start') + mSettings(m, 't_initializationPeriod')],
572
        + r_shutdown(unit, f, t)
573
            * sum(msft_realizedNoReset(m, s, f, t), p_msProbability(m, s) * p_msWeight(m, s))
574
575
        ); // END sum(ft_realizedNoReset)

576
577
* --- Diagnostic Results ------------------------------------------------------

578
// Only include these if '--diag=yes' given as a command line argument
579
$iftheni.diag '%diag%' == yes
580
// Estimated coefficients of performance
581
582
583
d_cop(unit, ft_realizedNoReset(f, t))${  [ord(t) > mSettings(m, 't_start') + mSettings(m, 't_initializationPeriod')]
                                         and sum(gnu_input(grid, node, unit), 1)
                                         }
584
585
586
587
588
589
590
    = sum(gnu_output(grid, node, unit),
        + r_gen(grid, node, unit, f, t)
        ) // END sum(gnu_output)
        / [ sum(gnu_input(grid_, node_, unit),
                -r_gen(grid_, node_, unit, f, t)
                ) // END sum(gnu_input)
            + 1${not sum(gnu_input(grid_, node_, unit), -r_gen(grid_, node_, unit, f, t))}
591
592
            ]
        + Eps; // Eps to correct GAMS plotting (zeroes are not skipped)
593
594

// Estimated efficiency
595
d_eff(unit_commodity(unit), ft_realizedNoReset(f, t))$[ord(t) > mSettings(m, 't_start') + mSettings(m, 't_initializationPeriod')]
596
597
598
599
600
601
602
    = sum(gnu_output(grid, node, unit),
        + r_gen(grid, node, unit, f, t)
        ) // END sum(gnu_output)
        / [ sum(uFuel(unit, 'main', fuel),
                + r_fuelUse(fuel, unit, f, t)
                ) // END sum(uFuel)
            + 1${not sum(uFuel(unit, 'main', fuel), r_fuelUse(fuel, unit, f, t))}
603
604
            ]
        + Eps; // Eps to correct GAMS plotting (zeroes are not skipped)
605
$endif.diag
606

607
); // END loop(m)
608