spine-tools / SpineOpt.jl

A highly adaptable modelling framework for multi-energy systems
https://www.tools-for-energy-system-modelling.org/
GNU General Public License v3.0
56 stars 13 forks source link

#187 decomposition merge2 - [merged] #256

Closed spine-o-bot closed 3 years ago

spine-o-bot commented 3 years ago

In GitLab by @DillonJ on Nov 19, 2020, 09:58

_Merges #187_decompositionmerge2 -> master

Overview

This merge request implements a decomposed bi-level structure to SpineOpt. The general approach is discussed in #187.

At a high level - this MR introduces a second, higher level master problem which has full view of the entire model horizon. The master problem optimizes the investment decision variables and passes them as fix_values to the sub-problem. The sub-problem here is the current SpineOpt model. It is an iterative approach where dual values from the sub-problem inform the master problem regarding the impact of the capacity decision variables on operating costs. This information is added to the master problem in the form of benders cuts.

This MR also contains the following changes :

Implementation Notes

Internal Data Structure

High-Level Algorithm

The high-level algorithm works as follows:

Dual Calculation

The optimize_model!() function has been updated to optionally include an additional step for the calculation of duals. The dual solution to a MIP problem is not well defined. The standard approach to obtaining marginal values from a MIP model is to relax the integer variables, fix them to their last solution value and re-solve the problem as an LP. This is the standard approach in energy system modelling to obtain energy prices. However, although this is the standard approach, it does need to be used with caution (see here for example). The main hazard associated with inferring duals in this way is that the impact on costs of an investment may be overstated. However, since these duals are used in Benders decomposition to obtain a lower bound on costs (i.e. the maximum potential value from an investment), this is ok and can be "corrected" in the next iteration. And finally, the benders gap will tell us how close our decomposed problem is to the optimal global solution.

This additional relaxed LP solve is done as follows:

This final fixed LP solve is trigged by specifying calculate_duals=true in the call to

optimize_model!()

Reporting dual values:

To report the dual of a constraint, one can add an output item with the corresponding constraint name (e.g. constraint_nodal_balance) and add that to a report. This will cause the corresponding constraint's relaxed problem marginal value will be reported in the output DB. When adding a constraint name as an output we need to preface the actual constraint name with "constraint_" to avoid ambiguity with variable names (e.g. units_available). So to report the marginal value of units_available we add an output object called "constraint_units_available".

To report the reduced_cost() for a variable which is the marginal value of the associated active bound or fix constraints on that variable, one can add an output object with the variable name prepended by "bound_". So, to report the units_on reduced_cost value, one would create an output item called "bound_units_on". If added to a report, this will cause the reduced cost of units_on in the final fixed LP to be written to the output db.

Finally, if any constraint duals or reduced_cost values are requested via a report, calculate_duals is set to true and the final fixed LP solve is triggered.

SpineOpt Template

These are the changes to the template:

spine-o-bot commented 3 years ago

In GitLab by @DillonJ on Nov 19, 2020, 10:00

changed the description

spine-o-bot commented 3 years ago

In GitLab by @DillonJ on Nov 19, 2020, 10:01

changed the description

spine-o-bot commented 3 years ago

In GitLab by @DillonJ on Nov 19, 2020, 10:02

changed the description

spine-o-bot commented 3 years ago

In GitLab by @DillonJ on Nov 19, 2020, 10:03

changed the description

spine-o-bot commented 3 years ago

In GitLab by @DillonJ on Nov 19, 2020, 10:07

added 1 commit

Compare with previous version

spine-o-bot commented 3 years ago

In GitLab by @DillonJ on Nov 19, 2020, 10:22

added 1 commit

Compare with previous version

spine-o-bot commented 3 years ago

In GitLab by @DillonJ on Nov 19, 2020, 11:01

changed the description

spine-o-bot commented 3 years ago

In GitLab by @DillonJ on Nov 19, 2020, 14:40

added 37 commits

Compare with previous version

spine-o-bot commented 3 years ago

In GitLab by @DillonJ on Nov 19, 2020, 14:42

OK - so here's where we are now :

Test Summary: | Pass  Total
test set      |  941    941
spine-o-bot commented 3 years ago

In GitLab by @manuelma on Nov 19, 2020, 16:05

Which branch should I checkout? I'm trying #187_decomposition_merge2 to no luck (plenty of No model of type spineopt_operations defined when running tests)???

spine-o-bot commented 3 years ago

In GitLab by @DillonJ on Nov 19, 2020, 16:10

Hi Manuel - yes it should be this one.

Do you have the latest SpineInterface? ;-)

spine-o-bot commented 3 years ago

In GitLab by @manuelma on Nov 19, 2020, 16:11

Which SpineInterface commit do I need?

Edit: Nevermind, I got it now.

spine-o-bot commented 3 years ago

In GitLab by @manuelma on Nov 19, 2020, 16:17

What's this?

spine-o-bot commented 3 years ago

In GitLab by @manuelma on Nov 19, 2020, 16:19

What's j, k, and current_bi? Where's current_bi defined in the global scope?

spine-o-bot commented 3 years ago

In GitLab by @manuelma on Nov 19, 2020, 16:21

Is the object_activity_control needed for decomposition to work?

spine-o-bot commented 3 years ago

In GitLab by @manuelma on Nov 19, 2020, 16:27

added 2 commits

Compare with previous version

spine-o-bot commented 3 years ago

In GitLab by @manuelma on Nov 19, 2020, 16:31

What's the purpose of the t argument here?

spine-o-bot commented 3 years ago

In GitLab by @DillonJ on Nov 19, 2020, 16:31

This does two things

  1. Originally there outputs which was not model dependent. I replaced this with m.ext[:outputs] which is model dependent. It's a list of outputs, so all things that need to be saved
  2. It works out if there are any bound* or constraint* outputs which would require the calculation of duals
spine-o-bot commented 3 years ago

In GitLab by @DillonJ on Nov 19, 2020, 16:33

No - but I wanted an easy way to test with and without the master model. This was hard otherwise.

spine-o-bot commented 3 years ago

In GitLab by @DillonJ on Nov 19, 2020, 16:34

If there's no t index, you have problems with the output and reporting functionality. In the end I never used this function actually. I think it could be removed.

spine-o-bot commented 3 years ago

In GitLab by @manuelma on Nov 19, 2020, 16:34

Thanks for the explanation! So any output that starts with the string bound_ or constraint_ need the duals be calculated? Is this robust?

Edit: by robust I mean, isn't there another way to 'mark' the fact that a variable needs to recalculate the duals other than using the name?

spine-o-bot commented 3 years ago

In GitLab by @manuelma on Nov 19, 2020, 16:37

added 1 commit

Compare with previous version

spine-o-bot commented 3 years ago

In GitLab by @manuelma on Nov 19, 2020, 16:39

Ok, thanks for the explanation. I'll check if it's called and if not I will remove it.

spine-o-bot commented 3 years ago

In GitLab by @manuelma on Nov 19, 2020, 16:40

changed this line in version 7 of the diff

spine-o-bot commented 3 years ago

In GitLab by @manuelma on Nov 19, 2020, 16:40

added 1 commit

Compare with previous version

spine-o-bot commented 3 years ago

In GitLab by @manuelma on Nov 19, 2020, 16:41

Nice.

spine-o-bot commented 3 years ago

In GitLab by @manuelma on Nov 19, 2020, 16:41

mentioned in commit 0a1e673311206c3c641ab3a77ffd1031cdb76fe5

spine-o-bot commented 3 years ago

In GitLab by @manuelma on Nov 19, 2020, 16:55

I just merged this into master. Thanks for the awesome job @DillonJ. I also went through the code and it feels very powerful. It might be that I just got to press the green button, but I'm feeling really excited about all this, such a promising tool, done with so limited resources.