Commit b01f1809 authored by Topi Rasku's avatar Topi Rasku
Browse files

Rewriting large portions of *3c_inputsLoop.gms* to make it more compact, and...

Rewriting large portions of *3c_inputsLoop.gms* to make it more compact, and hopefully increasíng performance as well.
parent 4d0b7ca9
...@@ -117,13 +117,16 @@ Sets ...@@ -117,13 +117,16 @@ Sets
effOnline(effSelector) "Efficiency selectors that use online variables" effOnline(effSelector) "Efficiency selectors that use online variables"
/ directOnLP, directOnMIP, lambda01*lambda12 ,incHR / // IMPORTANT! Online variables are generated based on this, so keep it up to date! / directOnLP, directOnMIP, lambda01*lambda12 ,incHR / // IMPORTANT! Online variables are generated based on this, so keep it up to date!
* --- General and Directional Sets -------------------------------------------- * --- General, Interval and Directional Sets ----------------------------------
// General Counter // General Counter
counter "General counter set" counter "General counter set"
/c000*c999/ /c000*c999/
cc(counter) "Temporary subset of counter used for calculations" cc(counter) "Temporary subset of counter used for calculations"
// Interval Step Counter
intervalStepCounter(counter, counter) "Interval step counter for time series averaging"
// Directional Sets // Directional Sets
up_down "Direction set used by some variables, e.g. reserve provisions and generation ramps" up_down "Direction set used by some variables, e.g. reserve provisions and generation ramps"
/ up, down / / up, down /
...@@ -172,6 +175,9 @@ Sets ...@@ -172,6 +175,9 @@ Sets
; // END Sets ; // END Sets
// Alias the counter set
alias(counter, counter_);
* ============================================================================= * =============================================================================
* --- Model Parameter Definitions --------------------------------------------- * --- Model Parameter Definitions ---------------------------------------------
* ============================================================================= * =============================================================================
......
...@@ -167,6 +167,11 @@ count_sample = 1; ...@@ -167,6 +167,11 @@ count_sample = 1;
cc(counter)${ mInterval(mSolve, 'stepsPerInterval', counter) } cc(counter)${ mInterval(mSolve, 'stepsPerInterval', counter) }
= yes; = yes;
// Determine the interval step counters for each interval
intervalStepCounter(cc(counter), counter_)
${ ord(counter_) <= mInterval(mSolve, 'stepsPerInterval', counter) }
= yes;
// Update tForecastNext // Update tForecastNext
tForecastNext(mSolve) tForecastNext(mSolve)
${ tSolveFirst >= tForecastNext(mSolve) } ${ tSolveFirst >= tForecastNext(mSolve) }
......
...@@ -303,121 +303,91 @@ loop(cc(counter), ...@@ -303,121 +303,91 @@ loop(cc(counter),
option clear = tt_; option clear = tt_;
tt_(tt_interval) = yes; tt_(tt_interval) = yes;
// If stepsPerInterval equals one, simply use all the steps within the block // Select and average time series data matching the intervals
if(mInterval(mSolve, 'stepsPerInterval', counter) = 1, ts_unit_(unit_timeseries(unit), param_unit, ft(f, tt_interval(t)))
= sum(intervalStepCounter(counter, counter_),
* --- Select time series data matching the intervals, for stepsPerInterval = 1, this is trivial. ts_unit(unit, param_unit, f, t+(ord(counter_) - 1 + dt_circular(t + (ord(counter_) - 1))))
)
ts_unit_(unit_timeseries(unit), param_unit, ft(f, tt_interval(t))) // Only if time series enabled for the unit / mInterval(mSolve, 'stepsPerInterval', counter);
= ts_unit(unit, param_unit, f, t+dt_circular(t));
$ontext
* Should these be handled here at all? See above comment
ts_effUnit_(effGroupSelectorUnit(effSelector, unit_timeseries(unit), effSelector), param_eff, ft(f, tt_interval(t)))
= ts_effUnit(effSelector, unit, effSelector, param_eff, f_solve, t+dt_circular(t));
ts_effGroupUnit_(effSelector, unit_timeseries(unit), param_eff, ft(f, tt_interval(t)))
= ts_effGroupUnit(effSelector, unit, param_eff, f_solve, t+dt_circular(t));
$offtext
ts_cf_(flowNode(flow, node), fts(f, tt_interval(t), s))
= ts_cf(flow, node, f + (df_scenario(f, t)$gn_scenarios(flow, node, 'ts_cf')),
t + (dt_scenarioOffset(flow, node, 'ts_cf', s)
+ dt_circular(t)$(not gn_scenarios(flow, node, 'ts_cf'))));
ts_influx_(gn(grid, node), fts(f, tt_interval(t), s))
= ts_influx(grid, node, f + (df_scenario(f, t)$gn_scenarios(grid, node, 'ts_node')),
t + (dt_scenarioOffset(grid, node, 'ts_influx', s)
+ dt_circular(t)$(not gn_scenarios(grid, node, 'ts_influx'))));
// Reserve demand relevant only up until reserve_length
ts_reserveDemand_(restypeDirectionNode(restype, up_down, node), ft(f, tt_interval(t)))
${ord(t) <= tSolveFirst + p_nReserves(node, restype, 'reserve_length')}
= ts_reserveDemand(restype, up_down, node,
f + (df_scenario(f,t)$gn_scenarios(restype, node, 'ts_reserveDemand')),
t+dt_circular(t));
ts_node_(gn_state(grid, node), param_gnBoundaryTypes, fts(f, tt_interval(t), s))
$p_gnBoundaryPropertiesForStates(grid, node, param_gnBoundaryTypes, 'useTimeseries')
= ts_node(grid, node, param_gnBoundaryTypes,
f + (df_scenario(f, t)$gn_scenarios(grid, node, 'ts_node')),
t + (dt_scenarioOffset(grid, node, param_gnBoundaryTypes, s)
+ dt_circular(t)$(not gn_scenarios(grid, node, 'ts_node'))));
// Fuel price time series
ts_fuelPrice_(fuel, tt_interval(t))
${ p_fuelPrice(fuel, 'useTimeSeries') }
= ts_fuelPrice(fuel, t+dt_circular(t));
* --- If stepsPerInterval exceeds 1 (stepsPerInterval < 1 not defined) --------
elseif mInterval(mSolve, 'stepsPerInterval', counter) > 1,
// Select and average time series data matching the intervals, for stepsPerInterval > 1
// Loop over the t:s of the interval
loop(ft(f_solve(f), tt_interval(t)),
// Select t:s within the interval
Option clear = tt;
tt(tt_(t_))
${ ord(t_) >= ord(t)
and ord(t_) < ord(t) + mInterval(mSolve, 'stepsPerInterval', counter)
}
= yes;
ts_unit_(unit_timeseries(unit), param_unit, f, t)
= sum(tt(t_), ts_unit(unit, param_unit, f, t_+dt_circular(t_)))
/ mInterval(mSolve, 'stepsPerInterval', counter);
$ontext $ontext
* Should these be handled here at all? See above comment * Should these be handled here at all? See above comment
ts_effUnit_(effGroupSelectorUnit(effSelector, unit_timeseries(unit), effSelector), param_eff, f_solve, t) ts_effUnit_(effGroupSelectorUnit(effSelector, unit_timeseries(unit), effSelector), param_eff, ft(f, tt_interval(t)))
= sum(tt(t_), ts_effUnit(effSelector, unit, effSelector, param_eff, f_solve, t_+dt_circular(t_)))) = sum(intervalStepCounter(counter, counter_),
/ mInterval(mSolve, 'stepsPerInterval', counter); ts_effUnit(effSelector, unit, effSelector, param_eff, f_solve, t+(ord(counter_) - 1 + dt_circular(t + ord(counter_) - 1)))
ts_effGroupUnit_(effSelector, unit_timeseries(unit), param_eff, f_solve, t) )
= sum(tt(t_), ts_effGroupUnit(effSelector, unit, param_eff, f_solve, t_+dt_circular(t_)))) / mInterval(mSolve, 'stepsPerInterval', counter);
/ mInterval(mSolve, 'stepsPerInterval', counter); ts_effGroupUnit_(effSelector, unit_timeseries(unit), param_eff, ft(f, tt_interval(t)))
= sum(intervalStepCounter(counter, counter_),
ts_effGroupUnit(effSelector, unit, param_eff, f_solve, t+(ord(counter_) - 1 + dt_circular(t + ord(counter_) - 1)))
)
/ mInterval(mSolve, 'stepsPerInterval', counter);
$offtext $offtext
ts_influx_(gn(grid, node), fts(f, t, s)) ts_influx_(gn(grid, node), fts(f, tt_interval(t), s))
= sum(tt(t_), ts_influx(grid, node, = sum(intervalStepCounter(counter, counter_),
f + (df_scenario(f, t)$gn_scenarios(grid, node, 'ts_influx')), ts_influx(grid, node,
t_ + (dt_scenarioOffset(grid, node, 'ts_influx', s) f + (df_scenario(f, t)$gn_scenarios(grid, node, 'ts_influx')),
+ dt_circular(t_)$(not gn_scenarios(grid, node, 'ts_influx'))))) t + ( ord(counter_) - 1
/ mInterval(mSolve, 'stepsPerInterval', counter); + dt_scenarioOffset(grid, node, 'ts_influx', s)
ts_cf_(flowNode(flow, node), fts(f, t, s)) + dt_circular(t + (ord(counter_) - 1))$(not gn_scenarios(grid, node, 'ts_influx'))))
= sum(tt(t_), ts_cf(flow, node, )
f + (df_scenario(f, t)$gn_scenarios(flow, node, 'ts_cf')), / mInterval(mSolve, 'stepsPerInterval', counter);
t_ + (dt_scenarioOffset(flow, node, 'ts_cf', s) ts_cf_(flowNode(flow, node), fts(f, tt_interval(t), s))
+ dt_circular(t_)$(not gn_scenarios(flow, node, 'ts_cf'))))) = sum(intervalStepCounter(counter, counter_),
/ mInterval(mSolve, 'stepsPerInterval', counter); ts_cf(flow, node,
// Reserves relevant only until reserve_length f + (df_scenario(f, t)$gn_scenarios(flow, node, 'ts_cf')),
ts_reserveDemand_(restypeDirectionNode(restype, up_down, node), f, t) t + ( ord(counter_) - 1
${ord(t) <= tSolveFirst + p_nReserves(node, restype, 'reserve_length') } + dt_scenarioOffset(flow, node, 'ts_cf', s)
= sum(tt(t_), ts_reserveDemand(restype, up_down, node, + dt_circular(t + (ord(counter_) - 1))$(not gn_scenarios(flow, node, 'ts_cf'))))
f + (df_scenario(f, t)$gn_scenarios(restype, node, 'ts_reserveDemand')), )
t_+ dt_circular(t_))) / mInterval(mSolve, 'stepsPerInterval', counter);
/ mInterval(mSolve, 'stepsPerInterval', counter); // Reserves relevant only until reserve_length
ts_node_(gn_state(grid, node), param_gnBoundaryTypes, fts(f, t, s)) ts_reserveDemand_(restypeDirectionNode(restype, up_down, node), ft(f, tt_interval(t)))
$p_gnBoundaryPropertiesForStates(grid, node, param_gnBoundaryTypes, 'useTimeseries') ${ord(t) <= tSolveFirst + p_nReserves(node, restype, 'reserve_length') }
// Take average if not a limit type = sum(intervalStepCounter(counter, counter_),
= (sum(tt(t_), ts_node(grid, node, param_gnBoundaryTypes, ts_reserveDemand(restype, up_down, node,
f + (df_scenario(f, t)$gn_scenarios(grid, node, 'ts_node')), f + (df_scenario(f, t)$gn_scenarios(restype, node, 'ts_reserveDemand')),
t_ + (dt_scenarioOffset(grid, node, param_gnBoundaryTypes, s) t + ( ord(counter_) - 1 + dt_circular(t + (ord(counter_) - 1))))
+ dt_circular(t_)$(not gn_scenarios(grid, node, 'ts_node'))))) )
/ mInterval(mSolve, 'stepsPerInterval', counter))$(not (sameas(param_gnBoundaryTypes, 'upwardLimit') / mInterval(mSolve, 'stepsPerInterval', counter);
or sameas(param_gnBoundaryTypes, 'downwardLimit') ts_node_(gn_state(grid, node), param_gnBoundaryTypes, fts(f, tt_interval(t), s))
or slack(param_gnBoundaryTypes))) $p_gnBoundaryPropertiesForStates(grid, node, param_gnBoundaryTypes, 'useTimeseries')
// Maximum lower limit // Take average if not a limit type
+ smax(tt(t_), ts_node(grid, node, param_gnBoundaryTypes, = (sum(intervalStepCounter(counter, counter_),
f + (df_scenario(f, t)$gn_scenarios(grid, node, 'ts_node')), ts_node(grid, node, param_gnBoundaryTypes,
t_ + (dt_scenarioOffset(grid, node, param_gnBoundaryTypes, s) f + (df_scenario(f, t)$gn_scenarios(grid, node, 'ts_node')),
+ dt_circular(t_)$(not gn_scenarios(grid, node, 'ts_node'))))) t + ( ord(counter_) - 1
$(sameas(param_gnBoundaryTypes, 'downwardLimit') or downwardSlack(param_gnBoundaryTypes)) + dt_scenarioOffset(grid, node, param_gnBoundaryTypes, s)
// Minimum upper limit + dt_circular(t + (ord(counter_) - 1))$(not gn_scenarios(grid, node, 'ts_node'))))
+ smin(tt(t_), ts_node(grid, node, param_gnBoundaryTypes, )
f + (df_scenario(f, t)$gn_scenarios(grid, node, 'ts_node')), / mInterval(mSolve, 'stepsPerInterval', counter))$( not (sameas(param_gnBoundaryTypes, 'upwardLimit')
t_ + (dt_scenarioOffset(grid, node, param_gnBoundaryTypes, s) or sameas(param_gnBoundaryTypes, 'downwardLimit')
+ dt_circular(t_)$(not gn_scenarios(grid, node, 'ts_node'))))) or slack(param_gnBoundaryTypes)))
$(sameas(param_gnBoundaryTypes, 'upwardLimit') or upwardSlack(param_gnBoundaryTypes)); // Maximum lower limit
// Fuel price time series + smax(intervalStepCounter(counter, counter_),
ts_fuelPrice_(fuel, t) ts_node(grid, node, param_gnBoundaryTypes,
${ p_fuelPrice(fuel, 'useTimeSeries') } f + (df_scenario(f, t)$gn_scenarios(grid, node, 'ts_node')),
= sum(tt(t_), ts_fuelPrice(fuel, t_+dt_circular(t_))) t + ( ord(counter_) - 1
/ mInterval(mSolve, 'stepsPerInterval', counter); + dt_scenarioOffset(grid, node, param_gnBoundaryTypes, s)
); // END loop(ft) + dt_circular(t + (ord(counter_) - 1))$(not gn_scenarios(grid, node, 'ts_node'))))
)
); // END if(stepsPerInterval) $(sameas(param_gnBoundaryTypes, 'downwardLimit') or downwardSlack(param_gnBoundaryTypes))
// Minimum upper limit
+ smin(intervalStepCounter(counter, counter_),
ts_node(grid, node, param_gnBoundaryTypes,
f + (df_scenario(f, t)$gn_scenarios(grid, node, 'ts_node')),
t + ( ord(counter_) - 1
+ dt_scenarioOffset(grid, node, param_gnBoundaryTypes, s)
+ dt_circular(t + (ord(counter_) - 1))$(not gn_scenarios(grid, node, 'ts_node'))))
)
$(sameas(param_gnBoundaryTypes, 'upwardLimit') or upwardSlack(param_gnBoundaryTypes));
// Fuel price time series
ts_fuelPrice_(fuel, tt_interval(t))
${ p_fuelPrice(fuel, 'useTimeSeries') }
= sum(intervalStepCounter(counter, counter_),
+ ts_fuelPrice(fuel, t+(ord(counter_) - 1 + dt_circular(t + (ord(counter_) - 1))))
)
/ mInterval(mSolve, 'stepsPerInterval', counter);
); // END loop(counter) ); // END loop(counter)
* --- Process unit time series data ------------------------------------------- * --- Process unit time series data -------------------------------------------
......
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