Add tap controls - #239
Conversation
…tage and q bounds
There was a problem hiding this comment.
Pull request overview
This PR refactors transformer tap handling by moving tap control behavior into the native branch construction path (gated by an enable_controls attribute and per-circuit TransformerControlObjective), while reorganizing/renaming related tests and tightening network-reduction “irreducible bus” logic for controlled devices and outages.
Changes:
- Add tap-control variable/constraint plumbing to the native AC/DC branch models (including new voltage- and reactive-flow control constraints).
- Restructure and expand transformer tap tests into separate “fixed tap” vs “controls” suites; remove legacy/disabled tap-control test files.
- Refactor irreducible-bus selection to incorporate outage-monitored/outaged components and controllable transformers.
Reviewed changes
Copilot reviewed 21 out of 21 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| test/test_voltage_control_tap_models.jl | Removes legacy VoltageControlTap model tests. |
| test/test_transformer_fixed_tap.jl | Adds fixed (off-nominal) tap physics tests across native models. |
| test/test_transformer_controls.jl | Adds transformer control-objective tests (tap variables + control bands). |
| test/test_power_flow_in_the_loop.jl | Removes commented PhaseShiftingTransformer PFitL test block. |
| test/test_postcontingency_mixed_outage_axes.jl | Updates outage pinning test to call the new helper. |
| test/test_native_transformer_tap.jl | Removes older fixed-tap + coefficient ground-truth tests (now relocated). |
| test/test_native_tapcontrol.jl | Removes disabled TapControl formulation tests. |
| test/test_native_network_reductions.jl | Removes commented PhaseAngleControl and tap regulated-bus error test blocks. |
| test/test_native_lpacc_model.jl | Re-enables/updates LPACC shunt validation gate test. |
| test/test_native_dcp_acp_models.jl | Re-enables use_slacks validation test for StaticBranchUnbounded. |
| test/test_device_branch_constructors.jl | Removes commented phase-shifting DC power flow test block. |
| test/runtests.jl | Removes DISABLED_TESTS entries (now empty). |
| test/Project.toml | Removes PowerFlows from test deps/sources (but tests still reference it). |
| test/includes.jl | Comments out using PowerFlows and const PFS = PowerFlows (but tests still reference PFS). |
| src/PowerOperationsModels.jl | Exports ReactivePowerFlowControlConstraint. |
| src/network_models/instantiate_network_model.jl | Refactors irreducible-bus selection; adds outage + controllable-transformer pinning. |
| src/core/network_formulations.jl | Removes old regulated-voltage/tap-current-form traits. |
| src/core/constraints.jl | Adds ReactivePowerFlowControlConstraint type. |
| src/ac_transmission_models/voltage_control_tap_models.jl | Removes legacy VoltageControlTap formulation implementation. |
| src/ac_transmission_models/branch_constructor.jl | Wires new tap-control variables/constraints into branch construction stages. |
| src/ac_transmission_models/AC_branches.jl | Implements tap-control variables, voltage/reactive control constraints, and tap-aware flow equations. |
Suppressed comments (3)
test/includes.jl:39
PFSis still referenced by active tests (e.g.test/test_power_flow_in_the_loop.jl), but the alias is commented out. This will raiseUndefVarError: PFS not definedat runtime.
const PSY = PowerSystems
const POM = PowerOperationsModels
const IOM = InfrastructureOptimizationModels
#const PFS = PowerFlows
const PSB = PowerSystemCaseBuilder
const PNM = PowerNetworkMatrices
test/Project.toml:23
PowerFlowsis removed from[deps], but multiple active tests (not just commented blocks) still rely on it via thePFSalias (seetest/test_power_flow_in_the_loop.jl). This will fail to instantiate the test environment.
This issue also appears on line 34 of the same file.
MathOptInterface = "b8f27783-ece8-5eb3-8dc8-9495eed66fee"
ParallelTestRunner = "d3525ed8-44d0-4b2c-a655-542cee43accc"
Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
PowerNetworkMatrices = "bed98974-b02a-5e2f-9fe0-a103f5c450dd"
PowerOperationsModels = "bed98974-b02a-5e2f-9ee0-a103f5c450dd"
PowerSystemCaseBuilder = "f00506e0-b84f-492a-93c2-c0a9afc4364e"
PowerSystems = "bcd98974-b02a-5e2f-9ee0-a103f5c450dd"
test/Project.toml:40
PowerFlowsis removed from[sources], but it’s still required by the active PFitL tests. Without a source entry (when using custom git sources for the other Sienna packages), resolving the test environment may pull an incompatible version or fail outright.
[sources]
InfrastructureOptimizationModels = {rev = "main", url = "https://github.com/Sienna-Platform/InfrastructureOptimizationModels.jl"}
InfrastructureSystems = {rev = "IS4", url = "https://github.com/Sienna-Platform/InfrastructureSystems.jl"}
PowerNetworkMatrices = {rev = "psy6", url = "https://github.com/Sienna-Platform/PowerNetworkMatrices.jl"}
PowerSystemCaseBuilder = {rev = "psy6", url = "https://github.com/Sienna-Platform/PowerSystemCaseBuilder.jl"}
PowerSystems = {rev = "psy6", url = "https://github.com/Sienna-Platform/PowerSystems.jl"}
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| using PowerNetworkMatrices | ||
| import PowerSystemCaseBuilder: PSITestSystems | ||
| using PowerFlows | ||
| #using PowerFlows | ||
| using DataFramesMeta |
There was a problem hiding this comment.
This was running into precompilation issues. Maybe something upstream changed.
| function _validate_controlled_branch_not_reduced( | ||
| network_model::NetworkModel, | ||
| devices::IS.FlattenIteratorWrapper{T}, | ||
| formulation_name::String, | ||
| ::Type{T}, | ||
| controlled_names, | ||
| ) where {T <: PSY.ACTransmission} |
There was a problem hiding this comment.
transformer_models.jl isn't used. I will remove it when I implement phase shifting.
I believe a parallel merge is the only merge that can happen; series merges are blocked by specifying irreducible buses.
| for circuit in PSY.get_circuits(transformer) | ||
| _control_enabled(circuit) || continue | ||
| _push_component_buses!(irreducible_buses, circuit) | ||
| push!(irreducible_buses, PSY.get_regulated_bus_number(circuit)) | ||
| end |
There was a problem hiding this comment.
I think the convention we're going to go for now is the regulated bus number must always be a valid bus number, so 0 doesn't carry special importance.
That said, I agree maybe we shouldn't be pinning the regulated bus on all controls.
|
@acostarelli I stacked this on top of the PR with the network changes |
Some refactoring of AC and reduction code