4b_outputInvariant.gms 30 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
20
21

// for performance, get rid of any zeros in r_gen (r_gen was already missing many zero values anyway)
r_gen(gnu, f, t)$((r_gen(gnu, f, t)=0)$r_gen(gnu, f, t))=0;

22
* =============================================================================
23
* --- Time Step Dependent Results ---------------------------------------------
24
* =============================================================================
25

26
27
// Need to loop over the model dimension, as this file is no longer contained in the modelSolves loop...
loop(m,
28

29
    option clear=startp; startp(t)$(ord(t) > mSettings(m, 't_start') + mSettings(m, 't_initializationPeriod'))=yes;
Topi Rasku's avatar
Topi Rasku committed
30
31
32
* --- Realized Individual Costs ----------------------------------------------

    // Variable O&M costs
33
    r_gnuVOMCost(gnu(grid, node, unit), ft_realizedNoReset(f,startp(t)))
Topi Rasku's avatar
Topi Rasku committed
34
35
        = 1e-6 // Scaling to MEUR
            * p_stepLengthNoReset(m, f, t)
36
            * abs(r_gen(grid, node, unit, f, t))
37
            * p_gnu(grid, node, unit, 'vomCosts');
Topi Rasku's avatar
Topi Rasku committed
38
39

    // Fuel and emission costs during normal operation
40
    r_uFuelEmissionCost(commodity, unit_commodity(unit), ft_realizedNoReset(f,startp(t)))$un_commodity(unit, commodity)
Topi Rasku's avatar
Topi Rasku committed
41
42
        = 1e-6 // Scaling to MEUR
            * p_stepLengthNoReset(m, f, t)
43
            * r_fuelUse(commodity, unit, f, t)
44
45
            * [ + p_price(commodity, 'price')$p_price(commodity, 'useConstant')
                + ts_price(commodity, t)$p_price(commodity, 'useTimeSeries')
Topi Rasku's avatar
Topi Rasku committed
46
                // Emission costs
47
48
                + sum(emission, p_unitEmissionCost(unit, commodity, emission))
              ];
Topi Rasku's avatar
Topi Rasku committed
49
50

    // Unit startup costs
51
    r_uStartupCost(unit, ft_realizedNoReset(f,startp(t)))$sum(starttype, unitStarttype(unit, starttype))
Topi Rasku's avatar
Topi Rasku committed
52
53
54
        = 1e-6 // Scaling to MEUR
            * sum(unitStarttype(unit, starttype),
                + r_startup(unit, starttype, f, t)
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
                    * [
                        + 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
70
              ); // END sum(starttype)
Topi Rasku's avatar
Topi Rasku committed
71

72
    //Variable Trnasfer Costs
73
    r_gnnVariableTransCost(gn2n_directional(grid, node_, node), ft_realizedNoReset(f,startp(t)))
74
75
        = 1e-6 // Scaling to MEUR
            * p_stepLengthNoReset(m, f, t)
76
                    *[+ p_gnn(grid, node, node_, 'variableTransCost')
77
                    * r_transferLeftward(grid, node_, node, f, t)
78
                    + p_gnn(grid, node_, node, 'variableTransCost')
79
80
                    * r_transferRightward(grid, node_, node, f, t)];

81
82
83
84
85
86
87
88
   // Transfer marginal value (Me) calculated from r_transfer * balanceMarginal
   r_gnnTransferMarginalValue(gn2n_directional(grid, node_, node), ft_realizedNoReset(f,startp(t)))
        = 1e-6 // Scaling to MEUR
            * p_stepLengthNoReset(m, f, t)
            * r_transfer(grid, node_, node, f, t)
            * r_balanceMarginal(grid, node, f, t)
    ;

Topi Rasku's avatar
Topi Rasku committed
89
    // Node state slack costs
90
    r_gnStateSlackCost(gn_stateSlack(grid, node), ft_realizedNoReset(f,startp(t)))
Topi Rasku's avatar
Topi Rasku committed
91
92
93
94
95
96
97
98
        = 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
99
    r_gnStorageValueChange(gn_state(grid, node))${ active(m, 'storageValue') }
Topi Rasku's avatar
Topi Rasku committed
100
101
102
        = 1e-6
            * [
                + sum(ft_realizedNoReset(f,t)${ ord(t) = mSettings(m, 't_end') + 1 },
103
                    + [
Topi Rasku's avatar
Topi Rasku committed
104
                        + p_storageValue(grid, node)${ not p_gn(grid, node, 'storageValueUseTimeSeries') }
105
106
                        + ts_storageValue(grid, node, f, t)${ p_gn(grid, node, 'storageValueUseTimeSeries') }
                      ]
Topi Rasku's avatar
Topi Rasku committed
107
108
                        * r_state(grid, node, f, t)
                    ) // END sum(ft_realizedNoReset)
109
                - sum(ft_realizedNoReset(f,t)${ ord(t) = mSettings(m, 't_start') + mSettings(m, 't_initializationPeriod') }, // INITIAL v_state NOW INCLUDED IN THE RESULTS
110
                    + [
Topi Rasku's avatar
Topi Rasku committed
111
                        + p_storageValue(grid, node)${ not p_gn(grid, node, 'storageValueUseTimeSeries') }
112
113
                        + ts_storageValue(grid, node, f, t)${ p_gn(grid, node, 'storageValueUseTimeSeries') }
                      ]
Topi Rasku's avatar
Topi Rasku committed
114
115
116
117
                        * r_state(grid, node, f, t)
                    ) // END sum(ft_realizedNoReset)
                ]; // END * 1e-6

118
* --- Total Cost Components (discounted) --------------------------------------
Topi Rasku's avatar
Topi Rasku committed
119
120
121

    // Total VOM costs
    r_gnuTotalVOMCost(gnu_output(grid, node, unit))
122
        = sum(ft_realizedNoReset(f,startp(t)),
Topi Rasku's avatar
Topi Rasku committed
123
            + r_gnuVOMCost(grid, node, unit, f, t)
124
                * 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
125
126
            );

127
128
    // Total Variable Transfer costs
    r_gnnTotalVariableTransCost(gn2n_directional(grid, node_, node))
129
        = sum(ft_realizedNoReset(f,startp(t)),
130
            + r_gnnVariableTransCost(grid, node_, node, f, t)
131
132
133
                * sum(msft_realizedNoReset(m, s, f, t), p_msProbability(m, s) * p_msWeight(m, s) * p_s_discountFactor(s))
            );

134
135
136
137
138
139
140
141
    // Total transfer marginal value over the simulation
    r_gnnTotalTransferMarginalValue(gn2n_directional(grid, node_, node))
        = sum(ft_realizedNoReset(f,startp(t)),
            + r_gnnTransferMarginalValue(grid, node_, node, f, t)
                * 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
142
    // Total fuel & emission costs
143
    r_uTotalFuelEmissionCost(commodity, unit)$un_commodity(unit, commodity)
144
        = sum(ft_realizedNoReset(f,startp(t)),
145
            + r_uFuelEmissionCost(commodity, unit, f, t)
146
                * 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
147
148
149
            );

    // Total unit startup costs
150
151
    r_uTotalStartupCost(unit)$sum(starttype, unitStarttype(unit, starttype))
        = sum(ft_realizedNoReset(f,startp(t)),
Topi Rasku's avatar
Topi Rasku committed
152
            + r_uStartupCost(unit, f, t)
153
                * 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
154
155
156
157
            );

    // Total state variable slack costs
    r_gnTotalStateSlackCost(gn_stateSlack(grid, node))
158
        = sum(ft_realizedNoReset(f,startp(t)),
Topi Rasku's avatar
Topi Rasku committed
159
            + r_gnStateSlackCost(grid, node, f, t)
160
                * 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
161
162
            );

Niina Helistö's avatar
Niina Helistö committed
163
164
165
    // Fixed O&M costs
    r_gnuFOMCost(gnu(grid, node, unit))
        = 1e-6 // Scaling to MEUR
166
167
            * sum(ms(m, s)${ sum(msft_realizedNoReset(m, s, f, t_), 1) }, // consider ms only if it has active msft_realizedNoReset
                + [
168
                    + 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
169
                    + r_invest(unit)$sum(msft_realizedNoReset(m, s, f, t_), uft(unit, f, t_)) // only units active in msft_realizedNoReset
170
                        * p_gnu(grid, node, unit, 'unitSize')
171
172
                    ]
                    * p_msAnnuityWeight(m, s) // Sample weighting to calculate annual costs
173
                    * p_s_discountFactor(s) // Discount costs
174
                ) // END * sum(ms)
Niina Helistö's avatar
Niina Helistö committed
175
176
177
178
179
            * p_gnu(grid, node, unit, 'fomCosts');

    // Unit investment costs
    r_gnuUnitInvestmentCost(gnu(grid, node, unit))
        = 1e-6 // Scaling to MEUR
180
            * sum(ms(m, s)${ sum(msft_realizedNoReset(m, s, f, t_), 1) }, // consider ms only if it has active msft_realizedNoReset
181
                + r_invest(unit)$sum(msft_realizedNoReset(m, s, f, t_), uft(unit, f, t_)) // only units active in msft_realizedNoReset
182
                    * p_msAnnuityWeight(m, s) // Sample weighting to calculate annual costs
183
                    * p_s_discountFactor(s) // Discount costs
184
                ) // END * sum(ms)
185
            * p_gnu(grid, node, unit, 'unitSize')
Niina Helistö's avatar
Niina Helistö committed
186
187
188
189
            * p_gnu(grid, node, unit, 'invCosts')
            * p_gnu(grid, node, unit, 'annuity');

    // Transfer link investment costs
190
    r_gnnLinkInvestmentCost(gn2n_directional(grid, from_node, to_node)) // gn2n_directional only, as in q_obj
Niina Helistö's avatar
Niina Helistö committed
191
        = 1e-6 // Scaling to MEUR
192
193
194
195
196
            * 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
197
                    * p_s_discountFactor(s) // Discount costs
198
                ) // END * sum(ms)
Niina Helistö's avatar
Niina Helistö committed
199
200
201
202
203
204
205
            * [
                + 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;

206
207
* --- Realized Nodal System Costs ---------------------------------------------

Niina Helistö's avatar
Niina Helistö committed
208
    // Total realized gn operating costs
209
    r_gnRealizedOperatingCost(gn(grid, node), ft_realizedNoReset(f, startp(t)))
210
211
212
213
214
        = + 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
215
216
217
218
219
          + sum(unit$(r_gen(grid, node, unit, f, t)$gnu_output(grid, node, unit)),
              + 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)
220
221
222
223
224
225
                *
                {
                  + sum(un_commodity(unit, commodity), r_uFuelEmissionCost(commodity, unit, f, t))
                  + r_uStartupCost(unit, f, t)
                }
            )
226
          + sum(gn2n_directional(grid, node_, node),
227
228
              // Variable Transfer costs
              + r_gnnVariableTransCost(grid, node_, node, f, t)
229
            )
230
231
          // Node state slack costs
          + r_gnStateSlackCost(grid, node, f, t);
232
233
234
235

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

236
    r_gnConsumption(gn(grid, node), ft_realizedNoReset(f, startp(t)))
237
238
239
240
241
242
243
244
        = 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)
                ];

245
246
247
* --- Total Energy Generation -------------------------------------------------

    // Total energy generation
248
    r_gnuTotalGen(gnu_output(grid, node, unit))
249
        = sum(ft_realizedNoReset(f, startp(t)),
250
251
            + r_gen(grid, node, unit, f, t)
                * p_stepLengthNoReset(m, f, t)
252
                * sum(msft_realizedNoReset(m, s, f, t), p_msProbability(m, s) * p_msWeight(m, s))
253
            ); // END sum(ft_realizedNoReset)
254

255
256
    r_gen_gnUnittype(gn(grid, node), unittype)$sum(unit$unitUnittype(unit, unittype), 1)
      = sum(gnu(grid,node,unit)$unitUnittype(unit, unittype),
257
            sum(ft_realizedNoReset(f, startp(t)),
258
259
260
261
262
263
              + 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)
        );

264
    // Energy generation by fuels
265
    r_genFuel(gn(grid, node), commodity, ft_realizedNoReset(f, startp(t)))$sum(gnu_input(grid_, commodity, unit)$gnu_output(grid, node, unit),r_gen(grid_, commodity, unit, f, t))
266
        = sum(gnu_output(grid, node, unit)$sum(gnu_input(grid_, commodity, unit), 1),
267
            + r_gen(grid, node, unit, f, t)
268
269
270
271
272
273
274
275
276
          );
// 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));
277

Juha Kiviluoma's avatar
Juha Kiviluoma committed
278
    // Energy generation by fuels
279
280
    r_genUnittype(gn(grid, node), unittype, ft_realizedNoReset(f,startp(t)))
        = sum(gnu_output(grid, node, unit)$unitUnittype(unit, unittype),
281
            + r_gen(grid, node, unit, f, t)
Juha Kiviluoma's avatar
Juha Kiviluoma committed
282
283
            ); // END sum(unit)

284
    // Total generation on each node by fuels
285
    r_gnTotalGenFuel(gn(grid, node), commodity)
286
        = sum(ft_realizedNoReset(f, startp(t)),
287
            + r_genFuel(grid, node, commodity, f, t)
288
                * p_stepLengthNoReset(m, f, t)
289
                * sum(msft_realizedNoReset(m, s, f, t), p_msProbability(m, s) * p_msWeight(m, s))
290
            ); // END sum(ft_realizedNoReset)
291

292
293
    // Total dummy generation/consumption
    r_gnTotalqGen(inc_dec, gn(grid, node))
294
        = sum(ft_realizedNoReset(f,startp(t)),
295
296
            + r_qGen(inc_dec, grid, node, f, t)
                * p_stepLengthNoReset(m, f, t)
297
                * sum(msft_realizedNoReset(m, s, f, t), p_msProbability(m, s) * p_msWeight(m, s))
298
299
            ); // END sum(ft_realizedNoReset)

300
301
302
* --- Emission Results --------------------------------------------------------

    // Emissions of units (only for commodities, not including startup fuels)
303
    r_emissions(commodity, emission, unit, ft_realizedNoReset(f,startp(t)))$un_commodity(unit, commodity)
304
305
306
307
308
309
310
311
312
        =   + 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)
313
        = sum(ft_realizedNoReset(f, startp(t)),
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
            + 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))
    ;

331
* --- Total Unit Online Results -----------------------------------------------
332

333
334
    // Total sub-unit-hours for units over the simulation
    r_uTotalOnline(unit)
335
        = sum(ft_realizedNoReset(f, startp(t)),
336
            + r_online(unit, f, t)
337
                * p_stepLengthNoReset(m, f, t)
338
                * sum(msft_realizedNoReset(m, s, f, t), p_msProbability(m, s) * p_msWeight(m, s))
339
            ); // END sum(ft_realizedNoReset)
340

341
    // Approximate utilization rates for gnus over the simulation
342
    r_gnuUtilizationRate(gnu_output(grid, node, unit))${ r_gnuTotalGen(grid, node, unit)
343
                                                         and ( p_gnu(grid, node, unit, 'capacity')
344
                                                               or r_invest(unit)
345
346
                                                               )
                                                         }
347
348
        = r_gnuTotalGen(grid, node, unit)
            / [
349
                + (p_gnu(grid, node, unit, 'capacity') + r_invest(unit)*p_gnu(grid, node, unit, 'unitSize'))
350
                    * (mSettings(m, 't_end') - (mSettings(m, 't_start') + mSettings(m, 't_initializationPeriod')) + 1)
351
                    * mSettings(m, 'stepLengthInHours')
352
353
354
355
                ]; // END division

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

356
    // Total reserve provisions over the simulation
357
    r_gnuTotalReserve(gnuRescapable(restype, up_down, grid, node, unit))
358
        = sum(ft_realizedNoReset(f, startp(t)),
359
            + r_reserve(restype, up_down, grid, node, unit, f, t)
360
                * p_stepLengthNoReset(m, f, t)
361
                * sum(msft_realizedNoReset(m, s, f, t), p_msProbability(m, s) * p_msWeight(m, s))
362
363
            ); // END sum(ft_realizedNoReset)

364
    // Total dummy reserve provisions over the simulation
365
    r_groupTotalqResDemand(restypeDirectionGroup(restype, up_down, group))
366
        = sum(ft_realizedNoReset(f, startp(t)),
367
            + r_qResDemand(restype, up_down, group, f, t)
368
                * p_stepLengthNoReset(m, f, t)
369
                * sum(msft_realizedNoReset(m, s, f, t), p_msProbability(m, s) * p_msWeight(m, s))
370
371
            ); // END sum(ft_realizedNoReset)

372
373
374
375
* --- Total Transfer and Spill ------------------------------------------------

    // Total transfer of energy between nodes
    r_gnnTotalTransfer(gn2n(grid, from_node, to_node))
376
        = sum(ft_realizedNoReset(f, startp(t)),
377
            + r_transfer(grid, from_node, to_node, f, t)
378
                * p_stepLengthNoReset(m, f, t)
379
                * sum(msft_realizedNoReset(m, s, f, t), p_msProbability(m, s) * p_msWeight(m, s))
380
381
            ); // END sum(ft_realizedNoReset)

382
383
    // Total energy spill from nodes
    r_gnTotalSpill(grid, node_spill(node))
384
        = sum(ft_realizedNoReset(f, startp(t)),
385
386
            + r_spill(grid, node, f, t)
                * p_stepLengthNoReset(m, f, t)
387
                * sum(msft_realizedNoReset(m, s, f, t), p_msProbability(m, s) * p_msWeight(m, s))
388
            ); // END sum(ft_realizedNoReset)
389

390
391
392
393
* =============================================================================
* --- Futher Time Step Independent Results ------------------------------------
* =============================================================================

394
* --- Scaling Marginal Values to EUR/MWh from MEUR/MWh ------------------------
395
396

// Energy balance
397
r_balanceMarginal(gn(grid, node), ft_realizedNoReset(f, startp(t)))
398
399
400
    = 1e6 * r_balanceMarginal(grid, node, f, t);

// Reserve balance
401
r_resDemandMarginal(restypeDirectionGroup(restype, up_down, group), ft_realizedNoReset(f, startp(t)))
402
    = 1e6 * r_resDemandMarginal(restype, up_down, group, f, t);
403

404
405
* --- Total Generation Results ------------------------------------------------

406
407
// Total generation in gn
r_gnTotalGen(gn(grid, node))
408
409
    = sum(gnu_output(grid, node, unit), r_gnuTotalGen(grid, node, unit));

410
411
412
// Total generation in g
r_gTotalGen(grid)
    = sum(gn(grid, node), r_gnTotalGen(grid, node));
413

414
// Total generation gnu/gn shares
415
r_gnuTotalGenShare(gnu_output(grid, node, unit))${ r_gnTotalGen(grid, node) > 0 }
416
417
418
419
    = r_gnuTotalGen(grid, node, unit)
        / r_gnTotalGen(grid, node);

// Total generation gn/g shares
420
r_gnTotalGenShare(gn(grid, node))${ r_gTotalGen(grid) > 0 }
421
422
423
    = r_gnTotalGen(grid, node)
        / r_gTotalGen(grid);

424
425
426
427
428
429
* --- Total Dummy Generation Results ------------------------------------------

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

430
431
* --- Total Energy Consumption Results ----------------------------------------

432
433
// Total consumption on each gn over the simulation
r_gnTotalConsumption(gn(grid, node))
434
    = sum(ft_realizedNoReset(f, startp(t)),
Niina Helistö's avatar
Niina Helistö committed
435
        + r_gnConsumption(grid, node, f ,t)
436
            * sum(msft_realizedNoReset(m, s, f, t), p_msProbability(m, s) * p_msWeight(m, s))
Niina Helistö's avatar
Niina Helistö committed
437
        );
438

439
440
441
// Total consumption in each grid over the simulation
r_gTotalConsumption(grid)
    = sum(gn(grid, node), r_gnTotalConsumption(grid, node));
442

443
// Total consumption gn/g share
444
r_gnTotalConsumptionShare(gn(grid, node))${ r_gTotalConsumption(grid) > 0 }
445
446
447
448
449
    = r_gnTotalConsumption(grid, node)
        / r_gTotalConsumption(grid);

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

450
// Total fuel consumption in grids over the simulation
451
452
r_gTotalGenFuel(grid, commodity)
    = sum(gn(grid, node), r_gnTotalGenFuel(grid, node, commodity));
453

454
// Total fuel consumption over the simulation
455
456
r_totalGenFuel(commodity)
    = sum(gn(grid, node), r_gnTotalGenFuel(grid, node, commodity));
457

458
// Total fuel consumption gn/g shares
459
460
r_gnTotalGenFuelShare(gn(grid, node), commodity)${ r_gnTotalGen(grid, node) }
    = r_gnTotalGenFuel(grid, node, commodity)
461
        / r_gnTotalGen(grid, node);
462
463
464

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

465
466
467
// Total spilled energy in each grid over the simulation
r_gTotalSpill(grid)
    = sum(gn(grid, node_spill(node)), r_gnTotalSpill(grid, node));
468

469
// Total spilled energy gn/g share
470
r_gnTotalSpillShare(gn(grid, node_spill))${ r_gTotalSpill(grid) > 0 }
471
472
473
    = r_gnTotalSpill(grid, node_spill)
        / r_gTotalSpill(grid);

474
* --- Total Costs Results (discounted) ----------------------------------------
475

Niina Helistö's avatar
Niina Helistö committed
476
477
// Total realized operating costs on each gn over the simulation
r_gnTotalRealizedOperatingCost(gn(grid, node))
478
    = sum(ft_realizedNoReset(f, startp(t)),
Niina Helistö's avatar
Niina Helistö committed
479
        + r_gnRealizedOperatingCost(grid, node, f ,t)
480
            * 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
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
        );

// 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
496
r_gnTotalRealizedOperatingCostShare(gn(grid, node))${ r_gTotalRealizedOperatingCost(grid) > 0 }
Niina Helistö's avatar
Niina Helistö committed
497
498
499
500
501
502
503
504
505
506
507
    = 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));

508
509
// Total realized costs on each gn over the simulation
r_gnTotalRealizedCost(gn(grid, node))
Niina Helistö's avatar
Niina Helistö committed
510
511
512
513
514
515
516
    = 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)
517
                / 2 // Half of the link costs are allocated to the receiving end
Niina Helistö's avatar
Niina Helistö committed
518
519
520
            )
        + sum(gn2n_directional(grid, node, to_node),
            + r_gnnLinkInvestmentCost(grid, node, to_node)
521
                / 2 // Half of the link costs are allocated to the sending end
Niina Helistö's avatar
Niina Helistö committed
522
            );
523

524
525
526
527
// Total realized net costs on each gn over the simulation
r_gnTotalRealizedNetCost(gn(grid, node))
    = r_gnTotalRealizedCost(grid, node) - r_gnStorageValueChange(grid, node);

528
529
530
// Total realized costs on each grid over the simulation
r_gTotalRealizedCost(grid)
    = sum(gn(grid, node), r_gnTotalRealizedCost(grid, node));
531

532
533
534
535
// Total realized net costs on each grid over the simulation
r_gTotalRealizedNetCost(grid)
    = sum(gn(grid, node), r_gnTotalRealizedNetCost(grid, node));

536
// Total realized costs gn/g share
537
r_gnTotalRealizedCostShare(gn(grid, node))${ r_gTotalRealizedCost(grid) > 0 }
538
539
540
    = r_gnTotalRealizedCost(grid, node)
        / r_gTotalRealizedCost(grid);

541
542
// Total realized costs over the simulation
r_totalRealizedCost
543
    = sum(gn(grid, node), r_gnTotalRealizedCost(grid, node));
544

Niina Helistö's avatar
Niina Helistö committed
545
// Total realized net operating costs over the simulation
546
547
548
r_totalRealizedNetCost
    = sum(gn(grid, node), r_gnTotalRealizedNetCost(grid, node));

549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
// 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;

569
570
571
* --- Reserve Provision Overlap Results ---------------------------------------

// Calculate the overlapping reserve provisions
572
573
574
575
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_);
576

577
578
* --- Total Reserve Provision Results -----------------------------------------

579
580
581
582
583
// 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)
584

585
586
587
588
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));
589
590
591

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

592
// Total unit online hours per sub-unit over the simulation
593
r_uTotalOnlinePerUnit(unit)${ p_unit(unit, 'unitCount') > 0 }
594
595
596
    = r_uTotalOnline(unit)
        / p_unit(unit, 'unitCount');

597
598
// Total sub-unit startups over the simulation
r_uTotalStartup(unit, starttype)
599
    = sum(ft_realizedNoReset(f, startp(t)),
600
        + r_startup(unit, starttype, f, t)
601
            * sum(msft_realizedNoReset(m, s, f, t), p_msProbability(m, s) * p_msWeight(m, s))
602
603
604
605
        ); // END sum(ft_realizedNoReset)

// Total sub-unit shutdowns over the simulation
r_uTotalShutdown(unit)
606
    = sum(ft_realizedNoReset(f, startp(t)),
607
        + r_shutdown(unit, f, t)
608
            * sum(msft_realizedNoReset(m, s, f, t), p_msProbability(m, s) * p_msWeight(m, s))
609
610
        ); // END sum(ft_realizedNoReset)

611
612
613
614
615
616
617
618
* --- Sum results for groups --------------------------------------------------

// gnTotalgen in units that belong to gnuGroups over the simulation
r_gnTotalGenGnuGroup(grid, node, group)
    = sum(unit $ {gnuGroup(grid, node, unit, group)},
        + r_gnuTotalGen(grid, node, unit)
         ); // END sum(unit)

619
620
* --- Diagnostic Results ------------------------------------------------------

621
// Only include these if '--diag=yes' given as a command line argument
622
$iftheni.diag '%diag%' == yes
623
// Estimated coefficients of performance
624
d_cop(unit, ft_realizedNoReset(f, startp(t)))$sum(gnu_input(grid, node, unit), 1)
625
626
627
628
629
630
631
    = 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))}
632
633
            ]
        + Eps; // Eps to correct GAMS plotting (zeroes are not skipped)
634

635
// Estimated efficiency, calculated from commodity based inputs
636
d_eff(unit_commodity(unit), ft_realizedNoReset(f, t))$[ord(t) > mSettings(m, 't_start') + mSettings(m, 't_initializationPeriod')]
637
638
639
    = sum(gnu_output(grid, node, unit),
        + r_gen(grid, node, unit, f, t)
        ) // END sum(gnu_output)
640
641
642
643
        / [ sum(gnu_input(grid, node, unit)$un_commodity(unit, node),
                + r_fuelUse(node, unit, f, t)
                ) // END sum(gnu_input)
            + 1${not sum(gnu_input(grid, node, unit)$un_commodity(unit, node), r_fuelUse(node, unit, f, t))}
644
645
            ]
        + Eps; // Eps to correct GAMS plotting (zeroes are not skipped)
646
$endif.diag
647

648
); // END loop(m)
649