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 /
q_balance
q_resDemand
q_resDemandLargestInfeedUnit
q_RateOfChangeOfFrequency
q_RateOfChangeOfFrequencyTrans
q_rateOfChangeOfFrequencyUnit
q_rateOfChangeOfFrequencyTransfer
q_resDemandLargestInfeedTransfer
q_resDemandLargestInfeedTransfer2
// Unit Operation
......
......@@ -214,8 +214,8 @@ param_gn "Possible parameters for grid, node" /
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."
capacityMargin "Capacity margin used in invest mode (MW)"
defaultFrequency "default frequency for each node"
ROCOF "Rate of change of frequency"
* defaultFrequency "default frequency for each node"
* ROCOF "Rate of change of frequency"
/
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" /
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"
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
update_frequency "Frequency of updating reserve contributions"
update_offset "Optional offset for delaying the reserve update frequency"
......
......@@ -55,10 +55,10 @@ 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_RateOfChangeOfFrequency(grid, node, unit, s, f, t) "N-1 Contingency with ROCOF"
q_RateOfChangeOfFrequencyTrans(grid, node, node, s, f, t) "N-1 transmission line Contingency with ROCOF"
q_rateOfChangeOfFrequencyUnit(group, unit, s, f, t) "N-1 unit 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_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
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"
......
......@@ -212,68 +212,92 @@ 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)}
;
q_RateOfChangeOfFrequency(grid, node, unit_fail(unit_), sft(s, f, t))
${ p_gn(grid, node, 'defaultFrequency')
and p_gn(grid, node, 'ROCOF')
q_rateOfChangeOfFrequencyUnit(group, unit_fail(unit_), sft(s, f, t))
${ p_groupPolicy(group, 'defaultFrequency')
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
[+ sum(gnu_output(grid, node, unit)${ ord(unit) ne ord(unit_)
},
+ p_gnu(grid, node, unit, 'inertia')
* p_gnu(grid ,node, unit, 'unitSizeMVA')
* [
+ v_online_LP(unit, s, f+df_central(f,t), t)
${uft_onlineLP(unit, f, t)}
+ v_online_MIP(unit, s, f+df_central(f,t), t)
${uft_onlineMIP(unit, f, t)}
+ v_gen(grid, node, unit, s, f, t)${not uft_online(unit, f, t)}
/ p_gnu(grid, node, unit, 'unitSizeGen')
] // * p_gnu
) // END sum(gnu_output)
]*p_gn(grid, node, 'ROCOF')*2
// Kinetic/rotational energy in the system
+ 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, 'unitSizeMVA')
* [
+ v_online_LP(unit, s, f+df_central(f,t), t)
${uft_onlineLP(unit, f, t)}
+ v_online_MIP(unit, s, f+df_central(f,t), t)
${uft_onlineMIP(unit, f, t)}
+ v_gen(grid, node, unit, s, f, t)${not uft_online(unit, f, t)}
/ p_gnu(grid, node, unit, 'unitSizeGen')
] // * p_gnu
) // END sum(gnu_output)
] // END * p_groupPolicy
=G=
// Demand for reserves due to a large unit that could fail
+ v_gen(grid,node,unit_,s,f,t) * p_gn(grid, node, 'defaultFrequency')
// Demand for kinetic/rotational energy due to a large unit that could fail
+ 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')
and p_gn(grid, node, 'ROCOF')
q_rateOfChangeOfFrequencyTransfer(group, gn(grid, node_), node_fail, sft(s, f, t))
${ 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
[+ sum(gnu_output(grid, node, unit),
+ p_gnu(grid, node, unit, 'inertia')
* p_gnu(grid ,node, unit, 'unitSizeMVA')
* [
+ v_online_LP(unit, s, f+df_central(f,t), t)
${uft_onlineLP(unit, f, t)}
+ v_online_MIP(unit, s, f+df_central(f,t), t)
${uft_onlineMIP(unit, f, t)}
+ v_gen(grid, node, unit, s, f, t)${not uft_online(unit, f, t)}
/ p_gnu(grid, node, unit, 'unitSizeGen')
] // * p_gnu
) // END sum(gnu_output)
]*p_gn(grid, node, 'ROCOF')*2
// Kinetic/rotational energy in the system
+ 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, 'unitSizeMVA')
* [
+ v_online_LP(unit, s, f+df_central(f,t), t)
${uft_onlineLP(unit, f, t)}
+ v_online_MIP(unit, s, f+df_central(f,t), t)
${uft_onlineMIP(unit, f, t)}
+ v_gen(grid, node, unit, s, f, t)${not uft_online(unit, f, t)}
/ p_gnu(grid, node, unit, 'unitSizeGen')
] // * p_gnu
) // END sum(gnu_output)
] // END * p_groupPolicy
=G=
// Demand for reserves due to a large unit that could fail
// Upward transmission due to potential interconnector failures
[+ p_gnn(grid, node_fail, node, 'portion_of_transfer_to_reserve')
* v_transferRightward(grid, node_fail, node, s, f, t)
+ p_gnn(grid, node, node_fail, 'portion_of_transfer_to_reserve')
* v_transferLeftward(grid, node, node_fail, s, f, t)
//Downward transmission 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)] * p_gn(grid, node, 'defaultFrequency')
// Demand for kinetic/rotational energy due to a large interconnector that could fail
+ p_groupPolicy(group, 'defaultFrequency')
* [
// Loss of import due to potential interconnector failures
+ p_gnn(grid, node_fail, node_, 'portion_of_transfer_to_reserve')
* v_transferRightward(grid, node_fail, node_, s, f, t)
* (1 - p_gnn(grid, node_fail, node_, 'transferLoss') )
+ p_gnn(grid, node_, node_fail, 'portion_of_transfer_to_reserve')
* v_transferLeftward(grid, node_, node_fail, s, f, t)
* (1 - p_gnn(grid, node_, node_fail, 'transferLoss') )
// 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 -------------------------------------------------
// 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.
......@@ -282,7 +306,9 @@ q_resDemandLargestInfeedTransfer(grid, restypeDirectionNode(restype, 'up', node)
${ 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, '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')
} ..
......@@ -352,7 +378,9 @@ q_resDemandLargestInfeedTransfer2(grid, restypeDirectionNode(restype, 'down', no
${ 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, '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')
} ..
......
......@@ -63,6 +63,11 @@ Option clear = vq_resMissing;
Option clear = q_obj;
Option clear = q_balance;
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
Option clear = q_maxDownward;
......
Markdown is supported
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