Commit 4ec02a9b authored by Niina Helistö's avatar Niina Helistö
Browse files

Adding the grid dimension to the reserve parameters and variables. Changes...

Adding the grid dimension to the reserve parameters and variables. Changes required to the input files. Removing the obsolete nuft set. Issue #69.
parent 67f18153
......@@ -134,10 +134,11 @@ r_resTransferLeftward
// Interesting reserve results
r_resDemandMarginal
r_nuTotalReserve
r_nuTotalReserveShare
r_nTotalReserve
r_gnuTotalReserve
r_gnuTotalReserveShare
r_groupTotalReserve
r_resDemandLargestInfeedUnit
* --- Investment Result Symbols -----------------------------------------------
// Interesting investment results
......@@ -152,7 +153,7 @@ r_gnTotalqGen
r_gTotalqGen
r_qResDemand
r_qResMissing
r_nTotalqResDemand
r_groupTotalqResDemand
r_qCapacity
r_solveStatus
......
......@@ -78,11 +78,11 @@ Sets
* --- Reserve types -----------------------------------------------------------
restype "Reserve types"
restypeDirection(restype, up_down) "Different combinations of reserve types and directions"
restypeDirectionNode(restype, up_down, node) "Nodes with reserve requirements"
resTypeDirectionNodeNode(restype, up_down, node, node) "Node node connections that can transfer reserves"
restypeDirectionGridNode(restype, up_down, grid, node) "Nodes with reserve requirements"
resTypeDirectionGridNodeNode(restype, up_down, grid, node, node) "Node node connections that can transfer reserves"
restypeDirectionGroup(restype, up_down, group)
restypeDirectionGridNodeGroup(restype, up_down, grid, node, group)
nuRescapable(restype, up_down, node, unit) "Units capable and available to provide particular reserves"
gnuRescapable(restype, up_down, grid, node, unit) "Units capable and available to provide particular reserves"
restypeReleasedForRealization(restype) "Reserve types that are released for the realized time intervals"
* --- Sets to define time, forecasts and samples ------------------------------
......@@ -143,7 +143,7 @@ $if defined scenario
uft_startupTrajectory(unit, f, t) "Units with start-up trajectories on intervals"
uft_shutdownTrajectory(unit, f, t) "Units with shutdown trajectories on intervals"
uft_aggregator_first(unit, f, t) "The first intervals when aggregator units are active"
nuft(node, unit, f, t) "Enables aggregation of nodes and units for later intervals"
* nuft(node, unit, f, t) "Enables aggregation of nodes and units for later intervals"
gnuft(grid, node, unit, f, t) "Enables aggregation of nodes and units for later intervals"
gnuft_ramp(grid, node, unit, f, t) "Units with ramp requirements or costs"
gnuft_rampCost(grid, node, unit, slack, f, t) "Units with ramp costs"
......
......@@ -51,13 +51,13 @@ Parameters
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, param_unit) "Unit data where energy type does not matter"
p_nReserves(node, restype, *) "Data defining the reserve rules in each node"
p_gnReserves(grid, node, restype, *) "Data defining the reserve rules in each node"
p_groupReserves(group, restype, *) "Data defining the reserve rules in each node group"
p_groupReserves3D(group, restype, up_down, param_policy) "Reserve policy in each node group separately for each reserve type and direction"
p_groupReserves4D(group, restype, up_down, group, param_policy) "Reserve policy in each node group separately for each reserve type and direction, also linking to another group"
p_nuReserves(node, unit, restype, *) "Reserve provision data for units"
p_nnReserves(node, node, restype, up_down) "Reserve provision data for node node connections"
p_nuRes2Res(node, unit, restype, up_down, restype) "The first type of reserve can be used also in the second reserve category (with a possible multiplier)"
p_gnuReserves(grid, node, unit, restype, *) "Reserve provision data for units"
p_gnnReserves(grid, node, node, restype, up_down) "Reserve provision data for node node connections"
p_gnuRes2Res(grid, node, unit, restype, up_down, restype) "The first type of reserve can be used also in the second reserve category (with a possible multiplier)"
p_gnPolicy(grid, node, param_policy, *) "Policy data for grid, node"
p_groupPolicy(group, param_policy) "Two-dimensional policy data for groups"
p_groupPolicy3D(group, param_policy, *) "Three-dimensional policy data for groups"
......@@ -127,7 +127,7 @@ Parameters
// 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_reserves(node, restype, f, t) "Forecast index displacement needed to reach the realized forecast when committing reserves"
df_reserves(grid, node, restype, f, t) "Forecast index displacement needed to reach the realized forecast when committing reserves"
df_reservesGroup(group, restype, f, t) "Forecast index displacement needed to reach the realized forecast when committing reserves"
df_scenario(f, t) "Forecast index displacement needed to get central forecast data for long-term scenarios"
......
......@@ -130,17 +130,17 @@ Parameters
* --- Reserve Provision Results -----------------------------------------------
// Reserve provision results required for model structure
r_reserve(restype, up_down, node, unit, f, t) "Unit capacity reserved for providing reserve of specific type (MW)"
r_resTransferRightward(restype, up_down, node, node, f, t) "Electricity transmission capacity from the first node to the second node reserved for providing reserves (MW)"
r_resTransferLeftward(restype, up_down, node, node, f, t) "Electricity transmission capacity from the second node to the first node reserved for providing reserves (MW)"
r_reserve2Reserve(restype, up_down, node, unit, restype, f, t) "Reserve provided for another reserve category (MW) (also included in r_reserve - this is just for debugging)"
r_reserve(restype, up_down, grid, node, unit, f, t) "Unit capacity reserved for providing reserve of specific type (MW)"
r_resTransferRightward(restype, up_down, grid, node, node, f, t) "Electricity transmission capacity from the first node to the second node reserved for providing reserves (MW)"
r_resTransferLeftward(restype, up_down, grid, node, node, f, t) "Electricity transmission capacity from the second node to the first node reserved for providing reserves (MW)"
r_reserve2Reserve(restype, up_down, grid, node, unit, restype, f, t) "Reserve provided for another reserve category (MW) (also included in r_reserve - this is just for debugging)"
// Interesting reserve results
r_resDemandMarginal(restype, up_down, group, f, t) "Marginal values of the q_resDemand equation"
r_nuTotalReserve(restype, up_down, node, unit) "Total nu reserve provision over the simulation (MW*h)"
r_nuTotalReserveShare(restype, up_down, node, unit) "Total nu/n reserve provision share over the simulation"
r_nTotalReserve(restype, up_down, node) "Total reserve provisions in nodes over the simulation (MW*h)"
r_resDemandLargestInfeedUnit(grid, f, t, restype, up_down, node) "Reserve Demand from the loss of largest infeed unit"
r_gnuTotalReserve(restype, up_down, grid, node, unit) "Total gnu reserve provision over the simulation (MW*h)"
r_gnuTotalReserveShare(restype, up_down, grid, node, unit) "Total gnu/group reserve provision share over the simulation"
r_groupTotalReserve(restype, up_down, group) "Total reserve provisions in groups over the simulation (MW*h)"
r_resDemandLargestInfeedUnit(restype, up_down, group, f, t) "Reserve Demand from the loss of largest infeed unit"
* --- Investment Results ------------------------------------------------------
......@@ -156,7 +156,7 @@ Parameters
r_gTotalqGen(inc_dec, grid) "Total dummy energy generation/consumption in g over the simulation (MWh)."
r_qResDemand(restype, up_down, group, f, t) "Dummy to decrease demand for a reserve (MW) before reserve commitment"
r_qResMissing(restype, up_down, group, f, t) "Dummy to decrease demand for a reserve (MW) after reserve commitment"
r_nTotalqResDemand(restype, up_down, group) "Total dummy reserve provisions in n over the simulation"
r_groupTotalqResDemand(restype, up_down, group) "Total dummy reserve provisions in the group over the simulation"
r_qCapacity(grid, node, f, t) "Dummy capacity to ensure capacity margin equation feasibility (MW)"
r_solveStatus(t, solve_info) "Information about the solve"
......
......@@ -45,9 +45,9 @@ $ifthen exist '%input_dir%/inputData.gdx'
$$loaddc p_groupReserves
$$loaddc p_groupReserves3D
$$loaddc p_groupReserves4D
$$loaddc p_nuReserves
$$loaddc p_nnReserves
$$loaddc p_nuRes2Res
$$loaddc p_gnuReserves
$$loaddc p_gnnReserves
$$loaddc p_gnuRes2Res
$$loaddc ts_reserveDemand
$$loaddc p_gnBoundaryPropertiesForStates
$$loaddc p_gnPolicy
......@@ -94,7 +94,7 @@ gngnu_constrainedOutputRatio
restype
restypeReleasedForRealization
p_gnn
p_nnReserves
p_gnnReserves
p_gnuBoundaryProperties
ts_node
ts_reserveDemand
......@@ -402,31 +402,31 @@ flowNode(flow, node)${ sum((f, t), ts_cf(flow, node, f, t))
// NOTE! Reserves can be disabled through the model settings file.
// The sets are disabled in "3a_periodicInit.gms" accordingly.
// Copy data from p_groupReserves to p_nReserves
// Copy data from p_groupReserves to p_gnReserves
loop(gnGroup(grid, node, group)${sum(restype, p_groupReserves(group, restype, 'reserve_length'))},
p_nReserves(node, restype, param_policy) = p_groupReserves(group, restype, param_policy);
p_nReserves(node, restype, up_down) = p_groupReserves(group, restype, up_down);
p_gnReserves(grid, node, restype, param_policy) = p_groupReserves(group, restype, param_policy);
p_gnReserves(grid, node, restype, up_down) = p_groupReserves(group, restype, up_down);
);
// Units with reserve provision capabilities
nuRescapable(restypeDirection(restype, up_down), nu(node, unit))
$ { p_nuReserves(node, unit, restype, up_down)
gnuRescapable(restypeDirection(restype, up_down), gnu(grid, node, unit))
$ { p_gnuReserves(grid, node, unit, restype, up_down)
}
= yes;
// Node-node connections with reserve transfer capabilities
restypeDirectionNodeNode(restypeDirection(restype, up_down), node, node_)
$ { p_nnReserves(node, node_, restype, up_down)
restypeDirectionGridNodeNode(restypeDirection(restype, up_down), gn2n(grid, node, node_))
$ { p_gnnReserves(grid, node, node_, restype, up_down)
}
= yes;
// Nodes with reserve requirements, units capable of providing reserves, or reserve capable connections
restypeDirectionNode(restypeDirection(restype, up_down), node)
$ { p_nReserves(node, restype, up_down)
or p_nReserves(node, restype, 'use_time_series')
or sum(nu(node, unit), p_nuReserves(node, unit, restype, 'portion_of_infeed_to_reserve'))
or sum(nu(node, unit), nuRescapable(restype, up_down, node, unit))
or sum(gn2n(grid, node, to_node), restypeDirectionNodeNode(restype, up_down, node, to_node))
restypeDirectionGridNode(restypeDirection(restype, up_down), gn(grid, node))
$ { p_gnReserves(grid, node, restype, up_down)
or p_gnReserves(grid, node, restype, 'use_time_series')
or sum(gnu(grid, node, unit), p_gnuReserves(grid, node, unit, restype, 'portion_of_infeed_to_reserve'))
or sum(gnu(grid, node, unit), gnuRescapable(restype, up_down, grid, node, unit))
or sum(gn2n(grid, node, to_node), restypeDirectionGridNodeNode(restype, up_down, grid, node, to_node))
}
= yes;
......@@ -443,19 +443,19 @@ restypeDirectionGridNodeGroup(restypeDirection(restype, up_down), gnGroup(grid,
* --- Correct values for critical reserve related parameters ------------------
// Reserve reliability assumed to be perfect if not provided in data
p_nuReserves(nu(node, unit), restype, 'reserveReliability')
${ not p_nuReserves(node, unit, restype, 'reserveReliability')
and sum(up_down, nuRescapable(restype, up_down, node, unit))
p_gnuReserves(gnu(grid, node, unit), restype, 'reserveReliability')
${ not p_gnuReserves(grid, node, unit, restype, 'reserveReliability')
and sum(up_down, gnuRescapable(restype, up_down, grid, node, unit))
}
= 1;
// Reserve provision overlap decreases the capacity of the overlapping category
p_nuReserves(nu(node, unit), restype, up_down)
${ nuRescapable(restype, up_down, node, unit) }
= p_nuReserves(node, unit, restype, up_down)
- sum(restype_${ p_nuRes2Res(node, unit, restype_, up_down, restype) },
+ p_nuReserves(node, unit, restype_, up_down)
* p_nuRes2Res(node, unit, restype_, up_down, restype)
p_gnuReserves(gnu(grid, node, unit), restype, up_down)
${ gnuRescapable(restype, up_down, grid, node, unit) }
= p_gnuReserves(grid, node, unit, restype, up_down)
- sum(restype_${ p_gnuRes2Res(grid, node, unit, restype_, up_down, restype) },
+ p_gnuReserves(grid, node, unit, restype_, up_down)
* p_gnuRes2Res(grid, node, unit, restype_, up_down, restype)
); // END sum(restype_)
* =============================================================================
......@@ -563,9 +563,9 @@ loop( unitStarttype(unit, starttypeConstrained),
* --- Check reserve related data ----------------------------------------------
// Check that reserve_length is long enough for properly commitment of reserves
loop( restypeDirectionNode(restype, up_down, node),
loop( restypeDirectionGridNode(restype, up_down, grid, node),
// Check that reserve_length is long enough for properly commitment of reserves
if(p_nReserves(node, restype, 'reserve_length') < p_nReserves(node, restype, 'update_frequency') + p_nReserves(node, restype, 'gate_closure'),
if(p_gnReserves(grid, node, restype, 'reserve_length') < p_gnReserves(grid, node, restype, 'update_frequency') + p_gnReserves(grid, node, restype, 'gate_closure'),
put log '!!! Error occurred on node ', node.tl:0 /;
put log '!!! Abort: The reserve_length parameter should be longer than update_frequency + gate_closure to fix the reserves properly!' /;
abort "The 'reserve_length' parameter should be longer than 'update_frequency' + 'gate_closure' to fix the reserves properly!"
......@@ -585,13 +585,13 @@ loop( restypeDirectionNode(restype, up_down, node),
); // END loop(restypeDirectionNode)
// Check that reserve overlaps are possible
loop( (nu(node, unit), restypeDirection(restype, up_down)),
if( p_nuReserves(node, unit, restype, up_down) < 0,
loop( (gnu(grid, node, unit), restypeDirection(restype, up_down)),
if( p_gnuReserves(grid, node, unit, restype, up_down) < 0,
put log '!!! Error occurred on unit ', unit.tl:0 /;
put log '!!! Abort: Overlapping reserve capacities in p_nuRes2Res can result in excess reserve production!' /;
abort "Overlapping reserve capacities in p_nuRes2Res can result in excess reserve production!"
); // END if(p_nuReserves)
); // END loop((nu,restypeDirection))
put log '!!! Abort: Overlapping reserve capacities in p_gnuRes2Res can result in excess reserve production!' /;
abort "Overlapping reserve capacities in p_gnuRes2Res can result in excess reserve production!"
); // END if(p_gnuReserves)
); // END loop((gnu,restypeDirection))
* =============================================================================
......
......@@ -43,9 +43,9 @@ Positive variables
v_spill(grid, node, s, f, t) "Spill of energy from storage node during an interval (MWh)"
v_transferRightward(grid, node, node, s, f, t) "Average electricity transmission level from the first node to the second node during an interval (MW)"
v_transferLeftward(grid, node, node, s, f, t) "Average electricity transmission level from the second node to the first node during an interval (MW)"
v_resTransferRightward(restype, up_down, node, node, s, f, t) "Electricity transmission capacity from the first node to the second node reserved for providing reserves (MW)"
v_resTransferLeftward(restype, up_down, node, node, s, f, t) "Electricity transmission capacity from the second node to the first node reserved for providing reserves (MW)"
v_reserve(restype, up_down, node, unit, s, f, t) "Unit capacity reserved for providing reserve of specific type (MW)"
v_resTransferRightward(restype, up_down, grid, node, node, s, f, t) "Electricity transmission capacity from the first node to the second node reserved for providing reserves (MW)"
v_resTransferLeftward(restype, up_down, grid, node, node, s, f, t) "Electricity transmission capacity from the second node to the first node reserved for providing reserves (MW)"
v_reserve(restype, up_down, grid, node, unit, s, f, t) "Unit capacity reserved for providing reserve of specific type (MW)"
v_investTransfer_LP(grid, node, node, t) "Invested transfer capacity (MW)"
v_online_LP(unit, s, f, t) "Number of sub-units online for 'units' with unit commitment restrictions (LP variant)"
v_invest_LP(unit, t) "Number of invested 'sub-units' (LP variant)"
......
......@@ -63,7 +63,7 @@ equations
// Unit Operation
q_maxDownward(grid, node, unit, mType, s, f, t) "Downward commitments will not undercut power plant minimum load constraints or maximum elec. consumption"
q_maxUpward(grid, node, unit, mType, s, f, t) "Upward commitments will not exceed maximum available capacity or consumed power"
q_reserveProvision(restype, up_down, node, unit, s, f, t) "Reserve provision limited for units"
q_reserveProvision(restype, up_down, grid, node, unit, s, f, t) "Reserve provision limited for units"
q_startshut(mType, s, unit, f, t) "Online capacity now minus online capacity in the previous interval is equal to started up minus shut down capacity"
q_startuptype(mType, s, starttype, unit, f, t) "Startup type depends on the time the unit has been non-operational"
q_onlineOnStartUp(s, unit, f, t) "Unit must be online after starting up"
......@@ -95,8 +95,8 @@ equations
q_transferLeftwardLimit(grid, node, node, s, f, t) "Transfer of energy and capacity reservations to the leftward direction are less than the transfer capacity"
q_resTransferLimitRightward(grid, node, node, s, f, t) "Transfer of energy and capacity reservations are less than the transfer capacity to the rightward direction"
q_resTransferLimitLeftward(grid, node, node, s, f, t) "Transfer of energy and capacity reservations are less than the transfer capacity to the leftward direction"
q_reserveProvisionRightward(restype, up_down, node, node, s, f, t) "Rightward reserve provision limited"
q_reserveProvisionLeftward(restype, up_down, node, node, s, f, t) "Leftward reserve provision limited"
q_reserveProvisionRightward(restype, up_down, grid, node, node, s, f, t) "Rightward reserve provision limited"
q_reserveProvisionLeftward(restype, up_down, grid, node, node, s, f, t) "Leftward reserve provision limited"
// State Variables
q_stateSlack(grid, node, slack, s, f, t) "Slack variable greater than the difference between v_state and the slack boundary"
......
......@@ -98,42 +98,42 @@ q_resDemand(restypeDirectionGroup(restype, up_down, group), sft(s, f, t))
// Reserve provision by capable units on this group
+ sum(gnuft(grid, node, unit, f, t)${ gnGroup(grid, node, group)
and nuRescapable(restype, up_down, node, unit)
and gnuRescapable(restype, up_down, grid, node, unit)
},
+ v_reserve(restype, up_down, node, unit, s, f+df_reserves(node, restype, f, t), t)
+ v_reserve(restype, up_down, grid, node, unit, s, f+df_reserves(grid, node, restype, f, t), t)
* [ // Account for reliability of reserves
+ 1${sft_realized(s, f+df_reserves(node, restype, f, t), t)} // reserveReliability limits the reliability of reserves locked ahead of time.
+ p_nuReserves(node, unit, restype, 'reserveReliability')${not sft_realized(s, f+df_reserves(node, restype, f, t), t)}
+ 1${sft_realized(s, f+df_reserves(grid, node, restype, f, t), t)} // reserveReliability limits the reliability of reserves locked ahead of time.
+ p_gnuReserves(grid, node, unit, restype, 'reserveReliability')${not sft_realized(s, f+df_reserves(grid, node, restype, f, t), t)}
] // END * v_reserve
) // END sum(gnuft)
// Reserve provision from other reserve categories when they can be shared
+ sum((gnuft(grid, node, unit, f, t), restype_)${ gnGroup(grid, node, group)
and p_nuRes2Res(node, unit, restype_, up_down, restype)
and p_gnuRes2Res(grid, node, unit, restype_, up_down, restype)
},
+ v_reserve(restype_, up_down, node, unit, s, f+df_reserves(node, restype_, f, t), t)
* p_nuRes2Res(node, unit, restype_, up_down, restype)
+ v_reserve(restype_, up_down, grid, node, unit, s, f+df_reserves(grid, node, restype_, f, t), t)
* p_gnuRes2Res(grid, node, unit, restype_, up_down, restype)
* [ // Account for reliability of reserves
+ 1${sft_realized(s, f+df_reserves(node, restype, f, t), t)} // reserveReliability limits the reliability of reserves locked ahead of time.
+ p_nuReserves(node, unit, restype, 'reserveReliability')${not sft_realized(s, f+df_reserves(node, restype, f, t), t)}
* p_nuReserves(node, unit, restype_, 'reserveReliability')
+ 1${sft_realized(s, f+df_reserves(grid, node, restype, f, t), t)} // reserveReliability limits the reliability of reserves locked ahead of time.
+ p_gnuReserves(grid, node, unit, restype, 'reserveReliability')${not sft_realized(s, f+df_reserves(grid, node, restype, f, t), t)}
* p_gnuReserves(grid, node, unit, restype_, 'reserveReliability')
] // END * v_reserve
) // END sum(gnuft)
// Reserve provision to this group via transfer links
+ sum(gn2n_directional(grid, node_, node)${ gnGroup(grid, node, group)
and not gnGroup(grid, node_, group)
and restypeDirectionNodeNode(restype, up_down, node_, node)
and restypeDirectionGridNodeNode(restype, up_down, grid, node_, node)
},
+ (1 - p_gnn(grid, node_, node, 'transferLoss') )
* v_resTransferRightward(restype, up_down, node_, node, s, f+df_reserves(node_, restype, f, t), t) // Reserves from another node - reduces the need for reserves in the node
* v_resTransferRightward(restype, up_down, grid, node_, node, s, f+df_reserves(grid, node_, restype, f, t), t) // Reserves from another node - reduces the need for reserves in the node
) // END sum(gn2n_directional)
+ sum(gn2n_directional(grid, node, node_)${ gnGroup(grid, node, group)
and not gnGroup(grid, node_, group)
and restypeDirectionNodeNode(restype, up_down, node_, node)
and restypeDirectionGridNodeNode(restype, up_down, grid, node_, node)
},
+ (1 - p_gnn(grid, node, node_, 'transferLoss') )
* v_resTransferLeftward(restype, up_down, node, node_, s, f+df_reserves(node_, restype, f, t), t) // Reserves from another node - reduces the need for reserves in the node
* v_resTransferLeftward(restype, up_down, grid, node, node_, s, f+df_reserves(grid, node_, restype, f, t), t) // Reserves from another node - reduces the need for reserves in the node
) // END sum(gn2n_directional)
=G=
......@@ -144,24 +144,24 @@ q_resDemand(restypeDirectionGroup(restype, up_down, group), sft(s, f, t))
// Reserve demand increase because of units
+ sum(gnuft(grid, node, unit, f, t)${ gnGroup(grid, node, group)
and p_nuReserves(node, unit, restype, 'reserve_increase_ratio') // Could be better to have 'reserve_increase_ratio' separately for up and down directions
and p_gnuReserves(grid, node, unit, restype, 'reserve_increase_ratio') // Could be better to have 'reserve_increase_ratio' separately for up and down directions
},
+ sum(gnu(grid, node, unit), v_gen(grid, node, unit, s, f, t)) // Reserve sets and variables are currently lacking the grid dimension...
* p_nuReserves(node, unit, restype, 'reserve_increase_ratio')
+ v_gen(grid, node, unit, s, f, t)
* p_gnuReserves(grid, node, unit, restype, 'reserve_increase_ratio')
) // END sum(nuft)
// Reserve provisions to other groups via transfer links
+ sum(gn2n_directional(grid, node, node_)${ gnGroup(grid, node, group)
and not gnGroup(grid, node_, group)
and restypeDirectionNodeNode(restype, up_down, node, node_)
and restypeDirectionGridNodeNode(restype, up_down, grid, node, node_)
}, // If trasferring reserves to another node, increase your own reserves by same amount
+ v_resTransferRightward(restype, up_down, node, node_, s, f+df_reserves(node, restype, f, t), t)
+ v_resTransferRightward(restype, up_down, grid, node, node_, s, f+df_reserves(grid, node, restype, f, t), t)
) // END sum(gn2n_directional)
+ sum(gn2n_directional(grid, node_, node)${ gnGroup(grid, node, group)
and not gnGroup(grid, node_, group)
and restypeDirectionNodeNode(restype, up_down, node, node_)
and restypeDirectionGridNodeNode(restype, up_down, grid, node, node_)
}, // If trasferring reserves to another node, increase your own reserves by same amount
+ v_resTransferLeftward(restype, up_down, node_, node, s, f+df_reserves(node, restype, f, t), t)
+ v_resTransferLeftward(restype, up_down, grid, node_, node, s, f+df_reserves(grid, node, restype, f, t), t)
) // END sum(gn2n_directional)
// Reserve demand feasibility dummy variables
......@@ -178,51 +178,51 @@ q_resDemandLargestInfeedUnit(restypeDirectionGroup(restype, 'up', group), unit_f
and not [ restypeReleasedForRealization(restype)
and ft_realized(f, t)
]
and sum(gnGroup(grid, node, group), p_nuReserves(node, unit_, restype, 'portion_of_infeed_to_reserve'))
and sum(gnGroup(grid, node, group), p_gnuReserves(grid, node, unit_, restype, 'portion_of_infeed_to_reserve'))
and uft(unit_, f, t) // only active units
and sum(gnGroup(grid, node, group), gnu_output(grid, node, unit_)) // only units with output capacity 'inside the group'
} ..
// Reserve provision by capable units on this group excluding the failing one
+ sum(gnuft(grid, node, unit, f, t)${ gnGroup(grid, node, group)
and nuRescapable(restype, 'up', node, unit)
and gnuRescapable(restype, 'up', grid, node, unit)
and (ord(unit_) ne ord(unit))
},
+ v_reserve(restype, 'up', node, unit, s, f+df_reserves(node, restype, f, t), t)
+ v_reserve(restype, 'up', grid, node, unit, s, f+df_reserves(grid, node, restype, f, t), t)
* [ // Account for reliability of reserves
+ 1${sft_realized(s, f+df_reserves(node, restype, f, t), t)} // reserveReliability limits the reliability of reserves locked ahead of time.
+ p_nuReserves(node, unit, restype, 'reserveReliability')${not sft_realized(s, f+df_reserves(node, restype, f, t), t)}
+ 1${sft_realized(s, f+df_reserves(grid, node, restype, f, t), t)} // reserveReliability limits the reliability of reserves locked ahead of time.
+ p_gnuReserves(grid, node, unit, restype, 'reserveReliability')${not sft_realized(s, f+df_reserves(grid, node, restype, f, t), t)}
] // END * v_reserve
) // END sum(nuft)
// Reserve provision from other reserve categories when they can be shared
+ sum((gnuft(grid, node, unit, f, t), restype_)${ gnGroup(grid, node, group)
and p_nuRes2Res(node, unit, restype_, 'up', restype)
and p_gnuRes2Res(grid, node, unit, restype_, 'up', restype)
and (ord(unit_) ne ord(unit))
},
+ v_reserve(restype_, 'up', node, unit, s, f+df_reserves(node, restype_, f, t), t)
* p_nuRes2Res(node, unit, restype_, 'up', restype)
+ v_reserve(restype_, 'up', grid, node, unit, s, f+df_reserves(grid, node, restype_, f, t), t)
* p_gnuRes2Res(grid, node, unit, restype_, 'up', restype)
* [ // Account for reliability of reserves
+ 1${sft_realized(s, f+df_reserves(node, restype, f, t), t)} // reserveReliability limits the reliability of reserves locked ahead of time.
+ p_nuReserves(node, unit, restype, 'reserveReliability')${not sft_realized(s, f+df_reserves(node, restype, f, t), t)}
* p_nuReserves(node, unit, restype_, 'reserveReliability')
+ 1${sft_realized(s, f+df_reserves(grid, node, restype, f, t), t)} // reserveReliability limits the reliability of reserves locked ahead of time.
+ p_gnuReserves(grid, node, unit, restype, 'reserveReliability')${not sft_realized(s, f+df_reserves(grid, node, restype, f, t), t)}
* p_gnuReserves(grid, node, unit, restype_, 'reserveReliability')
] // END * v_reserve
) // END sum(nuft)
// Reserve provision to this group via transfer links
+ sum(gn2n_directional(grid, node_, node)${ gnGroup(grid, node, group)
and not gnGroup(grid, node_, group)
and restypeDirectionNodeNode(restype, 'up', node_, node)
and restypeDirectionGridNodeNode(restype, 'up', grid, node_, node)
},
+ (1 - p_gnn(grid, node_, node, 'transferLoss') )
* v_resTransferRightward(restype, 'up', node_, node, s, f+df_reserves(node_, restype, f, t), t) // Reserves from another node - reduces the need for reserves in the node
* v_resTransferRightward(restype, 'up', grid, node_, node, s, f+df_reserves(grid, node_, restype, f, t), t) // Reserves from another node - reduces the need for reserves in the node
) // END sum(gn2n_directional)
+ sum(gn2n_directional(grid, node, node_)${ gnGroup(grid, node, group)
and not gnGroup(grid, node_, group)
and restypeDirectionNodeNode(restype, 'up', node_, node)
and restypeDirectionGridNodeNode(restype, 'up', grid, node_, node)
},
+ (1 - p_gnn(grid, node, node_, 'transferLoss') )
* v_resTransferLeftward(restype, 'up', node, node_, s, f+df_reserves(node_, restype, f, t), t) // Reserves from another node - reduces the need for reserves in the node
* v_resTransferLeftward(restype, 'up', grid, node, node_, s, f+df_reserves(grid, node_, restype, f, t), t) // Reserves from another node - reduces the need for reserves in the node
) // END sum(gn2n_directional)
=G=
......@@ -230,21 +230,21 @@ q_resDemandLargestInfeedUnit(restypeDirectionGroup(restype, 'up', group), unit_f
// Demand for reserves due to a large unit that could fail
+ sum(gnGroup(grid, node, group),
+ v_gen(grid, node, unit_, s, f, t)
* p_nuReserves(node, unit_, restype, 'portion_of_infeed_to_reserve')
* p_gnuReserves(grid, node, unit_, restype, 'portion_of_infeed_to_reserve')
) // END sum(gnGroup)
// Reserve provisions to other groups via transfer links
+ sum(gn2n_directional(grid, node, node_)${ gnGroup(grid, node, group)
and not gnGroup(grid, node_, group)
and restypeDirectionNodeNode(restype, 'up', node, node_)
and restypeDirectionGridNodeNode(restype, 'up', grid, node, node_)
}, // If trasferring reserves to another node, increase your own reserves by same amount
+ v_resTransferRightward(restype, 'up', node, node_, s, f+df_reserves(node, restype, f, t), t)
+ v_resTransferRightward(restype, 'up', grid, node, node_, s, f+df_reserves(grid, node, restype, f, t), t)
) // END sum(gn2n_directional)
+ sum(gn2n_directional(grid, node_, node)${ gnGroup(grid, node, group)
and not gnGroup(grid, node_, group)
and restypeDirectionNodeNode(restype, 'up', node, node_)
and restypeDirectionGridNodeNode(restype, 'up', grid, node, node_)
}, // If trasferring reserves to another node, increase your own reserves by same amount
+ v_resTransferLeftward(restype, 'up', node_, node, s, f+df_reserves(node, restype, f, t), t)
+ v_resTransferLeftward(restype, 'up', grid, node_, node, s, f+df_reserves(grid, node, restype, f, t), t)
) // END sum(gn2n_directional)
// Reserve demand feasibility dummy variables
......@@ -362,25 +362,25 @@ q_resDemandLargestInfeedTransferUp(restypeDirectionGroup(restype, 'up', group),
// Reserve provision by capable units on this group
+ sum(gnuft(grid, node, unit, f, t)${ gnGroup(grid, node, group)
and nuRescapable(restype, 'up', node, unit)
and gnuRescapable(restype, 'up', grid, node, unit)
},
+ v_reserve(restype, 'up', node, unit, s, f+df_reserves(node, restype, f, t), t)
+ v_reserve(restype, 'up', grid, node, unit, s, f+df_reserves(grid, node, restype, f, t), t)
* [ // Account for reliability of reserves
+ 1${sft_realized(s, f+df_reserves(node, restype, f, t), t)} // reserveReliability limits the reliability of reserves locked ahead of time.
+ p_nuReserves(node, unit, restype, 'reserveReliability')${not sft_realized(s, f+df_reserves(node, restype, f, t), t)}
+ 1${sft_realized(s, f+df_reserves(grid, node, restype, f, t), t)} // reserveReliability limits the reliability of reserves locked ahead of time.
+ p_gnuReserves(grid, node, unit, restype, 'reserveReliability')${not sft_realized(s, f+df_reserves(grid, node, restype, f, t), t)}
] // END * v_reserve
) // END sum(gnuft)
// Reserve provision from other reserve categories when they can be shared
+ sum((gnuft(grid, node, unit, f, t), restype_)${ gnGroup(grid, node, group)
and p_nuRes2Res(node, unit, restype_, 'up', restype)
and p_gnuRes2Res(grid, node, unit, restype_, 'up', restype)
},
+ v_reserve(restype_, 'up', node, unit, s, f+df_reserves(node, restype_, f, t), t)
* p_nuRes2Res(node, unit, restype_, 'up', restype)
+ v_reserve(restype_, 'up', grid, node, unit, s, f+df_reserves(grid, node, restype_, f, t), t)
* p_gnuRes2Res(grid, node, unit, restype_, 'up', restype)
* [ // Account for reliability of reserves
+ 1${sft_realized(s, f+df_reserves(node, restype, f, t), t)} // reserveReliability limits the reliability of reserves locked ahead of time.
+ p_nuReserves(node, unit, restype, 'reserveReliability')${not sft_realized(s, f+df_reserves(node, restype, f, t), t)}
* p_nuReserves(node, unit, restype_, 'reserveReliability')
+ 1${sft_realized(s, f+df_reserves(grid, node, restype, f, t), t)} // reserveReliability limits the reliability of reserves locked ahead of time.
+ p_gnuReserves(grid, node, unit, restype, 'reserveReliability')${not sft_realized(s, f+df_reserves(grid, node, restype, f, t), t)}
* p_gnuReserves(grid, node, unit, restype_, 'reserveReliability')
] // END * v_reserve
) // END sum(gnuft)
......@@ -388,18 +388,18 @@ q_resDemandLargestInfeedTransferUp(restypeDirectionGroup(restype, 'up', group),
+ sum(gn2n_directional(grid, from_node, to_node)${ gnGroup(grid, to_node, group)
and not gnGroup(grid, from_node, group)
and not (from_node(node_) and to_node(node_fail)) // excluding the failing link
and restypeDirectionNodeNode(restype, 'up', from_node, to_node)
and restypeDirectionGridNodeNode(restype, 'up', grid, from_node, to_node)
},
+ (1 - p_gnn(grid, from_node, to_node, 'transferLoss') )
* v_resTransferRightward(restype, 'up', from_node, to_node, s, f+df_reserves(from_node, restype, f, t), t)
* v_resTransferRightward(restype, 'up', grid, from_node, to_node, s, f+df_reserves(grid, from_node, restype, f, t), t)
) // END sum(gn2n_directional)
+ sum(gn2n_directional(grid, to_node, from_node)${ gnGroup(grid, to_node, group)
and not gnGroup(grid, from_node, group)
and not (to_node(node_) and from_node(node_fail)) // excluding the failing link
and restypeDirectionNodeNode(restype, 'up', from_node, to_node)
and restypeDirectionGridNodeNode(restype, 'up', grid, from_node, to_node)
},
+ (1 - p_gnn(grid, to_node, from_node, 'transferLoss') )
* v_resTransferLeftward(restype, 'up', to_node, from_node, s, f+df_reserves(from_node, restype, f, t), t)
* v_resTransferLeftward(restype, 'up', grid, to_node, from_node, s, f+df_reserves(grid, from_node, restype, f, t), t)
) // END sum(gn2n_directional)
=G=
......@@ -414,18 +414,18 @@ q_resDemandLargestInfeedTransferUp(restypeDirectionGroup(restype, 'up', group),
+ sum(gn2n_directional(grid, from_node, to_node)${ gnGroup(grid, from_node, group)
and not gnGroup(grid, to_node, group)
and not (from_node(node_) and to_node(node_fail)) // excluding the failing link
and restypeDirectionNodeNode(restype, 'up', from_node, to_node)
and restypeDirectionGridNodeNode(restype, 'up', grid, from_node, to_node)
},
// Reserve transfers to other nodes increase the reserve need of the present node
+ v_resTransferRightward(restype, 'up', from_node, to_node, s, f+df_reserves(from_node, restype, f, t), t)
+ v_resTransferRightward(restype, 'up', grid, from_node, to_node, s, f+df_reserves(grid, from_node, restype, f, t), t)
) // END sum(gn2n_directional)
+ sum(gn2n_directional(grid, to_node, from_node)${ gnGroup(grid, from_node, group)
and not gnGroup(grid, to_node, group)
and not (to_node(node_) and from_node(node_fail)) // excluding the failing link
and restypeDirectionNodeNode(restype, 'up', from_node, to_node)
and restypeDirectionGridNodeNode(restype, 'up', grid, from_node, to_node)
},
// Reserve transfers to other nodes increase the reserve need of the present node
+ v_resTransferLeftward(restype, 'up', to_node, from_node, s, f+df_reserves(from_node, restype, f, t), t)
+ v_resTransferLeftward(restype, 'up', grid, to_node, from_node, s, f+df_reserves(grid, from_node, restype, f, t), t)
) // END sum(gn2n_directional)
// Reserve demand feasibility dummy variables
......@@ -453,25 +453,25 @@ q_resDemandLargestInfeedTransferDown(restypeDirectionGroup(restype, 'down', grou
// Reserve provision by capable units on this group
+ sum(gnuft(grid, node, unit, f, t)${ gnGroup(grid, node, group)
and nuRescapable(restype, 'down', node, unit)
and gnuRescapable(restype, 'down', grid, node, unit)
},
+ v_reserve(restype, 'down', node, unit, s, f+df_reserves(node, restype, f, t), t)
+ v_reserve(restype, 'down', grid, node, unit, s, f+df_reserves(grid, node, restype, f, t), t)
* [ // Account for reliability of reserves
+ 1${sft_realized(s, f+df_reserves(node, restype, f, t), t)} // reserveReliability limits the reliability of reserves locked ahead of time.
+ p_nuReserves(node, unit, restype, 'reserveReliability')${not sft_realized(s, f+df_reserves(node, restype, f, t), t)}
+ 1${sft_realized(s, f+df_reserves(grid, node, restype, f, t), t)} // reserveReliability limits the reliability of reserves locked ahead of time.
+ p_gnuReserves(grid, node, unit, restype, 'reserveReliability')${not sft_realized(s, f+df_reserves(grid, node, restype, f, t), t)}
] // END * v_reserve
) // END sum(gnuft)
// Reserve provision from other reserve categories when they can be shared
+ sum((gnuft(grid, node, unit, f, t), restype_)${ gnGroup(grid, node, group)
and p_nuRes2Res(node, unit, restype_, 'down', restype)
and p_gnuRes2Res(grid, node, unit, restype_, 'down', restype)
},
+ v_reserve(restype_, 'down', node, unit, s, f+df_reserves(node, restype_, f, t), t)
* p_nuRes2Res(node, unit, restype_, 'down', restype)
+ v_reserve(restype_, 'down', grid, node, unit, s, f+df_reserves(grid, node, restype_, f, t), t)
* p_gnuRes2Res(grid, node, unit, restype_, 'down', restype)
* [ // Account for reliability of reserves
+ 1${sft_realized(s, f+df_reserves(node, restype, f, t), t)} // reserveReliability limits the reliability of reserves locked ahead of time.
+ p_nuReserves(node, unit, restype, 'reserveReliability')${not sft_realized(s, f+df_reserves(node, restype, f, t), t)}
* p_nuReserves(node, unit, restype_, 'reserveReliability')
+ 1${sft_realized(s, f+df_reserves(grid, node, restype, f, t), t)} // reserveReliability limits the reliability of reserves locked ahead of time.
+ p_gnuReserves(grid, node, unit, restype, 'reserveReliability')${not sft_realized(s, f+df_reserves(grid, node, restype, f, t), t)}
* p_gnuReserves(grid, node, unit, restype_, 'reserveReliability')
] // END * v_reserve
) // END sum(gnuft)
......@@ -479,18 +479,18 @@ q_resDemandLargestInfeedTransferDown(restypeDirectionGroup(restype, 'down', grou
+ sum(gn2n_directional(grid, from_node, to_node)${ gnGroup(grid, to_node, group)
and not gnGroup(grid, from_node, group)
and not (from_node(node_) and to_node(node_fail)) // excluding the failing link
and restypeDirectionNodeNode(restype, 'down', from_node, to_node)
and restypeDirectionGridNodeNode(restype, 'down', grid, from_node, to_node)
},
+ (1 - p_gnn(grid, from_node, to_node, 'transferLoss') )
* v_resTransferRightward(restype, 'down', from_node, to_node, s, f+df_reserves(from_node, restype, f, t), t)
* v_resTransferRightward(restype, 'down', grid, from_node, to_node, s, f+df_reserves(grid, from_node, restype, f, t), t)
) // END sum(gn2n_directional)
+ sum(gn2n_directional(grid, to_node, from_node)${ gnGroup(grid, to_node, group)
and not gnGroup(grid, from_node, group)
and not (to_node(node_) and from_node(node_fail)) // excluding the failing link
and restypeDirectionNodeNode(restype, 'down', from_node, to_node)
and restypeDirectionGridNodeNode(restype, 'down', grid, from_node, to_node)
},
+ (1 - p_gnn(grid, to_node, from_node, 'transferLoss') )
* v_resTransferLeftward(restype, 'down', to_node, from_node, s, f+df_reserves(from_node, restype, f, t), t)
* v_resTransferLeftward(restype, 'down', grid, to_node, from_node, s, f+df_reserves(grid, from_node, restype, f, t), t)
) // END sum(gn2n_directional)
=G=
......@@ -505,18 +505,18 @@ q_resDemandLargestInfeedTransferDown(restypeDirectionGroup(restype, 'down', grou
+ sum(gn2n_directional(grid, from_node, to_node)${ gnGroup(grid, from_node, group)
and not gnGroup(grid, to_node, group)
and not (from_node(node_) and to_node(node_fail)) // excluding the failing link
and restypeDirectionNodeNode(restype, 'down', from_node, to_node)
and restypeDirectionGridNodeNode(restype, 'down', grid, from_node, to_node)
},
// Reserve transfers to other nodes increase the reserve need of the present node
+ v_resTransferRightward(restype, 'down', from_node, to_node, s, f+df_reserves(from_node, restype, f, t), t)
+ v_resTransferRightward(restype, 'down', grid, from_node, to_node, s, f+df_reserves(grid, from_node, restype, f, t), t)
) // END sum(gn2n_directional)
+ sum(gn2n_directional(grid, to_node, from_node)${ gnGroup(grid, from_node, group)
and not gnGroup(grid, to_node, group)
and not (to_node(node_) and from_node(node_fail)) // excluding the failing link
and restypeDirectionNodeNode(restype, 'down', from_node, to_node)
and restypeDirectionGridNodeNode(restype, 'down', grid, from_node, to_node)
},
// Reserve transfers to other nodes increase the reserve need of the present node
+ v_resTransferLeftward(restype, 'down', to_node, from_node, s, f+df_reserves(from_node, restype, f, t), t)
+ v_resTransferLeftward(restype, 'down', grid, to_node, from_node, s, f+df_reserves(grid, from_node, restype, f, t), t)
) // END sum(gn2n_directional)
// Reserve demand feasibility dummy variables
......@@ -544,25 +544,25 @@ q_resDemandLargestInfeedTransfer(restypeDirectionGroup(restype, up_down, group),
// Reserve provision by capable units on this group
+ sum(gnuft(grid, node, unit, f, t)${ gnGroup(grid, node, group)
and nuRescapable(restype, up_down, node, unit)
and gnuRescapable(restype, up_down, grid, node, unit)
},
+ v_reserve(restype, up_down, node, unit, s, f+df_reserves(node, restype, f, t), t)
+ v_reserve(restype, up_down, grid, node, unit, s, f+df_reserves(grid, node, restype, f, t), t)
* [ // Account for reliability of reserves
+ 1${sft_realized(s, f+df_reserves(node, restype, f, t), t)} // reserveReliability limits the reliability of reserves locked ahead of time.
+ p_nuReserves(node, unit, restype, 'reserveReliability')${not sft_realized(s, f+df_reserves(node, restype, f, t), t)}
+ 1${sft_realized(s, f+df_reserves(grid, node, restype, f, t), t)} // reserveReliability limits the reliability of reserves locked ahead of time.
+ p_gnuReserves(grid, node, unit, restype, 'reserveReliability')${not sft_realized(s, f+df_reserves(grid, node, restype, f, t), t)}
] // END * v_reserve
) // END sum(gnuft)
// Reserve provision from other reserve categories when they can be shared
+ sum((gnuft(grid, node, unit, f, t), restype_)${ gnGroup(grid, node, group)
and p_nuRes2Res(node, unit, restype_, up_down, restype)
and p_gnuRes2Res(grid, node, unit, restype_, up_down, restype)