Skip to content

make ptdf diag lazy#304

Merged
jd-lara merged 4 commits into
mainfrom
jd/make_ptdf_diag_lazy
May 20, 2026
Merged

make ptdf diag lazy#304
jd-lara merged 4 commits into
mainfrom
jd/make_ptdf_diag_lazy

Conversation

@jd-lara
Copy link
Copy Markdown
Member

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

This PR makes the calculation of the MODF faster by making the PTDF diagonal calculation lazy which is only needed for certain calculations like potential for islanding and not for all cases.

These changes prevent populating the whole diagonal by default and reduce the construction times.

Issues with construction times were reported by @yonghongchen8 when using the EI

It also extends the testing and docs for VirtualMODF

@jd-lara jd-lara requested review from Copilot and m-bossart May 20, 2026 05:48
@jd-lara jd-lara marked this pull request as ready for review May 20, 2026 05:48
@jd-lara jd-lara self-assigned this May 20, 2026
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 improves VirtualMODF construction performance by avoiding eager computation of the diag(PTDF·A) vector and instead computing/caching it on first access. It also adds a faster implementation of _get_PTDF_A_diag and extends tests/docs around MODF/LODF correctness and the new lazy behavior.

Changes:

  • Make VirtualMODF.PTDF_A_diag lazily computed via a getproperty hook with caching + logging.
  • Optimize _get_PTDF_A_diag by exploiting incidence sparsity (two nonzeros per row) and reduced-index mapping.
  • Add N-2 MODF identity tests, lazy-caching/logging tests, and documentation for VirtualMODF.

Reviewed changes

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

Show a summary per file
File Description
src/virtual_modf_calculations.jl Implements lazy PTDF_A_diag computation/caching via getproperty; removes eager precompute in constructor.
src/virtual_lodf_calculations.jl Reworks _get_PTDF_A_diag to a faster sparse-aware implementation and loosens K typing.
test/test_virtual_modf.jl Adds N-2 MODF vs LODF/PTDF identity checks, lazy-diag logging/cache behavior tests, and an N-2 islanding pseudoinverse ground-truth check.
test/test_virtual_lodf.jl Adds correctness test comparing _get_PTDF_A_diag to a slower reference implementation.
test/test_modf_lodf_reductions.jl Adds helper + test to validate N-2 identity under network reductions.
docs/src/reference/network_matrices_overview.md Documents VirtualMODF conceptually and adds it to the axes overview table.
docs/src/how_to_guides/compute_network_matrices.md Adds a “Computing Virtual MODF Matrix” usage example and updates the axes table.

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

Comment on lines 170 to 194
for i in 1:n_branches
# Extract BA column for valid indices
fill!(ba_col, 0.0)
for idx in 1:n_valid
bus_idx = valid_ix[idx]
ba_col[idx] = BA[bus_idx, i]
@inbounds for k in SparseArrays.nzrange(BA, i)
valid_i = bus_to_valid_idx[ba_rv[k]]
valid_i > 0 || continue
ba_col[valid_i] = ba_nz[k]
end

solve!(K, ba_col)
_solve_factorization(K, ba_col)

# Map back to full bus indices
fill!(ptdf_row, 0.0)
for idx in 1:n_valid
ptdf_row[valid_ix[idx]] = ba_col[idx]
# ba_col is now PTDF row i in valid-index space; H[e,e] = ptdf[from] - ptdf[to].
f = arc_from_valid[i]
t = arc_to_valid[i]
v_f = if f > 0
ba_col[f]
else
0.0
end

# Compute diagonal element: sum of PTDF[i,j] * A[i,j] for all buses j
for j in 1:n_buses
diag_[i] += ptdf_row[j] * A[i, j]
v_t = if t > 0
ba_col[t]
else
0.0
end
@inbounds diag_[i] = v_f - v_t
end
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think this is correct; it seems like this will not work for all backends

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Right now we only support KLU as a backend for MODF. We can address this when merging #302

Comment on lines +124 to +128
!isempty(diag) && return diag
@lock getfield(vmodf, :solver_lock) begin
diag = getfield(vmodf, :PTDF_A_diag)
!isempty(diag) && return diag
n_arcs = length(getfield(vmodf, :axes)[1])
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 20, 2026

Performance Results

Precompile Time

Main This Branch Delta
2.092 s 2.083 s -0.4%

Execution Time

Test Main This Branch Delta
matpower_ACTIVSg2000_sys-Build PTDF First 1.657 s 1.771 s +6.9%
matpower_ACTIVSg2000_sys-Build PTDF Second 97.0 ms 72.9 ms -24.9%
matpower_ACTIVSg2000_sys-Build Ybus First 13.7 ms 119.3 ms +773.1%
matpower_ACTIVSg2000_sys-Build Ybus Second 12.3 ms 12.7 ms +3.5%
matpower_ACTIVSg2000_sys-Build LODF First 548.4 ms 519.7 ms -5.2%
matpower_ACTIVSg2000_sys-Build LODF Second 162.1 ms 154.8 ms -4.5%
matpower_ACTIVSg2000_sys-Build VirtualMODF First 3.588 s 4.777 s +33.1%
matpower_ACTIVSg2000_sys-Build VirtualMODF Second 253.7 ms 598.5 ms +135.9%
matpower_ACTIVSg2000_sys-VirtualMODF Query 10 rows 511.7 ms 497.5 ms -2.8%
matpower_ACTIVSg2000_sys-Radial network reduction First 443.4 ms 467.9 ms +5.5%
matpower_ACTIVSg2000_sys-Radial network reduction Second 0.7 ms 0.8 ms +13.4%
matpower_ACTIVSg2000_sys-Degree two network reduction First 1.687 s 1.701 s +0.9%
matpower_ACTIVSg2000_sys-Degree two network reduction Second 1.0 ms 0.9 ms -14.8%
Base_Eastern_Interconnect_515GW-Build Ybus First 3.715 s 3.595 s -3.2%
Base_Eastern_Interconnect_515GW-Build Ybus Second 3.514 s 3.667 s +4.3%
Base_Eastern_Interconnect_515GW-Radial network reduction First 37.3 ms 115.5 ms +210.1%
Base_Eastern_Interconnect_515GW-Radial network reduction Second 37.8 ms 33.5 ms -11.6%
Base_Eastern_Interconnect_515GW-Degree two network reduction First 361.7 ms 351.3 ms -2.9%
Base_Eastern_Interconnect_515GW-Degree two network reduction Second 41.1 ms 37.4 ms -9.0%

@jd-lara jd-lara merged commit 2d1d97f into main May 20, 2026
8 checks passed
@jd-lara jd-lara deleted the jd/make_ptdf_diag_lazy branch May 20, 2026 23:02
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.

3 participants