Skip to content

Conversation

@JZL
Copy link
Contributor

@JZL JZL commented Aug 1, 2025

Hi,

I was looking at Benders-decomposed runs of Macro, specifically the value of linking constraints, and noticed that the CO2 Cap Constraint budget would sometimes go (extremely) negative. For the problem I was testing this would cause the subproblem to be infeasible but, after more testing and this change, was generally slowing down convergence.

This PR allows users to add a policy_lower_bound key to nodes.json [e.g. 1] which sets a lower bound for the budget variables, although I've only ever used 0.

Validation

I tested informally on a large-scale GenX_to_Macro case and it showed similar visual results (can run a more numeric comparison). It also removed the need for all infeasibility cuts.

I've tested more closely the one_zone_electricity_only tutorial. The Results/*csv outputs are within 1.25% tolerance for any individual entry (for capacity, costs, and undiscounted_costs.csv. Flows.csv which can have different battery discharge edge timings, etc) which is very similar to the tolerance when testing benders vs monolithic. It also goes from 13 to 18 iterations for 1e-5 convergence (and converges faster in the beginning).

Next Steps

I was unsure where to put this in the docs, or if it makes sense to do that now. I can add it to the CO2 Capacity Constraint docs (although technically it's not created at that function, just related) or just in the general parameter section. I can also create an analogous PR to MacroEnergyExamples modifying some of the example's node.json and noting why it was modified. But I've been talking with Filippo about ways of automatically detecting when such a lower bound can be added, in which case only very advanced users would need to modify it (if they have some prior on a (non-obvious potentially non-zero) lower bound). So for now, this PR has it as a semi-hidden parameter.

I also did not add new tests, but the current ones passed

It is almost entirely a direct copy of the rhs_policy code. My only question was in attributes_to_scale, if this should be scaled -- it made sense to me in abstract but I didn't test it (and was unsure how to).

[1]
nodes.json:

...
{
    "type": "CO2",
    "global_data": {
        "time_interval": "CO2"
    },
    "instance_data": [
        {
            "id": "co2_sink",
            "constraints": {
                "CO2CapConstraint": true
            },
            "rhs_policy": {
                "CO2CapConstraint": 0
            },
            "policy_lower_bound": {
                "CO2CapConstraint": 0
            }
        }
    ]
}                                                                                                                                                                                            

Type of change

  • Performance improvement (please add a section below for benchmark results or performance metrics)

Checklist:

  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation (e.g., docstrings for new functions, updated/new .md files in the docs folder)
  • My changes generate no new warnings
  • I have tested the code to ensure it works as expected
  • New and existing unit tests pass locally with my changes:
julia> using Pkg
julia> Pkg.test("MacroEnergy")

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.

2 participants