Commit b89322d8 authored by Niina Helistö's avatar Niina Helistö
Browse files

Updating the two ROCOF constraints so that they apply to a group of nodes...

Updating the two ROCOF constraints so that they apply to a group of nodes instead of individual nodes.

The transfer ROCOF constraint considers failures of interconnectors with one end inside the group and one end outside the group. 'DefaultFrequency' and 'ROCOF' are now p_groupPolicy parameters instead of p_gn parameters.
parent 2db4c958
...@@ -24,8 +24,8 @@ Model schedule / ...@@ -24,8 +24,8 @@ Model schedule /
q_balance q_balance
q_resDemand q_resDemand
q_resDemandLargestInfeedUnit q_resDemandLargestInfeedUnit
q_RateOfChangeOfFrequency q_rateOfChangeOfFrequencyUnit
q_RateOfChangeOfFrequencyTrans q_rateOfChangeOfFrequencyTransfer
q_resDemandLargestInfeedTransfer q_resDemandLargestInfeedTransfer
q_resDemandLargestInfeedTransfer2 q_resDemandLargestInfeedTransfer2
// Unit Operation // Unit Operation
......
...@@ -214,8 +214,8 @@ param_gn "Possible parameters for grid, node" / ...@@ -214,8 +214,8 @@ param_gn "Possible parameters for grid, node" /
boundStartToEnd "Force the last states to equal the first state" boundStartToEnd "Force the last states to equal the first state"
forecastLength "Length of forecasts in use for the node (hours). After this, the node will use the central forecast." forecastLength "Length of forecasts in use for the node (hours). After this, the node will use the central forecast."
capacityMargin "Capacity margin used in invest mode (MW)" capacityMargin "Capacity margin used in invest mode (MW)"
defaultFrequency "default frequency for each node" * defaultFrequency "default frequency for each node"
ROCOF "Rate of change of frequency" * ROCOF "Rate of change of frequency"
/ /
param_gnBoundaryTypes "Types of boundaries that can be set for a node with a state variable" / param_gnBoundaryTypes "Types of boundaries that can be set for a node with a state variable" /
...@@ -356,6 +356,8 @@ param_policy "Set of possible data parameters for grid, node, regulation" / ...@@ -356,6 +356,8 @@ param_policy "Set of possible data parameters for grid, node, regulation" /
constrainedOnlineMultiplier "Multiplier a(i) for online units in equation Sum(i, a(i)*v_online(i)) <= b" constrainedOnlineMultiplier "Multiplier a(i) for online units in equation Sum(i, a(i)*v_online(i)) <= b"
constrainedOnlineTotalMax "Total maximum b for online units in equation Sum(i, a(i)*v_online(i)) <= b" constrainedOnlineTotalMax "Total maximum b for online units in equation Sum(i, a(i)*v_online(i)) <= b"
minCons "minimum consumption of storage unit when charging" minCons "minimum consumption of storage unit when charging"
ROCOF "Maximum rate of change of frequency (Hz/s)"
defaultFrequency "Nominal frequency in the system (Hz)"
// Reserve related parameters, currently without a proper parameter set // Reserve related parameters, currently without a proper parameter set
update_frequency "Frequency of updating reserve contributions" update_frequency "Frequency of updating reserve contributions"
update_offset "Optional offset for delaying the reserve update frequency" update_offset "Optional offset for delaying the reserve update frequency"
......
...@@ -55,10 +55,10 @@ equations ...@@ -55,10 +55,10 @@ equations
q_balance(grid, node, mType, s, f, t) "Energy demand must be satisfied at each node" 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_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_resDemandLargestInfeedUnit(grid, restype, up_down, node, unit, s, f, t) "N-1 Reserve"
q_RateOfChangeOfFrequency(grid, node, unit, s, f, t) "N-1 Contingency with ROCOF" q_rateOfChangeOfFrequencyUnit(group, unit, s, f, t) "N-1 unit contingency with ROCOF"
q_RateOfChangeOfFrequencyTrans(grid, node, node, s, f, t) "N-1 transmission line Contingency with ROCOF" q_rateOfChangeOfFrequencyTransfer(group, grid, node, node, s, f, t) "N-1 transmission line contingency with ROCOF"
q_resDemandLargestInfeedTransfer(grid, restype, up_down, node, node, s, f, t) "N-1 up reserve for transmission lines" q_resDemandLargestInfeedTransfer(grid, restype, up_down, node, node, s, f, t) "N-1 up reserve for transmission lines"
q_resDemandLargestInfeedTransfer2(grid, restype, up_down, node, node, s, f, t) "N-1 up reserve for transmission lines" q_resDemandLargestInfeedTransfer2(grid, restype, up_down, node, node, s, f, t) "N-1 down reserve for transmission lines"
// Unit Operation // 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_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_maxUpward(grid, node, unit, mType, s, f, t) "Upward commitments will not exceed maximum available capacity or consumed power"
......
...@@ -212,13 +212,19 @@ q_resDemandLargestInfeedUnit(grid, restypeDirectionNode(restype, 'up', node), un ...@@ -212,13 +212,19 @@ q_resDemandLargestInfeedUnit(grid, restypeDirectionNode(restype, 'up', node), un
- 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)} - 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)}
; ;
q_RateOfChangeOfFrequency(grid, node, unit_fail(unit_), sft(s, f, t)) q_rateOfChangeOfFrequencyUnit(group, unit_fail(unit_), sft(s, f, t))
${ p_gn(grid, node, 'defaultFrequency') ${ p_groupPolicy(group, 'defaultFrequency')
and p_gn(grid, node, 'ROCOF') and p_groupPolicy(group, 'ROCOF')
and uft(unit_, f, t)
and sum(gnu_output(grid, node, unit_)${gnGroup(grid, node, group)}, 1) // only units with output capacity 'inside the group'
} .. } ..
// Kinectic energy in the system // Kinetic/rotational energy in the system
[+ sum(gnu_output(grid, node, unit)${ ord(unit) ne ord(unit_) + p_groupPolicy(group, 'ROCOF')*2
* [
+ sum(gnu_output(grid, node, unit)${ ord(unit) ne ord(unit_)
and gnGroup(grid, node, group)
and gnuft(grid, node, unit, f, t)
}, },
+ p_gnu(grid, node, unit, 'inertia') + p_gnu(grid, node, unit, 'inertia')
* p_gnu(grid ,node, unit, 'unitSizeMVA') * p_gnu(grid ,node, unit, 'unitSizeMVA')
...@@ -231,21 +237,34 @@ q_RateOfChangeOfFrequency(grid, node, unit_fail(unit_), sft(s, f, t)) ...@@ -231,21 +237,34 @@ q_RateOfChangeOfFrequency(grid, node, unit_fail(unit_), sft(s, f, t))
/ p_gnu(grid, node, unit, 'unitSizeGen') / p_gnu(grid, node, unit, 'unitSizeGen')
] // * p_gnu ] // * p_gnu
) // END sum(gnu_output) ) // END sum(gnu_output)
]*p_gn(grid, node, 'ROCOF')*2 ] // END * p_groupPolicy
=G= =G=
// Demand for reserves due to a large unit that could fail // Demand for kinetic/rotational energy due to a large unit that could fail
+ v_gen(grid,node,unit_,s,f,t) * p_gn(grid, node, 'defaultFrequency') + p_groupPolicy(group, 'defaultFrequency')
* sum(gnu_output(grid, node, unit_)${ gnGroup(grid, node, group)
},
+ v_gen(grid, node, unit_ , s, f, t)
) // END sum(gnu_output)
; ;
q_RateOfChangeOfFrequencyTrans(grid, node, node_fail, sft(s, f, t))
${ p_gn(grid, node, 'defaultFrequency') q_rateOfChangeOfFrequencyTransfer(group, gn(grid, node_), node_fail, sft(s, f, t))
and p_gn(grid, node, 'ROCOF') ${ p_groupPolicy(group, 'defaultFrequency')
and p_groupPolicy(group, 'ROCOF')
and gnGroup(grid, node_, group) // only interconnectors where one end is 'inside the group'
and not gnGroup(grid, node_fail, group) // and the other end is 'outside the group'
and [ p_gnn(grid, node_, node_fail, 'portion_of_transfer_to_reserve')
or p_gnn(grid, node_fail, node_, 'portion_of_transfer_to_reserve')
]
} .. } ..
// Kinectic energy in the system // Kinetic/rotational energy in the system
[+ sum(gnu_output(grid, node, unit), + p_groupPolicy(group, 'ROCOF')*2
* [
+ sum(gnu_output(grid, node, unit)${ gnGroup(grid, node, group)
and gnuft(grid, node, unit, f, t)
},
+ p_gnu(grid, node, unit, 'inertia') + p_gnu(grid, node, unit, 'inertia')
* p_gnu(grid ,node, unit, 'unitSizeMVA') * p_gnu(grid ,node, unit, 'unitSizeMVA')
* [ * [
...@@ -257,23 +276,28 @@ q_RateOfChangeOfFrequencyTrans(grid, node, node_fail, sft(s, f, t)) ...@@ -257,23 +276,28 @@ q_RateOfChangeOfFrequencyTrans(grid, node, node_fail, sft(s, f, t))
/ p_gnu(grid, node, unit, 'unitSizeGen') / p_gnu(grid, node, unit, 'unitSizeGen')
] // * p_gnu ] // * p_gnu
) // END sum(gnu_output) ) // END sum(gnu_output)
]*p_gn(grid, node, 'ROCOF')*2 ] // END * p_groupPolicy
=G= =G=
// Demand for reserves due to a large unit that could fail // Demand for kinetic/rotational energy due to a large interconnector that could fail
// Upward transmission due to potential interconnector failures + p_groupPolicy(group, 'defaultFrequency')
[+ p_gnn(grid, node_fail, node, 'portion_of_transfer_to_reserve') * [
* v_transferRightward(grid, node_fail, node, s, f, t) // Loss of import due to potential interconnector failures
+ p_gnn(grid, node, node_fail, 'portion_of_transfer_to_reserve') + p_gnn(grid, node_fail, node_, 'portion_of_transfer_to_reserve')
* v_transferLeftward(grid, node, node_fail, s, f, t) * v_transferRightward(grid, node_fail, node_, s, f, t)
//Downward transmission due to potential interconnector failures * (1 - p_gnn(grid, node_fail, node_, 'transferLoss') )
+ p_gnn(grid, node_fail, node, 'portion_of_transfer_to_reserve') + p_gnn(grid, node_, node_fail, 'portion_of_transfer_to_reserve')
* v_transferLeftward(grid, node_fail, node, s, f, t) * v_transferLeftward(grid, node_, node_fail, s, f, t)
+ p_gnn(grid, node, node_fail, 'portion_of_transfer_to_reserve') * (1 - p_gnn(grid, node_, node_fail, 'transferLoss') )
* v_transferRightward(grid, node, node_fail, s, f, t)] * p_gn(grid, node, 'defaultFrequency') // Loss of export due to potential interconnector failures
+ p_gnn(grid, node_fail, node_, 'portion_of_transfer_to_reserve')
* v_transferLeftward(grid, node_fail, node_, s, f, t)
+ p_gnn(grid, node_, node_fail, 'portion_of_transfer_to_reserve')
* v_transferRightward(grid, node_, node_fail, s, f, t)
] // END * p_groupPolicy
; ;
* --- N-1 Upward reserve demand due to a possibility that an interconnector that is transferring power to the node fails ------------------------------------------------- * --- N-1 Upward reserve demand due to a possibility that an interconnector that is transferring power to the node fails -------------------------------------------------
// 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! 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. // 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.
...@@ -282,7 +306,9 @@ q_resDemandLargestInfeedTransfer(grid, restypeDirectionNode(restype, 'up', node) ...@@ -282,7 +306,9 @@ q_resDemandLargestInfeedTransfer(grid, restypeDirectionNode(restype, 'up', node)
${ ord(t) < tSolveFirst + p_nReserves(node, restype, 'reserve_length') ${ ord(t) < tSolveFirst + p_nReserves(node, restype, 'reserve_length')
and not [ restypeReleasedForRealization(restype) and not [ restypeReleasedForRealization(restype)
and sft_realized(s, f, t)] and sft_realized(s, f, t)]
and (p_gnn(grid, node, node_fail, 'portion_of_transfer_to_reserve') or p_gnn(grid, node_fail, node, 'portion_of_transfer_to_reserve')) and [ p_gnn(grid, node, node_fail, 'portion_of_transfer_to_reserve')
or p_gnn(grid, node_fail, node, 'portion_of_transfer_to_reserve')
]
and p_nReserves(node, restype, 'LossOfTrans') and p_nReserves(node, restype, 'LossOfTrans')
} .. } ..
...@@ -352,7 +378,9 @@ q_resDemandLargestInfeedTransfer2(grid, restypeDirectionNode(restype, 'down', no ...@@ -352,7 +378,9 @@ q_resDemandLargestInfeedTransfer2(grid, restypeDirectionNode(restype, 'down', no
${ ord(t) < tSolveFirst + p_nReserves(node, restype, 'reserve_length') ${ ord(t) < tSolveFirst + p_nReserves(node, restype, 'reserve_length')
and not [ restypeReleasedForRealization(restype) and not [ restypeReleasedForRealization(restype)
and sft_realized(s, f, t)] and sft_realized(s, f, t)]
and (p_gnn(grid, node, node_fail, 'portion_of_transfer_to_reserve') or p_gnn(grid, node_fail, node, 'portion_of_transfer_to_reserve')) and [ p_gnn(grid, node, node_fail, 'portion_of_transfer_to_reserve')
or p_gnn(grid, node_fail, node, 'portion_of_transfer_to_reserve')
]
and p_nReserves(node, restype, 'LossOfTrans') and p_nReserves(node, restype, 'LossOfTrans')
} .. } ..
......
...@@ -63,6 +63,11 @@ Option clear = vq_resMissing; ...@@ -63,6 +63,11 @@ Option clear = vq_resMissing;
Option clear = q_obj; Option clear = q_obj;
Option clear = q_balance; Option clear = q_balance;
Option clear = q_resDemand; Option clear = q_resDemand;
Option clear = q_resDemandLargestInfeedUnit;
Option clear = q_rateOfChangeOfFrequencyUnit;
Option clear = q_rateOfChangeOfFrequencyTransfer;
Option clear = q_resDemandLargestInfeedTransfer;
Option clear = q_resDemandLargestInfeedTransfer2;
// Unit Operation // Unit Operation
Option clear = q_maxDownward; Option clear = q_maxDownward;
......
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