Commit db7765b6 authored by Juha Kiviluoma's avatar Juha Kiviluoma
Browse files

Fixes and clean ups. Most importantly a term in the q_maxUpward was updated to...

Fixes and clean ups. Most importantly a term in the q_maxUpward was updated to point to the correct start up time period (hopefully).
parent ee512c1d
relaxfixedinfeas = 1
......@@ -59,10 +59,9 @@ Parameters
p_effGroupUnit(effSelector, unit, *) "Unit data specific to a efficiency group (e.g. left border of the unit)"
p_uNonoperational(unit, starttype, min_max) "Non-operational time after being shut down before start up"
p_uStartup(unit, starttype, cost_consumption, unit_capacity) "Startup cost and fuel consumption"
p_u_maxRampInLastRunUpInterval(unit) "Ramp speed in the last interval for the run-up to min. load"
p_u_maxOutputInLastRunUpInterval(unit) "Ramp speed in the last interval for the run-up to min. load"
p_u_runUpTimeIntervals(unit) "Time intervals required for the run-up phase"
p_ut_startup(unit, t)
p_ut_runUp(unit, t)
p_ut_runUp(unit, t) "Ramp rate for the time intervals where the unit is being started up to the minimum load"
// Time dependent unit & fuel parameters
ts_unit(unit, *, f, t) "Time dependent unit data, where energy type doesn't matter"
ts_effUnit(effSelector, unit, effSelector, *, f, t) "Time dependent data for piece-wise linear efficiency blocks"
......@@ -86,10 +85,11 @@ Parameters
// Time displacement arrays
dt(t) "Displacement needed to reach the previous time period (in time periods)"
dt_circular(t) "Circular t displacement if the time series data is not long enough to cover the model horizon"
dtt(t, t) "Displacement needed to reach any previous time period (in time periods)"
dt_toStartup(unit, t) "Displacement from the current time period to the time period where the unit has been started up in case online variable changes from 0 to 1"
dt_starttypeUnitCounter(starttype, unit, counter) "Displacement needed to account for starttype constraints"
dt_downtimeUnitCounter(unit, counter) "Displacement needed to account for downtime constraints"
dt_uptimeUnitCounter(unit, counter) "Displacement needed to account for uptime constraints"
dtt(t, t) "Displacement needed to reach any previous time period (in time periods)"
// Forecast displacement arrays
df(f, t) "Displacement needed to reach the realized forecast on the current time step"
......
......@@ -397,14 +397,13 @@ q_maxDownward(m, gnuft(grid, node, unit, f, t))${ [ ord(t) < tSolveFirst + m
and [unit_investLP(unit) or unit_investMIP(unit)]
]
} ..
// Energy generation/consumption
+ v_gen(grid, node, unit, f, t)
// Considering output constraints (e.g. cV line)
+ sum(gngnu_constrainedOutputRatio(grid, node, grid_, node_, unit),
+ p_gnu(grid_, node_, unit, 'cV')
* v_gen(grid_, node_, unit, f, t)
+ sum(gngnu_constrainedOutputRatio(grid, node, grid_output, node_, unit),
+ p_gnu(grid_output, node_, unit, 'cV')
* v_gen(grid_output, node_, unit, f, t)
) // END sum(gngnu_constrainedOutputRatio)
// Downward reserve participation
......@@ -425,8 +424,9 @@ q_maxDownward(m, gnuft(grid, node, unit, f, t))${ [ ord(t) < tSolveFirst + m
+ v_online_MIP(unit, f+df_central(f,t), t)${uft_onlineMIP(unit, f, t)} // MIP online variant
] // END v_online
// Units that are in the run-up phase need to keep up with the run-up ramp rate (contained in p_ut_runUp)
+ p_gnu(grid, node, unit, 'unitSizeGen')
* sum(t_$(ord(t_) > ord(t) + p_ut_startup(unit, t) and ord(t_) <= ord(t) and uft_online(unit, f, t_)),
* sum(t_$(ord(t_) > ord(t) + dt_toStartup(unit, t) and ord(t_) <= ord(t) and uft_online(unit, f, t_)),
+ sum(unitStarttype(unit, starttype),
+ v_startup(unit, starttype, f, t_) * sum(t__${ord(t__) = ord(t) - ord(t_) + 1}, p_ut_runUp(unit, t__)) //t+dtt(t,t_)
)
......@@ -469,7 +469,7 @@ q_noReserveInRunUp(m, gnuft(grid, node, unit, f, t))$[ ord(t) < tSolveFirst +
v_gen(grid, node, unit, f, t)
=G=
+ p_gnu(grid, node, unit, 'unitSizeGen')
* sum(t_$(ord(t_) > ord(t) + p_ut_startup(unit, t) and ord(t_) <= ord(t) and uft_online(unit, f, t_)),
* sum(t_$(ord(t_) > ord(t) + dt_toStartup(unit, t) and ord(t_) <= ord(t) and uft_online(unit, f, t_)),
+ sum(unitStarttype(unit, starttype),
+ v_startup(unit, starttype, f, t_) * sum(t__${ord(t__) = ord(t) - ord(t_) + 1}, p_ut_runUp(unit, t__)) //t+dtt(t,t_)
)
......@@ -483,7 +483,7 @@ $ontext
+ v_invest_LP(unit, t_)${unit_investLP(unit)} // NOTE! v_invest_LP also for consuming units is positive
+ v_invest_MIP(unit, t_)${unit_investMIP(unit)} // NOTE! v_invest_MIP also for consuming units is positive
) // END sum(t_invest)
- sum(t_$(ord(t_) >= ord(t) + p_ut_startup(unit, t) and ord(t_) < ord(t) and uft_online(unit, f, t_)),
- sum(t_$(ord(t_) >= ord(t) + dt_toStartup(unit, t) and ord(t_) < ord(t) and uft_online(unit, f, t_)),
+ sum(unitStarttype(unit, starttype),
+ v_startup(unit, starttype, f, t_)
)
......@@ -565,16 +565,18 @@ q_maxUpward(m, gnuft(grid, node, unit, f, t))${ [ ord(t) < tSolveFirst + mSett
] // END * p_gnu(unitSizeGen)
] // END * p_unit(availability)
// Units that are in the run-up phase need to keep up with the run-up ramp rate (contained in p_ut_runUp)
+ p_gnu(grid, node, unit, 'unitSizeGen')
* sum(t_$(ord(t_) > ord(t) + p_ut_startup(unit, t) and ord(t_) < ord(t) and uft_online(unit, f, t_)),
* sum(t_$(ord(t_) > ord(t) + dt_toStartup(unit, t) and ord(t_) < ord(t) and uft_online(unit, f, t_)),
+ sum(unitStarttype(unit, starttype),
+ v_startup(unit, starttype, f, t_) * sum(t__${ord(t__) = ord(t) - ord(t_) + 1}, p_ut_runUp(unit, t__)) //t+dtt(t,t_)
+ v_startup(unit, starttype, f, t_) * sum(t__${ord(t__) = ord(t) - ord(t_) + 1}, p_ut_runUp(unit, t__))
)
)$p_u_runUpTimeIntervals(unit)
// Units that are in the last time interval of the run-up phase are limited by the p_u_maxOutputInLastRunUpInterval
+ p_gnu(grid, node, unit, 'unitSizeGen')
* sum(t_$(ord(t_) = ord(t) and uft_online(unit, f, t_)),
* sum(t_$(ord(t_) = ord(t) + dt_toStartup(unit, t) and uft_online(unit, f, t_)),
+ sum(unitStarttype(unit, starttype),
+ v_startup(unit, starttype, f, t_) * p_u_maxRampInLastRunUpInterval(unit) //t+dtt(t,t_)
+ v_startup(unit, starttype, f, t_) * p_u_maxOutputInLastRunUpInterval(unit)
)
)$p_u_runUpTimeIntervals(unit)
;
......@@ -599,7 +601,7 @@ q_startshut(m, uft_online(unit, f, t))${ ord(t) + dt(t) > mSettings(m, 't_start'
// Unit startup and shutdown
+ sum(unitStarttype(unit, starttype),
+ v_startup(unit, starttype, f+df_central(f,t+p_ut_startup(unit,t)), t+p_ut_startup(unit, t))
+ v_startup(unit, starttype, f+df_central(f,t+dt_toStartup(unit,t)), t+dt_toStartup(unit, t))
) // END sum(starttype)
- v_shutdown(unit, f, t)
;
......@@ -614,7 +616,7 @@ q_startshut(m, uft_online(unit, f, t))${ ord(t) + dt(t) > mSettings(m, 't_start'
q_startuptype(m, starttypeConstrained(starttype), uft_online(unit, f, t))${ unitStarttype(unit, starttype) } ..
// Startup type
+ v_startup(unit, starttype, f+df_central(f,t+p_ut_startup(unit,t)), t+p_ut_startup(unit, t))
+ v_startup(unit, starttype, f+df_central(f,t+dt_toStartup(unit,t)), t+dt_toStartup(unit, t))
=L=
......@@ -665,7 +667,7 @@ q_onlineOnStartUp(uft_online(unit, f, t))${sum(starttype, unitStarttype(unit, st
=G=
+ sum(unitStarttype(unit, starttype),
+ v_startup(unit, starttype, f+df(f,t+p_ut_startUp(unit, t)), t+p_ut_startUp(unit, t))
+ v_startup(unit, starttype, 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
) // END sum(starttype)
;
......@@ -703,7 +705,7 @@ q_onlineMinUptime(m, uft_online(unit, f, t))${ p_unit(unit, 'minOperationHours'
// Units that have minimum operation time requirements active
+ sum(counter${dt_uptimeUnitCounter(unit, counter)},
+ sum(unitStarttype(unit, starttype),
+ v_startup(unit, starttype, f+df(f,t+(dt_uptimeUnitCounter(unit, counter)+p_ut_startUp(unit, t))), t+(dt_uptimeUnitCounter(unit, counter)+p_ut_startUp(unit, t)))
+ v_startup(unit, starttype, f+df(f,t+(dt_uptimeUnitCounter(unit, counter)+dt_toStartup(unit, t))), t+(dt_uptimeUnitCounter(unit, counter)+dt_toStartup(unit, t)))
) // END sum(starttype)
) // END sum(counter)
;
......@@ -937,7 +939,7 @@ q_conversionSOS2IntermediateOutput(suft(effLambda(effGroup), unit, f, t)) ..
+ sum(gnu_output(grid, node, unit)$p_u_runUpTimeIntervals(unit),
+ p_gnu(grid, node, unit, 'unitSizeGen')
) // END sum(gnu_output)
* sum(t_$(ord(t_) > ord(t) + p_ut_startup(unit, t) and ord(t_) <= ord(t) and uft_online(unit, f, t_)),
* sum(t_$(ord(t_) > ord(t) + dt_toStartup(unit, t) and ord(t_) <= ord(t) and uft_online(unit, f, t_)),
+ sum(unitStarttype(unit, starttype),
+ v_startup(unit, starttype, f, t_) * sum(t__${ord(t__) = ord(t) - ord(t_) + 1}, p_ut_runUp(unit, t__)) //t+dtt(t,t_)
)
......
......@@ -319,14 +319,14 @@ loop(m,
loop(t${ord(t)<=ceil(p_u_runUpTimeIntervals(unit))},
p_ut_runUp(unit, t)=p_unit(unit, 'rampSpeedToMinLoad') * (ceil(p_u_runUpTimeIntervals(unit) - ord(t) + 1));
);
p_u_maxRampInLastRunUpInterval(unit) =
p_u_maxOutputInLastRunUpInterval(unit) =
+ p_unit(unit, 'rampSpeedToMinLoad') * (tmp-floor(tmp)) / mSettings(m, 'intervalInHours')
+ smin(gnu(grid, node, unit), p_gnu(grid, node, unit, 'maxRampUp')) * (ceil(tmp)-tmp) / mSettings(m, 'intervalInHours');
unitStarttype(unit, 'cold') = no;
unitStarttype(unit, 'cold')${ p_unit(unit, 'startCostCold')
or p_unit(unit, 'startFuelConsCold')
or p_u_runUpTimeIntervals(unit) > 1
or (p_u_runUpTimeIntervals(unit) <= 1 and p_u_maxRampInLastRunUpInterval(unit) < 1)
or (p_u_runUpTimeIntervals(unit) <= 1 and p_u_maxOutputInLastRunUpInterval(unit) < 1)
}
= yes;
) // END loop(unit)
......
......@@ -456,18 +456,18 @@ p_msft_probability(msft(mSolve, s, f, t))
Option clear = dtt;
dtt(t,t_)$(t_active(t) and (t_active(t_) or ord(t_) = tSolveFirst) and ord(t_)<=ord(t)) = sum(t__$(ord(t__)>ord(t_) and ord(t__) <= ord(t)), dt(t__));
Option clear = p_ut_startUp;
Option clear = dt_toStartup;
loop(unit$(p_u_runUpTimeIntervals(unit)),
loop(t$t_active(t),
tmp = 1;
loop(t_${t_active(t_) and ord(t_) <= ord(t) and tmp = 1},
if (-dtt(t,t_) < p_u_runUpTimeIntervals(unit),
p_ut_startup(unit, t) = dtt(t,t_+dt(t));
dt_toStartup(unit, t) = dtt(t,t_+dt(t));
tmp = 0;
);
);
if (tmp = 1,
p_ut_startup(unit, t) = dt(t);
dt_toStartup(unit, t) = dt(t);
tmp=0;
);
);
......
......@@ -180,7 +180,7 @@ v_online_MIP.up(uft_onlineMIP(unit, f, t))${ not unit_investMIP(unit) }
v_startup.up(unitStarttype(unit, starttype), f, t)${uft_online(unit, f, t) and not unit_investLP(unit) and not unit_investMIP(unit) }
= p_unit(unit, 'unitCount')
;
v_startup.up(unitStarttype(unit, starttype), f, t)${uft_online(unit, f, t) and not t_active(t-p_ut_startup(unit,t))} = 0;
v_startup.up(unitStarttype(unit, starttype), f, t)${uft_online(unit, f, t) and not t_active(t-dt_toStartup(unit,t))} = 0;
//These might speed up, but they should be applied only to the new part of the horizon (should be explored)
*v_startup.l(unitStarttype(unit, starttype), f, t)${uft_online(unit, f, t) and not unit_investLP(unit) } = 0;
......@@ -379,7 +379,7 @@ loop(mft_start(mSolve, f, t),
v_state.fx(gn_state(grid, node), f, t)
= r_state(grid, node, f, t);
v_startup.fx(unitStarttype(unit, starttype), f, t)
= r_startup(unit, starttype, f, t);
= round(r_startup(unit, starttype, f, t), 4);
); // END if(tSolveFirst)
) // END loop(mftStart)
......
......@@ -21,15 +21,18 @@ $offtext
if (mSolve('schedule'),
schedule.holdfixed = 1; // Enable holdfixed, which makes the GAMS compiler convert fixed variables into parameters for the solver.
schedule.OptFile = 1;
solve schedule using mip minimizing v_obj;
); // END IF SCHEDULE
if (mSolve('building'),
building.holdfixed = 1;
building.OptFile = 1;
solve building using mip minimizing v_obj;
); // END IF BUILDING
if (mSolve('invest'),
invest.holdfixed = 1; // Enable holdfixed, which makes the GAMS compiler convert fixed variables into parameters for the solver.
invest.OptFile = 1;
solve invest using mip minimizing v_obj;
); // END IF INVEST
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