Commit 1090265f authored by Erkka Rinne's avatar Erkka Rinne
Browse files

Enabled stochastic scenarios for cf too

parent 3a3504a9
......@@ -143,7 +143,7 @@ Parameters
// Aliases used for intervals (time step aggregation)
// NOTE: Sample dimension has to be last because of the scenario reduction algorithm
ts_influx_(grid, node, f, t, s)
ts_cf_(flow, node, f, t)
ts_cf_(flow, node, f, t, s)
ts_influx_temp(grid, node, s, f, t)
ts_reserveDemand_(restype, up_down, node, f, t)
ts_node_(grid, node, param_gnBoundaryTypes, f, t)
......@@ -152,6 +152,8 @@ Parameters
// Help parameters for calculating smoothening of time series
ts_influx_mean(grid, node, f, t) "Mean of ts_influx"
ts_influx_std(grid, node, f, t) "Standard deviation of ts_influx"
ts_cf_mean(flow, node, f, t) "Mean of ts_cf"
ts_cf_std(flow, node, f, t) "Standard deviation of ts_cf"
p_autocorrelation(node, timeseries) "Autocorrelation of time series for the node and time series type (lag = 1 time step)"
......
......@@ -183,6 +183,6 @@ Option clear = r_qResDemand;
Parameters
d_cop(unit, f, t) "Coefficients of performance of conversion units"
d_eff(unit, f, t) "Efficiency of generation units using fuel"
d_capacityFactor(flow, node, f, t) "Diagnostic capacity factors (accounting for GAMS plotting error)"
d_capacityFactor(flow, node, s, f, t) "Diagnostic capacity factors (accounting for GAMS plotting error)"
d_nodeState(grid, node, param_gnBoundaryTypes, f, t) "Diagnostic temperature forecasts (accounting for GAMS plotting error)"
;
......@@ -229,7 +229,7 @@ q_maxDownward(m, s, gnuft(grid, node, unit, f, t))${msft(m, s, f, t)
* [
// Capacity factors for flow units
+ sum(flowUnit(flow, unit),
+ ts_cf_(flow, node, f, t)
+ ts_cf_(flow, node, f, t, s)
) // END sum(flow)
+ 1${not unit_flow(unit)}
] // END * p_unit(availability)
......@@ -305,7 +305,7 @@ q_maxUpward(m, s, gnuft(grid, node, unit, f, t))${msft(m, s, f, t)
* [
// Capacity factor for flow units
+ sum(flowUnit(flow, unit),
+ ts_cf_(flow, node, f, t)
+ ts_cf_(flow, node, f, t, s)
) // END sum(flow)
+ 1${not unit_flow(unit)}
] // END * p_unit(availability)
......@@ -394,7 +394,7 @@ q_reserveProvision(nuRescapable(restypeDirectionNode(restype, up_down, node), un
* [
// ... and capacity factor for flow units
+ sum(flowUnit(flow, unit),
+ ts_cf_(flow, node, f, t)
+ ts_cf_(flow, node, f, t, s)
) // END sum(flow)
+ 1${not unit_flow(unit)}
]
......@@ -1667,7 +1667,7 @@ q_capacityMargin(gn(grid, node), sft(s, f, t))${ p_gn(grid, node, 'capacityMa
* [
// Capacity factors for flow units
+ sum(flowUnit(flow, unit)${ nu(node, unit) },
+ ts_cf_(flow, node, f, t)
+ ts_cf_(flow, node, f, t, s)
) // END sum(flow)
+ 1${not unit_flow(unit)}
]
......
......@@ -230,8 +230,8 @@ loop(cc(counter),
// Select time series data matching the intervals, for stepsPerInterval = 1, this is trivial.
loop(ft(f_solve, tt_block(t)),
ts_cf_(flowNode(flow, node), f_solve, t)
= ts_cf(flow, node, f_solve, t+dt_circular(t));
ts_cf_(flowNode(flow, node), f_solve, t, s)$msf(mSolve, s, f_solve)
= ts_cf(flow, node, f_solve, t + (dt_sampleOffset(node, s) + dt_circular(t)));
ts_influx_(gn(grid, node), f_solve, t, s)$msf(mSolve, s, f_solve)
= ts_influx(grid, node, f_solve, t + (dt_sampleOffset(node, s) + dt_circular(t)));
ts_unit_(unit, param_unit, f_solve, t)
......@@ -305,8 +305,8 @@ loop(cc(counter),
ts_influx_(gn(grid, node), f_solve, t, s)$msf(mSolve, s, f_solve)
= sum(tt(t_), ts_influx(grid, node, f_solve, t_ + (dt_sampleOffset(node, s) + dt_circular(t_))))
/ p_stepLength(mSolve, f_solve, t);
ts_cf_(flowNode(flow, node), f_solve, t)
= sum(tt(t_), ts_cf(flow, node, f_solve, t_+dt_circular(t_)))
ts_cf_(flowNode(flow, node), f_solve, t, s)$msf(mSolve, s, f_solve)
= sum(tt(t_), ts_cf(flow, node, f_solve, t_ + (dt_sampleOffset(node, s) + dt_circular(t_))))
/ p_stepLength(mSolve, f_solve, t);
ts_unit_(unit, param_unit, f_solve, t)
${ p_unit(unit, 'useTimeseries')} // Only include units with timeseries attributed to them
......@@ -454,9 +454,19 @@ if(active(mSolve, 'scenred'),
$$include 'inc/scenred.gms'
);
* --- Calculate statistics of time series data --------------------------------
* --- Smooting of stochastic sceanrios ---------------------------------------
$ontext
First calculate standard deviation for over all samples, then smoothen the scenarios
following the methodology presented in [1, p. 443]. This avoids a discontinuity
`jump' after the initial sample.
[1] A. Helseth, B. Mo, A. Lote Henden, and G. Warland, "Detailed long-term hydro-
thermal scheduling for expansion planning in the Nordic power system," IET Gener.
Transm. Distrib., vol. 12, no. 2, pp. 441 - 447, 2018.
$offtext
loop(gn(grid, node)$sum(timeseries, p_autocorrelation(node, timeseries)),
* Influx
loop(gn(grid, node)$p_autocorrelation(node, 'ts_influx'),
ts_influx_mean(grid, node, ft(f, t))$mf_central(mSolve, f)
= sum(s_parallel(s), ts_influx_(grid, node, f, t, s)) / sum(s_parallel, 1);
......@@ -466,7 +476,7 @@ loop(gn(grid, node)$sum(timeseries, p_autocorrelation(node, timeseries)),
/ sum(s_parallel, 1)
);
* Correct values for smoother scenarios, following the methodology in [1, p. 443]
// Do smoothing
loop(mst_end(ms_initial(mSolve, s_), t_),
ts_influx_(grid, node, ft(f, t), s)$(ts_influx_std(grid, node, f, t_+dt_circular(t_))
and sft(s, f, t)
......@@ -486,11 +496,38 @@ loop(gn(grid, node)$sum(timeseries, p_autocorrelation(node, timeseries)),
);
);
$ontext
[1] A. Helseth, B. Mo, A. Lote Henden, and G. Warland, "Detailed long-term hydro-
thermal scheduling for expansion planning in the Nordic power system," IET Gener.
Transm. Distrib., vol. 12, no. 2, pp. 441 - 447, 2018.
$offtext
* CF
loop(flowNode(flow, node)$p_autocorrelation(node, 'ts_cf'),
ts_cf_mean(flow, node, ft(f, t))$mf_central(mSolve, f)
= sum(s_parallel(s), ts_cf_(flow, node, f, t, s)) / sum(s_parallel, 1);
ts_cf_std(flow, node, ft(f, t))$mf_central(mSolve, f)
= sqrt(sum(s_parallel(s), sqr(ts_cf_(flow, node, f, t, s)
- ts_cf_mean(flow, node, f, t)))
/ sum(s_parallel, 1)
);
// Do smoothing
loop(mst_end(ms_initial(mSolve, s_), t_),
ts_cf_(flow, node, ft(f, t), s)$(ts_cf_std(flow, node, f, t_+dt_circular(t_))
and sft(s, f, t)
and not ms_initial(mSolve, s))
= ts_cf_(flow, node, f, t, s)
+ (ts_cf_(flow, node, f, t_, s_)
- ts_cf_(flow, node, f, t_, s))
* (ts_cf_std(flow, node, f, t+dt_circular(t))
/ ts_cf_std(flow, node, f, t_+dt_circular(t_)))
* power(p_autocorrelation(node, 'ts_cf'), abs(ord(t) - ord(t_)));
// Ensure not above max or below min
ts_cf_(flow, node, f, t, s)$(ts_cf_(flow, node, f, t, s) < p_tsMinValue(node, 'ts_cf'))
= p_tsMinValue(node, 'ts_cf');
ts_cf_(flow, node, f, t, s)$(ts_cf_(flow, node, f, t, s) > p_tsMaxValue(node, 'ts_cf'))
= p_tsMaxValue(node, 'ts_cf');
);
);
* =============================================================================
* --- Defining unit aggregations and ramps ------------------------------------
......
......@@ -143,7 +143,7 @@ v_gen.up(gnu_output(grid, node, unit_flow), sft(s, f, t))${gnuft(grid, node, uni
= sum(flow${ flowUnit(flow, unit_flow)
and nu(node, unit_flow)
},
+ ts_cf_(flow, node, f, t)
+ ts_cf_(flow, node, f, t, s)
* p_gnu(grid, node, unit_flow, 'maxGen')
* p_unit(unit_flow, 'availability')
) // END sum(flow)
......@@ -170,7 +170,7 @@ v_gen.lo(gnu_input(grid, node, unit_flow), sft(s, f, t))${gnuft(grid, node, unit
= - sum(flow${ flowUnit(flow, unit_flow)
and nu(node, unit_flow)
},
+ ts_cf_(flow, node, f, t)
+ ts_cf_(flow, node, f, t, s)
* p_gnu(grid, node, unit_flow, 'maxCons')
* p_unit(unit_flow, 'availability')
) // END sum(flow)
......
......@@ -158,11 +158,12 @@ r_qGen(inc_dec, gn(grid, node), f, t)
* =============================================================================
// Capacity factors for examining forecast errors
d_capacityFactor(flowNode(flow, node), f_solve(f), t_active(t))${ sum(flowUnit(flow, unit), nu(node, unit)) }
= ts_cf_(flow, node, f, t)
+ ts_cf(flow, node, f, t)${ not ts_cf_(flow, node, f, t) }
- 1e-3${ not ts_cf_(flow, node, f, t)
and not ts_cf(flow, node, f, t)
d_capacityFactor(flowNode(flow, node), s, f_solve(f), t_active(t))${sft(s, f, t)
and sum(flowUnit(flow, unit), nu(node, unit)) }
= ts_cf_(flow, node, f, t, s)
+ ts_cf(flow, node, f, t + dt_sampleOffset(node, s))${ not ts_cf_(flow, node, f, t, s) }
- 1e-3${ not ts_cf_(flow, node, f, t, s)
and not ts_cf(flow, node, f, t + dt_sampleOffset(node, s))
}
;
// Temperature forecast for examining the error
......
......@@ -6,10 +6,6 @@ if(mSettings(mSolve, 'red_num_leaves')
p_sProbability(s)$ms(mSolve, s) = p_msProbability_orig(mSolve, s);
* SCENRED2 parameters
*ScenRedParms('num_time_steps') = 2;
*ScenRedParms('num_leaves') = card(s) - 1;
*ScenRedParms('num_nodes') = card(s);
*ScenRedParms('num_random') = card(grid) * card(node) * card(f) * mSettings('schedule', 't_horizon');
ScenRedParms('red_num_leaves') = mSettings(mSolve, 'red_num_leaves');
ScenRedParms('red_percentage') = mSettings(mSolve, 'red_percentage');
ScenRedParms('scen_red') = 1; // Reduce scenarios
......@@ -24,7 +20,7 @@ $endif
* Data exchange and execute SCENRED2
execute_unload 'output/srin.gdx', ScenRedParms,
s, ss, p_sProbability,
ts_influx_;
ts_influx_, ts_cf_;
execute 'scenred2 inc/scenred.cmd';
execute_load 'output/srout.gdx', ScenRedReport,
p_sProbability=red_prob;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment