@@ -23,13 +23,16 @@ Backbone has been designed with a modular structure, making it easier to change

* 1d_results.gms - Contains definitions for the model results.

* 1e_inputs.gms - Contains instructions on how to load input data, as well as forms a lot of helpful sets based on said data, for example in order to facilitate writing the constraints.

* 2a_variables.gms - Contains variable definitions used by the models.

* 2b_equations.gms - Contains the equation definitions for the models.

* 2b_eqDeclarations.gms - Contains equation declarations for the models.

* 2c_objective.gms - Contains the objective function definition.

* 2d_constraints.gms - Contains definitions for constraint equations.

**Model Definition Files* - Contains GAMS definitions for different models, essentially lists the equations (constraints) that apply. Current files include *schedule.gms*, *building.gms* and *invest.gms*.

* 3a_periodicInit.gms - Initializes various data and sets for the solve loop.

* 3b_inputsLoop.gms - Instructions for possible data import inside the solve loop, as well as forecast in-the-loop improvements.

* 3c_periodicLoop.gms - Contains instructions for the forecast-time structure of the desired model.

* 3d_setVariableLimits.gms - Defines the variable boundaries for each solve.

* 3e_solve.gms - Contains the GAMS solve command for using the solver.

* 3f_afterSolve.gms - Fixes some variable values after solve.

* 4a_outputVariant.gms - Contains instructions for storing desired results during the solve loop.

* 4b_outputInvariant.gms - Calculates further results post-solve.

* 4c_outputQuickFile.gms

...

...

@@ -37,10 +40,11 @@ Backbone has been designed with a modular structure, making it easier to change

Most of these files are under *\inc* in the Backbone folder, except for the model definition files being housed under *\defModels*. Other than the abovementioned files, a few key input files are required for Backbone to work. These are assumed to be found under *\input* and are briefly described below.

* inputData.gdx - Contains most of the input data about the system to be modelled.

* 1_options.gms - Contains options to control the solver. Not required but included if exists.

* timeAndSamples.inc - Contains definitions for the time, forecast and sample index ranges.

* modelsInit.gms - Contains model parameters for the solve (or a link to a template under *\defModels* to be used). Useful for any additional GAMS scripting.

Backbone folder contains two template files *timeAndSamples_temp.inc* and *modelsInit_temp.gms* to provide examples of the input format. These files can be copied into *\input* and renamed to *timeAndSamples.inc* and *modelsInit.gms*.

Backbone folder contains three template files *1_options_temp.gms*, *timeAndSamples_temp.inc*, and *modelsInit_temp.gms* to provide examples of the input format. These files can be copied into *\input* and renamed to *1_options.gms*, *timeAndSamples.inc*, and *modelsInit.gms*.

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_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;

// Define Realized and Central forecasts

...

...

@@ -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;

...

...

@@ -113,16 +113,19 @@ if (mType('invest'),

// Define unit aggregation and efficiency levels starting indeces

mSettingsEff('invest', 'level1') = 1;

* ---- Define output settings for results

// Define threshold for omitting start-up and shutdown trajectories

mSettings('invest', '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;

mSettings('invest', '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

* --- Control the solver ------------------------------------------------------

// Control the use of advanced basis

mSettings('invest', 'loadPoint') = 2; // 0 = no basis, 1 = latest solve, 2 = all solves, 3 = first solve

mSettings('invest', 'savePoint') = 2; // 0 = no basis, 1 = latest solve, 2 = all solves, 3 = first solve

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_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)

t_start, // First time step for the start of simulation

t_jump, // Number of time steps realized with each solve

t_horizon, // Length of the simulation horizon (central forecast)

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, // End index of a time step interval

loadPoint, // Load advanced basis; 0 = no basis, 1 = latest solve, 2 = all solves, 3 = first solve

savePoint, // Save advanced basis; 0 = no basis, 1 = latest solve, 2 = all solves, 3 = 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

...

...

@@ -53,7 +53,8 @@ Sets

// Features

t_reserveLength, // Length of reserve provision horizon in time steps

t_aggregate, // Unit aggregation threshold time index

results_t_start // time period where results outputting starts

t_omitTrajectories, // Threshold time index for omitting start-up and shutdown trajectories

results_t_start // Time index where results outputting starts

/

// Solve info

...

...

@@ -141,8 +142,6 @@ Sets

/ hot, warm /

cost_consumption "Startup cost or startup fuel consumption"

/ cost, consumption /

unit_capacity "Unit or capacity based parameter"

/ unit, capacity / // Is capacity needed anymore?

// Other Features

feature "Set of optional model features" /

...

...

@@ -212,8 +211,8 @@ Sets

* --- Parameter Data Related Sets ---------------------------------------------

param_gn "Possible parameters for grid, node" /

selfDischargeLoss "Self discharge rate of the node [MW/v_state]"

energyStoredPerUnitOfState "A possible unit conversion if v_state uses something else than MWh"

selfDischargeLoss "Self discharge rate of the node (MW/[v_state])"

energyStoredPerUnitOfState "A possible unit conversion if v_state uses something else than MWh (MWh/[v_state])"

boundStart "A flag to bound the first t in the run using reference constant or time series"

boundStartAndEnd "A flag that both start and end are bound using reference constant or time series"

boundEnd "A flag to bound last t in each solve based on the reference constant or time series"

...

...

@@ -245,93 +244,94 @@ param_gnBoundaryProperties "Properties that can be set for the different boundar

/

param_gnn "Set of possible data parameters for grid, node, node (nodal interconnections)" /

transferCap "Transfer capacity limits"

transferCapBidirectional "Total bidirectional transfer capacity limit"

transferLoss "Transfer losses"

diffCoeff "Coefficients for energy diffusion between nodes"

boundStateMaxDiff "Maximum difference of node state pairs"

transferCap "Transfer capacity limits (MW)"

transferCapBidirectional "Total bidirectional transfer capacity limit (MW)"

transferLoss "Transfer losses"

diffCoeff "Coefficients for energy diffusion between nodes (MW/[v_state])"

boundStateMaxDiff "Maximum difference of node state pairs ([v_state])"

transferCapInvLimit "Capacity limit for investments (MW)"

investMIP "Choice of making integer investment instead of continous investment (MW versus number of links)"

unitSize "Size of one link for integer investments (MW)"

invCost "Investment cost (/MW)"

annuity "Investment annuity"

investMIP "A flag to make integer investment instead of continous investment (MW versus number of links)"

unitSize "Size of one link for integer investments (MW)"

invCost "Investment cost (EUR/MW)"

annuity "Investment annuity"

/

param_gnu "Set of possible data parameters for grid, node, unit" /

maxGen "Maximum output capacity (MW)"

maxCons "Maximum loading capacity (MW)"

cB "Share of output"

cV "Reduction in primary output when increasing secondary output, e.g. reduction of electricity generation due to heat generation in extraction CHP (MWh_e/MWh_h)"

maxRampUp "Speed to ramp up (p.u. / min)"

maxRampDown "Speed to ramp down (p.u. / min)"

rampUpCost "Wear and tear cost of ramping up (/MW)"

rampDownCost "Wear and tear cost of ramping down (/MW)"

upperLimitCapacityRatio "Ratio of the upper limit of the node state and the unit capacity investment"

unitSizeGen "Output capacity of one unit for integer investments (MW)"

unitSizeCons "Loading capacity of one unit for integer investments (MW)"

unitSizeTot "Sum of output and loading capacity of one unit (MW)"

unitSizeGenNet "Output minus loading capacity of one unit (MW)"

invCosts "Investment costs (/MW)"

annuity "Investment annuity factor"

fomCosts "Fixed operation and maintenance costs (/MW/a)"

inertia "Inertia of the unit (s)"

unitSizeMVA "Generator MVA rating (MVA)"

maxGen "Maximum output capacity (MW)"

maxCons "Maximum loading capacity (MW)"

cB "Share of output"

cV "Reduction in primary output when increasing secondary output, e.g. reduction of electricity generation due to heat generation in extraction CHP (MWh_e/MWh_h)"

maxRampUp "Speed to ramp up (p.u./min)"

maxRampDown "Speed to ramp down (p.u./min)"

rampUpCost "Wear and tear cost of ramping up (EUR/MW)" // redundant

rampDownCost "Wear and tear cost of ramping down (EUR/MW)" // redundant

upperLimitCapacityRatio "Ratio of the upper limit of the node state and the unit capacity investment ([v_state]/MW)"

unitSizeGen "Output capacity of one subunit for integer investments (MW)"

unitSizeCons "Loading capacity of one subunit for integer investments (MW)"

unitSizeTot "Sum of output and loading capacity of one subunit (MW)"

invCosts "Investment costs (EUR/MW)"

annuity "Investment annuity factor"

fomCosts "Fixed operation and maintenance costs (EUR/MW/a)"

inertia "Inertia of the unit (s)"

unitSizeMVA "Generator MVA rating of one subunit (MVA)"

/

param_gnuBoundaryProperties "Properties that can be set for the different boundaries" /

rampLimit "Maximum ramp speed (p.u./min)"

rampCost "Wear and tear cost of ramping up (EUR/MW)"

/

param_unit "Set of possible data parameters for units" /

unitCount "Number of subunits if aggregated"

unitCount "Number of subunits if aggregated"

outputCapacityTotal "Output capacity of the unit, calculated by summing all the outputs together by default, unless defined in data"

unitOutputCapacityTotal "Output capacity of the unit, calculated by summing all the unit output sizes together by default"

availability "Availability of given energy conversion technology (p.u.)"

omCosts "Variable operation and maintenance costs (/MWh)"

lastCounter "last member in use of the general counter"

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"

* intervalLength "Length of the interval to be calculated, considering end of modelling period" // redundant

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"

...

...

@@ -49,6 +49,7 @@ Parameters

p_gnBoundaryPropertiesForStates(grid, node, param_gnBoundaryTypes, param_gnBoundaryProperties) "Properties of different state boundaries and limits"

p_gnn(grid, node, node, param_gnn) "Data for interconnections between energy nodes"

p_gnu(grid, node, unit, param_gnu) "Unit data where energy type matters"

p_gnuBoundaryProperties(grid, node, unit, slack, param_gnuBoundaryProperties) "Properties for unit boundaries where energy type matters"

p_unit(unit, *) "Unit data where energy type does not matter"

p_nReserves(node, restype, *) "Data defining the reserve rules in each node"

p_nuReserves(node, unit, restype, *) "Reserve provision data for units"

...

...

@@ -61,11 +62,15 @@ Parameters

p_effUnit(effSelector, unit, effSelector, *) "Data for piece-wise linear efficiency blocks"

p_effGroupUnit(effSelector, unit, *) "Unit data specific to a efficiency group (e.g. left border of the unit)"

p_uNonoperational(unit, starttype, min_max) "Non-operational time after being shut down before start up"

p_uStartup(unit, starttype, cost_consumption, unit_capacity) "Startup cost and fuel consumption"

p_uStartup(unit, starttype, cost_consumption) "Startup cost and fuel consumption"

p_u_maxOutputInLastRunUpInterval(unit) "Maximum output in the last interval for the run-up to min. load (p.u.)"

p_u_runUpTimeIntervals(unit) "Time intervals required for the run-up phase"

p_u_runUpTimeIntervalsCeil(unit) "Ceiling of time intervals required for the run-up phase"

p_ut_runUp(unit, t) "Output for the time intervals where the unit is being started up to the minimum load (minimum output in the last interval) (p.u.)"

p_u_runUpTimeIntervals(unit) "Time steps required for the run-up phase"

p_u_runUpTimeIntervalsCeil(unit) "Ceiling of time steps required for the run-up phase"

p_ut_runUp(unit, t) "Output for the time steps where the unit is being started up to the minimum load (minimum output in the last interval) (p.u.)"

p_u_maxOutputInFirstShutdownInterval(unit) "Maximum output in the first interval for the shutdown from min. load (p.u.)"

p_u_shutdownTimeIntervals(unit) "Time steps required for the shutdown phase"

p_u_shutdownTimeIntervalsCeil(unit) "Ceiling of time steps required for the shutdown phase"

p_ut_shutdown(unit, t) "Output for the time steps where the unit is being shut down from the minimum load (minimum output in the first interval) (p.u.)"

// Time dependent unit & fuel parameters

ts_unit(unit, *, f, t) "Time dependent unit data, where energy type doesn't matter"

ts_effUnit(effSelector, unit, effSelector, *, f, t) "Time dependent data for piece-wise linear efficiency blocks"

...

...

@@ -87,46 +92,47 @@ Scalar p_sWeightSum "Sum of sample weights";

* --- Model structure ---------------------------------------------------------

Parameters

// Time displacement arrays

dt(t) "Displacement needed to reach the previous time period (in time periods)"

dt_noReset(t) "Displacement needed to reach the previous time period (in time periods)"

dt(t) "Displacement needed to reach the previous time interval (in time steps)"

dt_noReset(t) "Displacement needed to reach the previous time interval (in time steps)"

dt_circular(t) "Circular t displacement if the time series data is not long enough to cover the model horizon"

dt_next(t) "Displacement needed to reach the next time period (in time periods)"

dtt(t, t) "Displacement needed to reach any previous time period (in time periods)"

dt_toStartup(unit, t) "Displacement from the current time period to the time period where the unit has been started up in case online variable changes from 0 to 1"

dt_starttypeUnitCounter(starttype, unit, counter) "Displacement needed to account for starttype constraints"

dt_downtimeUnitCounter(unit, counter) "Displacement needed to account for downtime constraints"

dt_uptimeUnitCounter(unit, counter) "Displacement needed to account for uptime constraints"

dt_next(t) "Displacement needed to reach the next time interval (in time steps)"

dtt(t, t) "Displacement needed to reach any previous time interval (in time steps)"

dt_toStartup(unit, t) "Displacement from the current time interval to the time interval where the unit was started up in case online variable changes from 0 to 1 (in time steps)"

dt_toShutdown(unit, t) "Displacement from the current time interval to the time interval where the shutdown phase began in case generation becomes 0 (in time steps)"

dt_starttypeUnitCounter(starttype, unit, counter) "Displacement needed to account for starttype constraints (in time steps)"

dt_downtimeUnitCounter(unit, counter) "Displacement needed to account for downtime constraints (in time steps)"

dt_uptimeUnitCounter(unit, counter) "Displacement needed to account for uptime constraints (in time steps)"

// Forecast displacement arrays

df(f, t) "Displacement needed to reach the realized forecast on the current time step"

df_central(f, t) "Displacement needed to reach the central forecast - this is needed when the forecast tree gets reduced in dynamic equations"

df_nReserves(node, restype, f, t) "Forecast index displacement needed to reach the realized forecast when committing reserves."

df_nReserves(node, restype, f, t) "Forecast index displacement needed to reach the realized forecast when committing reserves"