Multi-stage and multi-instance models #901
Labels
Type: epic
A larger goal that encompasses multiple issues
Zone: data & import
Stuff going in and how it's processed
Zone: model implementation
How the formulation is implemented in code
In Mopo Task 4.6 the aim is to enable solve sequences (e.g. multi-stage investment models; storage value combined with dispatch; unit commitment and realisation of reserves) and other cases where multiple instances of SpineOpt need to be populated (e.g. resource adequacy, decomposition).
@DillonJ, @trobob and @manuelma need resource adequacy for another project, but it could be done in a way that helps to build the machinery for all of these use cases. There is further discussion about this in e-mail, since ER has been thinking a lot about how to do the resource adequacy part, but I'll summarize the approach from the generic perspective - we need specific issues for the things that will support specific implementations (e.g. resource adequacy will need to be able to generate random samples of outages).
Also, the approach presented here is influenced by the work already done for FlexTool where nested models work quite nicely: https://irena-flextool.github.io/flextool/how_to/#how-to-use-nested-rolling-window-solves-investments-and-long-term-storage
What new parameters are needed and how to organize them
Currently SpineOpt has a
model
class that contains the parameters that specify how the model behaves at the high level. If we have multiple models in a sequence, we need to be able to chain model instances. One way to do this is to split themodel
tomodel
andsolve
classes. Thenmodel
class entity could define the sequence of solves (e.g. through an array parametersolves
). Another option would be to allow self-referencing:model
object could have a parametercontain_models
. It can be more messy, because it does not allow for a clear distinction what parameters belong to all solves and what are solve specific. So, probably best to have a new class:solve
. For nested models, where information needs to be passed between upper and lower level solves, there is still a need for parameter like contains_solve in thesolve
class, so that the nested structure can be established between solves.Many new parameters will be specific to information passed between models or to the way the specific parts of the model need to be instantiated. For example: how to inform which storage's value to pass between solves or how to define units/connections to be included in randomized outages. These should have their own issues (and then link to this one), so that this generic issue does not come too messy.
A wrapper to orchestrate model solves
A wrapper function (similar to current decomposition approach) that orchestrates the solving of model instances. It passes information between models when needed (e.g. storage value to a lower level model or actual storage content from lower level to upper level.
Update the model in the loop
As the model instances can be very similar between solves (especially in resource adequacy), it can be efficient to just update the model instead of building new model instances. There should also be user controlled parallelisation when it is helpful (it could be efficient to run as many scenarios in parallel as there are cores).
Hot-starts could also be used between upper and lower models: water value model probably solves the same problem as the dispatch but with less temporal detail – it could be a good basis. However, that could come later (and solve in a separate issue).
Result processing
What information is taken from the multiple solves - user needs to be able to limit this in a nice way. Probably depends on the particular type of model, so best to tackle in separate issues. However, maybe there are couple of broad categories:
The text was updated successfully, but these errors were encountered: