Commit 818c3cff authored by Topi Rasku's avatar Topi Rasku
Browse files

#65: *v_startup* divided into *v_startup_LP* and *v_startup_MIP* variants to...

#65: *v_startup* divided into *v_startup_LP* and *v_startup_MIP* variants to avoid undesired behavior when using integer online variables.
parent 9230f447
...@@ -23,6 +23,7 @@ Free variables ...@@ -23,6 +23,7 @@ Free variables
v_transfer(grid, node, node, s, f, t) "Average electricity transmission level from node to node during an interval (MW)" v_transfer(grid, node, node, s, f, t) "Average electricity transmission level from node to node during an interval (MW)"
; ;
Integer variables Integer variables
v_startup_MIP(unit, starttype, s, f, t) "Sub-units started up after/during an interval (p.u.), (MIP variant)"
v_online_MIP(unit, s, f, t) "Number of sub-units online for units with unit commitment restrictions" v_online_MIP(unit, s, f, t) "Number of sub-units online for units with unit commitment restrictions"
v_invest_MIP(unit, t) "Number of invested sub-units" v_invest_MIP(unit, t) "Number of invested sub-units"
v_investTransfer_MIP(grid, node, node, t) "Number of invested transfer links" v_investTransfer_MIP(grid, node, node, t) "Number of invested transfer links"
...@@ -35,7 +36,7 @@ SOS2 variables ...@@ -35,7 +36,7 @@ SOS2 variables
; ;
Positive variables Positive variables
v_fuelUse(fuel, unit, s, f, t) "Fuel use of a unit during an interval (MWh_fuel)" v_fuelUse(fuel, unit, s, f, t) "Fuel use of a unit during an interval (MWh_fuel)"
v_startup(unit, starttype, s, f, t) "Sub-units started up after/during an interval (p.u.)" v_startup_LP(unit, starttype, s, f, t) "Sub-units started up after/during an interval (p.u.), (LP variant)"
v_shutdown(unit, s, f, t) "Sub-units shut down after/during an interval (p.u.)" v_shutdown(unit, s, f, t) "Sub-units shut down after/during an interval (p.u.)"
v_genRampUpDown(grid, node, unit, slack, s, f, t) "Change in energy generation or consumption over an interval, separated into different 'slacks' (MW/h)" v_genRampUpDown(grid, node, unit, slack, s, f, t) "Change in energy generation or consumption over an interval, separated into different 'slacks' (MW/h)"
v_spill(grid, node, s, f, t) "Spill of energy from storage node during an interval (MWh)" v_spill(grid, node, s, f, t) "Spill of energy from storage node during an interval (MWh)"
......
...@@ -89,7 +89,10 @@ q_obj .. ...@@ -89,7 +89,10 @@ q_obj ..
// Start-up costs, initial startup free as units could have been online before model started // Start-up costs, initial startup free as units could have been online before model started
+ sum(uft_online(unit, f, t), + sum(uft_online(unit, f, t),
+ sum(unitStarttype(unit, starttype), + sum(unitStarttype(unit, starttype),
+ v_startup(unit, starttype, s, f, t) // Cost of starting up + [ // Unit startup variables
+ v_startup_LP(unit, starttype, s, f, t)${ uft_onlineLP(unit, f, t) }
+ v_startup_MIP(unit, starttype, s, f, t)${ uft_onlineMIP(unit, f, t) }
]
* [ // Startup variable costs * [ // Startup variable costs
+ p_uStartup(unit, starttype, 'cost') + p_uStartup(unit, starttype, 'cost')
......
...@@ -259,7 +259,12 @@ q_maxDownward(gnu(grid, node, unit), msft(m, s, f, t))${gnuft(grid, node, unit, ...@@ -259,7 +259,12 @@ q_maxDownward(gnu(grid, node, unit), msft(m, s, f, t))${gnuft(grid, node, unit,
+ p_gnu(grid, node, unit, 'unitSizeGen') + p_gnu(grid, node, unit, 'unitSizeGen')
* sum(unitStarttype(unit, starttype)${uft_startupTrajectory(unit, f, t)}, * sum(unitStarttype(unit, starttype)${uft_startupTrajectory(unit, f, t)},
sum(runUpCounter(unit, counter)${t_active(t+dt_trajectory(counter))}, // Sum over the run-up intervals sum(runUpCounter(unit, counter)${t_active(t+dt_trajectory(counter))}, // Sum over the run-up intervals
+ v_startup(unit, starttype, s, f+df(f, t+dt_trajectory(counter)), t+dt_trajectory(counter)) + [
+ v_startup_LP(unit, starttype, s, f+df(f, t+dt_trajectory(counter)), t+dt_trajectory(counter))
${ uft_onlineLP(unit, f+df(f, t+dt_trajectory(counter)), t+dt_trajectory(counter)) }
+ v_startup_MIP(unit, starttype, s, f+df(f, t+dt_trajectory(counter)), t+dt_trajectory(counter))
${ uft_onlineMIP(unit, f+df(f, t+dt_trajectory(counter)), t+dt_trajectory(counter)) }
]
* p_uCounter_runUpMin(unit, counter) * p_uCounter_runUpMin(unit, counter)
) // END sum(runUpCounter) ) // END sum(runUpCounter)
) // END sum(unitStarttype) ) // END sum(unitStarttype)
...@@ -380,7 +385,12 @@ q_maxUpward(gnu(grid, node, unit), msft(m, s, f, t))${gnuft(grid, node, unit, f, ...@@ -380,7 +385,12 @@ q_maxUpward(gnu(grid, node, unit), msft(m, s, f, t))${gnuft(grid, node, unit, f,
+ p_gnu(grid, node, unit, 'unitSizeGen') + p_gnu(grid, node, unit, 'unitSizeGen')
* sum(unitStarttype(unit, starttype)${uft_startupTrajectory(unit, f, t)}, * sum(unitStarttype(unit, starttype)${uft_startupTrajectory(unit, f, t)},
sum(runUpCounter(unit, counter)${t_active(t+dt_trajectory(counter))}, // Sum over the run-up intervals sum(runUpCounter(unit, counter)${t_active(t+dt_trajectory(counter))}, // Sum over the run-up intervals
+ v_startup(unit, starttype, s, f+df(f, t+dt_trajectory(counter)), t+dt_trajectory(counter)) + [
+ v_startup_LP(unit, starttype, s, f+df(f, t+dt_trajectory(counter)), t+dt_trajectory(counter))
${ uft_onlineLP(unit, f+df(f, t+dt_trajectory(counter)), t+dt_trajectory(counter)) }
+ v_startup_MIP(unit, starttype, s, f+df(f, t+dt_trajectory(counter)), t+dt_trajectory(counter))
${ uft_onlineMIP(unit, f+df(f, t+dt_trajectory(counter)), t+dt_trajectory(counter)) }
]
* p_uCounter_runUpMax(unit, counter) * p_uCounter_runUpMax(unit, counter)
) // END sum(runUpCounter) ) // END sum(runUpCounter)
) // END sum(unitStarttype) ) // END sum(unitStarttype)
...@@ -451,7 +461,10 @@ q_startshut(m, s, uft_online(unit, f, t))$msft(m, s, f, t) .. ...@@ -451,7 +461,10 @@ q_startshut(m, s, uft_online(unit, f, t))$msft(m, s, f, t) ..
// Add startup of units dt_toStartup before the current t (no start-ups for aggregator units before they become active) // Add startup of units dt_toStartup before the current t (no start-ups for aggregator units before they become active)
+ sum(unitStarttype(unit, starttype), + sum(unitStarttype(unit, starttype),
+ v_startup(unit, starttype, s, f+df(f,t+dt_toStartup(unit, t)), t+dt_toStartup(unit, t)) + v_startup_LP(unit, starttype, s, f+df(f,t+dt_toStartup(unit, t)), t+dt_toStartup(unit, t))
${ uft_onlineLP(unit, f+df(f,t+dt_toStartup(unit, t)), t+dt_toStartup(unit, t)) }
+ v_startup_MIP(unit, starttype, s, f+df(f,t+dt_toStartup(unit, t)), t+dt_toStartup(unit, t))
${ uft_onlineMIP(unit, f+df(f,t+dt_toStartup(unit, t)), t+dt_toStartup(unit, t)) }
)${not [unit_aggregator(unit) and ord(t) + dt_toStartup(unit, t) <= tSolveFirst + p_unit(unit, 'lastStepNotAggregated')]} // END sum(starttype) )${not [unit_aggregator(unit) and ord(t) + dt_toStartup(unit, t) <= tSolveFirst + p_unit(unit, 'lastStepNotAggregated')]} // END sum(starttype)
// NOTE! According to 3d_setVariableLimits, // NOTE! According to 3d_setVariableLimits,
...@@ -473,7 +486,8 @@ q_startuptype(m, s, starttypeConstrained(starttype), uft_online(unit, f, t)) ...@@ -473,7 +486,8 @@ q_startuptype(m, s, starttypeConstrained(starttype), uft_online(unit, f, t))
${msft(m, s, f, t) and unitStarttype(unit, starttype)} .. ${msft(m, s, f, t) and unitStarttype(unit, starttype)} ..
// Startup type // Startup type
+ v_startup(unit, starttype, s, f, t) + v_startup_LP(unit, starttype, s, f, t)${ uft_onlineLP(unit, f, t) }
+ v_startup_MIP(unit, starttype, s, f, t)${ uft_onlineMIP(unit, f, t) }
=L= =L=
...@@ -539,7 +553,10 @@ q_onlineOnStartUp(s, uft_online(unit, f, t)) ...@@ -539,7 +553,10 @@ q_onlineOnStartUp(s, uft_online(unit, f, t))
=G= =G=
+ sum(unitStarttype(unit, starttype), + sum(unitStarttype(unit, starttype),
+ v_startup(unit, starttype, s, f+df(f,t+dt_toStartup(unit, t)), t+dt_toStartup(unit, t)) //dt_toStartup displaces the time step to the one where the unit would be started up in order to reach online at t + v_startup_LP(unit, starttype, s, f+df(f,t+dt_toStartup(unit, t)), t+dt_toStartup(unit, t)) //dt_toStartup displaces the time step to the one where the unit would be started up in order to reach online at t
${ uft_onlineLP(unit, f+df(f,t+dt_toStartup(unit, t)), t+dt_toStartup(unit, t)) }
+ v_startup_MIP(unit, starttype, s, f+df(f,t+dt_toStartup(unit, t)), t+dt_toStartup(unit, t)) //dt_toStartup displaces the time step to the one where the unit would be started up in order to reach online at t
${ uft_onlineMIP(unit, f+df(f,t+dt_toStartup(unit, t)), t+dt_toStartup(unit, t)) }
) // END sum(starttype) ) // END sum(starttype)
; ;
...@@ -576,19 +593,27 @@ q_onlineMinUptime(m, s, uft_online(unit, f, t)) ...@@ -576,19 +593,27 @@ q_onlineMinUptime(m, s, uft_online(unit, f, t))
=G= =G=
// Units that have minimum operation time requirements active // Units that have minimum operation time requirements active
+ sum(unitCounter(unit, counter)${dt_uptimeUnitCounter(unit, counter)}, + sum(unitCounter(unit, counter)${ dt_uptimeUnitCounter(unit, counter)
and t_active(t+(dt_uptimeUnitCounter(unit, counter)+dt_toStartup(unit, t) + 1)) // Don't sum over counters that don't point to an active time step
},
+ sum(unitStarttype(unit, starttype), + sum(unitStarttype(unit, starttype),
+ v_startup(unit, starttype, s, f+df(f,t+(dt_uptimeUnitCounter(unit, counter)+dt_toStartup(unit, t) + 1)), t+(dt_uptimeUnitCounter(unit, counter)+dt_toStartup(unit, t) + 1)) + v_startup_LP(unit, starttype, s, f+df(f,t+(dt_uptimeUnitCounter(unit, counter)+dt_toStartup(unit, t) + 1)), t+(dt_uptimeUnitCounter(unit, counter)+dt_toStartup(unit, t) + 1))
${t_active(t+(dt_uptimeUnitCounter(unit, counter)+dt_toStartup(unit, t) + 1))} ${ uft_onlineLP(unit, f+df(f,t+(dt_uptimeUnitCounter(unit, counter)+dt_toStartup(unit, t) + 1)), t+(dt_uptimeUnitCounter(unit, counter)+dt_toStartup(unit, t) + 1)) }
+ v_startup_MIP(unit, starttype, s, f+df(f,t+(dt_uptimeUnitCounter(unit, counter)+dt_toStartup(unit, t) + 1)), t+(dt_uptimeUnitCounter(unit, counter)+dt_toStartup(unit, t) + 1))
${ uft_onlineMIP(unit, f+df(f,t+(dt_uptimeUnitCounter(unit, counter)+dt_toStartup(unit, t) + 1)), t+(dt_uptimeUnitCounter(unit, counter)+dt_toStartup(unit, t) + 1)) }
) // END sum(starttype) ) // END sum(starttype)
) // END sum(counter) ) // END sum(counter)
// Units that have minimum operation time requirements active (aggregated units in the past horizon or if they have an online variable) // Units that have minimum operation time requirements active (aggregated units in the past horizon or if they have an online variable)
+ sum(unitAggregator_unit(unit, unit_), + sum(unitAggregator_unit(unit, unit_),
+ sum(unitCounter(unit, counter)${dt_uptimeUnitCounter(unit, counter)}, + sum(unitCounter(unit, counter)${ dt_uptimeUnitCounter(unit, counter)
and t_active(t+(dt_uptimeUnitCounter(unit, counter)+dt_toStartup(unit, t) + 1)) // Don't sum over counters that don't point to an active time step
},
+ sum(unitStarttype(unit, starttype), + sum(unitStarttype(unit, starttype),
+ v_startup(unit, starttype, s, f+df(f,t+(dt_uptimeUnitCounter(unit, counter)+dt_toStartup(unit, t) + 1)), t+(dt_uptimeUnitCounter(unit, counter)+dt_toStartup(unit, t) + 1)) + v_startup_LP(unit, starttype, s, f+df(f,t+(dt_uptimeUnitCounter(unit, counter)+dt_toStartup(unit, t) + 1)), t+(dt_uptimeUnitCounter(unit, counter)+dt_toStartup(unit, t) + 1))
${t_active(t+(dt_uptimeUnitCounter(unit, counter)+dt_toStartup(unit, t) + 1))} ${ uft_onlineLP(unit, f+df(f,t+(dt_uptimeUnitCounter(unit, counter)+dt_toStartup(unit, t) + 1)), t+(dt_uptimeUnitCounter(unit, counter)+dt_toStartup(unit, t) + 1)) }
+ v_startup_MIP(unit, starttype, s, f+df(f,t+(dt_uptimeUnitCounter(unit, counter)+dt_toStartup(unit, t) + 1)), t+(dt_uptimeUnitCounter(unit, counter)+dt_toStartup(unit, t) + 1))
${ uft_onlineMIP(unit, f+df(f,t+(dt_uptimeUnitCounter(unit, counter)+dt_toStartup(unit, t) + 1)), t+(dt_uptimeUnitCounter(unit, counter)+dt_toStartup(unit, t) + 1)) }
) // END sum(starttype) ) // END sum(starttype)
) // END sum(counter) ) // END sum(counter)
)${unit_aggregator(unit)} // END sum(unit_) )${unit_aggregator(unit)} // END sum(unit_)
...@@ -696,7 +721,10 @@ q_rampUpLimit(m, s, gnuft_ramp(grid, node, unit, f, t))${ ord(t) > msStart(m, s ...@@ -696,7 +721,10 @@ q_rampUpLimit(m, s, gnuft_ramp(grid, node, unit, f, t))${ ord(t) > msStart(m, s
* 60 > 0 * 60 > 0
) )
}, },
+ v_startup(unit, starttype, s, f, t) + v_startup_LP(unit, starttype, s, f, t)
${ uft_onlineLP(unit, f, t) }
+ v_startup_MIP(unit, starttype, s, f, t)
${ uft_onlineMIP(unit, f, t) }
) // END sum(starttype) ) // END sum(starttype)
* p_gnu(grid, node, unit, 'unitSizeTot') * p_gnu(grid, node, unit, 'unitSizeTot')
* ( * (
...@@ -713,7 +741,12 @@ q_rampUpLimit(m, s, gnuft_ramp(grid, node, unit, f, t))${ ord(t) > msStart(m, s ...@@ -713,7 +741,12 @@ q_rampUpLimit(m, s, gnuft_ramp(grid, node, unit, f, t))${ ord(t) > msStart(m, s
+ p_gnu(grid, node, unit, 'unitSizeTot') + p_gnu(grid, node, unit, 'unitSizeTot')
* sum(unitStarttype(unit, starttype)${uft_startupTrajectory(unit, f, t)}, * sum(unitStarttype(unit, starttype)${uft_startupTrajectory(unit, f, t)},
sum(runUpCounter(unit, counter)${t_active(t+dt_trajectory(counter))}, // Sum over the run-up intervals sum(runUpCounter(unit, counter)${t_active(t+dt_trajectory(counter))}, // Sum over the run-up intervals
+ v_startup(unit, starttype, s, f+df(f, t+dt_trajectory(counter)), t+dt_trajectory(counter)) + [
+ v_startup_LP(unit, starttype, s, f+df(f, t+dt_trajectory(counter)), t+dt_trajectory(counter))
${ uft_onlineLP(unit, f+df(f, t+dt_trajectory(counter)), t+dt_trajectory(counter)) }
+ v_startup_MIP(unit, starttype, s, f+df(f, t+dt_trajectory(counter)), t+dt_trajectory(counter))
${ uft_onlineMIP(unit, f+df(f, t+dt_trajectory(counter)), t+dt_trajectory(counter)) }
]
* [ * [
+ p_unit(unit, 'rampSpeedToMinLoad') + p_unit(unit, 'rampSpeedToMinLoad')
+ ( p_gnu(grid, node, unit, 'maxRampUp') - p_unit(unit, 'rampSpeedToMinLoad') )${ not runUpCounter(unit, counter+1) } // Ramp speed adjusted for the last run-up interval + ( p_gnu(grid, node, unit, 'maxRampUp') - p_unit(unit, 'rampSpeedToMinLoad') )${ not runUpCounter(unit, counter+1) } // Ramp speed adjusted for the last run-up interval
...@@ -854,7 +887,10 @@ q_rampDownLimit(m, s, gnuft_ramp(grid, node, unit, f, t))${ ord(t) > msStart(m, ...@@ -854,7 +887,10 @@ q_rampDownLimit(m, s, gnuft_ramp(grid, node, unit, f, t))${ ord(t) > msStart(m,
* 60 > 0 * 60 > 0
) )
}, },
+ v_startup(unit, starttype, s, f, t) + v_startup_LP(unit, starttype, s, f, t)
${ uft_onlineLP(unit, f, t) }
+ v_startup_MIP(unit, starttype, s, f, t)
${ uft_onlineMIP(unit, f, t) }
) // END sum(starttype) ) // END sum(starttype)
* p_gnu(grid, node, unit, 'unitSizeTot') * p_gnu(grid, node, unit, 'unitSizeTot')
* ( * (
...@@ -922,7 +958,12 @@ q_rampSlack(m, s, gnuft_rampCost(grid, node, unit, slack, f, t))${ ord(t) > msS ...@@ -922,7 +958,12 @@ q_rampSlack(m, s, gnuft_rampCost(grid, node, unit, slack, f, t))${ ord(t) > msS
+ p_gnu(grid, node, unit, 'unitSizeTot') + p_gnu(grid, node, unit, 'unitSizeTot')
* sum(unitStarttype(unit, starttype)${uft_startupTrajectory(unit, f, t)}, * sum(unitStarttype(unit, starttype)${uft_startupTrajectory(unit, f, t)},
sum(runUpCounter(unit, counter)${t_active(t+dt_trajectory(counter))}, // Sum over the run-up intervals sum(runUpCounter(unit, counter)${t_active(t+dt_trajectory(counter))}, // Sum over the run-up intervals
+ v_startup(unit, starttype, s, f+df(f, t+dt_trajectory(counter)), t+dt_trajectory(counter)) + [
+ v_startup_LP(unit, starttype, s, f+df(f, t+dt_trajectory(counter)), t+dt_trajectory(counter))
${ uft_onlineLP(unit, f+df(f, t+dt_trajectory(counter)), t+dt_trajectory(counter)) }
+ v_startup_MIP(unit, starttype, s, f+df(f, t+dt_trajectory(counter)), t+dt_trajectory(counter))
${ uft_onlineMIP(unit, f+df(f, t+dt_trajectory(counter)), t+dt_trajectory(counter)) }
]
* [ * [
+ p_unit(unit, 'rampSpeedToMinLoad') + p_unit(unit, 'rampSpeedToMinLoad')
+ ( p_gnuBoundaryProperties(grid, node, unit, slack, 'rampLimit') - p_unit(unit, 'rampSpeedToMinLoad') )${ not runUpCounter(unit, counter+1) } // Ramp speed adjusted for the last run-up interval + ( p_gnuBoundaryProperties(grid, node, unit, slack, 'rampLimit') - p_unit(unit, 'rampSpeedToMinLoad') )${ not runUpCounter(unit, counter+1) } // Ramp speed adjusted for the last run-up interval
...@@ -1031,7 +1072,12 @@ q_conversionDirectInputOutput(s, suft(effDirect(effGroup), unit, f, t))$sft(s, f ...@@ -1031,7 +1072,12 @@ q_conversionDirectInputOutput(s, suft(effDirect(effGroup), unit, f, t))$sft(s, f
// Run-up 'online state' // Run-up 'online state'
+ sum(unitStarttype(unit, starttype)${uft_startupTrajectory(unit, f, t)}, + sum(unitStarttype(unit, starttype)${uft_startupTrajectory(unit, f, t)},
+ sum(runUpCounter(unit, counter)${t_active(t+dt_trajectory(counter))}, // Sum over the run-up intervals + sum(runUpCounter(unit, counter)${t_active(t+dt_trajectory(counter))}, // Sum over the run-up intervals
+ v_startup(unit, starttype, s, f+df(f, t+dt_trajectory(counter)), t+dt_trajectory(counter)) + [
+ v_startup_LP(unit, starttype, s, f+df(f, t+dt_trajectory(counter)), t+dt_trajectory(counter))
${ uft_onlineLP(unit, f+df(f, t+dt_trajectory(counter)), t+dt_trajectory(counter)) }
+ v_startup_MIP(unit, starttype, s, f+df(f, t+dt_trajectory(counter)), t+dt_trajectory(counter))
${ uft_onlineMIP(unit, f+df(f, t+dt_trajectory(counter)), t+dt_trajectory(counter)) }
]
* p_uCounter_runUpMin(unit, counter) * p_uCounter_runUpMin(unit, counter)
/ p_unit(unit, 'op00') // Scaling the p_uCounter_runUp using minload / p_unit(unit, 'op00') // Scaling the p_uCounter_runUp using minload
) // END sum(runUpCounter) ) // END sum(runUpCounter)
...@@ -1086,7 +1132,12 @@ q_conversionIncHR(s, suft(effIncHR(effGroup), unit, f, t))$sft(s, f, t) .. ...@@ -1086,7 +1132,12 @@ q_conversionIncHR(s, suft(effIncHR(effGroup), unit, f, t))$sft(s, f, t) ..
// Run-up 'online state' // Run-up 'online state'
+ sum(unitStarttype(unit, starttype)${uft_startupTrajectory(unit, f, t)}, + sum(unitStarttype(unit, starttype)${uft_startupTrajectory(unit, f, t)},
+ sum(runUpCounter(unit, counter)${t_active(t+dt_trajectory(counter))}, // Sum over the run-up intervals + sum(runUpCounter(unit, counter)${t_active(t+dt_trajectory(counter))}, // Sum over the run-up intervals
+ v_startup(unit, starttype, s, f+df(f, t+dt_trajectory(counter)), t+dt_trajectory(counter)) + [
+ v_startup_LP(unit, starttype, s, f+df(f, t+dt_trajectory(counter)), t+dt_trajectory(counter))
${ uft_onlineLP(unit, f+df(f, t+dt_trajectory(counter)), t+dt_trajectory(counter)) }
+ v_startup_MIP(unit, starttype, s, f+df(f, t+dt_trajectory(counter)), t+dt_trajectory(counter))
${ uft_onlineMIP(unit, f+df(f, t+dt_trajectory(counter)), t+dt_trajectory(counter)) }
]
* p_uCounter_runUpMin(unit, counter) * p_uCounter_runUpMin(unit, counter)
/ p_unit(unit, 'hrop00') // Scaling the p_uCounter_runUp using minload / p_unit(unit, 'hrop00') // Scaling the p_uCounter_runUp using minload
) // END sum(runUpCounter) ) // END sum(runUpCounter)
...@@ -1229,7 +1280,12 @@ q_conversionSOS2Constraint(s, suft(effLambda(effGroup), unit, f, t))$sft(s, f, t ...@@ -1229,7 +1280,12 @@ q_conversionSOS2Constraint(s, suft(effLambda(effGroup), unit, f, t))$sft(s, f, t
// Run-up 'online state' // Run-up 'online state'
+ sum(unitStarttype(unit, starttype)${uft_startupTrajectory(unit, f, t)}, + sum(unitStarttype(unit, starttype)${uft_startupTrajectory(unit, f, t)},
+ sum(runUpCounter(unit, counter)${t_active(t+dt_trajectory(counter))}, // Sum over the run-up intervals + sum(runUpCounter(unit, counter)${t_active(t+dt_trajectory(counter))}, // Sum over the run-up intervals
+ v_startup(unit, starttype, s, f+df(f, t+dt_trajectory(counter)), t+dt_trajectory(counter)) + [
+ v_startup_LP(unit, starttype, s, f+df(f, t+dt_trajectory(counter)), t+dt_trajectory(counter))
${ uft_onlineLP(unit, f+df(f, t+dt_trajectory(counter)), t+dt_trajectory(counter)) }
+ v_startup_MIP(unit, starttype, s, f+df(f, t+dt_trajectory(counter)), t+dt_trajectory(counter))
${ uft_onlineMIP(unit, f+df(f, t+dt_trajectory(counter)), t+dt_trajectory(counter)) }
]
* p_uCounter_runUpMin(unit, counter) * p_uCounter_runUpMin(unit, counter)
/ p_unit(unit, 'op00') // Scaling the p_uCounter_runUp using minload / p_unit(unit, 'op00') // Scaling the p_uCounter_runUp using minload
) // END sum(runUpCounter) ) // END sum(runUpCounter)
...@@ -1973,7 +2029,12 @@ q_emissioncap(group, emission)${ p_groupPolicy3D(group, 'emissionCap', emission ...@@ -1973,7 +2029,12 @@ q_emissioncap(group, emission)${ p_groupPolicy3D(group, 'emissionCap', emission
// Start-up emissions // Start-up emissions
+ sum(uft_online(unit_fuel, f, t), + sum(uft_online(unit_fuel, f, t),
+ sum(unitStarttype(unit_fuel, starttype), + sum(unitStarttype(unit_fuel, starttype),
+ v_startup(unit_fuel, starttype, s, f, t) + [
+ v_startup_LP(unit_fuel, starttype, s, f, t)
${ uft_onlineLP(unit_fuel, f, t) }
+ v_startup_MIP(unit_fuel, starttype, s, f, t)
${ uft_onlineMIP(unit_fuel, f, t) }
]
* sum(uFuel(unit_fuel, 'startup', fuel), * sum(uFuel(unit_fuel, 'startup', fuel),
+ p_uStartup(unit_fuel, starttype, 'consumption') + p_uStartup(unit_fuel, starttype, 'consumption')
* p_uFuel(unit_fuel, 'startup', fuel, 'fixedFuelFraction') * p_uFuel(unit_fuel, 'startup', fuel, 'fixedFuelFraction')
......
...@@ -36,7 +36,8 @@ Option clear = v_help_inc; ...@@ -36,7 +36,8 @@ Option clear = v_help_inc;
Option clear = v_sos2; Option clear = v_sos2;
// Positive Variables // Positive Variables
Option clear = v_fuelUse; Option clear = v_fuelUse;
Option clear = v_startup; Option clear = v_startup_LP;
Option clear = v_startup_MIP;
Option clear = v_shutdown; Option clear = v_shutdown;
Option clear = v_genRampUpDown; Option clear = v_genRampUpDown;
Option clear = v_spill; Option clear = v_spill;
......
...@@ -226,17 +226,31 @@ v_online_MIP.up(unit, sft(s, f, t))${uft_onlineMIP(unit, f, t) and not unit_inve ...@@ -226,17 +226,31 @@ v_online_MIP.up(unit, sft(s, f, t))${uft_onlineMIP(unit, f, t) and not unit_inve
] ]
; ;
$ontext
// NOTE! These are unnecessary?
// Free the upper bound of start-up and shutdown variables (if previously bounded) // Free the upper bound of start-up and shutdown variables (if previously bounded)
v_startup.up(unitStarttype(unit, starttype), sft(s, f, t)) = inf; v_startup_LP.up(unitStarttype(unit, starttype), sft(s, f, t))
${ uft_onlineLP(unit, f, t) }
= inf;
v_startup_MIP.up(unitStarttype(unit, starttype), sft(s, f, t))
${ uft_onlineMIP(unit, f, t) }
= inf;
v_shutdown.up(unit, sft(s, f, t))$uft(unit, f, t) = inf; v_shutdown.up(unit, sft(s, f, t))$uft(unit, f, t) = inf;
$offtext
// v_startup cannot exceed unitCount // v_startup cannot exceed unitCount
v_startup.up(unitStarttype(unit, starttype), sft(s, f, t))${ uft_online(unit, f, t) v_startup_LP.up(unitStarttype(unit, starttype), sft(s, f, t))
and not unit_investLP(unit) ${ uft_onlineLP(unit, f, t)
and not unit_investMIP(unit) and not unit_investLP(unit)
} and not unit_investMIP(unit)
= p_unit(unit, 'unitCount') }
; = p_unit(unit, 'unitCount');
v_startup_MIP.up(unitStarttype(unit, starttype), sft(s, f, t))
${ uft_onlineMIP(unit, f, t)
and not unit_investLP(unit)
and not unit_investMIP(unit)
}
= p_unit(unit, 'unitCount');
// v_shutdown cannot exceed unitCount // v_shutdown cannot exceed unitCount
v_shutdown.up(unit, sft(s, f, t))${uft_online(unit, f, t) v_shutdown.up(unit, sft(s, f, t))${uft_online(unit, f, t)
...@@ -443,7 +457,8 @@ loop((mft_start(mSolve, f, t), ms_initial(mSolve, s)), ...@@ -443,7 +457,8 @@ loop((mft_start(mSolve, f, t), ms_initial(mSolve, s)),
= p_gnu(grid, node, unit, 'initialGeneration'); = p_gnu(grid, node, unit, 'initialGeneration');
// Startup and shutdown variables are not applicable at the first time step // Startup and shutdown variables are not applicable at the first time step
v_startup.fx(unitStarttype(unit, starttype), s, f, t) = 0; v_startup_LP.fx(unitStarttype(unit_online_LP, starttype), s, f, t) = 0;
v_startup_MIP.fx(unitStarttype(unit_online_MIP, starttype), s, f, t) = 0;
v_shutdown.fx(unit, s, f, t) = 0; v_shutdown.fx(unit, s, f, t) = 0;
else // For all other solves, fix the initial state values based on previous results. else // For all other solves, fix the initial state values based on previous results.
...@@ -467,10 +482,12 @@ loop((mft_start(mSolve, f, t), ms_initial(mSolve, s)), ...@@ -467,10 +482,12 @@ loop((mft_start(mSolve, f, t), ms_initial(mSolve, s)),
// Needed for modelling hot and warm start-ups, minimum uptimes and downtimes, and run-up and shutdown phases. // Needed for modelling hot and warm start-ups, minimum uptimes and downtimes, and run-up and shutdown phases.
if( tSolveFirst <> mSettings(mSolve, 't_start'), // Avoid rewriting the fixes on the first solve handled above if( tSolveFirst <> mSettings(mSolve, 't_start'), // Avoid rewriting the fixes on the first solve handled above
v_startup.fx(unitStarttype(unit, starttype), sft_realizedNoReset(s, f, t_active(t))) v_startup_LP.fx(unitStarttype(unit_online_LP(unit), starttype), sft_realizedNoReset(s, f, t_active(t)))
${ ord(t) <= tSolveFirst // Only fix previously realized time steps ${ ord(t) <= tSolveFirst } // Only fix previously realized time steps
and unit_online(unit) // Check if the unit has an online variable on the first effLevel = r_startup(unit, starttype, f, t);
}
v_startup_MIP.fx(unitStarttype(unit_online_MIP(unit), starttype), sft_realizedNoReset(s, f, t_active(t)))
${ ord(t) <= tSolveFirst } // Only fix previously realized time steps
= r_startup(unit, starttype, f, t); = r_startup(unit, starttype, f, t);
v_shutdown.fx(unit, sft_realizedNoReset(s, f, t_active(t))) v_shutdown.fx(unit, sft_realizedNoReset(s, f, t_active(t)))
......
...@@ -49,7 +49,8 @@ loop(sft_realized(s, f, t), ...@@ -49,7 +49,8 @@ loop(sft_realized(s, f, t),
; ;
// Unit startup and shutdown history // Unit startup and shutdown history
r_startup(unit, starttype, f, t)${ uft_online(unit, f, t) and [ord(t) > mSettings(mSolve, 't_start') + mSettings(mSolve, 't_initializationPeriod')] } r_startup(unit, starttype, f, t)${ uft_online(unit, f, t) and [ord(t) > mSettings(mSolve, 't_start') + mSettings(mSolve, 't_initializationPeriod')] }
= v_startup.l(unit, starttype, s, f, t) = v_startup_LP.l(unit, starttype, s, f, t)${ uft_onlineLP(unit, f, t) }
+ v_startup_MIP.l(unit, starttype, s, f, t)${ uft_onlineMIP(unit, f, t) }
; ;
r_shutdown(uft_online(unit, f, t))$[ord(t) > mSettings(mSolve, 't_start') + mSettings(mSolve, 't_initializationPeriod')] r_shutdown(uft_online(unit, f, t))$[ord(t) > mSettings(mSolve, 't_start') + mSettings(mSolve, 't_initializationPeriod')]
= v_shutdown.l(unit, s, f, t) = v_shutdown.l(unit, 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