Commit 9e90d49e authored by Topi Rasku's avatar Topi Rasku
Browse files

Implemented new "uftt" sets for reducing the time required to generate...

Implemented new "uftt" sets for reducing the time required to generate startuptype and minimum up-/downtime equations. Started using the tt(t) set to limit the time required for looping over t in some places, but could probably be utilized further.

There are still some old uses of the tt_ set as temporary subset of t, which is not really ideal when it comes to naming conventions.
parent 9f964971
......@@ -218,27 +218,27 @@ loop(counter${mInterval(mSolve, 'intervalLength', counter)},
// Loop over the t:s of the interval
loop(ft(fSolve, tInterval(t)),
// Select t:s within the interval
Option clear = tt;
tt(t_)${ ord(t_) >= ord(t)
Option clear = tt_;
tt_(t_)${ ord(t_) >= ord(t)
and ord(t_) < ord(t) + mInterval(mSolve, 'intervalLength', counter)
}
= yes;
ts_influx_(gn(grid, node), fSolve, t)
= sum(tt(t_), ts_influx(grid, node, fSolve, t_+dt_circular(t_)))
= sum(tt_(t_), ts_influx(grid, node, fSolve, t_+dt_circular(t_)))
/ p_stepLength(mSolve, fSolve, t);
ts_cf_(flow, node, fSolve, t)${ sum(grid, gn(grid, node)) // Only include nodes with grids attributed to them
}
= sum(tt(t_), ts_cf(flow, node, fSolve, t_+dt_circular(t_)))
= sum(tt_(t_), ts_cf(flow, node, fSolve, t_+dt_circular(t_)))
/ p_stepLength(mSolve, fSolve, t);
ts_unit_(unit, param_unit, fSolve, t)${ p_unit(unit, 'useTimeseries') } // Only include units with timeseries attributed to them
= sum(tt(t_), ts_unit(unit, param_unit, fSolve, t_+dt_circular(t_)))
= sum(tt_(t_), ts_unit(unit, param_unit, fSolve, t_+dt_circular(t_)))
/ p_stepLength(mSolve, fSolve, t);
// Reserves relevant only until t_reserveLength
ts_reserveDemand_(restypeDirectionNode(restype, up_down, node), fSolve, t)${ ord(t) <= tSolveFirst + mSettings(mSolve, 't_reserveLength') }
= sum(tt(t_), ts_reserveDemand(restype, up_down, node, fSolve, t_+dt_circular(t_)))
= sum(tt_(t_), ts_reserveDemand(restype, up_down, node, fSolve, t_+dt_circular(t_)))
/ p_stepLength(mSolve, fSolve, t);
ts_nodeState_(gn_state(grid, node), param_gnBoundaryTypes, fSolve, t)${ p_gnBoundaryPropertiesForStates(grid, node, param_gnBoundaryTypes, 'useTimeseries') }
= sum(tt(t_), ts_nodeState(grid, node, param_gnBoundaryTypes, fSolve, t_+dt_circular(t_)))
= sum(tt_(t_), ts_nodeState(grid, node, param_gnBoundaryTypes, fSolve, t_+dt_circular(t_)))
/ p_stepLength(mSolve, fSolve, t);
); // END loop(ft)
......@@ -395,7 +395,7 @@ sufts(suft(effGroup, unit, f, t), effSelector)${ effGroupSelector(effGroup, e
Option clear = uft_online;
Option clear = uft_onlineLP;
Option clear = uft_onlineMIP;
Option clear = uft_online_last;
*Option clear = uft_online_last;
// Determine the time steps when units need to have online variables.
loop(suft(effOnline, uft(unit, f, t)),
......@@ -427,18 +427,37 @@ loop(effGroupSelectorUnit(effDirectOff, unit, effDirectOff_)${ p_unit(unit, 'use
// Alternatively, one might require that the 'rb' is defined in a similar structure, so that the max 'rb' is located in the same index for all ft(f,t)
// Calculate unit wide parameters for each efficiency group
loop(unit,
loop(effLevel${mSettingsEff(mSolve, effLevel)},
loop(effLevelGroupUnit(effLevel, effGroup, unit),
ts_effGroupUnit(effGroup, unit, 'rb', ft(f, t))${ sum(effSelector, ts_effUnit(effGroup, unit, effSelector, 'rb', f, t))}
= smax(effSelector$effGroupSelectorUnit(effGroup, unit, effSelector), ts_effUnit(effGroup, unit, effSelector, 'rb', f, t));
ts_effGroupUnit(effGroup, unit, 'lb', ft(f, t))${ sum(effSelector, ts_effUnit(effGroup, unit, effSelector, 'lb', f, t))}
= smin(effSelector${effGroupSelectorUnit(effGroup, unit, effSelector)}, ts_effUnit(effGroup, unit, effSelector, 'lb', f, t));
ts_effGroupUnit(effGroup, unit, 'slope', ft(f, t))${sum(effSelector, ts_effUnit(effGroup, unit, effSelector, 'slope', f, t))}
= smin(effSelector$effGroupSelectorUnit(effGroup, unit, effSelector), ts_effUnit(effGroup, unit, effSelector, 'slope', f, t)); // Uses maximum efficiency for the group
); // END loop(effLevelGroupUnit)
); // END loop(effLevel)
); // END loop(unit)
loop(effLevelGroupUnit(effLevel, effGroup, unit)${mSettingsEff(mSolve, effLevel)},
ts_effGroupUnit(effGroup, unit, 'rb', ft(f, t))${ sum(effSelector, ts_effUnit(effGroup, unit, effSelector, 'rb', f, t))}
= smax(effSelector$effGroupSelectorUnit(effGroup, unit, effSelector), ts_effUnit(effGroup, unit, effSelector, 'rb', f, t));
ts_effGroupUnit(effGroup, unit, 'lb', ft(f, t))${ sum(effSelector, ts_effUnit(effGroup, unit, effSelector, 'lb', f, t))}
= smin(effSelector${effGroupSelectorUnit(effGroup, unit, effSelector)}, ts_effUnit(effGroup, unit, effSelector, 'lb', f, t));
ts_effGroupUnit(effGroup, unit, 'slope', ft(f, t))${sum(effSelector, ts_effUnit(effGroup, unit, effSelector, 'slope', f, t))}
= smin(effSelector$effGroupSelectorUnit(effGroup, unit, effSelector), ts_effUnit(effGroup, unit, effSelector, 'slope', f, t)); // Uses maximum efficiency for the group
); // END loop(effLevelGroupUnit)
* --- Define the time steps necessary for startup, downtime and uptime constraints
// Time windows for startups
Option clear = uftt_startupType;
uftt_startupType(starttype, uft_online(unit, f, t), tt_(t_))${ ord(t_) > [ord(t)-p_uNonoperational(unit, starttype, 'max') / mSettings(mSolve, 'intervalInHours') / (p_stepLengthNoReset(mSolve, f, t_) + 1${not p_stepLengthNoReset(mSolve, f, t_)})]
and ord(t_)<=[ord(t)-p_uNonoperational(unit, starttype, 'min') / mSettings(mSolve, 'intervalInHours') / (p_stepLengthNoReset(mSolve, f, t_) + 1${not p_stepLengthNoReset(mSolve, f, t_)})]
}
= yes;
// Time windows for minimum uptime requirements
Option clear = uftt_minUptime;
uftt_minUptime(uft_online(unit, f, t), tt_(t_))${ ord(t_)>=[ord(t)-p_unit(unit, 'minOperationTime') / mSettings(mSolve, 'intervalInHours') / (p_stepLengthNoReset(mSolve,f,t_) + 1${not p_stepLengthNoReset(mSolve, f, t_)})]
and ord(t_)<ord(t)
}
= yes;
// Time windows for minimum downtime requirements
Option clear = uftt_minDowntime;
uftt_minDowntime(uft_online(unit, f, t), tt_(t_))${ ord(t_)>=[ord(t)-p_unit(unit, 'minShutDownTime') / mSettings(mSolve, 'intervalInHours') / (p_stepLengthNoReset(mSolve,f,t_) + 1${not p_stepLengthNoReset(mSolve, f, t_)})]
and ord(t_)<ord(t)
}
= yes;
* -----------------------------------------------------------------------------
* --- Probabilities -----------------------------------------------------------
......
......@@ -108,7 +108,7 @@ Sets
uft_online(unit, f, t) "Units with any online and startup variables on time steps"
uft_onlineLP(unit, f, t) "Units with LP online and startup variables on time steps"
uft_onlineMIP(unit, f, t) "Units with MIP online and startup variables on time steps"
uft_online_last(unit, f, t) "Last (f,t) when online variables are included"
* uft_online_last(unit, f, t) "Last (f,t) when online variables are included"
* uft_online_incl_previous(unit, f, t) "Units with online and startup variables on time periods including the last realized period from previous solve"
nuft(node, unit, f, t) "Enables aggregation of nodes and units for later time periods"
gnuft(grid, node, unit, f, t) "Enables aggregation of nodes and units for later time periods"
......@@ -119,6 +119,11 @@ Sets
effGroupSelector(effSelector, effSelector) "Efficiency selectors included in efficiency groups, e.g. Lambda02 contains Lambda01 and Lambda02."
effLevelGroupUnit(effLevel, effSelector, unit) "What efficiency selectors are in use for each unit at each efficiency representation level"
effGroupSelectorUnit(effSelector, unit, effSelector) "Group name for efficiency selector set, e.g. Lambda02 contains Lambda01 and Lambda02"
// Auxiliary time step sets for startup and shutdown constraints
uftt_startupType(starttype, unit, f, t, t) "Set of time steps where special startup conditions apply for units"
uftt_minUptime(unit, f, t, t) "Set of time steps where minimum uptime constraints apply for units"
uftt_minDowntime(unit, f, t, t) "Set of time steps where minimum downtype constrains apply for units"
;
* Set initial values to avoid errors when checking if parameter contents have been loaded from input data
fRealization('f00') = yes;
......
......@@ -566,10 +566,7 @@ q_startuptype(m, starttypeConstrained(starttype), uft_online(unit, f, t)) ..
=L=
// Subunit shutdowns within special startup timeframe
+ sum(t_${ ord(t_) > [ord(t)-p_uNonoperational(unit, starttype, 'max') / mSettings(m, 'intervalInHours') / p_stepLengthNoReset(m, f, t_)]
and ord(t_)<=[ord(t)-p_uNonoperational(unit, starttype, 'min') / mSettings(m, 'intervalInHours') / p_stepLengthNoReset(m, f, t_)]
and p_stepLengthNoReset(m, f, t_)
},
+ sum(uftt_startupType(starttype, unit, f, t, t_),
+ v_shutdown(unit, f+df(f,t_), t_)
) // END sum(t_)
;
......@@ -590,10 +587,7 @@ q_onlineLimit(m, uft_online(unit, f, t))${ p_unit(unit, 'minShutDownTime')
+ p_unit(unit, 'unitCount')
// Number of units unable to start due to restrictions
- sum(t_${ ord(t_)>=[ord(t)-p_unit(unit, 'minShutDownTime') / mSettings(m, 'intervalInHours') / p_stepLengthNoReset(m,f,t_)]
and ord(t_)<ord(t)
and p_stepLengthNoReset(m, f+df(f,t_), t_)
},
- sum(uftt_minDowntime(unit, f, t, t_),
+ v_shutdown(unit, f+df(f,t_), t_)
) // END sum(t_)
......@@ -616,10 +610,7 @@ q_onlineMinUptime(m, uft_online(unit, f, t))${ p_unit(unit, 'minOperationTime')
=G=
// Units that have minimum operation time requirements active
+ sum(t_${ ord(t_)>=[ord(t)-p_unit(unit, 'minOperationTime') / mSettings(m, 'intervalInHours') / p_stepLengthNoReset(m,f,t_)]
and ord(t_)<ord(t)
and p_stepLengthNoReset(m, f, t_)
},
+ sum(uftt_minUptime(unit, f, t, t_),
+ sum(starttype,
+ v_startup(unit, starttype, f+df(f,t_), t_)
) // END sum(starttype)
......
......@@ -33,14 +33,15 @@ if (mSettings(mSolve, 'readForecastsInTheLoop') and ord(tSolve) >= tForecastNext
tLatestForecast(t)$(ord(t) = ord(tSolve)) = yes;
// Define updated time window
Option clear = tt;
tt(t)${ ord(t) >= ord(tSolve)
and ord(t) <= ord(tSolve) + mSettings(mSolve, 't_forecastLength') + mSettings(mSolve, 't_ForecastJump')
} = yes;
Option clear = tt_;
tt_(t)${ ord(t) >= ord(tSolve)
and ord(t) <= ord(tSolve) + mSettings(mSolve, 't_forecastLength') + mSettings(mSolve, 't_ForecastJump')
}
= yes;
// Update capacity factor data
loop(tLatestForecast, // There should be only one latest forecast
ts_cf(flow, node, f, tt(t))${ ts_forecast(flow, node, tLatestForecast, f, t) // Only update data for capacity factors with forecast. NOTE! This results in problems if the forecast has values of zero!
ts_cf(flow, node, f, tt_(t))${ ts_forecast(flow, node, tLatestForecast, f, t) // Only update data for capacity factors with forecast. NOTE! This results in problems if the forecast has values of zero!
and mf(mSolve, f)
} = ts_forecast(flow,node,tLatestForecast,f,t);
);
......@@ -48,11 +49,12 @@ if (mSettings(mSolve, 'readForecastsInTheLoop') and ord(tSolve) >= tForecastNext
// Read the tertiary reserve requirements
put_utility 'gdxin' / 'input\tertiary\' tSolve.tl:0 '.gdx';
execute_load ts_tertiary;
ts_reserveDemand('tertiary', up_down, node, f, tt(t))${ mf(mSolve, f)
and gn('elec', node)
and not fRealization(f)
* } = min(500, ts_tertiary('wind', node, tSolve, up_down, t) * sum(flowUnit('wind', unit), p_gnu('elec', node, unit, 'maxGen')));
} = max(p_nReserves(node, 'primary', up_down), ts_tertiary('wind', node, tSolve, up_down, t) * sum(flowUnit('wind', unit), p_gnu('elec', node, unit, 'maxGen')));
ts_reserveDemand('tertiary', up_down, node, f, tt_(t))${ mf(mSolve, f)
and gn('elec', node)
and not fRealization(f)
}
* = min(500, ts_tertiary('wind', node, tSolve, up_down, t) * sum(flowUnit('wind', unit), p_gnu('elec', node, unit, 'maxGen')));
= max(p_nReserves(node, 'primary', up_down), ts_tertiary('wind', node, tSolve, up_down, t) * sum(flowUnit('wind', unit), p_gnu('elec', node, unit, 'maxGen')));
); // END IF readForecastsInTheLoop
......@@ -64,14 +66,15 @@ putclose log;
if(mSettings(mSolve, 'forecasts') > 0,
// Define updated time window
Option clear = tt;
tt(t)${ ord(t) >= ord(tSolve)
and ord(t) <= ord(tSolve) + f_improve
} = yes;
Option clear = tt_;
tt_(t)${ ord(t) >= ord(tSolve)
and ord(t) <= ord(tSolve) + f_improve
}
= yes;
// Improve capacity factors, linear improvement towards fRealization
loop(fRealization(f_),
ts_cf(flow, node, f, tt(t))${ not fRealization(f)
ts_cf(flow, node, f, tt_(t))${ not fRealization(f)
and fRealization(f_)
and mf(mSolve, f)
} = (
......
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