Skip to content

Added Support for DCOPF Constrained Expansion - #915

Open
dlcole3 wants to merge 52 commits into
GenXProject:developfrom
dlcole3:dc/support_dcopf_expansion
Open

Added Support for DCOPF Constrained Expansion#915
dlcole3 wants to merge 52 commits into
GenXProject:developfrom
dlcole3:dc/support_dcopf_expansion

Conversation

@dlcole3

@dlcole3 dlcole3 commented Jul 15, 2026

Copy link
Copy Markdown
Collaborator

Description

This PR adds code to support expansion decisions of DCOPF constrained GenX models that can be solved both monolithically or using Benders Decomposition. This work was originally started by @sambuddhac. It includes updates to settings, inputs loading, model construction, and solution methods. Part of the motivation for this work is supporting nodal spatial resolution of CEMs. In these cases, you might solve with DCOPF constraints, and you might also want to have integer decisions on new transmisison or generation builds (e.g., CC might be built in 500 MW increments to avoid unrealistic modular CC construction in lots of different zones). This PR is intended as a second step after the Benders PR (#914) is merged.

  • There is now a DiscreteInvestments flag in the settings of GenX. This controls whether there can be integer variables in the model (not that I chose to call this DiscreteInvestments over IntegerInvestments because MacroEnergySolvers.jl already has an IntegerInvestments setting). This can be applied to both resources and transmission lines. If DiscreteInvestments is set to 1, then GenX will look for a column header Discrete_Build in the Network.csv, Thermal.csv, and Vre.CSV and throw a warning statement if none of these files have the column header. This header controls which resources or lines can have discrete builds. This also gives the user flexiblity in controlling which components should be treated as integer/binary build decisions.
  • DC-OPF constraints now support expansion and discrete new builds. Previously, DC-OPF was only applied to fixed, existing networks. Now, there are model constraints permitting line expansion as well as new lines on existing or new corridors.
  • Network.csv supports additional column names. If the Discrete_Build column has a 1, then there can be at least one new line constructed on that corridor. GenX internally builds a new DataFrame with each line separated out with individual flow variables on them. This is important for handling DC-OPF constraints. In addition, it supports the case where there may be multiple discrete parallel lines on a corridor, and the user can pass these directly with only one line of the CSV. There is an additional constraint added which adds a solve order to identical lines to avoid degeneracy.
  • Line expansion supports both expansion and discrete new builds in the same model (though new lines cannot be expanded). If a user sets Discrete_Build to zero, but there is a nonzero Line_Max_Reinforcement_MW, then that line will be treated as the traditional line expansion available in GenX (note that this can essentially be thought of as reconductoring). If the discrete build flag is set to 1, then Line_Max_Reinforcement_MW is used to determine the size of the new lines (note: we can restructure this if you think new lines should have more columns to support this instead of using the existing), with the New_Line_Cap_Size_MW column name used to determine how may lines fit into Line_Max_Reinforcement_MW.
  • When DC_OPF is on with discrete builds, lines are placed into different sets inside the inputs dictionary internally. These are FIXED_LINES which are lines that can't be expanded, EXPANSION_LINES, which are lines that have continuous reinforcement on them, DISCRETE_BUILD_LINES which are lines that have a binary build decision associated with them, and PHANTOM_LINES, which are the DISCRETE_BUILD_LINES which are on new corridors (this is important for the line angle limit constraints, which you only want to have applied if the line is built).
  • There is a new example case 12 that is a copy of example case 10 but with line data adjusted to support new builds.
  • There are new tests that example case 12 (but with a smaller time horizon) for testing purposes, both with and without Benders
  • Benders decomposition has been extended to work with discrete build decisions following the methods outlined in this paper. This includes a transport model and LP hotstarting. MacroEnergySolvers.jl supports the LP relaxation of binary decisions, but I had two concerns with using its methods and defined my own in GenX: 1) I want the flexibility to turn off the stabilization method after hot starting is finished, and 2) binary varaibles do not get an explicit upper bound set on them inside MacroEnergySolvers which I think can cause issues for the big M constraints here.
  • The documentation has been updated to describe how these new features can be used

A couple of additional notes:

  • Line losses have not been tested in this PR. I believe that they should still work because all the lines use the vFLOW variable, and this will be zero for any line not constructed. @sambuddhac may have a better idea on whether this is the case.
  • Multistage runs are not explicitly handled in this PR.
  • The Changelog has been updated, but it is a continuation of the former Benders PR, so the updates are at the end of the Benders work. Not sure if the Benders PR gets merged if we will need to update that Changelog
  • For problems with lots of nodes/zones, GenX can be quite slow. There is a need for future model construction improvements to handle problems with large zones. This is planned and will follow up this PR.

@gschivley and I had discussions on the above structuring, so tagging him in case he wants to give input on how it came together.

What type of PR is this? (check all applicable)

  • Feature
  • Bug Fix
  • Documentation Update
  • Code Refactor
  • Performance Improvements

Related Tickets & Documents

This PR also address the feature request of #900

Checklist

  • Code changes are sufficiently documented; i.e. new functions contain docstrings and .md files under /docs/src have been updated if necessary.
  • The latest changes on the target branch have been incorporated, so that any conflicts are taken care of before merging. This can be accomplished either by merging in the target branch (e.g. 'git merge develop') or by rebasing on top of the target branch (e.g. 'git rebase develop'). Please do not hesitate to reach out to the GenX development team if you need help with this.
  • Code has been tested to ensure all functionality works as intended.
  • CHANGELOG.md has been updated (if this is a 'notable' change).
  • I consent to the release of this PR's code under the GNU General Public license.

How this can be tested

There is a new example case (12) and a new set of unit tests. The unit tests run a smaller time horizon version of example 12 with both monolithic and Benders. In addition, the unit test running the three zone case also runs it with DiscreteInvestments=1 to test integer build decisions on resources.

Post-approval checklist for GenX core developers

After the PR is approved

  • Check that the latest changes on the target branch are incorporated, either via merge or rebase
  • Remember to squash and merge if incorporating into develop

dlcole3 added 30 commits June 3, 2026 10:35
@dlcole3
dlcole3 marked this pull request as ready for review July 21, 2026 00:20
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.

1 participant