Skip to content

Conversation

@abelsiqueira
Copy link
Member

@abelsiqueira abelsiqueira commented Oct 10, 2025

BLOCKED until other rolling horizon PRs are merged.

Create a tutorial for rolling horizon with a similar output to the JuMP tutorial https://jump.dev/JuMP.jl/stable/tutorials/algorithms/rolling_horizon/.

Related issues

Closes #1385
Part of #1365

Checklist

  • I am following the contributing guidelines
  • Tests are passing
  • Lint workflow is passing
  • Docs were updated and workflow is passing

@github-actions
Copy link
Contributor

github-actions bot commented Oct 10, 2025

🤖 CompareMPS report

✅ MPS files match

@abelsiqueira abelsiqueira force-pushed the 1385-rolling-horizon-docs branch from 9e35443 to 2e0b250 Compare October 10, 2025 16:16
@codecov
Copy link

codecov bot commented Oct 10, 2025

Codecov Report

❌ Patch coverage is 97.29730% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 98.47%. Comparing base (eb442c5) to head (bdbab55).
⚠️ Report is 4 commits behind head on main.

Files with missing lines Patch % Lines
src/rolling-horizon/rolling-horizon.jl 90.47% 4 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1387      +/-   ##
==========================================
- Coverage   98.61%   98.47%   -0.14%     
==========================================
  Files          38       42       +4     
  Lines        1368     1511     +143     
==========================================
+ Hits         1349     1488     +139     
- Misses         19       23       +4     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@abelsiqueira abelsiqueira force-pushed the 1385-rolling-horizon-docs branch 2 times, most recently from 052a4d1 to 99f0185 Compare October 13, 2025 09:02
@github-actions
Copy link
Contributor

📝 Check the documentation preview: https://tulipaenergy.github.io/TulipaEnergyModel.jl/previews/PR1387

@abelsiqueira abelsiqueira mentioned this pull request Oct 13, 2025
4 tasks
@datejada datejada requested review from clizbe and datejada October 14, 2025 09:07
@abelsiqueira abelsiqueira force-pushed the 1385-rolling-horizon-docs branch from 99f0185 to f3f8bf7 Compare October 15, 2025 09:38
@abelsiqueira
Copy link
Member Author

@clizbe, the tutorial here can be reviewed in parallel to the rest of the rolling horizon changes

@abelsiqueira abelsiqueira force-pushed the 1385-rolling-horizon-docs branch from bdbab55 to f7c284d Compare October 23, 2025 08:42
@abelsiqueira abelsiqueira marked this pull request as ready for review October 24, 2025 12:05
@abelsiqueira abelsiqueira changed the title [WIP] Rolling horizon tutorial Rolling horizon tutorial Oct 24, 2025
@abelsiqueira
Copy link
Member Author

This has been rebased and marked as ready to review

Copy link
Member

@datejada datejada left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @abelsiqueira, I left a minor comments, but generally speaking, I like it 😄
Anyway, let's wait for @clizbe's comments, since she has a sharp eye for the documentation 😉

Comment on lines 352 to 374
Finally, as a sanity check, we can compare that indeed both solutions reach the same demand value by comparing the aggregated outgoing flow and the charge between the rolling horizon and the no-rolling horizon versions.

```@example rolling_horizon
outgoing_rh = thermal_rh + solar_rh + discharge_rh
outgoing_no_rh = thermal_no_rh + solar_no_rh + discharge_no_rh

Plots.plot(
Plots.plot(timestep, outgoing_no_rh - outgoing_rh, title="thermal + solar + discharge error"),
Plots.plot(timestep, charge_no_rh - charge_rh, title="charge error"),
layout = (2, 1),
size = (800, 150 * 2),
xticks = 1:move_forward:horizon_length,
)
```
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think for the sanity check, it is better to have a table here with the min, max, and average error. In addition, the definition of the error should be only one as:

error = demand + charging - thermal - solar - discharge

The sanity check is that this should be zero or within the tolerances of the solver.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the review, @datejada. I'll wait for @clizbe's review to make a single update.

Copy link
Member

@clizbe clizbe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR! Looks like a nice tutorial. I didn't run the code, but read through it. I think there's some context missing (or maybe in different sections of the docs) and I wonder about the window naming. Is this the standard naming convention? If not, can we come up with something more intuitive?

@abelsiqueira
Copy link
Member Author

Thanks for the review @clizbe, I've committed the easy and commented on the rest

@datejada
Copy link
Member

datejada commented Nov 26, 2025

@clizbe, it is not on you, I am the one sorry here, I have not been able to explain myself correctly with the RH, let me try again 😜

  1. The solutions will differ as long as there are constraints connecting different time periods, such as energy storage balance, ramping constraints, and unit commitment. Since we have a battery in this case, energy storage balance constraints are crucial, leading us to expect feasible solutions.

  2. Why do we anticipate these differences? When we optimize for an entire week at once, the model benefits from perfect foresight of the optimization horizon. This means that at the beginning of the week, the model knows what will happen by the end, allowing it to optimize the storage level from the first hour based on this comprehensive information. In contrast, a rolling horizon approach limits the optimization to a two-day window. As a result, the model cannot foresee events that occur later in the week and can only optimize for the immediate two days. While this creates suboptimal outcomes for the overall week, it remains a viable solution.

  3. Why accept suboptimal solutions? There are a couple of reasons. First, solving an entire planning horizon (like a full year) may not be feasible or could take a long time. The rolling horizon approach provides a practical approximation to the perfect foresight model. Second, using smaller optimization models allows for a more accurate representation of market dynamics. With detailed considerations (like startup/shutdown processes, ramping, and DC optimal power flow), players are often limited in their foresight to just a few days, leading to suboptimal decisions. This reality is naturally reflected in the prices generated by the rolling horizon method.

  4. How do we define uncertainty in our model? Uncertainty refers to potential future scenarios that occur with specific probabilities, such as a dry weather year, a wet weather year, or an average weather year, each with associated probabilities A, B, and C, respectively.

  5. Does uncertainty affect the rolling horizon approach? Not really. The rolling horizon analysis typically focuses on a single scenario (for example, a dry weather year). The differences in the solutions arise not from uncertainty but from the fact that each optimization window is shorter than the overall horizon for that scenario.

  6. Some might argue that a shorter optimization window allows the rolling horizon to account for future uncertainty. However, as defined in Tulipa, this is not an accurate use of the term uncertainty in this context. The rolling horizon simply prevents the solution from anticipating future events that lie outside its optimization window.

  7. Is there a way in which the rolling horizon approach and the full model yield the same results? Yes, if there are no intertemporal constraints—such as those related to storage, ramping, or unit commitment—the solutions will be identical.


Plots.plot(both_plots..., layout = (2, 1), size = (800, 150 * 2))
```

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After this, I would add the comparison of the duals for the sake of completeness.

@clizbe
Copy link
Member

clizbe commented Nov 26, 2025

You should make a TED talk! ;)

@abelsiqueira abelsiqueira force-pushed the 1385-rolling-horizon-docs branch 3 times, most recently from 8362f38 to f2cf145 Compare December 1, 2025 12:20
abelsiqueira and others added 5 commits December 1, 2025 13:20
Co-authored-by: Lauren Clisby <lclisby@gmail.com>
Co-authored-by: Abel Soares Siqueira <abel.siqueira@esciencecenter.nl>
Co-authored-by: Abel Soares Siqueira <abel.siqueira@esciencecenter.nl>
clizbe and others added 6 commits December 1, 2025 13:20
Co-authored-by: Abel Soares Siqueira <abel.siqueira@esciencecenter.nl>
Co-authored-by: Abel Soares Siqueira <abel.siqueira@esciencecenter.nl>
Co-authored-by: Lauren Clisby <lclisby@gmail.com>
@abelsiqueira abelsiqueira force-pushed the 1385-rolling-horizon-docs branch from f2cf145 to e338235 Compare December 1, 2025 12:20
@abelsiqueira
Copy link
Member Author

@datejada, I've updated the errors now as well, let me know if that's what you're looking for

@abelsiqueira abelsiqueira requested a review from datejada December 1, 2025 12:25
Copy link
Member

@datejada datejada left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@abelsiqueira Thanks for the changes in the PR. I have a suggestion for the wording in the last part, but I'm pre-approving, so you can merge after accepting the change.

Co-authored-by: Diego Alejandro Tejada Arango <12887482+datejada@users.noreply.github.com>
@abelsiqueira abelsiqueira merged commit 50f38d4 into main Dec 1, 2025
4 checks passed
@abelsiqueira abelsiqueira deleted the 1385-rolling-horizon-docs branch December 1, 2025 14:55
@abelsiqueira
Copy link
Member Author

Thanks for the reviews @clizbe and @datejada, the tutorial looks much better now!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Documentation updates related to rolling horizon

4 participants