Skip to main content

Module augmented

Module augmented 

Source
Expand description

The bordered (n+1) × (n+1) system, and why it is the one that works.

§Why not a bordered solve

The tempting cheap route is to keep the plain n × n Jacobian, reuse its factorization, and recover Δλ by block elimination — two solves against J plus a scalar. It is rejected on a mathematical basis, not a performance one: J is exactly the matrix that goes singular at the nose, so the Schur complement d − bᵀJ⁻¹c is the quotient of two quantities that both vanish there. Every backend in this crate reports singularity only as a non-finite result vector (sparse::RealSparseSystem::solve_values) and none offers a condition estimate, so there is no way to detect the transition either. The augmented matrix, by contrast, stays non-singular through the nose.

§Why it stays non-singular

At a simple fold J has a one-dimensional null space span(v), and transversality gives −Δs ∉ range(J). The bordered matrix

[ J    -Δs ]
[ bᵀ     d ]

is then non-singular iff bᵀv ≠ 0. For Parametrization::PseudoArcLength b = t_x, and at the nose t = (v, 0), so bᵀv = ‖v‖² ≠ 0. For Parametrization::Local b = e_k with k = argmax|t_i| = argmax|v_i|, so bᵀv = v_k ≠ 0. That is the entire reason this form exists.

§The border row must stay sparse, and this is measured

The λ column is emitted at every row regardless of whether Δs is zero there, so the pattern does not depend on which buses carry load. That is free: COLAMD’s dense_col threshold trips on it, the column is ordered last, and the factors are then exactly the bordered factorization. Measured on case1354pegase (n = 2449), a bordered solve with a sparse border row costs 1.4× a plain Newton solve.

The border row is a different story, and the naive choice is a disaster. Emitting it densely — which Parametrization::PseudoArcLength genuinely needs, since its row is the previous tangent — costs 92× the plain solve at the same size, while the symbolic analysis stays at 1.0×. So this is numeric fill during factorization, not a bad ordering, and no amount of reasoning about COLAMD’s dense-row handling makes it go away. At 119 buses the same comparison is 1.7×, which is why the problem is invisible on small fixtures.

Hence Parametrization::Local is the default: its row is a single entry e_k, and it carries the same transversality guarantee at the nose (bᵀv = v_k ≠ 0, because k is chosen as the tangent’s largest component). k changes rarely — far from the nose the tangent is dominated by λ, so k = n and this degenerates to Natural; near the nose a voltage component takes over — and a change costs one re-analysis, the same price a bus-type change already pays.

So the pattern is fixed for as long as the continuation index is, rather than for the whole segment. border_columns says which columns the row occupies, and corrector::Segment re-analyzes when they change.

Structs§

AugmentedPattern
A JacobianPattern plus the border, in one fixed emission order: the Jacobian’s own entries, then the λ column top to bottom, then the border row’s own columns in order.
Layout
The Newton unknown layout, derived once per segment.

Enums§

Parametrization
Which equation closes the n power-flow equations in n+1 unknowns.

Functions§

border_columns
Which columns the border row structurally occupies, for a parametrization whose continuation index is k in a system of n unknowns.
dominant_index
The index of the tangent’s largest component — the unknown that is locally the best continuation parameter, and the one Parametrization::Local pins.