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

Merge branch 'LossOfLargestInterconnector' into dev. Includes updates related...

Merge branch 'LossOfLargestInterconnector' into dev. Includes updates related to issues #69, #90, #91.
parents b19561d7 ee281454
...@@ -24,6 +24,9 @@ Model building / ...@@ -24,6 +24,9 @@ Model building /
q_balance q_balance
* q_resDemand * q_resDemand
* q_resDemandLargestInfeedUnit * q_resDemandLargestInfeedUnit
* q_rateOfChangeOfFrequencyUnit
* q_rateOfChangeOfFrequencyTransfer
* q_resDemandLargestInfeedTransfer
// Unit Operation // Unit Operation
q_maxDownward q_maxDownward
...@@ -34,6 +37,8 @@ Model building / ...@@ -34,6 +37,8 @@ Model building /
* q_reserveProvisionOnline * q_reserveProvisionOnline
* q_startup * q_startup
* q_startuptype * q_startuptype
* q_onlineOnStartUp
* q_offlineAfterShutDown
* q_onlineLimit * q_onlineLimit
* q_onlineMinUptime * q_onlineMinUptime
* q_onlineCyclic * q_onlineCyclic
...@@ -80,6 +85,7 @@ Model building / ...@@ -80,6 +85,7 @@ Model building /
* q_emissioncap * q_emissioncap
* q_energyShareMax * q_energyShareMax
* q_energyShareMin * q_energyShareMin
* q_ReserveShareMax
$ifthen exist '%input_dir%/building_additional_constraints.gms' $ifthen exist '%input_dir%/building_additional_constraints.gms'
$$include '%input_dir%/building_additional_constraints.gms' // Declare additional constraints from the input data $$include '%input_dir%/building_additional_constraints.gms' // Declare additional constraints from the input data
......
...@@ -23,7 +23,10 @@ Model invest / ...@@ -23,7 +23,10 @@ Model invest /
q_obj q_obj
q_balance q_balance
q_resDemand q_resDemand
q_resDemandLargestInfeedUnit q_resDemandLargestInfeedUnit // Use with extra caution if there are several sub-units
q_rateOfChangeOfFrequencyUnit // Use with extra caution if there are several sub-units
q_rateOfChangeOfFrequencyTransfer
q_resDemandLargestInfeedTransfer
// Unit Operation // Unit Operation
q_maxDownward q_maxDownward
...@@ -82,6 +85,7 @@ Model invest / ...@@ -82,6 +85,7 @@ Model invest /
q_emissioncap q_emissioncap
q_energyShareMax q_energyShareMax
q_energyShareMin q_energyShareMin
q_ReserveShareMax
$ifthen exist '%input_dir%/invest_additional_constraints.gms' $ifthen exist '%input_dir%/invest_additional_constraints.gms'
$$include '%input_dir%/invest_additional_constraints.gms' // Declare additional constraints from the input data $$include '%input_dir%/invest_additional_constraints.gms' // Declare additional constraints from the input data
......
...@@ -23,7 +23,10 @@ Model schedule / ...@@ -23,7 +23,10 @@ Model schedule /
q_obj q_obj
q_balance q_balance
q_resDemand q_resDemand
q_resDemandLargestInfeedUnit q_resDemandLargestInfeedUnit // Use with extra caution if there are several sub-units
q_rateOfChangeOfFrequencyUnit // Use with extra caution if there are several sub-units
q_rateOfChangeOfFrequencyTransfer
q_resDemandLargestInfeedTransfer
// Unit Operation // Unit Operation
q_maxDownward q_maxDownward
...@@ -82,6 +85,7 @@ Model schedule / ...@@ -82,6 +85,7 @@ Model schedule /
* q_emissioncap * q_emissioncap
* q_energyShareMax * q_energyShareMax
* q_energyShareMin * q_energyShareMin
q_ReserveShareMax
$ifthen exist '%input_dir%/schedule_additional_constraints.gms' $ifthen exist '%input_dir%/schedule_additional_constraints.gms'
$$include '%input_dir%/schedule_additional_constraints.gms' // Declare additional constraints from the input data $$include '%input_dir%/schedule_additional_constraints.gms' // Declare additional constraints from the input data
......
...@@ -99,6 +99,10 @@ v_help_inc ...@@ -99,6 +99,10 @@ v_help_inc
q_obj q_obj
q_balance q_balance
q_resDemand q_resDemand
q_resDemandLargestInfeedUnit
q_rateOfChangeOfFrequencyUnit
q_rateOfChangeOfFrequencyTransfer
q_resDemandLargestInfeedTransfer
// Unit Operation // Unit Operation
q_maxDownward q_maxDownward
......
...@@ -134,10 +134,11 @@ r_resTransferLeftward ...@@ -134,10 +134,11 @@ r_resTransferLeftward
// Interesting reserve results // Interesting reserve results
r_resDemandMarginal r_resDemandMarginal
r_nuTotalReserve r_gnuTotalReserve
r_nuTotalReserveShare r_gnuTotalReserveShare
r_nTotalReserve r_groupTotalReserve
r_resDemandLargestInfeedUnit r_resDemandLargestInfeedUnit
* --- Investment Result Symbols ----------------------------------------------- * --- Investment Result Symbols -----------------------------------------------
// Interesting investment results // Interesting investment results
...@@ -152,7 +153,7 @@ r_gnTotalqGen ...@@ -152,7 +153,7 @@ r_gnTotalqGen
r_gTotalqGen r_gTotalqGen
r_qResDemand r_qResDemand
r_qResMissing r_qResMissing
r_nTotalqResDemand r_groupTotalqResDemand
r_qCapacity r_qCapacity
r_solveStatus r_solveStatus
......
...@@ -214,6 +214,8 @@ param_gn "Possible parameters for grid, node" / ...@@ -214,6 +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"
* 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" /
...@@ -247,6 +249,7 @@ param_gnn "Set of possible data parameters for grid, node, node (nodal interconn ...@@ -247,6 +249,7 @@ param_gnn "Set of possible data parameters for grid, node, node (nodal interconn
unitSize "Size of one link for integer investments (MW)" unitSize "Size of one link for integer investments (MW)"
invCost "Investment cost (EUR/MW)" invCost "Investment cost (EUR/MW)"
annuity "Investment annuity" annuity "Investment annuity"
portion_of_transfer_to_reserve "Portion to cover incase fail"
/ /
param_gnu "Set of possible data parameters for grid, node, unit" / param_gnu "Set of possible data parameters for grid, node, unit" /
...@@ -353,6 +356,8 @@ param_policy "Set of possible data parameters for grid, node, regulation" / ...@@ -353,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"
...@@ -363,6 +368,8 @@ param_policy "Set of possible data parameters for grid, node, regulation" / ...@@ -363,6 +368,8 @@ param_policy "Set of possible data parameters for grid, node, regulation" /
reserve_increase_ratio "Unit output is multiplied by this factor to get the increase in reserve demand" reserve_increase_ratio "Unit output is multiplied by this factor to get the increase in reserve demand"
portion_of_infeed_to_reserve "Proportion of the generation of a tripping unit that needs to be covered by reserves from other units" portion_of_infeed_to_reserve "Proportion of the generation of a tripping unit that needs to be covered by reserves from other units"
offlineReserveCapability "Proportion of an offline unit which can contribute to a category of reserve" offlineReserveCapability "Proportion of an offline unit which can contribute to a category of reserve"
ReserveShareMax "Maximum reserve share of a group of units"
LossOfTrans
/ /
* --- Efficiency Approximation Related Sets ----------------------------------- * --- Efficiency Approximation Related Sets -----------------------------------
......
...@@ -56,6 +56,7 @@ Sets ...@@ -56,6 +56,7 @@ Sets
flowNode(flow, node) "Nodes with flows" flowNode(flow, node) "Nodes with flows"
* --- Sets bounding geography and units --------------------------------------- * --- Sets bounding geography and units ---------------------------------------
group "A group of units, transfer links, nodes, etc."
gn(grid, node) "Grids and their nodes" gn(grid, node) "Grids and their nodes"
* NOTE! Should it be possible to permit time-series form upper or lower bounds on states? If so, then gn() needs rethinking. * NOTE! Should it be possible to permit time-series form upper or lower bounds on states? If so, then gn() needs rethinking.
gn2n(grid, node, node) "All (directional) transfer links between nodes in specific energy grids" gn2n(grid, node, node) "All (directional) transfer links between nodes in specific energy grids"
...@@ -77,10 +78,12 @@ Sets ...@@ -77,10 +78,12 @@ Sets
* --- Reserve types ----------------------------------------------------------- * --- Reserve types -----------------------------------------------------------
restype "Reserve types" restype "Reserve types"
restypeDirection(restype, up_down) "Different combinations of reserve types and directions" restypeDirection(restype, up_down) "Different combinations of reserve types and directions"
restypeDirectionNode(restype, up_down, node) "Nodes with reserve requirements" restypeDirectionGridNode(restype, up_down, grid, node) "Nodes with reserve requirements"
resTypeDirectionNodeNode(restype, up_down, node, node) "Node node connections that can transfer reserves" resTypeDirectionGridNodeNode(restype, up_down, grid, node, node) "Node node connections that can transfer reserves"
nuRescapable(restype, up_down, node, unit) "Units capable and available to provide particular reserves" restypeDirectionGroup(restype, up_down, group)
nuOfflineRescapable(restype, node, unit) "Units capable and available to provide offline reserves" restypeDirectionGridNodeGroup(restype, up_down, grid, node, group)
gnuRescapable(restype, up_down, grid, node, unit) "Units capable and available to provide particular reserves"
gnuOfflineRescapable(restype, grid, node, unit) "Units capable and available to provide offline reserves"
restypeReleasedForRealization(restype) "Reserve types that are released for the realized time intervals" restypeReleasedForRealization(restype) "Reserve types that are released for the realized time intervals"
offlineRes (restype) "Reserve types where offline reserve provision possible" offlineRes (restype) "Reserve types where offline reserve provision possible"
offlineResUnit (unit) "Units where offline reserve provision possible" offlineResUnit (unit) "Units where offline reserve provision possible"
...@@ -105,7 +108,7 @@ Sets ...@@ -105,7 +108,7 @@ Sets
ft(f, t) "Combination of forecasts and t:s in the current solve" ft(f, t) "Combination of forecasts and t:s in the current solve"
ft_realized(f, t) "Realized ft" ft_realized(f, t) "Realized ft"
ft_realizedNoReset(f, t) "Full set of realized ft, facilitates calculation of results" ft_realizedNoReset(f, t) "Full set of realized ft, facilitates calculation of results"
ft_reservesFixed(node, restype, f, t) "Forecast-time steps with reserves fixed due to commitments on a previous solve." ft_reservesFixed(group, restype, f, t) "Forecast-time steps with reserves fixed due to commitments on a previous solve."
mft(mType, f, t) "Combination of forecasts and t:s in the current model solve" mft(mType, f, t) "Combination of forecasts and t:s in the current model solve"
msf(mType, s, f) "Combination of samples and forecasts in the models" msf(mType, s, f) "Combination of samples and forecasts in the models"
msft(mType, s, f, t) "Combination of models, samples, forecasts and t's" msft(mType, s, f, t) "Combination of models, samples, forecasts and t's"
...@@ -143,7 +146,7 @@ $if defined scenario ...@@ -143,7 +146,7 @@ $if defined scenario
uft_startupTrajectory(unit, f, t) "Units with start-up trajectories on intervals" uft_startupTrajectory(unit, f, t) "Units with start-up trajectories on intervals"
uft_shutdownTrajectory(unit, f, t) "Units with shutdown 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" 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(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_ramp(grid, node, unit, f, t) "Units with ramp requirements or costs"
gnuft_rampCost(grid, node, unit, slack, f, t) "Units with ramp costs" gnuft_rampCost(grid, node, unit, slack, f, t) "Units with ramp costs"
...@@ -159,7 +162,6 @@ $if defined scenario ...@@ -159,7 +162,6 @@ $if defined scenario
shutdownCounter(unit, counter) "Counter used for unit shutdown intervals" shutdownCounter(unit, counter) "Counter used for unit shutdown intervals"
* --- Sets used for grouping of units, transfer links, nodes, etc. ------------ * --- Sets used for grouping of units, transfer links, nodes, etc. ------------
group "A group of units, transfer links, nodes, etc."
uGroup(unit, group) "Units in particular groups" uGroup(unit, group) "Units in particular groups"
gnuGroup(grid, node, unit, group) "Combination of grids, nodes and units in particular groups" gnuGroup(grid, node, unit, group) "Combination of grids, nodes and units in particular groups"
gn2nGroup(grid, node, node, group) "Transfer links in particular groups" gn2nGroup(grid, node, node, group) "Transfer links in particular groups"
...@@ -183,8 +185,7 @@ alias(f, f_, f__); ...@@ -183,8 +185,7 @@ alias(f, f_, f__);
alias(s, s_, s__); alias(s, s_, s__);
alias(grid, grid_, grid_output); alias(grid, grid_, grid_output);
alias(unit, unit_); 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, node_left, node_right);
alias(node, from_node, to_node);
alias(effSelector, effSelector_); alias(effSelector, effSelector_);
alias(effDirect, effDirect_); alias(effDirect, effDirect_);
alias(effDirectOff, effDirectOff_); alias(effDirectOff, effDirectOff_);
...@@ -198,6 +199,7 @@ alias(hr, hr_, hr__); ...@@ -198,6 +199,7 @@ alias(hr, hr_, hr__);
alias(fuel, fuel_); alias(fuel, fuel_);
alias(effLevel, effLevel_); alias(effLevel, effLevel_);
alias(restype, restype_); alias(restype, restype_);
alias(group, group_);
*if(active('rampSched'), *if(active('rampSched'),
......
...@@ -51,10 +51,13 @@ Parameters ...@@ -51,10 +51,13 @@ Parameters
p_gnu(grid, node, unit, param_gnu) "Unit data where energy type matters" 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_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_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_nuReserves(node, unit, restype, *) "Reserve provision data for units" p_groupReserves(group, restype, *) "Data defining the reserve rules in each node group"
p_nnReserves(node, node, restype, up_down) "Reserve provision data for node node connections" p_groupReserves3D(group, restype, up_down, param_policy) "Reserve policy in each node group separately for each reserve type and direction"
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_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_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_gnPolicy(grid, node, param_policy, *) "Policy data for grid, node"
p_groupPolicy(group, param_policy) "Two-dimensional policy data for groups" p_groupPolicy(group, param_policy) "Two-dimensional policy data for groups"
p_groupPolicy3D(group, param_policy, *) "Three-dimensional policy data for groups" p_groupPolicy3D(group, param_policy, *) "Three-dimensional policy data for groups"
...@@ -124,7 +127,8 @@ Parameters ...@@ -124,7 +127,8 @@ Parameters
// Forecast displacement arrays // Forecast displacement arrays
df(f, t) "Displacement needed to reach the realized forecast on the current time step" 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_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" df_scenario(f, t) "Forecast index displacement needed to get central forecast data for long-term scenarios"
df_realization(f, t) "Displacement needed to reach the realized forecast on the current time step when no forecast is available" df_realization(f, t) "Displacement needed to reach the realized forecast on the current time step when no forecast is available"
...@@ -151,7 +155,7 @@ Parameters ...@@ -151,7 +155,7 @@ Parameters
// Used mostly for raw data storage // Used mostly for raw data storage
ts_influx(grid, node, f, t) "External power inflow/outflow during a time step (MWh/h)" ts_influx(grid, node, f, t) "External power inflow/outflow during a time step (MWh/h)"
ts_cf(flow, node, f, t) "Available capacity factor time series (p.u.)" ts_cf(flow, node, f, t) "Available capacity factor time series (p.u.)"
ts_reserveDemand(restype, up_down, node, f, t) "Reserve demand in region in the time step (MW)" ts_reserveDemand(restype, up_down, group, f, t) "Reserve demand in region in the time step (MW)"
ts_node(grid, node, param_gnBoundaryTypes, f, t) "Fix the states of a node according to time-series form exogenous input ([v_state])" ts_node(grid, node, param_gnBoundaryTypes, f, t) "Fix the states of a node according to time-series form exogenous input ([v_state])"
ts_fuelPriceChange(fuel, t) "Initial fuel price and consequent changes in fuel price (EUR/MWh)" ts_fuelPriceChange(fuel, t) "Initial fuel price and consequent changes in fuel price (EUR/MWh)"
ts_fuelPrice(fuel, t) "Fuel price time series (EUR/MWh)" ts_fuelPrice(fuel, t) "Fuel price time series (EUR/MWh)"
...@@ -161,7 +165,7 @@ Parameters ...@@ -161,7 +165,7 @@ Parameters
// NOTE: Sample dimension has to be last because of the scenario reduction algorithm // NOTE: Sample dimension has to be last because of the scenario reduction algorithm
ts_influx_(grid, node, s, f, t) "Mean external power inflow/outflow during a time step (MWh/h)" ts_influx_(grid, node, s, f, t) "Mean external power inflow/outflow during a time step (MWh/h)"
ts_cf_(flow, node, s, f, t) "Mean available capacity factor time series (p.u.)" ts_cf_(flow, node, s, f, t) "Mean available capacity factor time series (p.u.)"
ts_reserveDemand_(restype, up_down, node, f, t) "Mean reserve demand in region in the time step (MW)" ts_reserveDemand_(restype, up_down, group, f, t) "Mean reserve demand in region in the time step (MW)"
ts_node_(grid, node, param_gnBoundaryTypes, s, f, t) "Mean value of ts_node" ts_node_(grid, node, param_gnBoundaryTypes, s, f, t) "Mean value of ts_node"
ts_fuelPrice_(fuel, t) "Mean fuel price time during time step (EUR/MWh)" ts_fuelPrice_(fuel, t) "Mean fuel price time during time step (EUR/MWh)"
...@@ -171,7 +175,7 @@ Parameters ...@@ -171,7 +175,7 @@ Parameters
ts_effGroupUnit_update(effSelector, unit, param_eff, f, t) ts_effGroupUnit_update(effSelector, unit, param_eff, f, t)
ts_influx_update(grid, node, f, t) ts_influx_update(grid, node, f, t)
ts_cf_update(flow, node, f, t) ts_cf_update(flow, node, f, t)
ts_reserveDemand_update(restype, up_down, node, f, t) ts_reserveDemand_update(restype, up_down, group, f, t)
ts_node_update(grid, node, param_gnBoundaryTypes, f, t) ts_node_update(grid, node, param_gnBoundaryTypes, f, t)
ts_fuelPriceChange_update(fuel, t) ts_fuelPriceChange_update(fuel, t)
ts_unavailability_update(unit, t) ts_unavailability_update(unit, t)
......
...@@ -130,17 +130,17 @@ Parameters ...@@ -130,17 +130,17 @@ Parameters
* --- Reserve Provision Results ----------------------------------------------- * --- Reserve Provision Results -----------------------------------------------
// Reserve provision results required for model structure // 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_reserve(restype, up_down, grid, 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_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, node, node, f, t) "Electricity transmission capacity from the second node to the first 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, node, unit, restype, f, t) "Reserve provided for another reserve category (MW) (also included in r_reserve - this is just for debugging)" 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 // Interesting reserve results
r_resDemandMarginal(restype, up_down, node, f, t) "Marginal values of the q_resDemand equation" 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_gnuTotalReserve(restype, up_down, grid, node, unit) "Total gnu reserve provision over the simulation (MW*h)"
r_nuTotalReserveShare(restype, up_down, node, unit) "Total nu/n reserve provision share over the simulation" r_gnuTotalReserveShare(restype, up_down, grid, node, unit) "Total gnu/group reserve provision share over the simulation"
r_nTotalReserve(restype, up_down, node) "Total reserve provisions in nodes over the simulation (MW*h)" r_groupTotalReserve(restype, up_down, group) "Total reserve provisions in groups over the simulation (MW*h)"
r_resDemandLargestInfeedUnit(grid, f, t, restype, up_down, node) "Reserve Demand from the loss of largest infeed unit" r_resDemandLargestInfeedUnit(restype, up_down, group, f, t) "Reserve Demand from the loss of largest infeed unit"
* --- Investment Results ------------------------------------------------------ * --- Investment Results ------------------------------------------------------
...@@ -154,9 +154,9 @@ Parameters ...@@ -154,9 +154,9 @@ Parameters
r_qGen(inc_dec, grid, node, f, t) "Dummy energy generation (increase) or consumption (generation decrease) to ensure equation feasibility (MW)" r_qGen(inc_dec, grid, node, f, t) "Dummy energy generation (increase) or consumption (generation decrease) to ensure equation feasibility (MW)"
r_gnTotalqGen(inc_dec, grid, node) "Total dummy energy generation/consumption in gn over the simulation (MWh)." r_gnTotalqGen(inc_dec, grid, node) "Total dummy energy generation/consumption in gn over the simulation (MWh)."
r_gTotalqGen(inc_dec, grid) "Total dummy energy generation/consumption in g over the simulation (MWh)." r_gTotalqGen(inc_dec, grid) "Total dummy energy generation/consumption in g over the simulation (MWh)."
r_qResDemand(restype, up_down, node, f, t) "Dummy to decrease demand for a reserve (MW) before reserve commitment" r_qResDemand(restype, up_down, group, f, t) "Dummy to decrease demand for a reserve (MW) before reserve commitment"
r_qResMissing(restype, up_down, node, f, t) "Dummy to decrease demand for a reserve (MW) after 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, node) "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_qCapacity(grid, node, f, t) "Dummy capacity to ensure capacity margin equation feasibility (MW)"
r_solveStatus(t, solve_info) "Information about the solve" r_solveStatus(t, solve_info) "Information about the solve"
......
...@@ -32,6 +32,7 @@ $ifthen exist '%input_dir%/inputData.gdx' ...@@ -32,6 +32,7 @@ $ifthen exist '%input_dir%/inputData.gdx'
$$loaddc unitUnitEffLevel $$loaddc unitUnitEffLevel
$$loaddc uFuel $$loaddc uFuel
$$loaddc effLevelGroupUnit $$loaddc effLevelGroupUnit
$$loaddc group
$$loaddc p_gn $$loaddc p_gn
$$loaddc p_gnn $$loaddc p_gnn
$$loaddc p_gnu $$loaddc p_gnu
...@@ -41,10 +42,12 @@ $ifthen exist '%input_dir%/inputData.gdx' ...@@ -41,10 +42,12 @@ $ifthen exist '%input_dir%/inputData.gdx'
$$loaddc restype $$loaddc restype
$$loaddc restypeDirection $$loaddc restypeDirection
$$loaddc restypeReleasedForRealization $$loaddc restypeReleasedForRealization
$$loaddc p_nReserves $$loaddc p_groupReserves
$$loaddc p_nuReserves $$loaddc p_groupReserves3D
$$loaddc p_nnReserves $$loaddc p_groupReserves4D
$$loaddc p_nuRes2Res $$loaddc p_gnuReserves
$$loaddc p_gnnReserves
$$loaddc p_gnuRes2Res
$$loaddc ts_reserveDemand $$loaddc ts_reserveDemand
$$loaddc p_gnBoundaryPropertiesForStates $$loaddc p_gnBoundaryPropertiesForStates
$$loaddc p_gnPolicy $$loaddc p_gnPolicy
...@@ -61,7 +64,6 @@ $ifthen exist '%input_dir%/inputData.gdx' ...@@ -61,7 +64,6 @@ $ifthen exist '%input_dir%/inputData.gdx'
$$loaddc ts_node $$loaddc ts_node
$$loaddc t_invest $$loaddc t_invest
$$loaddc p_storageValue $$loaddc p_storageValue
$$loaddc group
$$loaddc uGroup $$loaddc uGroup
$$loaddc gnuGroup $$loaddc gnuGroup
$$loaddc gn2nGroup $$loaddc gn2nGroup
...@@ -92,7 +94,7 @@ gngnu_constrainedOutputRatio ...@@ -92,7 +94,7 @@ gngnu_constrainedOutputRatio
restype restype
restypeReleasedForRealization restypeReleasedForRealization
p_gnn p_gnn
p_nnReserves p_gnnReserves
p_gnuBoundaryProperties p_gnuBoundaryProperties
ts_node ts_node
ts_reserveDemand ts_reserveDemand
...@@ -312,6 +314,7 @@ gn2n(grid, from_node, to_node)${ p_gnn(grid, from_node, to_node, 'transferCap ...@@ -312,6 +314,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, from_node, to_node, 'transferCapBidirectional')
or p_gnn(grid, to_node, from_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, 'transferCapInvLimit')
or p_gnn(grid, from_node, to_node, 'portion_of_transfer_to_reserve')
} }
= yes; = yes;
...@@ -399,63 +402,79 @@ flowNode(flow, node)${ sum((f, t), ts_cf(flow, node, f, t)) ...@@ -399,63 +402,79 @@ flowNode(flow, node)${ sum((f, t), ts_cf(flow, node, f, t))
// NOTE! Reserves can be disabled through the model settings file. // NOTE! Reserves can be disabled through the model settings file.
// The sets are disabled in "3a_periodicInit.gms" accordingly. // The sets are disabled in "3a_periodicInit.gms" accordingly.
// Copy data from p_groupReserves to p_gnReserves
loop(gnGroup(grid, node, group)${sum(restype, p_groupReserves(group, restype, 'reserve_length'))},
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 // Units with reserve provision capabilities
nuRescapable(restypeDirection(restype, up_down), nu(node, unit)) gnuRescapable(restypeDirection(restype, up_down), gnu(grid, node, unit))
$ { p_nuReserves(node, unit, restype, up_down) $ { p_gnuReserves(grid, node, unit, restype, up_down)
} }
= yes; = yes;
// Units with offline reserve provision capabilities // Units with offline reserve provision capabilities
nuOfflineRescapable(restype, nu(node, unit)) gnuOfflineRescapable(restype, gnu(grid, node, unit))
$ { p_nuReserves(node, unit, restype, 'offlineReserveCapability') $ { p_gnuReserves(grid, node, unit, restype, 'offlineReserveCapability')
} }
= yes; = yes;
// Restypes with offline reserve provision possibility // Restypes with offline reserve provision possibility
offlineRes(restype) offlineRes(restype)
$ {sum(nu(node, unit), p_nuReserves(node, unit, restype, 'offlineReserveCapability')) $ {sum(gnu(grid, node, unit), p_gnuReserves(grid, node, unit, restype, 'offlineReserveCapability'))
} }
= yes; = yes;
// Units with offline reserve provision possibility // Units with offline reserve provision possibility
offlineResUnit(unit) offlineResUnit(unit)
$ {sum((node, restype), p_nuReserves(node, unit, restype, 'offlineReserveCapability')) $ {sum((gn(grid, node), restype), p_gnuReserves(grid, node, unit, restype, 'offlineReserveCapability'))
} }
= yes; = yes;
// Node-node connections with reserve transfer capabilities // Node-node connections with reserve transfer capabilities
restypeDirectionNodeNode(restypeDirection(restype, up_down), node, node_) restypeDirectionGridNodeNode(restypeDirection(restype, up_down), gn2n(grid, node, node_))
$ { p_nnReserves(node, node_, restype, up_down) $ { p_gnnReserves(grid, node, node_, restype, up_down)
} }
= yes; = yes;
// Nodes with reserve requirements, units capable of providing reserves, or reserve capable connections // Nodes with reserve requirements, units capable of providing reserves, or reserve capable connections
restypeDirectionNode(restypeDirection(restype, up_down), node) restypeDirectionGridNode(restypeDirection(restype, up_down), gn(grid, node))
$ { p_nReserves(node, restype, up_down) $ { p_gnReserves(grid, node, restype, up_down)
or p_nReserves(node, restype, 'use_time_series') or p_gnReserves(grid, node, restype, 'use_time_series')
or sum(nu(node, unit), p_nuReserves(node, unit, restype, 'portion_of_infeed_to_reserve')) or sum(gnu(grid, node, unit), p_gnuReserves(grid, node, unit, restype, 'portion_of_infeed_to_reserve'))
or sum(nu(node, unit), nuRescapable(restype, up_down, node, unit)) or sum(gnu(grid, node, unit), gnuRescapable(restype, up_down, grid, node, unit))
or sum(gn2n(grid, node, to_node), restypeDirectionNodeNode(restype, up_down, node, to_node)) or sum(gn2n(grid, node, to_node), restypeDirectionGridNodeNode(restype, up_down, grid, node, to_node))
}
= yes;
// Groups with reserve requirements
restypeDirectionGroup(restypeDirection(restype, up_down), group)
$ { p_groupReserves(group, restype, 'reserve_length')
}
= yes;
restypeDirectionGridNodeGroup(restypeDirection(restype, up_down), gnGroup(grid, node, group))
$ { p_groupReserves(group, restype, 'reserve_length')
} }
= yes; = yes;
* --- Correct values for critical reserve related parameters ------------------ * --- Correct values for critical reserve related parameters ------------------
// Reserve reliability assumed to be perfect if not provided in data // Reserve reliability assumed to be perfect if not provided in data
p_nuReserves(nu(node, unit), restype, 'reserveReliability') p_gnuReserves(gnu(grid, node, unit), restype, 'reserveReliability')
${ not p_nuReserves(node, unit, restype, 'reserveReliability') ${ not p_gnuReserves(grid, node, unit, restype, 'reserveReliability')
and sum(up_down, nuRescapable(restype, up_down, node, unit)) and sum(up_down, gnuRescapable(restype, up_down, grid, node, unit))
} }
= 1; = 1;
// Reserve provision overlap decreases the capacity of the overlapping category // Reserve provision overlap decreases the capacity of the overlapping category
loop(restype, loop(restype,
p_nuReserves(nu(node, unit), restype, up_down) p_gnuReserves(gnu(grid, node, unit), restype, up_down)
${ nuRescapable(restype, up_down, node, unit) } ${ gnuRescapable(restype, up_down, grid, node, unit) }
= p_nuReserves(node, unit, restype, up_down) = p_gnuReserves(grid, node, unit, restype, up_down)
- sum(restype_${ p_nuRes2Res(node, unit, restype_, up_down, restype) }, - sum(restype_${ p_gnuRes2Res(grid, node, unit, restype_, up_down, restype) },
+ p_nuReserves(node, unit, restype_, up_down) + p_gnuReserves(grid, node, unit, restype_, up_down)
* p_nuRes2Res(node, unit, restype_, up_down, restype) * p_gnuRes2Res(grid, node, unit, restype_, up_down, restype)
); // END sum(restype_) ); // END sum(restype_)
); );
...@@ -572,22 +591,35 @@ loop( unitStarttype(unit, starttypeConstrained), ...@@ -572,22 +591,35 @@ loop( unitStarttype(unit, starttypeConstrained),
* --- Check reserve related data ---------------------------------------------- * --- Check reserve related data ----------------------------------------------
// Check that reserve_length is long enough for properly commitment of reserves // 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),
if(p_nReserves(node, restype, 'reserve_length') < p_nReserves(node, restype, 'update_frequency') + p_nReserves(node, restype, 'gate_closure'), // Check that reserve_length is long enough for properly commitment of reserves
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 '!!! 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!' /; 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!"