I started using OEMOF about 2-3 months ago and I am currently developing an optimisation model of an energy system with different sectors, like electricity, heat and gas. Some of the components have time-dependent generation or costs.To increase the computing efficiency. I want to implement a rolling optimisation.
Here comes my question:
Is it possible, to define an optimisation interval (like for example one week) in the statement
model = solph.Model(my_energysystem)
model.solve(solver = solver, solve_kwargs={'tee': True})
or do I have to create a model for each timerange, and append the results to a dataframe or similar data structure?
I would be very thankful for any kind of help.
Not sure if this is remotely useful, but the mosaik project is, as I understand it, designed to run multiple model instances in some kind of coordinated fashion:
Steinbrink, Cornelius (2017). A non-intrusive uncertainty quantification system for modular smart grid co-simulation. Oldenburg, Germany: University of Oldenburg. PhD thesis.
I assume you are only doing a dispatch optimisation? In the case of investment, your approach would obviously not work.
Generally, you may create the different model instances, compute them (even in parallel, using the python e.g. multiprocessing package) and then concat the results. BUT:
Of course you need to check what is going to happen with all model variables which are used in constraints with two (or more) consecutive timesteps. This will be storage filling levels, but also minimum up/downtimes, gradients and for specific components like the DSMSink even more (really cool demand side component ;))
That’s why the approach is called “rolling”. You will start with the first e.g. n=168 Timesteps, then fix the n-x variables (say fix the first day, i.e. 168-144), then run for timestep 24…168+24 on so on.
Now: You could implement this rolling approach. however, I am not sure if that rolling approach will speed up your whole tool, because you will construct a lot of (small) models. This again will depend on the complexity of your model. If its a rather easy to solve, purely linear model, it is maybe not the best way to go. If you have a rather hard to solve MILP, rolling horizon may make sense.
Finally, if you are looking for reducing runtimes of your model you may reduce the number of timesteps by selecting representative periods of your timeseries data using e.g. [tsam](https://github.com/FZJ-IEK3-VSA/tsam). And then run a model for a couple of representative weeks instead of a whole year (some accuracy will be lost). This approach has been used by @CKaldemeyer and is doumented in his Phd Thesis pp. 62
as Simon indicated, the short reply would be:
No, there is no such thing as predefined timeslices supported yet in oemof.solph.
Here is a longer version:
Several people have implemented rolling horizon approaches, most times by simply putting the model build, solve and results extraction process into a for-loop and extracting and concatenating results.
As you mentioned, this creates some computational overhead due to the model building in each iteration. So it does only make sense when your model is complex from a mathematical point of view and solving it in an integral run is not an option. Be aware that (MILP) constraints interlinking different time slices would be a thing that is not supported by the framework and which you would have to take care if you use that model type.
Of course, there may be other motivations for rolling horizon, such as (closer to reality) scheduling with limited foresight.
thank you all for your inputs
The approach with the for loop from @dlr_jk would probably have been the best option in my case, as more complex rolling approaches, like that from @simnh would make the whole model more complex.
Thank you @robbie.morrison for mentioning the Mosaik project, maybe I will consider it in my future works.
I could now solve the compution time issue. A few variables caused this problem. A slight adaption of the model was the solution, so the rolling optimisation was not necessary in the end.
Is there a way to save the state (incl. flow values, the times for min/maxuptime/downtimes) of tilmestep?
I want to do something like:
data frame with 800000 time steps.
solve simulation for n time steps i to i+n, take solution of timestep i as result, save the state i of the model, then load the state i as current initial values (this must contain everything: times running/off, values of the flows etc etc) start the simulation for steps i+1 to i+n+1 …..
I can set SOME initial states in the model… but how do I get all the other important states?
Well, you can extract the values from the model results. Those numbers that have to be transferred to a new model with the shifted time index. I see three situations where state tracking is needed:
Storage content: Obviously needed and rather easy to do. Give an initial_storage_level.
Uptime/Downtime: Manual tracking is needed, e.g. to properly reduce minumum_downtime for the first time steps if the Flow was down before.
Gradient limits in ramps: This would need increased overlap of the time frames. As we do not allow a mix of fix and variable flow values, the value for the last past step would have to be encoded using Flow(nominal_capacity=P, min=[q] + Nt*[0] max=[q] + Nt*[1]), where Nt = N - 2 is the number of time steps that remain flexible when N is the number of time points. (We have N - 1 time steps defined by N points in time.)
If you do not have ramping constraints, I do not see why you need to give Flow values. (Warm start to reduce computational time would be nice to have but I don’t know how to do that.)