Commit 5a90bf0c authored by ran li's avatar ran li Committed by ran li
Browse files

The reserve for largest interconnector(transmission line) is included, with...

The reserve for largest interconnector(transmission line) is included, with separate equations for up and down reserve
parent 0d4bee7d
......@@ -24,7 +24,8 @@ Model schedule /
q_balance
q_resDemand
q_resDemandLargestInfeedUnit
q_resDemandLargestInfeedIntDown
q_resDemandLargestInfeedIntUp
// Unit Operation
q_maxDownward
q_maxUpward
......
......@@ -247,6 +247,7 @@ param_gnn "Set of possible data parameters for grid, node, node (nodal interconn
unitSize "Size of one link for integer investments (MW)"
invCost "Investment cost (EUR/MW)"
annuity "Investment annuity"
ReservePortion "Portion to cover incase fail"
/
param_gnu "Set of possible data parameters for grid, node, unit" /
......
......@@ -49,7 +49,7 @@ Sets
unit_investLP(unit) "Units with continuous investments allowed"
unit_investMIP(unit) "Units with integer investments allowed"
unit_timeseries(unit) "Units with time series enabled"
unit_incHRAdditionalConstraints(unit) "Units that use the two additional incremental heat rate constraints"
unit_incHRAdditionalConstraints(unit) "Units that use the two additional incremental heat rate constraints"
* --- Nodes -------------------------------------------------------------------
node_spill(node) "Nodes that can spill; used to remove v_spill variables where not relevant"
......@@ -180,7 +180,7 @@ alias(f, f_, f__);
alias(s, s_, s__);
alias(grid, grid_, grid_output);
alias(unit, unit_);
alias(node, from_node, to_node, node_, node_input, node_output);
alias(node, from_node, to_node, node_, node_input, node_output, node_fail);
alias(node, from_node, to_node);
alias(effSelector, effSelector_);
alias(effDirect, effDirect_);
......
......@@ -312,6 +312,7 @@ gn2n(grid, from_node, to_node)${ p_gnn(grid, from_node, to_node, 'transferCap
or p_gnn(grid, from_node, to_node, 'transferCapBidirectional')
or p_gnn(grid, to_node, from_node, 'transferCapBidirectional')
or p_gnn(grid, from_node, to_node, 'transferCapInvLimit')
or p_gnn(grid, from_node, to_node, 'ReservePortion')
}
= yes;
......
......@@ -55,6 +55,8 @@ equations
q_balance(grid, node, mType, s, f, t) "Energy demand must be satisfied at each node"
q_resDemand(restype, up_down, node, s, f, t) "Procurement for each reserve type is greater than demand"
q_resDemandLargestInfeedUnit(grid, restype, up_down, node, unit, s, f, t) "N-1 Reserve"
q_resDemandLargestInfeedIntDown(grid, restype, up_down, node, node, s, f, t)
q_resDemandLargestInfeedIntUp(grid, restype, up_down, node, node, s, f, t)
// 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"
......
......@@ -129,7 +129,7 @@ q_resDemand(restypeDirectionNode(restype, up_down, node), sft(s, f, t))
=G=
// Demand for reserves
+ ts_reserveDemand_(restype, up_down, node, f, t)${p_nReserves(node, restype, 'use_time_series')}
+ ts_reserveDemand(restype, up_down, node, f, t)${p_nReserves(node, restype, 'use_time_series')}
+ p_nReserves(node, restype, up_down)${not p_nReserves(node, restype, 'use_time_series')}
// Reserve demand increase because of units
......@@ -197,7 +197,7 @@ q_resDemandLargestInfeedUnit(grid, restypeDirectionNode(restype, 'up', node), un
=G=
// Demand for reserves of the failing one
v_gen(grid,node,unit_,s,f,t) * p_nuReserves(node, unit_, restype, 'portion_of_infeed_to_reserve')
+ v_gen(grid,node,unit_,s,f,t) * p_nuReserves(node, unit_, restype, 'portion_of_infeed_to_reserve')
// Reserve provisions to another nodes via transfer links
+ sum(gn2n_directional(grid, node, node_)${restypeDirectionNodeNode(restype, 'up', node, node_)}, // If trasferring reserves to another node, increase your own reserves by same amount
......@@ -211,6 +211,175 @@ q_resDemandLargestInfeedUnit(grid, restypeDirectionNode(restype, 'up', node), un
- vq_resDemand(restype, 'up', node, s, f+df_reserves(node, restype, f, t), t)
- vq_resMissing(restype, 'up', node, s, f+df_reserves(node, restype, f, t), t)${ft_reservesFixed(node, restype, f+df_reserves(node, restype, f, t), t)}
;
* --- N-1 Downward Reserve Demand for interconnector----------------------------------------------------------
// NOTE! Currently, there are multiple identical instances of the reserve balance equation being generated for each forecast branch even when the reserves are committed and identical between the forecasts.
// NOTE! This could be solved by formulating a new "ft_reserves" set to cover only the relevant forecast-time steps, but it would possibly make the reserves even more confusing.
q_resDemandLargestInfeedIntDown(grid, restypeDirectionNode(restype, 'down', node), node_fail, sft(s, f, t))
${ ord(t) < tSolveFirst + p_nReserves(node, restype, 'reserve_length')
and not [ restypeReleasedForRealization(restype)
and sft_realized(s, f, t)]
and p_gnn(grid, node, node_fail, 'ReservePortion')
} ..
// Reserve provision by capable units on this node
+ sum(nuft(node, unit, f, t)${nuRescapable(restype, 'down', node, unit)},
+ v_reserve(restype, 'down', node, unit, s, f+df_reserves(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)}
] // END * v_reserve
) // END sum(nuft)
// Reserve provision from other reserve categories when they can be shared
+ sum((nuft(node, unit, f, t), restype_)${p_nuRes2Res(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)
* [ // 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')
] // END * v_reserve
) // END sum(nuft)
// Reserve provision to this node via transfer links
+ sum(gn2n_directional(grid, node_, node)${restypeDirectionNodeNode(restype, 'down', node_, node) and (ord(node_) eq ord(node_fail))},
+ (1 - p_gnn(grid, node_, node, 'transferLoss') )
* v_resTransferRightward(restype, 'down', node_, node, s, f+df_reserves(node_, restype, f, t), t)
* (1-p_gnn(grid, node_, node, 'ReservePortion'))
// Reserves from the partly failing transmission line - reduces the need for reserves in the node
) // END sum(gn2n_directional)
+ sum(gn2n_directional(grid, node, node_)${restypeDirectionNodeNode(restype, 'down', node_, node) and (ord(node_) eq ord(node_fail))},
+ (1 - p_gnn(grid, node, node_, 'transferLoss') )
* v_resTransferLeftward(restype, 'down', node, node_, s, f+df_reserves(node_, restype, f, t), t)
* (1-p_gnn(grid, node, node_, 'ReservePortion'))
// Reserves from the partly failing transmission line - reduces the need for reserves in the node
) // END sum(gn2n_directional)
+ sum(gn2n_directional(grid, node_, node)${restypeDirectionNodeNode(restype, 'down', node_, node) and (ord(node_) ne ord(node_fail))},
+ (1 - p_gnn(grid, node_, node, 'transferLoss') )
* v_resTransferRightward(restype, 'down', node_, node, s, f+df_reserves(node_, restype, f, t), t)
// Reserves from the partly failing transmission line - reduces the need for reserves in the node
) // END sum(gn2n_directional)
+ sum(gn2n_directional(grid, node, node_)${restypeDirectionNodeNode(restype, 'down', node_, node) and (ord(node_) ne ord(node_fail))},
+ (1 - p_gnn(grid, node, node_, 'transferLoss') )
* v_resTransferLeftward(restype, 'down', node, node_, s, f+df_reserves(node_, restype, f, t), t)
// Reserves from the partly failing transmission line - reduces the need for reserves in the node
) // END sum(gn2n_directional)
=G=
// Demand for reserves
+ p_gnn(grid, node, node_fail, 'ReservePortion')*v_transferRightward(grid, node, node_fail, s, f, t)$p_nReserves(node, restype, 'Trans')
// Reserve provisions to another nodes via transfer links
+ sum(gn2n_directional(grid, node, node_)${restypeDirectionNodeNode(restype, 'down', node, node_) and (ord(node_) eq ord(node_fail))},
// If trasferring through the failing line, increase your own reserves by the portion
+ v_resTransferRightward(restype, 'down', node, node_, s, f+df_reserves(node, restype, f, t), t)
* p_gnn(grid, node_, node, 'ReservePortion')
) // END sum(gn2n_directional)
+ sum(gn2n_directional(grid, node_, node)${restypeDirectionNodeNode(restype, 'down', node, node_) and (ord(node_) eq ord(node_fail))},
// If trasferring through the failing line, increase your own reserves by the portion
+ v_resTransferLeftward(restype, 'down', node_, node, s, f+df_reserves(node, restype, f, t), t)
* p_gnn(grid, node, node_, 'ReservePortion')
) // END sum(gn2n_directional)
+ sum(gn2n_directional(grid, node, node_)${restypeDirectionNodeNode(restype, 'down', node, node_) and (ord(node_) ne ord(node_fail))},
// If trasferring through the good line, increase your own reserves by same amount
+ v_resTransferRightward(restype, 'down', node, node_, s, f+df_reserves(node, restype, f, t), t)
) // END sum(gn2n_directional)
+ sum(gn2n_directional(grid, node_, node)${restypeDirectionNodeNode(restype, 'down', node, node_) and (ord(node_) ne ord(node_fail))},
// If trasferring through the good line, increase your own reserves by same amount
+ v_resTransferLeftward(restype, 'down', node_, node, s, f+df_reserves(node, restype, f, t), t)
) // END sum(gn2n_directional)
// Reserve demand feasibility dummy variables
- vq_resDemand(restype, 'down', node, s, f+df_reserves(node, restype, f, t), t)
- vq_resMissing(restype, 'down', node, s, f+df_reserves(node, restype, f, t), t)${ft_reservesFixed(node, restype, f+df_reserves(node, restype, f, t), t)}
;
* --- N-1 Upward Reserve Demand for interconnector----------------------------------------------------------
// NOTE! Currently, there are multiple identical instances of the reserve balance equation being generated for each forecast branch even when the reserves are committed and identical between the forecasts.
// NOTE! This could be solved by formulating a new "ft_reserves" set to cover only the relevant forecast-time steps, but it would possibly make the reserves even more confusing.
q_resDemandLargestInfeedIntUp(grid, restypeDirectionNode(restype, 'up', node), node_fail, sft(s, f, t))
${ ord(t) < tSolveFirst + p_nReserves(node, restype, 'reserve_length')
and not [ restypeReleasedForRealization(restype)
and sft_realized(s, f, t)]
and p_gnn(grid, node_fail, node, 'ReservePortion')
} ..
// Reserve provision by capable units on this node
+ sum(nuft(node, unit, f, t)${nuRescapable(restype, 'up', node, unit)},
+ v_reserve(restype, 'up', node, unit, s, f+df_reserves(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)}
] // END * v_reserve
) // END sum(nuft)
// Reserve provision from other reserve categories when they can be shared
+ sum((nuft(node, unit, f, t), restype_)${p_nuRes2Res(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)
* [ // 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')
] // END * v_reserve
) // END sum(nuft)
// Reserve provision to this node via transfer links
+ sum(gn2n_directional(grid, node_, node)${restypeDirectionNodeNode(restype, 'up', node_, node) and (ord(node_) eq ord(node_fail))},
+ (1 - p_gnn(grid, node_, node, 'transferLoss') )
* v_resTransferRightward(restype, 'up', node_, node, s, f+df_reserves(node_, restype, f, t), t)
* (1-p_gnn(grid, node_, node, 'ReservePortion'))
// Reserves from the partly failing transmission line - reduces the need for reserves in the node
) // END sum(gn2n_directional)
+ sum(gn2n_directional(grid, node, node_)${restypeDirectionNodeNode(restype, 'up', node_, node) and (ord(node_) eq ord(node_fail))},
+ (1 - p_gnn(grid, node, node_, 'transferLoss') )
* v_resTransferLeftward(restype, 'up', node, node_, s, f+df_reserves(node_, restype, f, t), t)
* (1-p_gnn(grid, node, node_, 'ReservePortion'))
// Reserves from the partly failing transmission line - reduces the need for reserves in the node
) // END sum(gn2n_directional)
+ sum(gn2n_directional(grid, node_, node)${restypeDirectionNodeNode(restype, 'up', node_, node) and (ord(node_) ne ord(node_fail))},
+ (1 - p_gnn(grid, node_, node, 'transferLoss') )
* v_resTransferRightward(restype, 'up', node_, node, s, f+df_reserves(node_, restype, f, t), t)
// Reserves from the partly failing transmission line - reduces the need for reserves in the node
) // END sum(gn2n_directional)
+ sum(gn2n_directional(grid, node, node_)${restypeDirectionNodeNode(restype, 'up', node_, node) and (ord(node_) ne ord(node_fail))},
+ (1 - p_gnn(grid, node, node_, 'transferLoss') )
* v_resTransferLeftward(restype, 'up', node, node_, s, f+df_reserves(node_, restype, f, t), t)
// Reserves from the partly failing transmission line - reduces the need for reserves in the node
) // END sum(gn2n_directional)
=G=
// Demand for reserves
+ p_gnn(grid, node_fail, node, 'ReservePortion')*v_transferLeftward(grid, node, node_fail, s, f, t)$p_nReserves(node, restype, 'Trans')
// Reserve provisions to another nodes via transfer links
+ sum(gn2n_directional(grid, node, node_)${restypeDirectionNodeNode(restype, 'up', node, node_) and (ord(node_) eq ord(node_fail))},
// If trasferring through the failing line, increase your own reserves by the portion
+ v_resTransferRightward(restype, 'up', node, node_, s, f+df_reserves(node, restype, f, t), t)
* p_gnn(grid, node_, node, 'ReservePortion')
) // END sum(gn2n_directional)
+ sum(gn2n_directional(grid, node_, node)${restypeDirectionNodeNode(restype, 'up', node, node_) and (ord(node_) eq ord(node_fail))},
// If trasferring through the failing line, increase your own reserves by the portion
+ v_resTransferLeftward(restype, 'up', node_, node, s, f+df_reserves(node, restype, f, t), t)
* p_gnn(grid, node, node_, 'ReservePortion')
) // END sum(gn2n_directional)
+ sum(gn2n_directional(grid, node, node_)${restypeDirectionNodeNode(restype, 'up', node, node_) and (ord(node_) ne ord(node_fail))},
// If trasferring through the good line, increase your own reserves by same amount
+ v_resTransferRightward(restype, 'up', node, node_, s, f+df_reserves(node, restype, f, t), t)
) // END sum(gn2n_directional)
+ sum(gn2n_directional(grid, node_, node)${restypeDirectionNodeNode(restype, 'up', node, node_) and (ord(node_) ne ord(node_fail))},
// If trasferring through the good line, increase your own reserves by same amount
+ v_resTransferLeftward(restype, 'up', node_, node, s, f+df_reserves(node, restype, f, t), t)
) // END sum(gn2n_directional)
// Reserve demand feasibility dummy variables
- vq_resDemand(restype, 'up', node, s, f+df_reserves(node, restype, f, t), t)
- vq_resMissing(restype, 'up', node, s, f+df_reserves(node, restype, f, t), t)${ft_reservesFixed(node, restype, f+df_reserves(node, restype, f, t), t)}
;
* --- Maximum Downward Capacity -----------------------------------------------
q_maxDownward(gnu(grid, node, unit), msft(m, s, f, t))
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment