Skip to content

Reactive power control loops #381

Draft
jd-lara wants to merge 14 commits into
mainfrom
jd/discrete-control-homotopy
Draft

Reactive power control loops #381
jd-lara wants to merge 14 commits into
mainfrom
jd/discrete-control-homotopy

Conversation

@jd-lara
Copy link
Copy Markdown
Member

@jd-lara jd-lara commented May 29, 2026

This PR implements the homotopy approach Agarwal's paper and also improvements to handle the outer loop reactive power limits check.

image

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds discrete reactive-control support for AC power flow, centered on voltage-controlling tap transformers and switched shunts via an outer λ-continuation loop, while also including solver-performance and robustness refactors.

Changes:

  • Adds ControlledDeviceSet, controlled tap/shunt metadata extraction, continuation control, snapping/restoration, and public wiring through AC power-flow types and PowerFlowData.
  • Refactors AC/DC solver internals for lower allocation, including AC Jacobian structure caching, DC scratch typing, LM scratch buffers, and residual/Jacobian function-field removal.
  • Updates robust homotopy, Cholesky, trust-region/Iwamoto logic, documentation, and regression tests.

Reviewed changes

Copilot reviewed 26 out of 26 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
src/discrete_control/controlled_devices.jl Defines controlled device types, parameter application, and discrete snapping.
src/discrete_control/control_metadata.jl Builds controlled devices from PSY system metadata.
src/discrete_control/control_continuation.jl Implements the outer λ-continuation, probing, stepping, snapping, and restore flow.
src/definitions.jl Adds discrete-control constants.
src/PowerFlows.jl Exports and includes the new discrete-control subsystem.
src/PowerFlowData.jl Stores controlled device sets on power-flow data and wires construction.
src/power_flow_types.jl Adds control_discrete_devices to AC formulations.
src/solve_ac_power_flow.jl Routes AC solves through Q-limit or discrete-control paths.
src/solve_dc_power_flow.jl Refactors DC scratch/cache usage and solve workers.
src/ac_power_flow_residual.jl Removes stored residual function field.
src/ac_power_flow_jacobian.jl Removes stored Jacobian function field and adds Jacobian structure caching.
src/rectangular_ci_power_flow_residual.jl Removes stored residual function field and updates comments.
src/rectangular_ci_power_flow_jacobian.jl Removes stored Jacobian function field.
src/mixed_cpb_power_flow_residual.jl Removes stored residual function field.
src/mixed_cpb_power_flow_jacobian.jl Removes stored Jacobian function field.
src/power_flow_method.jl Updates trust-region dogleg scratch use and generalizes Iwamoto multiplier.
src/levenberg-marquardt.jl Adds LM scratch buffers to reduce allocations.
src/RobustHomotopy/homotopy_hessian.jl Optimizes homotopy Hessian/gradient assembly.
src/RobustHomotopy/HessianSolver/cholesky_solver.jl Uses CHOLMOD success status for PD checks.
docs/src/explanation/discrete_control.md Adds discrete-control explanation and metadata documentation.
docs/make.jl Adds the new documentation page to the docs navigation.
test/test_discrete_control.jl Adds discrete-control unit and integration coverage.
test/test_utils/common.jl Adds test systems for tap/shunt control scenarios.
test/test_iterative_methods.jl Adds/updates Iwamoto multiplier tests.
test/test_homotopy_hessian.jl Adds intermediate-t homotopy Hessian regression coverage.
test/test_ac_nr_allocations.jl Adds allocation regression tests for AC Jacobian and DC reuse paths.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +111 to +114
function apply_parameter!(d::ControlledSwitchedShunt, data, b::Float64, ts::Int)
data.bus_active_power_constant_impedance_withdrawals[d.bus_ix, ts] = d.g0
data.bus_reactive_power_constant_impedance_withdrawals[d.bus_ix, ts] = -b
d.current = b
Comment on lines +116 to +117
The outer loop `_control_continuation!` runs up to
`MAX_CONTROL_OUTER_ITERATIONS = 20` passes. Each pass:
Comment on lines +126 to +133
**Under-relaxation.** The factor $\omega$ is chosen so the local iteration-map
slope magnitude is at most `CONTROL_CONTRACTION = 0.7`. The closed-loop slope
is bounded by $|h - \ell| \cdot S/4 \cdot |\partial|V|/\partial p|$ (the
maximum sigmoid derivative times the plant gain), giving

$$\omega \leq \frac{1 + \theta}{1 + |g'|}$$

where $\theta = 0.7$ is the contraction target and $g'$ is the closed-loop
Comment on lines +64 to +66
else
apply_parameter!(d, data, reached, ts)
step /= 2.0
Comment on lines +229 to +230
else
step /= 2.0
Comment on lines +38 to +40
apply_parameter!(d, data, p0, ts)
ok2 = _solve_with_q_limits!(pf, data, ts; kwargs...)
reliable = ok1 && ok2 && h != 0.0
Comment on lines +66 to +70
For `ControlledTap`, `apply_parameter!` rewrites four `nzval` entries of the
sparse Y-bus in place using cached linear offsets (`nz_offsets::NTuple{4,Int}`)
resolved once at device-set construction. The delta update
`nzval[k] += Y_new − Y_old` preserves any parallel-branch contributions already
in the shared slot; `d.current` (not the lossy `nzval`) is the authoritative
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 30, 2026

Performance Results

Precompile Time

Main This Branch Delta
2.356 s 2.581 s +9.6%

Solve Time

Polar AC

Test Main This Branch Delta
NewtonRaphsonACPowerFlow First Solve 12.044 s 15.168 s +25.9%
NewtonRaphsonACPowerFlow Second Solve 122.4 ms 488.5 ms +299.0%
RobustHomotopyPowerFlow First Solve 16.862 s 18.809 s +11.5%
RobustHomotopyPowerFlow Second Solve 8.085 s 7.979 s -1.3%
NewtonRaphsonACPowerFlow(iwamoto) First Solve 205.9 ms 2.106 s +923.1%
NewtonRaphsonACPowerFlow(iwamoto) Second Solve 539.0 ms 80.1 ms -85.1%
TrustRegionACPowerFlow(iwamoto) First Solve 1.808 s 4.128 s +128.3%
TrustRegionACPowerFlow(iwamoto) Second Solve 81.8 ms 79.7 ms -2.6%

Rectangular CI

Test Main This Branch Delta
ACRectangularPowerFlow{NR} First Solve 5.446 s 9.46 s +73.7%
ACRectangularPowerFlow{NR} Second Solve 39.1 ms 39.1 ms -0.0%
ACRectangularPowerFlow{NR}(iwamoto) First Solve 165.6 ms 2.018 s +1118.6%
ACRectangularPowerFlow{NR}(iwamoto) Second Solve 39.1 ms 38.9 ms -0.4%
ACRectangularPowerFlow{TR} First Solve 5.93 s 9.462 s +59.5%
ACRectangularPowerFlow{TR} Second Solve 58.0 ms 39.9 ms -31.2%
ACRectangularPowerFlow{TR}(iwamoto_fallback) First Solve 167.3 ms 2.028 s +1111.8%
ACRectangularPowerFlow{TR}(iwamoto_fallback) Second Solve 40.2 ms 39.8 ms -0.9%

Mixed CPB

Test Main This Branch Delta
ACMixedPowerFlow{NR} First Solve 5.321 s 9.009 s +69.3%
ACMixedPowerFlow{NR} Second Solve 442.1 ms 40.6 ms -90.8%
ACMixedPowerFlow{NR}(iwamoto) First Solve 168.0 ms 1.995 s +1087.7%
ACMixedPowerFlow{NR}(iwamoto) Second Solve 41.3 ms 40.4 ms -2.0%
ACMixedPowerFlow{TR} First Solve 5.384 s 8.858 s +64.5%
ACMixedPowerFlow{TR} Second Solve 43.7 ms 42.5 ms -2.7%
ACMixedPowerFlow{TR}(iwamoto_fallback) First Solve 170.0 ms 2.006 s +1079.6%
ACMixedPowerFlow{TR}(iwamoto_fallback) Second Solve 59.1 ms 54.6 ms -7.5%
ACMixedPowerFlow{LM} First Solve 7.738 s 11.018 s +42.4%
ACMixedPowerFlow{LM} Second Solve 922.2 ms 885.4 ms -4.0%

DC

Test Main This Branch Delta
DCPowerFlow First Solve 3.813 s 3.675 s -3.6%
DCPowerFlow Second Solve 14.4 ms 14.1 ms -2.6%
PTDFDCPowerFlow First Solve 1.522 s 2.047 s +34.5%
PTDFDCPowerFlow Second Solve 67.1 ms 63.0 ms -6.2%
vPTDFDCPowerFlow First Solve 5.607 s 5.565 s -0.7%
vPTDFDCPowerFlow Second Solve 3.067 s 2.919 s -4.8%

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