Commit 563f3409 authored by Niina Helistö's avatar Niina Helistö
Browse files

Merge branch 'generic_forecast_loop_read' into Fix_ramp_constraints

parents f65ff1ef ec904731
options
// Solution gap: the first one reached will end iteration
optca = 0 // Absolute gap between the found solution and the best possible solution
optcr = 0.0004 // Relative gap between the found solution and the best possible solution
solvelink = %Solvelink.Loadlibrary% // Solvelink controls how the problem is passed from GAMS to the solver. Loadlibrary constant means that the model is passed in core without the use of temporary files.
* profile = 8 // Profile will show the execution speed of statements at the defined depth within loops.
* bratio = 0.25 // How large share of the candidate elements need to be found for advanced basis in LP problems. Default 0.25.
* solveopt = merge // How solution values are stored after multiple solves. Default merge.
* savepoint = 1 // NOTE! Savepoint is controlled by Backbone model options.
threads = -1 // How many cores the solver can use: 0 = all cores; negative values = all cores - n
$ifi not '%debug%' == 'yes'
solprint = Silent // Controls solution file outputs - debug mode will be more verbose
;
......@@ -69,18 +69,8 @@ $onempty // Allow empty data definitions
* Output file streams
files log /''/, gdx, f_info /'output\info.txt'/;
options
optca = 0
optcr = 0.0004
* profile = 8
solvelink = %Solvelink.Loadlibrary%
* bratio = 0.25
* solveopt = merge
* savepoint = 1
threads = 1
$ifi not '%debug%' == 'yes'
solprint = Silent
;
* Include options file to control the solver
$if exist 'input\1_options.gms' $include 'input\1_options.gms';
* === Definitions, sets, parameters and input data=============================
......@@ -112,9 +102,11 @@ $include 'defModels\invest.gms'
// Load model input parameters
$include 'input\modelsInit.gms'
* === Simulation ==============================================================
$include 'inc\3a_periodicInit.gms' // Initialize modelling loop
loop(modelSolves(mSolve, tSolve),
solveCount = solveCount + 1;
$$include 'inc\3b_inputsLoop.gms' // Read input data that is updated within the loop
$$include 'inc\3c_periodicLoop.gms' // Update modelling loop
$$include 'inc\3d_setVariableLimits.gms' // Set new variable limits (.lo and .up)
......@@ -123,7 +115,7 @@ loop(modelSolves(mSolve, tSolve),
$$include 'inc\4a_outputVariant.gms' // Store results from the loop
$iftheni.debug '%debug%' == 'yes'
putclose gdx;
put_utility 'gdxout' / 'output\'mSolve.tl:0, '-', tSolve.tl:0, '.gdx';
put_utility 'gdxout' / 'output\' mSolve.tl:0 '-' tSolve.tl:0 '.gdx';
execute_unload
$$include defOutput\debugSymbols.inc
;
......
......@@ -73,9 +73,9 @@ if (mType('building'),
// Define forecast properties and features
mSettings('building', 't_forecastStart') = 0;
mSettings('building', 't_forecastLength') = 0;
mSettings('building', 't_forecastLengthUnchanging') = 0; // Length of forecasts in time steps - this does not decrease when the solve moves forward (requires forecast data that is longer than the horizon at first)
mSettings('building', 't_forecastLengthDecreasesFrom') = 0; // Length of forecasts in time steps - this decreases when the solve moves forward until the new forecast data is read (then extends back to full length)
mSettings('building', 't_forecastJump') = 0;
mSettings('building', 'readForecastsInTheLoop') = 0;
// Define Realized and Central forecasts
* mf_realization('building', f) = no;
......@@ -99,7 +99,7 @@ if (mType('building'),
// Lenght of reserve horizon
mSettings('building', 't_reserveLength') = 0;
* --- Define Unit Efficiency Approximations -----------------------------------
* --- Define Unit Approximations ----------------------------------------------
// Define unit aggregation threshold
mSettings('building', 't_aggregate') = 0;
......@@ -110,4 +110,15 @@ if (mType('building'),
// Define threshold for omitting start-up and shutdown trajectories
mSettings('schedule', 't_omitTrajectories') = 8761;
* --- Define output settings for results --------------------------------------
// Define when to start outputting results - allows to skip an initialization period. Uses ord(t) > results_t_start in the code.
mSettings('schedule', 'results_t_start') = 1;
* --- Control the solver ------------------------------------------------------
// Control the use of advanced basis
mSettings('schedule', 'loadPoint') = 2; // 0 = no basis, 1 = latest solve, 2 = all solves, 3 = first solve
mSettings('schedule', 'savePoint') = 2; // 0 = no basis, 1 = latest solve, 2 = all solves, 3 = first solve
); // END if(mType)
......@@ -79,9 +79,9 @@ if (mType('invest'),
// Define forecast properties and features
mSettings('invest', 't_forecastStart') = 0;
mSettings('invest', 't_forecastLength') = 0;
mSettings('invest', 't_forecastLengthUnchanging') = 0; // Length of forecasts in time steps - this does not decrease when the solve moves forward (requires forecast data that is longer than the horizon at first)
mSettings('building', 't_forecastLengthDecreasesFrom') = 0; // Length of forecasts in time steps - this decreases when the solve moves forward until the new forecast data is read (then extends back to full length)
mSettings('invest', 't_forecastJump') = 0;
mSettings('invest', 'readForecastsInTheLoop') = 0;
// Define Realized and Central forecasts
mf_realization('invest', f) = no;
......@@ -105,7 +105,7 @@ if (mType('invest'),
// Lenght of reserve horizon
mSettings('invest', 't_reserveLength') = 36; // CHECK THIS
* --- Define Unit Efficiency Approximations -----------------------------------
* --- Define Unit Approximations ----------------------------------------------
// Define unit aggregation threshold
mSettings('invest', 't_aggregate') = 8761;
......@@ -116,6 +116,17 @@ if (mType('invest'),
// Define threshold for omitting start-up and shutdown trajectories
mSettings('schedule', 't_omitTrajectories') = 8761;
* --- Define output settings for results --------------------------------------
// Define when to start outputting results - allows to skip an initialization period. Uses ord(t) > results_t_start in the code.
mSettings('schedule', 'results_t_start') = 1;
* --- Control the solver ------------------------------------------------------
// Control the use of advanced basis
mSettings('schedule', 'loadPoint') = 2; // 0 = no basis, 1 = latest solve, 2 = all solves, 3 = first solve
mSettings('schedule', 'savePoint') = 2; // 0 = no basis, 1 = latest solve, 2 = all solves, 3 = first solve
); // END if(mType)
......@@ -81,9 +81,19 @@ if (mType('schedule'),
// Define forecast properties and features
mSettings('schedule', 't_forecastStart') = 1;
mSettings('schedule', 't_forecastLength') = 36;
mSettings('schedule', 't_forecastLengthUnchanging') = 36; // Length of forecasts in time steps - this does not decrease when the solve moves forward (requires forecast data that is longer than the horizon at first)
mSettings('building', 't_forecastLengthDecreasesFrom') = 168; // Length of forecasts in time steps - this decreases when the solve moves forward until the new forecast data is read (then extends back to full length)
mSettings('schedule', 't_forecastJump') = 24;
mSettings('schedule', 'readForecastsInTheLoop') = 1;
mTimeseries_loop_read('schedule', 'ts_reserveDemand') = no;
mTimeseries_loop_read('schedule', 'ts_unit') = no;
mTimeseries_loop_read('schedule', 'ts_effUnit') = no;
mTimeseries_loop_read('schedule', 'ts_effGroupUnit') = no;
mTimeseries_loop_read('schedule', 'ts_influx') = no;
mTimeseries_loop_read('schedule', 'ts_cf') = no;
mTimeseries_loop_read('schedule', 'ts_reserveDemand') = no;
mTimeseries_loop_read('schedule', 'ts_nodeState') = no;
mTimeseries_loop_read('schedule', 'ts_fuelPriceChange') = no;
mTimeseries_loop_read('schedule', 'ts_unavailability') = no;
// Define Realized and Central forecasts
mf_realization('schedule', f) = no;
......@@ -110,7 +120,7 @@ if (mType('schedule'),
// Lenght of reserve horizon
mSettings('schedule', 't_reserveLength') = 36;
* --- Define Unit Efficiency Approximations -----------------------------------
* --- Define Unit Approximations ----------------------------------------------
// Define unit aggregation threshold
mSettings('schedule', 't_aggregate') = 168;
......@@ -122,4 +132,15 @@ if (mType('schedule'),
// Define threshold for omitting start-up and shutdown trajectories
mSettings('schedule', 't_omitTrajectories') = 8761;
* --- Define output settings for results --------------------------------------
// Define when to start outputting results - allows to skip an initialization period. Uses ord(t) > results_t_start in the code.
mSettings('schedule', 'results_t_start') = 1;
* --- Control the solver ------------------------------------------------------
// Control the use of advanced basis
mSettings('schedule', 'loadPoint') = 2; // 0 = no basis, 1 = latest solve, 2 = all solves, 3 = first solve
mSettings('schedule', 'savePoint') = 2; // 0 = no basis, 1 = latest solve, 2 = all solves, 3 = first solve
); // END if(mType)
......@@ -36,6 +36,8 @@ Sets
t_jump, // Number of time steps realized with each solve
t_horizon, // Length of the simulation horizon in time steps (central forecast)
t_end, // Last time step of the simulation
loadPoint, // load advanced basis; 0 = no basis, 1 = all solves, 2 = first solve
savePoint, // save advanced basis; 0 = no basis, 1 = all solves, 2 = first solve
intervalEnd, // Last time step in the block of intervals with the same length
intervalLength, // Number of time steps aggregated within interval
IntervalInHours, // Length of one time step in hours
......@@ -43,15 +45,16 @@ Sets
// Samples and Forecasts
samples, // Number of active samples
forecasts, // Number of active forecasts
t_forecastLengthUnchanging, // Length of forecasts in time steps - this does not decrease when the solve moves forward (requires forecast data that is longer than the horizon at first)
t_forecastLengthDecreasesFrom, // Length of forecasts in time steps - this decreases when the solve moves forward until the new forecast data is read (then extends back to full length)
t_forecastStart, // Time step for first reading the forecasts (not necessarily t_start)
t_forecastLength, // Length of forecasts in time steps
t_forecastJump, // Number of time steps between each update of the forecasts
readForecastsInTheLoop, // Flag for updating forecasts in the solve loop
// Features
t_reserveLength, // Length of reserve provision horizon in time steps
t_aggregate, // Unit aggregation threshold time index
t_omitTrajectories // Threshold time index for omitting start-up and shutdown trajectories
t_omitTrajectories, // Threshold time index for omitting start-up and shutdown trajectories
results_t_start // time period where results outputting starts
/
// Solve info
......@@ -149,6 +152,21 @@ Sets
extraRes "Use extra tertiary reserves for error in elec. load during time step"
rampSched "Use power based scheduling"
/
* --- Set to declare time series that will be read between solves ------------------------------------------------------
timeseries "Names of time series that could be loop read from files between solves" /
ts_unit
ts_effUnit
ts_effGroupUnit
ts_influx
ts_cf
ts_reserveDemand
ts_nodeState
ts_fuelPriceChange
ts_fuelPrice
ts_unavailability
/
; // END Sets
* =============================================================================
......
......@@ -30,6 +30,9 @@ Sets
unit_flow(unit) "Unit that depend directly on variable energy flows (RoR, solar PV, etc.)"
unit_fuel(unit) "Units using a commercial fuel"
unit_minLoad(unit) "Units that have unit commitment restrictions (e.g. minimum power level)"
unit_online(unit) "Units that have an online variable in the first effLevel level1"
unit_online_LP(unit) "Units that have an LP online variable in the first effLevel level1"
unit_online_MIP(unit) "Units that have an MIP online variable in the first effLevel level1"
unit_aggregate(unit) "Aggregate units aggragating several units"
unit_noAggregate(unit) "Units that are not aggregated at all"
unit_slope(unit) "Units with piecewise linear efficiency constraints"
......@@ -126,6 +129,9 @@ Sets
gnuGroup(grid, node, unit, group) "Combination of grids, nodes and units in particular groups"
gn2nGroup(grid, node, node, group) "Transfer links in particular groups"
gnGroup(grid, node, group) "Combination of grids and nodes in particular groups"
* --- Set of timeseries that will be read from files between solves
mTimeseries_loop_read(mType, timeseries) "Those time series that will be read between solves"
;
* Set initial values to avoid errors when checking if parameter contents have been loaded from input data
Option clear = modelSolves;
......
......@@ -18,6 +18,7 @@ $offtext
* --- Internal counters -------------------------------------------------------
Scalars
errorcount /0/
solveCount /0/
tSolveFirst "counter (ord) for the first t in the solve"
tSolveLast "counter for the last t in the solve"
tCounter "counter for t" /0/
......@@ -25,6 +26,7 @@ Scalars
ts_length "Length of time series (t)"
continueLoop "Helper to stop the looping early"
intervalLength "Legnth of the interval to be calculated, considering end of modelling period"
currentForecastLength "Length of the forecast in the curren solve, minimum of unchanging and decreasing forecast lengths"
count "General counter"
count_lambda, count_lambda2 "Counter for lambdas"
cum_slope "Cumulative for slope"
......@@ -37,7 +39,8 @@ Scalars
tmp_op "Temporary parameter for operating point"
tmp_count_op "Counting the number of valid operating points in the unit data"
f_improve / 12 /
tRealizedLast "counter (ord) for the last realized t in the solve";
tRealizedLast "counter (ord) for the last realized t in the solve"
firstResultsOutputSolve /1/;
;
* --- Power plant and fuel data -----------------------------------------------
......@@ -136,10 +139,6 @@ Parameters
ts_reserveDemand_(restype, up_down, node, f, t)
ts_nodeState_(grid, node, param_gnBoundaryTypes, f, t)
ts_fuelPrice_(fuel, t)
// Temporary data time series for updating forecasts and reserve demand
ts_forecast(flow, node, t, f, t)
ts_tertiary(*,node,t,*,t)
;
* --- Other time dependent parameters -----------------------------------------
......
......@@ -140,6 +140,13 @@ unit_minload(unit)${ p_unit(unit, 'op00') > 0 // If the first defined operati
}
= yes;
// Units with online variables in the effLevel 'level1'
unit_online(unit)${ sum(effSelector$effOnline(effSelector), effLevelGroupUnit('level1', effSelector, unit)) }
= yes;
unit_online_LP(unit)${ sum(effSelector, effLevelGroupUnit('level1', 'directOnLP', unit)) }
= yes;
unit_online_MIP(unit) = unit_online(unit) - unit_online_LP(unit);
// Units with flows/fuels
unit_flow(unit)${ sum(flow, flowUnit(flow, unit)) }
= yes;
......
......@@ -21,15 +21,28 @@ $offtext
put log 'ord tSolve: ';
put log ord(tSolve) /;
putclose log;
if (mSettings(mSolve, 'readForecastsInTheLoop') and ord(tSolve) >= tForecastNext(mSolve),
put_utility 'gdxin' / 'input\forecasts\' tSolve.tl:0 '.gdx';
execute_load ts_forecast = forecast;
loop(mTimeseries_loop_read(mSolve, timeseries)${ord(tSolve) >= tForecastNext(mSolve)},
put_utility 'gdxin' / 'input\' timeseries.tl:0 '\' tSolve.tl:0 '.gdx';
if (mTimeseries_loop_read(mSolve, 'ts_unit'), execute_load ts_unit);
if (mTimeseries_loop_read(mSolve, 'ts_effUnit'), execute_load ts_effUnit);
if (mTimeseries_loop_read(mSolve, 'ts_effGroupUnit'), execute_load ts_effGroupUnit);
if (mTimeseries_loop_read(mSolve, 'ts_influx'), execute_load ts_influx);
if (mTimeseries_loop_read(mSolve, 'ts_cf'), execute_load ts_cf);
if (mTimeseries_loop_read(mSolve, 'ts_reserveDemand'), execute_load ts_reserveDemand);
if (mTimeseries_loop_read(mSolve, 'ts_nodeState'), execute_load ts_nodeState);
if (mTimeseries_loop_read(mSolve, 'ts_fuelPriceChange'), execute_load ts_fuelPriceChange);
if (mTimeseries_loop_read(mSolve, 'ts_unavailability'), execute_load ts_unavailability);
);
if (ord(tSolve) >= tForecastNext(mSolve),
// Update the next forecast
tForecastNext(mSolve)${ ord(tSolve) >= tForecastNext(mSolve) }
tForecastNext(mSolve)
= tForecastNext(mSolve) + mSettings(mSolve, 't_forecastJump');
);
$ontext
// Define t_latestForecast
Option clear = t_latestForecast;
t_latestForecast(tSolve) = yes;
......@@ -37,7 +50,7 @@ if (mSettings(mSolve, 'readForecastsInTheLoop') and ord(tSolve) >= tForecastNext
// Define updated time window
Option clear = tt_forecast;
tt_forecast(t_full(t))${ ord(t) >= ord(tSolve)
and ord(t) <= ord(tSolve) + mSettings(mSolve, 't_forecastLength') + mSettings(mSolve, 't_forecastJump')
and ord(t) <= ord(tSolve) + mSettings(mSolve, 't_forecastLengthUnchanging') + mSettings(mSolve, 't_forecastJump')
}
= yes;
......@@ -63,9 +76,8 @@ if (mSettings(mSolve, 'readForecastsInTheLoop') and ord(tSolve) >= tForecastNext
= ts_tertiary('wind', node, t+ddt(t), up_down, t)
* sum(flowUnit('wind', unit), p_gnu('elec', node, unit, 'maxGen'));
); // END IF readForecastsInTheLoop
$offtext
putclose log;
* --- Improve forecasts -------------------------------------------------------
*$ontext
......@@ -73,6 +85,13 @@ putclose log;
if(mSettings(mSolve, 'forecasts') > 0,
// Define updated time window
Option clear = tt_forecast;
tt_forecast(t_full(t))${ ord(t) >= ord(tSolve)
and ord(t) <= ord(tSolve) + mSettings(mSolve, 't_forecastLengthUnchanging') + mSettings(mSolve, 't_forecastJump')
}
= yes;
// Define updated time window
Option clear = tt;
tt(tt_forecast(t))${ ord(t) > ord(tSolve)
......
......@@ -130,8 +130,7 @@ tSolveFirst = ord(tSolve); // tSolveFirst: the start of the current solve, t0 u
// Is there any case where t_forecastLength should be larger than t_horizon?
// If not, add a check for mSettings(mSolve, 't_forecastLength') <= mSettings(mSolve, 't_horizon')
// and change the line below to 'tSolveLast = ord(tSolve) + mSettings(mSolve, 't_horizon');'
tSolveLast = ord(tSolve) + max(mSettings(mSolve, 't_forecastLength'), mSettings(mSolve, 't_horizon')); // tSolveLast: the end of the current solve
Option clear = t_current;
tSolveLast = ord(tSolve) + max(mSettings(mSolve, 't_forecastLengthUnchanging'), mSettings(mSolve, 't_horizon')); // tSolveLast: the end of the current solveOption clear = t_current;
t_current(t_full(t))${ ord(t) >= tSolveFirst
and ord (t) <= tSolveLast
}
......@@ -155,6 +154,10 @@ tCounter = 1;
cc(counter)${ mInterval(mSolve, 'intervalLength', counter) }
= yes;
currentForecastLength = min( mSettings(mSolve, 't_forecastLengthUnchanging'), // Unchanging forecast length would remain the same
mSettings(mSolve, 't_forecastLengthDecreasesFrom') - [mSettings(mSolve, 't_forecastJump') - {tForecastNext(mSolve) - tSolveFirst}] // While decreasing forecast length has a fixed horizon point and thus gets shorter
); // Smallest forecast horizon is selected
// Loop over the defined blocks of intervals
loop(cc(counter),
// Loop over defined samples
......@@ -191,7 +194,7 @@ loop(cc(counter),
msft(msf(mSolve, s, f_solve), tt_interval(t))${ not mf_central(mSolve, f_solve)
and not mf_realization(mSolve, f_solve)
and ord(t) > tSolveFirst + mSettings(mSolve, 't_jump')
and ord(t) < tSolveFirst + mSettings(mSolve, 't_forecastLength')
and ord(t) < tSolveFirst + currentForecastLength
}
= yes;
......@@ -252,7 +255,7 @@ loop(cc(counter),
msft(msf(mSolve, s, f_solve), tt_interval(t))${ not mf_central(mSolve, f_solve)
and not mf_realization(mSolve, f_solve)
and ord(t) > tSolveFirst + mSettings(mSolve, 't_jump')
and ord(t) < tSolveFirst + mSettings(mSolve, 't_forecastLength')
and ord(t) < tSolveFirst + currentForecastLength
}
= yes;
......@@ -359,7 +362,7 @@ df(f_solve(f), t_active(t))${ ord(t) <= tSolveFirst + mSettings(mSolve, 't_jump'
// Forecast displacement between central and forecasted timesteps at the end of forecast horizon
Option clear = df_central; // This can be reset.
df_central(ft(f,t))${ ord(t) = tSolveFirst + mSettings(mSolve, 't_forecastLength') - p_stepLength(mSolve, f, t) / mSettings(mSolve, 'intervalInHours')
df_central(ft(f,t))${ ord(t) = tSolveFirst + mSettings(mSolve, 't_forecastLengthUnchanging') - p_stepLength(mSolve, f, t) / mSettings(mSolve, 'intervalInHours')
and not mf_realization(mSolve, f)
}
= sum(mf_central(mSolve, f_), ord(f_) - ord(f));
......
......@@ -15,6 +15,34 @@ 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
* =============================================================================
* --- Controlling the use of previous solutions to have a first guess ---------
* =============================================================================
* 0 = no basis, 1 = latest solve, 2 = all solves, 3 = first solve
if (mSettings(mSolve, 'loadPoint') = 1 and solveCount > 1,
put_utility 'gdxin' / mSolve.tl:0 '_p.gdx';
execute_loadpoint;
elseif mSettings(mSolve, 'loadPoint') = 2,
put_utility 'gdxin' / 'schedule_p' solveCount:0:0 '.gdx';
execute_loadpoint;
elseif mSettings(mSolve, 'loadPoint') = 3 and solveCount = 1,
put_utility 'gdxin' / mSolve.tl:0 '_p.gdx';
execute_loadpoint;
);
if (mSettings(mSolve, 'savePoint') = 1,
option savepoint = 1;
elseif mSettings(mSolve, 'savePoint') = 2,
option savepoint = 2;
elseif mSettings(mSolve, 'savePoint') = 3 and solveCount = 1,
option savepoint = 1;
elseif mSettings(mSolve, 'savePoint') = 3 and solveCount > 1,
option savepoint = 0;
);
* =============================================================================
* --- Solve Commands ----------------------------------------------------------
* =============================================================================
......
......@@ -24,72 +24,91 @@ $offtext
* --- Result arrays required by model dynamics --------------------------------
if(tSolveFirst >= mSettings(mSolve, 'results_t_start') - mSettings(mSolve, 't_jump') and firstResultsOutputSolve,
firstResultsOutputSolve = 0;
r_state(gn_state(grid, node), f_solve, t) $[ord(t) = mSettings(mSolve, 'results_t_start')]
= v_state.l(grid, node, f_solve, t);
r_online(unit, f_solve, t)$[unit_online(unit) and ord(t) = mSettings(mSolve, 'results_t_start')]
= v_online_LP.l(unit, f_solve, t)$unit_online_LP(unit)
+ v_online_MIP.l(unit, f_solve, t)$unit_online_MIP(unit);
);
// Realized state history
r_state(gn_state(grid, node), ft_realized(f, t))
r_state(gn_state(grid, node), ft_realized(f, t))$[ord(t) > mSettings(mSolve, 'results_t_start')]
= v_state.l(grid, node, f, t)
;
// Realized unit online history
r_online(uft_online(unit, ft_realized(f, t)))
r_online(uft_online(unit, ft_realized(f, t)))$[ord(t) > mSettings(mSolve, 'results_t_start')]
= v_online_LP.l(unit, f, t)${ uft_onlineLP(unit, f, t) }
+ v_online_MIP.l(unit, f, t)${ uft_onlineMIP(unit, f, t) }
;
// Reserve provisions of units
r_reserve(nuRescapable(restype, up_down, node, unit), f_solve(f), t_active(t))${ mft_nReserves(node, restype, mSolve, f, t) or
sum(f_, df_nReserves(node, restype, f_, t)) or
[ ord(t) > tSolveFirst + mSettings(mSolve, 't_jump')
and ord(t) <= tSolveFirst + mSettings(mSolve, 't_jump') + p_nReserves(node, restype, 'gate_closure') - mod(tSolveFirst - 1 + mSettings(mSolve, 't_jump'), p_nReserves(node, restype, 'update_frequency'))
and tSolveFirst <= mSettings(mSolve, 't_end') - mSettings(mSolve, 't_jump')
]
}
r_reserve(nuRescapable(restype, up_down, node, unit), f_solve(f), t_active(t))${ [ord(t) > mSettings(mSolve, 'results_t_start')] and
(
mft_nReserves(node, restype, mSolve, f, t) or
sum(f_, df_nReserves(node, restype, f_, t)) or
[ ord(t) > tSolveFirst + mSettings(mSolve, 't_jump')
and ord(t) <= tSolveFirst + mSettings(mSolve, 't_jump') + p_nReserves(node, restype, 'gate_closure') - mod(tSolveFirst - 1 + mSettings(mSolve, 't_jump'), p_nReserves(node, restype, 'update_frequency'))
and tSolveFirst <= mSettings(mSolve, 't_end') - mSettings(mSolve, 't_jump')
]
)
}
= v_reserve.l(restype, up_down, node, unit, f, t)
;
// Reserve transfer capacity
r_resTransferRightward(restypeDirectionNode(restype, up_down, from_node), to_node, f_solve(f), t_active(t))${ restypeDirectionNode(restype, up_down, to_node)
and [ mft_nReserves(from_node, restype, mSolve, f, t)
or sum(f_, df_nReserves(from_node, restype, f_, t))
or [ ord(t) > tSolveFirst + mSettings(mSolve, 't_jump')
and ord(t) <= tSolveFirst + mSettings(mSolve, 't_jump') + p_nReserves(from_node, restype, 'gate_closure') - mod(tSolveFirst - 1 + mSettings(mSolve, 't_jump'), p_nReserves(from_node, restype, 'update_frequency'))
and tSolveFirst <= mSettings(mSolve, 't_end') - mSettings(mSolve, 't_jump')
]
]
}
r_resTransferRightward(restypeDirectionNode(restype, up_down, from_node), to_node, f_solve(f), t_active(t))${ [ord(t) > mSettings(mSolve, 'results_t_start')] and
(
restypeDirectionNode(restype, up_down, to_node)
and [ mft_nReserves(from_node, restype, mSolve, f, t)
or sum(f_, df_nReserves(from_node, restype, f_, t))
or [ ord(t) > tSolveFirst + mSettings(mSolve, 't_jump')
and ord(t) <= tSolveFirst + mSettings(mSolve, 't_jump') + p_nReserves(from_node, restype, 'gate_closure') - mod(tSolveFirst - 1 + mSettings(mSolve, 't_jump'), p_nReserves(from_node, restype, 'update_frequency'))
and tSolveFirst <= mSettings(mSolve, 't_end') - mSettings(mSolve, 't_jump')
]
]
)
}
= v_resTransferRightward.l(restype, up_down, from_node, to_node, f, t)
;
r_resTransferLeftward(restypeDirectionNode(restype, up_down, from_node), to_node, f_solve(f), t_active(t))${ restypeDirectionNode(restype, up_down, to_node)
and [ mft_nReserves(from_node, restype, mSolve, f, t)
or sum(f_, df_nReserves(from_node, restype, f_, t))
or [ ord(t) > tSolveFirst + mSettings(mSolve, 't_jump')
and ord(t) <= tSolveFirst + mSettings(mSolve, 't_jump') + p_nReserves(from_node, restype, 'gate_closure') - mod(tSolveFirst - 1 + mSettings(mSolve, 't_jump'), p_nReserves(from_node, restype, 'update_frequency'))
and tSolveFirst <= mSettings(mSolve, 't_end') - mSettings(mSolve, 't_jump')
]
]
}
r_resTransferLeftward(restypeDirectionNode(restype, up_down, from_node), to_node, f_solve(f), t_active(t))${ [ord(t) > mSettings(mSolve, 'results_t_start')] and
(
{ restypeDirectionNode(restype, up_down, to_node)
and [ mft_nReserves(from_node, restype, mSolve, f, t)
or sum(f_, df_nReserves(from_node, restype, f_, t))
or [ ord(t) > tSolveFirst + mSettings(mSolve, 't_jump')
and ord(t) <= tSolveFirst + mSettings(mSolve, 't_jump') + p_nReserves(from_node, restype, 'gate_closure') - mod(tSolveFirst - 1 + mSettings(mSolve, 't_jump'), p_nReserves(from_node, restype, 'update_frequency'))
and tSolveFirst <= mSettings(mSolve, 't_end') - mSettings(mSolve, 't_jump')
]
]
}
)
}
= v_resTransferLeftward.l(restype, up_down, from_node, to_node, f, t)
;
// Unit startup and shutdown history
r_startup(unit, starttype, ft_realized(f, t))${ uft_online(unit, f, t) }
r_startup(unit, starttype, ft_realized(f, t))${ uft_online(unit, f, t) and [ord(t) > mSettings(mSolve, 'results_t_start')] }
= v_startup.l(unit, starttype, f, t)
;
r_shutdown(uft_online(unit, ft_realized(f, t)))
r_shutdown(uft_online(unit, ft_realized(f, t)))$[ord(t) > mSettings(mSolve, 'results_t_start')]
= v_shutdown.l(unit, f, t)
;
* --- Interesting results -----------------------------------------------------
// Unit generation and consumption
r_gen(gnuft(grid, node, unit, ft_realized(f, t)))
r_gen(gnuft(grid, node, unit, ft_realized(f, t)))$[ord(t) > mSettings(mSolve, 'results_t_start')]
= v_gen.l(grid, node, unit, f, t)
;
// Fuel use of units
r_fuelUse(fuel, uft(unit_fuel, ft_realized(f, t)))
r_fuelUse(fuel, uft(unit_fuel, ft_realized(f, t)))$[ord(t) > mSettings(mSolve, 'results_t_start')]
= v_fuelUse.l(fuel, unit_fuel, f, t)
;
// Transfer of energy between nodes
r_transfer(gn2n(grid, from_node, to_node), ft_realized(f, t))
r_transfer(gn2n(grid, from_node, to_node), ft_realized(f, t))$[ord(t) > mSettings(mSolve, 'results_t_start')]
= v_transfer.l(grid, from_node, to_node, f, t)
;
// Energy spilled from nodes
r_spill(gn(grid, node), ft_realized(f, t))
r_spill(gn(grid, node), ft_realized(f, t))$[ord(t) > mSettings(mSolve, 'results_t_start')]
= v_spill.l(grid, node, f, t)
;
// Total Objective function
......@@ -97,15 +116,15 @@ r_totalObj
= r_totalObj + v_obj.l
;
// q_balance marginal values
r_balanceMarginal(gn(grid, node), ft_realized(f, t))
r_balanceMarginal(gn(grid, node), ft_realized(f, t))$[ord(t) > mSettings(mSolve, 'results_t_start')]
= q_balance.m(grid, node, mSolve, f, t)
;
// q_resDemand marginal values
r_resDemandMarginal(restypeDirectionNode(restype, up_down, node), ft_realized(f, t))
r_resDemandMarginal(restypeDirectionNode(restype, up_down, node), ft_realized(f, t))$[ord(t) > mSettings(mSolve, 'results_t_start')]
= q_resDemand.m(restype, up_down, node, f, t)
;
// v_stateSlack values for calculation of realized costs later on
r_stateSlack(gn_stateSlack(grid, node), slack, ft_realized(f, t))
r_stateSlack(gn_stateSlack(grid, node), slack, ft_realized(f, t))$[ord(t) > mSettings(mSolve, 'results_t_start')]
= v_stateSlack.l(grid, node, slack, f, t)
;
// Unit investments
......@@ -116,11 +135,11 @@ r_unitInvestment(unit)${unit_investLP(unit) or unit_investMIP(unit)}
* --- Feasibility results -----------------------------------------------------
// Dummy generation & consumption
r_qGen(inc_dec, gn(grid, node), ft_realized(f, t))
r_qGen(inc_dec, gn(grid, node), ft_realized(f, t))$[ord(t) > mSettings(mSolve, 'results_t_start')]
= vq_gen.l(inc_dec, grid, node, f, t)
;
// Dummy reserve demand changes
r_qResDemand(restypeDirectionNode(restype, up_down, node), ft_realized(f, t))
r_qResDemand(restypeDirectionNode(restype, up_down, node), ft_realized(f, t))$[ord(t) > mSettings(mSolve, 'results_t_start')]
= vq_resDemand.l(restype, up_down, node, f, t)
;
......
......@@ -25,14 +25,14 @@ loop(m,
* --- Realized Individual Costs ----------------------------------------------
// Variable O&M costs
r_gnuVOMCost(gnu_output(grid, node, unit), ft_realizedNoReset(f,t))
r_gnuVOMCost(gnu_output(grid, node, unit), ft_realizedNoReset(f,t))$[ord(t) > mSettings(m, 'results_t_start')]
= 1e-6 // Scaling to MEUR
* p_stepLengthNoReset(m, f, t)
* r_gen(grid, node, unit, f, t)
* p_unit(unit, 'omCosts');
// Fuel and emission costs during normal operation
r_uFuelEmissionCost(fuel, unit_fuel(unit), ft_realizedNoReset(f,t))${ uFuel(unit, 'main', fuel) }
r_uFuelEmissionCost(fuel, unit_fuel(unit), ft_realizedNoReset(f,t))${ uFuel(unit, 'main', fuel) and [ord(t) > mSettings(m, 'results_t_start')]}
= 1e-6 // Scaling to MEUR
* p_stepLengthNoReset(m, f, t)
* r_fuelUse(fuel, unit, f, t)
......@@ -43,7 +43,7 @@ loop(m,
];
// Unit startup costs
r_uStartupCost(unit, ft_realizedNoReset(f,t))${ sum(starttype, unitStarttype(unit, starttype)) }
r_uStartupCost(unit, ft_realizedNoReset(f,t))${ sum(starttype, unitStarttype(unit, starttype)) and [ord(t) > mSettings(m, 'results_t_start')]}
= 1e-6 // Scaling to MEUR
* sum(unitStarttype(unit, starttype),
+ r_startup(unit, starttype, f, t)
......@@ -65,7 +65,7 @@ loop(m,
); // END sum(unitStarttype)
// Node state slack costs
r_gnStateSlackCost(gn_stateSlack(grid, node), ft_realizedNoReset(f,t))
r_gnStateSlackCost(gn_stateSlack(grid, node), ft_realizedNoReset(f,t))$[ord(t) > mSettings(m, 'results_t_start')]
= 1e-6 // Scaling to MEUR