
Inside the Admittance Matrix - BambooGrid Series Part 3


When a power-flow calculation finishes, the result looks deceptively simple: bus voltages, phase angles, line flows, transformer loading.
What happens between the network diagram and those numbers is much more interesting.
Before Newton–Raphson can solve anything, the electrical network first has to be translated into a mathematical model. Lines, transformers, impedances, shunts and electrical connections are assembled into the bus admittance matrix, or Ybus. That matrix describes how every bus is electrically connected to every other bus and how strongly those buses influence one another.
The solver then combines Ybus with the operating conditions of the network: loads consume active and reactive power, generators inject power, some buses hold their voltage, and one bus provides the reference for the entire system. From there, Newton–Raphson repeatedly adjusts the unknown bus voltages until the power calculated from those voltages matches the power that was specified.
That sounds abstract when written as equations. On a small network, however, the whole process can be followed almost line by line.
In this article we use the same two-bus BambooGrid network from Part 2 and open the solver one layer at a time. We will:
- build its admittance matrix from the transformer parameters;
- see what diagonal and off-diagonal cells actually represent;
- explain why a transformer phase shift makes Ybus asymmetric;
- connect slack, PV and PQ bus types to the variables Newton–Raphson actually solves;
- follow the mismatch, Jacobian and voltage correction through individual iterations;
- and see why the same valid network can converge in three iterations from one starting point and fail completely from another.
The goal is not to reproduce every equation inside a production-grade power-flow solver. It is to make the important pieces visible enough that pressing Run no longer feels like sending the network into a black box.
Everything below can be reproduced directly in BambooGrid, including the admittance matrix itself.
The network we will follow
We reuse the network from Part 2, and the reason is entirely practical.
Most explanations of the admittance matrix use a network large enough that the matrix has to be described rather than shown. Here the matrix has four cells. All four fit on screen at once, every one of them can be traced back to a transformer nameplate, and there is nothing hidden in a corner of the grid that we are quietly ignoring.
The network is a small substation feeding an industrial site:
- a 110 kV bus where the external grid connects — the strong upstream network that sets the voltage reference;
- a 20 kV bus carrying a 5 MW + 1 MVAr load and 2 MW of solar;
- a 25 MVA 110/20 kV transformer between them, a standard type with its tap at neutral.
You can open it directly: bamboo.kickstage.com/?s=SUI6Hdxi

The Part 2 network, solved — 0.9946 p.u. at the MV bus, 12.8 % transformer loading.
BambooGrid is open source under the MIT License and uses pandapower for the underlying electrical calculations. The viewer exposes the same network representation used by the solver, but in a form where the relationship between the diagram, the matrix and the final power-flow result can be explored directly.
Press Run, and the load flow returns two voltages:
| Bus | VM (p.u.) | VA (degrees) |
|---|---|---|
| Bus (110 kV) | 1.000000 | 0.000000 |
| MV Bus (20 kV) | 0.994553 | −150.821554 |
The voltage magnitude is unremarkable — a little under one per unit, exactly what you would expect for a loaded transformer.
The angle is stranger. −150.82° is an enormous phase displacement for a network this small and this lightly loaded. Part 2 established that bus angles drive active-power flow, and 3 MW across a 25 MVA transformer should not displace anything by 150 degrees.
So either the result is wrong, or something in the model is contributing an angle that has nothing to do with power transfer.
It is the second one. And the explanation is sitting in the admittance matrix, which is where we go next.
Building the admittance matrix
Ybus answers one question: if I know the voltage at every bus, what current is being injected at every bus?
Written out, that is all it is:
For a network with n buses, Y has n rows and n columns. Ours has two of each. You can follow along by opening Study ▸ Admittance matrix… — the panel floats over the diagram rather than covering it, so hovering a cell can highlight the buses that cell belongs to.
The matrix has to be built before it can be read, and building it takes three moves: get the transformer's impedance into the network's units, turn that impedance into an admittance, then place the admittances into cells.
From nameplate percentages to per-unit impedance
Our only branch is the transformer, so the entire matrix comes from its nameplate. Two values on that nameplate describe its series impedance: vk = 12 %, the short-circuit impedance magnitude, and vkr = 0.41 %, the resistive part of it.
Percentages of what, though? This is the step that trips people up. Those percentages are relative to the transformer's own 25 MVA rating. They describe that specific machine, not the network it sits in.
But a matrix has to be in one consistent set of units, because it will eventually hold contributions from a 25 MVA transformer, a 40 MVA transformer and a cable all at once. So each component's private percentages get rebased onto a single per-unit base shared by the whole network:
Worth pausing on the base itself, because it will explain the size of every number that follows.
This network uses a 1 MVA base, not the textbook 100 MVA
BambooGrid's per-unit base is the network's sn_mva, which defaults to 1 MVA — the panel footer states it: "Per-unit on 1 MVA base." Textbooks almost always use 100 MVA, so every admittance in this post is 100× larger than the equivalent textbook figure. If a worked example elsewhere disagrees with what you see here, check the base before you check the arithmetic. There is a small upside: on a 1 MVA base, a per-unit mismatch and an MVA mismatch are the same number, which makes the convergence tolerance much easier to read later on.
A quick reality check that these per-unit numbers describe a real transformer: on the transformer's own 25 MVA base at 110 kV, Zbase = 110² / 25 = 484 Ω, so 12 % is 58.1 Ω of reactance. That is an entirely normal figure for a 25 MVA unit.
From impedance to admittance
Impedance and admittance are reciprocals, which has one consequence worth stating plainly before the numbers arrive: a strong branch has a small impedance, so it shows up as a large admittance. Large numbers in Ybus mean tight electrical coupling, not big components.
So the 208 is not a suspicious value. It is 1 divided by 0.0048 — what a firmly connected branch looks like when the base is 1 MVA.
The transformer contributes one more thing. Beyond the series impedance that carries power through it, there is a magnetising branch: the small current the transformer draws simply to keep its core energised, whether or not anything is connected downstream. Two more nameplate values describe it — iron losses pfe = 14 kW and no-load current i0 = 0.07 % — giving a shunt admittance of 0.014 − j0.0105 p.u.
Because that magnetising branch physically sits in the middle of the winding, the T-model splits it in half and hangs half at each end: 0.0070 − j0.00525 per side.
So the 208 is not a suspicious value. It is 1 divided by 0.0048 — what a firmly connected branch looks like when the base is 1 MVA.
The transformer contributes one more thing. Beyond the series impedance that carries power through it, there is a magnetising branch: the small current the transformer draws simply to keep its core energised, whether or not anything is connected downstream. Two more nameplate values describe it — iron losses pfe = 14 kW and no-load current i0 = 0.07 % — giving a shunt admittance of 0.014 − j0.0105 p.u.
Because that magnetising branch physically sits in the middle of the winding, the T-model splits it in half and hangs half at each end: 0.0070 − j0.00525 per side.
Placing the admittances into cells
Now the matrix can be filled in, and there are only two rules.
A diagonal cell Y[i,i] is the self-admittance of bus i — everything electrically touching that bus, added up. Every branch leaving it, plus every shunt sitting on it.
An off-diagonal cell Y[i,j] is the negative of the admittance connecting bus i to bus j. If the two buses are not directly connected, the cell is zero.
The minus sign is the part that looks arbitrary, and it is worth a sentence. Current leaving bus i through a branch depends on the voltage difference across that branch. Expanding that difference gives a positive term multiplying bus i's own voltage and a negative term multiplying the neighbour's. The diagonal collects the positive terms; the off-diagonals collect the negative ones. The sign is bookkeeping, not physics.
For our MV bus, the diagonal is the series admittance plus its half of the magnetising branch:
Which is exactly what the viewer reports. Hover the top-left cell and the footer reads:
That is the whole construction. Four cells, all four traceable to four numbers on a nameplate.
Reading the matrix
With the matrix built, the question becomes what to look at.
The panel offers three modes, and they are not three ways of drawing the same thing — they answer different questions.
|Y| shows the magnitude of each cell on a teal ramp, scaled logarithmically. This is the structural view: it tells you which buses are coupled and how tightly, and on a real network the pattern of coloured cells traces the shape of the grid.
G shows conductance, the real part. Conductance is where losses live.
B shows susceptance, the imaginary part — reactive coupling. In transmission networks this dominates almost completely, and ours is no exception: −208 against +7. That ratio is the numerical expression of something Part 2 established physically, that transformer and line behaviour is overwhelmingly reactive.

The same four cells in the viewer's three modes, drawn with the app's own colour ramps. |Y| uses a log-scaled teal ramp for structure; G and B use a diverging ramp, red for positive and blue for negative. G is where the story turns out to be.

Rows and columns are buses. Hovering a cell spotlights the buses it couples on the diagram.
One honest warning about the |Y| view on a network this small.
The colour ramp auto-scales to the range that is actually present
In our 2×2, all four magnitudes fall within 0.003 % of each other — 208.3306 to 208.3361. The ramp faithfully stretches that rounding-level difference across its full span, so the diagonal appears saturated and the off-diagonal appears pale, which reads as a dramatic difference that is not there. On a network of any real size this behaviour is exactly what you want, because the genuine spread runs to orders of magnitude. On a two-bus network, trust the numbers and the G/B views instead.
Which brings us to the thing that is genuinely worth looking at here.
Why a phase shift makes Ybus asymmetric
Look at the two off-diagonal cells side by side:
These two cells describe the same transformer. Y[0,1] is the MV bus's view of it; Y[1,0] is the 110 kV bus's view. And they disagree — not slightly, but by the sign of their real part. One is +110, the other is −98.
That should be alarming, because admittance matrices are supposed to be symmetric. Y[i,j] should equal Y[j,i], for a reason that sounds unarguable: a piece of copper admits current equally well in both directions, so both ends of a branch should describe it identically.
Switch the panel to G mode and the disagreement becomes visual rather than numerical. That mode uses a diverging ramp — red for positive, blue for negative — so the two cells belonging to one transformer render in opposite colours.

The same transformer reads +110 from one end and −98 from the other.
So is this a bug?
No — and the evidence is in what the two cells have in common. Their magnitudes are identical to every digit: 208.3306 both ways. Whatever differs between them is not about how much admittance there is. It is purely about angle:
Sixty degrees. And our transformer is a YNd5 vector group — a star winding on the high side, delta on the low side — whose shift_degree is 150.
The two cells are separated by exactly twice the transformer's phase shift.
That factor of two is not a coincidence, and it comes straight from how a phase-shifting branch is modelled. A transformer's turns ratio is not just a number, it is a complex number τ = t · e^(jθ): the magnitude t scales voltage between the two sides, and the angle θ rotates it. A delta–star connection genuinely rotates the voltage phasor, by 150° for a YNd5 group, and that rotation lives in θ.
When you work out the two off-diagonal terms, the ratio appears differently in each:
Dividing by τ rotates one way. Dividing by its conjugate rotates the other. The magnitudes are untouched, because |τ| = |conj(τ)|. So the two cells must have equal magnitude and must differ in angle by 2θ — which is precisely what we measured.
The asymmetry is not an artefact. It is the matrix faithfully recording that crossing this transformer in one direction rotates voltage by +150°, and crossing it the other way rotates by −150°.
And this also solves the mystery from the beginning of the post. The MV bus angle of −150.82° was never 150 degrees of power-transfer displacement. It is the vector group's 150° rotation, plus 0.82° of genuine electrical angle from pushing 3 MW across the transformer. The strange result and the strange matrix are the same fact, seen twice.
Why textbooks still say Ybus is symmetric
They are not wrong, only incomplete. Symmetry holds for every passive series branch — lines, cables, plain impedances — and introductory treatments build Ybus from lines alone, where it always holds. Phase-shifting transformers are the exception, and they break it only in the off-diagonals. The result is that the first time an engineer builds a matrix for a real network with a delta–star transformer, it violates the rule they were taught, and it looks like a modelling error.
Two edits that prove it
The nice thing about a claim like this is that it is testable in one field change.
Set the transformer's phase shift to 0 — a Yy0 group instead of YNd5 — and the matrix becomes textbook-symmetric.

One field, two matrices. With the shift removed, both off-diagonals read −7.1146 + 208.2091j — identical, both blue, and now plainly the negative of the series admittance, exactly as the rule promised.
Note what did not change. The voltage magnitude is still 0.994553, the transformer still carries the same power, the losses are identical. Removing the phase shift did not change the physics of the power flow; it changed the reference frame the angles are reported in.
Now put the shift back and move the tap to −9 instead. This breaks a different symmetry:
The off-diagonals still match in magnitude — 240.84 both ways — because the phase shift has not changed. But the diagonals, which were identical before, now read 208 against 278.
That is the other half of the complex ratio: the magnitude t rather than the angle θ. Changing the tap changes the effective turns ratio, and the term for the bus on the tap side gets scaled by 1/t². Nine steps of 1.5 % off the HV side gives t = 0.865, so 1/t² = 1.336 — and 278.28 / 208.21 is 1.336.
So the two parts of a transformer's ratio disturb two different symmetries, which is a genuinely useful thing to know when a matrix looks wrong:
| TRANSFORMER FEATURE | WHAT IT CHANGES IN YBUS |
|---|---|
| Phase shift θ (vector group) | Off-diagonal angles — the matrix stops being symmetric |
| Tap ratio t (tap position) | Diagonal magnitudes — the two ends stop matching |
What the solver is actually solving for
We now have Ybus, and it is worth being precise about what we do not have.
Ybus is the network. It knows every impedance and every connection. It does not know that there is a 5 MW load at the MV bus, or that the external grid holds 110 kV, because none of that is in the wiring — it is in the operating conditions.
I = Y · V is a relationship, not a solution. Both I and V are unknown.
What breaks the deadlock is that we know something about every bus, just not the same thing at every bus. And here is the part that surprises people: a power flow does not solve for flows at all. It solves for complex voltage at every bus — a magnitude and an angle. Once those are known, every current, every flow and every loading follows by arithmetic.
So each bus contributes two unknowns. To make the problem solvable, each bus must also contribute two known quantities, and each bus type is really just a statement about which two of the four quantities — P, Q, |V| and θ — you are supplying.
BambooGrid picks the type from whatever you attached to the bus.
A PQ bus is the common case. You specify how much active and reactive power is being consumed or injected, and the solver works out what voltage results. Loads and static generators create PQ buses, and so does a bus with nothing on it at all — its scheduled power is simply zero.
A PV bus is what you get from a generator. Instead of specifying reactive power, you specify active power and the voltage the machine should hold, and the solver works out how much reactive power that demands. This is closer to how real generation behaves: a unit is dispatched for MW and regulates its terminal voltage.
The slack bus is the reference, and every network needs exactly one per electrical island. Its voltage magnitude and angle are both fixed, which makes it the zero that all other angles are measured against. In exchange, both its P and Q are unknowns — and this is the point of it. Losses cannot be known before the solve, because losses depend on the currents, which depend on the voltages, which are what we are solving for. Something has to absorb whatever imbalance remains at the end.
That is the slack.
| BUS TYPE | ELEMENT | YOU SPECIFY | SOLVER RETURNS |
|---|---|---|---|
| Slack | External grid | |V|, θ | P, Q |
| PV | Generator | P, |V| | Q, θ |
| PQ | Load, static generator, or nothing | P, Q | |V|, θ |
In our network the accounting is short.
The 110 kV bus is the slack — the external grid holds it at 1.0 p.u. and 0°. Both of its power values are results, and after the solve they read 3.0156 MW and 1.0592 MVAr flowing in from the grid. That 0.0156 MW above the 3 MW the load actually needs is the transformer's losses, discovered rather than specified.
The MV bus is a PQ bus. The load takes 5 MW + 1 MVAr, the solar injects 2 MW, and the solver only cares about the sum: a net scheduled injection of −3 MW and −1 MVAr.
Which leaves exactly two unknowns in the entire network — the magnitude and angle at the MV bus. The slack contributes none.
Why the 2 MW of solar does not make this a PV bus
The solar is modelled as an sgen, a fixed P and Q injection, so the bus stays PQ and its voltage sags to 0.9946. Replace it with a Generator and you are making a different statement: hold this bus at a voltage, and tell me what reactive power that takes. Do exactly that — a 2 MW generator holding 1.0 p.u. — and the solver returns +1.13 MVAr from the generator, with the voltage now at 1.0 by definition. Identical active power, completely different reactive picture. The bus type is not a modelling detail; it is a statement about what the equipment controls.
Following Newton–Raphson through its iterations
Two unknowns and two equations. If the relationship were linear we would be done already.
It is not, and it is worth seeing exactly where the nonlinearity enters. Power at a bus is voltage times the conjugate of current, and current is Ybus times voltage:
The unknown voltage appears twice — once on its own, once inside the sum. The equations are quadratic in the thing we are solving for, and there is no rearrangement that isolates V.
So we stop trying to solve directly, and start correcting instead. Newton–Raphson turns an unsolvable equation into a repeated, answerable question:
If these were the bus voltages, how wrong would the resulting powers be?
Every iteration answers it and acts on the answer, in four movements.
First, the mismatch. Take the current voltage guess, push it through Ybus, and compute what power that implies at each bus. Subtract the power that was actually scheduled. What remains is the amount by which the guess violates physics — and crucially, it is a number, so we know not just that we are wrong but by how much.
Second, the Jacobian. Knowing the error does not tell us which way to move. The Jacobian is the matrix of partial derivatives ∂(P,Q)/∂(θ,|V|): how much each mismatch changes when each unknown changes. It is built from Ybus and the current voltages, which means it has to be rebuilt every iteration — the network's sensitivity depends on where it is operating.
Third, solve. With the error and the sensitivities in hand, solving one linear system gives the correction to apply to the unknowns. This is the step that replaces the impossible nonlinear solve with a possible linear one.
Fourth, update and check. Apply the correction, recompute the mismatch, and see whether it is small enough to stop.
For our network the unknown vector has two entries, so the Jacobian is 2×2 — small enough to print. Starting from 1.0 p.u. at −150° (where that starting angle comes from is the subject of the next section), the iterations run like this:

Quadratic convergence, on a log axis. Each error is roughly the square of the one before it, so the bars fall in near-equal steps on a log scale — and the last one overshoots the tolerance by five orders of magnitude.
| ITERATION | LARGEST MISMATCH (p.u.) | VM (p.u.) | VA(degrees) |
|---|---|---|---|
| 0 | 3.007 | 1.000000 | −150.000000 |
| 1 | 2.640 × 10⁻² | 0.994685 | −150.817051 |
| 2 | 4.157 × 10⁻⁶ | 0.994553 | −150.821553 |
| 3 | 1.459 × 10⁻¹³ | 0.994553 | −150.821554 |
Read the voltage columns first. After one correction the answer is already right to three decimal places. The remaining two iterations are the solver convincing itself.
Now read the mismatch column, which is the more interesting one: 3 → 0.026 → 0.000004 → 0.0000000000001.
Each error is roughly the square of the one before it. That is quadratic convergence, and it is Newton–Raphson's defining property: the number of correct digits roughly doubles every iteration. It is also why power-flow solvers are configured to give up after ten or twenty iterations rather than hundreds. A Newton–Raphson iteration that is going to converge does so almost immediately; one that has not converged in ten iterations is usually not converging at all.
Why is it so well behaved here? The Jacobian at the first step explains it:
Compare that with Y[0,0] = 7.1216 − j208.2143. The same 208 dominates, because ∂P/∂θ is governed largely by susceptance, as is ∂Q/∂|V|. The matrix is strongly diagonal, which means the two unknowns barely interfere with each other: angle mostly moves active power, magnitude mostly moves reactive power. The linear solve is well conditioned and the first correction lands almost exactly on target.
By the second iteration the Jacobian has hardly moved — −206.98 and −206.13 in place of −208.21 and −208.22. A nearly-converged problem is a nearly-linear problem, which is why the last steps are so cheap.
And pandapower, solving the same network properly, reports 3 iterations and lands on vm = 0.994553, va = −150.821554. The hand-worked trace and the production solver agree to every digit shown.
Where the names come from?
Newton described the iteration for polynomials; Joseph Raphson published the general form in 1690. Applying it to power flow came nearly three centuries later — the formulation that made large AC networks tractable on a computer was published by William Tinney and Clifford Hart at Bonneville Power Administration in 1967. It is still what runs when you press Run.
Convergence, and why the starting point decides it
There is a caveat hiding in that description of quadratic convergence: it applies once the guess is close enough to the answer.
Far from the solution, the linearisation the Jacobian provides is not a good approximation of the real equations, and a Newton–Raphson step can overshoot into a region that is worse than where it started. Repeat that a few times and the iteration wanders off instead of settling down.
Our network turns out to be an unusually good demonstration of this, precisely because of that 150° phase shift. And the setting that controls it lives under Study ▸ Study settings.
init decides where the solver begins. A flat start puts every bus at 1.0 p.u. and 0°, which is the obvious guess and a perfectly good one for most networks. A dc start first runs a linearised DC power flow — cheap, always solvable — and uses its angles as the starting point. auto, the default, picks sensibly, which in practice means a DC start whenever voltage angles are being calculated. results starts from the previous solve, which is what makes re-running after a small edit fast.
On our network, that choice is not a performance detail:
| INIT | RESULT |
|---|---|
| auto (default) | Converged, 3 iterations |
| dc | Converged, 3 iterations |
| flat | Did not converge after 10 iterations |
The same network, the same load, the same transformer. One starting point solves it in three iterations; the other fails outright.
The reason is the 150°. A flat start places the MV bus at 0° when the answer is −150.82°, so the initial mismatch is not the 3 p.u. we saw in the trace but around 386 p.u. From that far away the Jacobian is describing a completely different operating point, the correction it produces is meaningless, and the iteration never recovers.
A DC initialisation avoids this because the linearised model it solves includes branch phase shifts. It starts near −150°, close enough that the first real correction is already almost right.
The practical lesson generalises well beyond this example. When a power flow fails to converge, there are two quite different questions, and they are easy to conflate.
Is the electrical model wrong — or is the model fine, and the solver simply unable to reach the answer from where it started?
The first kind of failure is a bad impedance, a missing connection, an unsupplied island, or a network genuinely operating past the point of voltage collapse. The second is a network full of delta–star transformers failing from a flat start — and no amount of checking impedances will ever find it.

The remaining settings matter less often, but each has a case.
calculate_voltage_angles should stay on for any network with transformers. Turn it off and the MV bus reports −0.82° rather than −150.82°: the vector-group rotation is dropped from the reported angle. Magnitudes and flows are unchanged, so this is a reporting convention rather than a different solve — but with it off, angles at different voltage levels can no longer be compared to each other.
tolerance_mva is how small the mismatch has to be before the solver declares success, and it defaults to 1 × 10⁻⁸. Our solve finishes at 1.5 × 10⁻¹³, five orders of magnitude past it, which is quadratic convergence overshooting on its final step. This is why tightening the tolerance rarely costs an iteration and loosening it rarely saves one — the last step tends to blow through whatever target you set.
algorithm defaults to Newton–Raphson, which is the right answer for almost every network. The alternatives exist for when it is not: iwamoto_nr damps the step length for heavily loaded networks near collapse, where a full Newton step overshoots; bfsw (backward/forward sweep) exploits the structure of purely radial distribution feeders; fdbx and fdxb are fast-decoupled variants that reuse a constant Jacobian to trade accuracy for speed; and gs (Gauss–Seidel) is mainly of historical interest, since it converges linearly rather than quadratically.
max_iteration is best left on auto. Raising it rarely rescues a diverging solve, because divergence is not slowness — it mostly just makes the failure take longer.
What changes on a larger network
Everything above used a matrix with four cells. Real networks produce matrices with thousands, and a few things only become apparent at that size.
The matrix is mostly empty, and that is the important structural fact. A bus connects to a handful of neighbours, not to all n buses, so almost every off-diagonal cell is zero. The viewer draws those as blank rather than as zeros, which means the coloured cells trace the topology of the network directly — you can often recognise the shape of the grid in the pattern. That sparsity is also why large power flows are computationally feasible at all: the linear solve inside each iteration exploits it rather than treating the matrix as dense.
Above twelve buses the numbers disappear from the cells. There is no room for them, and at that scale the pattern is what you are reading anyway. Hovering any cell still gives its exact complex value in the footer.
A row is not always one bus. Close a bus–bus switch and the two buses become electrically the same node, so they share a single row, labelled Bus 3 + Bus 4. Open it and the row splits into two. The matrix reflects switching state, not just drawn geometry.
Some rows have no bus behind them at all. A three-winding transformer is modelled internally as three branches meeting at a star point, which is a real electrical node that you never drew. It appears as a row labelled Internal node with nothing to highlight on the diagram. Out-of-service and isolated buses go the other way: they have no row, and a footer note counts them.
And the matrix is available even when the solve is not. Ybus depends only on impedances and connections, never on the solution, so the panel still shows it after a failed power flow, with a banner noting the failure. That makes it a genuine diagnostic rather than a curiosity: when a network will not converge, the matrix can still tell you whether it is wired the way you believe it is.
Closing thoughts
A power-flow solver can look complicated because several ideas are usually introduced at once: complex numbers, per-unit quantities, bus types, admittance matrices, nonlinear equations, Jacobians and numerical convergence.
But the actual chain from network model to solution is remarkably systematic.
The physical components come first.
A transformer, line or impedance contributes electrical parameters. Those parameters are converted into admittances and assembled into Ybus, which becomes the compact mathematical description of how the network is connected.
Ybus does not tell us the final voltages by itself. It tells us how currents and voltages are related.
The bus definitions then provide the operating constraints. A PQ bus tells the solver what active and reactive power should be present. A PV bus fixes active power and voltage magnitude. The slack bus anchors the voltage angle and absorbs the remaining power imbalance.
What remains is a nonlinear problem.
Newton–Raphson solves it by repeatedly asking a simple question:
If these were the bus voltages, how wrong would the resulting powers be?
The mismatch measures that error.
The Jacobian estimates how the voltages should move to reduce it.
The solver applies the correction and asks the same question again.
On our small example, only three corrections are needed.
The admittance matrix viewer makes another important point visible: Ybus is not just an intermediate data structure hidden inside the solver. It contains real information about the network.
A transformer phase shift appears as an asymmetry between its off-diagonal terms.
A tap change alters the magnitude relationships in the matrix.
Opening or closing a switch changes its structure.
Adding more buses turns the small 2 × 2 example into a sparse matrix whose pattern begins to resemble the topology of the network itself.
This also gives us a useful way to think about failed power flows.
When a calculation does not converge, there are two different questions to ask:
Is the electrical model itself correct? And can the numerical solver reach its solution from the chosen starting point?
Ybus helps with the first question. Solver settings, initialization and convergence behaviour help with the second.
That distinction is useful far beyond this two-bus example.
The best way to explore it is to make the network slightly wrong on purpose.
- Set the transformer phase shift to zero and watch the matrix become symmetric.
- Move the tap and watch the diagonal values separate.
- Open a connection and watch the topology change.
- Switch from a DC initialization to a flat start and watch a network that normally converges in three iterations fail.
- Once those relationships become visible, the power-flow solver stops looking like a black box.
It becomes what it really is: a mathematical translation of the network you drew, followed by an iterative search for the set of voltages that makes that network obey the power equations.
How a power grid turns a pile of noisy, redundant meter readings into one clean, trustworthy picture of itself — watched live, on a real network.

