Load Flow Analysis of A Five-Bus Power System

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 10

Load Flow Analysis of a Five-Bus Power

System
Introduction
This application analyzes this five-bus power system, and calculates the voltages and real and reactive
powers at each bus.

Generators inject power (distribution substations) and loads remove power. The power flow equations
are derived from nodal power balances at each bus i using Kirchoff's Current Law

where

voltage magnitude, Vi
i
real power, Pi
reactive power, Qi

These variables are known for each bus (where the suffix G and D stand for generation and demand
respectively).
Bus type Unknown variable Known variable

Slack |V|, PG, QG


D, QD
Always has a
generator
PQ PG, QG, PD, QD |V|,
PV |V|, PG, PD, QD , QG

Larger power systems (for example, those modeling real-life distribution systems) can consist of tens of
thousands of buses; the number of nonlinear equations needed to model these systems is similarly
large. For these, power systems engineers use dedicated tools with specialized solvers.

Smaller systems can be modeled and studied in Maple, perhaps to experiment with or optimize
different topologies, investigate numerical techniques, or reinforce the underlying theory.

This Maple application demonstrates two approaches to numerically solving the load flow equations.

The symbolic real and reactive load flow equations are generated, and solved with fsolve (a
powerful numerical equation solver). This is quick to set up, but may be slower for larger
systems.
The system Jacobian is constructed, and solved with Newton-Raphson iteration (this method
requires more initial setup, but may be faster for larger systems)

> restart:

Properties

Transmission Lines and Transformer Data


Each row of the following matrix contains the properties of a transmission line

Column Data
1 Sending end bus
2 Receiving end bus
3 Series impedance in pu
4 Shunt admittance in pu

> Series := Matrix([[1, 2, 0.042 + I * 0.168, I * 0.020 ]


,[1, 5, 0.031 + I * 0.126, I * 0.0014]
,[2, 3, 0.031 + I * 0.126, I * 0.014 ]
,[3, 4, 0.084 + I * 0.336, I * 0.04 ]
,[3, 5, 0.053 + I * 0.21, I * 0.024 ]
,[4, 5, 0.063 + I * 0.252, I * 0.06 ]]):
Shunt Data
If no shunt equipment is available, enter any bus number in the first column and 0 in the second
column of the shunt array.

Shunt elements may represent reactive power compensation at certain system buses. In this case, the
reactance of the corresponding compensation device (capacitor or inductor) is calculated and its
admittance is entered in the above array. If lines are compensated by series capacitors, the reactance
of the capacitor is subtracted from the line series reactance and the net reactance is included in the
array Series.
> Shunt := Matrix([1, 0]):

Bus data
Bus number
> Bus := Vector([1, 2, 3, 4, 5]):

Generated real power on the bus (per unit)


> P__G := Vector([0, 0, 1.8, 0, 0]):

Real load power on the bus (per unit)


> P__L := Vector([0.65, 1.15, 0.7, 0.7, 0.85]):

Reactive load power on the bus (per unit)


> Q__L := Vector([0.3, 0.6, 0.4, 0.3, 0.4]):

Magnitude of the bus voltage (per unit). This is fixed for the slack (first value) and PV buses (third
value), and is the initial guess for PQ buses.
> V := Vector([1.04, 0.961, 1.02, 0.92, 0.968]):

Voltage phase angle in radians. This is normally 0 for the slack bus (the first value). The remaining
values are the initial guess of the bus voltage phase angles for the other buses
> delta := Vector([0, 0, 0, 0, 0]):

Bus type (0 for the slack bus, 1 for PV bus, 2 for PQ-bus)
> bus_type := Vector(["slack", "PQ", "PV", "PQ", "PQ"]):

Initialization
Number of buses. series elements and shunt elements
> N_bus := numelems(Bus):
N_ser := numelems(Series[.., 1]):
N_sh := numelems(Shunt[.., 1]):

Terminals of series and shunt equipment


> Is := Re(Series[.., 1]):
Js := Re(Series[.., 2]):
Ish := Re(Shunt [.., 1]):

Real power injection (net)


> Pb := P__G - P__L

(3.1)

Reactive power injection (net)


> Qb := -Q__L

(3.2)

Nodal Admittance Matrix


Initialize the nodal admittance matrix.
> Y__bus := Matrix(N_bus, N_bus):

Add series elements to the nodal admittance matric


> for i from 1 to N_ser do
Y__bus[Is[i], Is[i]] := Y__bus[Is[i], Is[i]] + Series[i, 4] +
1/Series[i, 3];
Y__bus[Is[i], Js[i]] := Y__bus[Is[i], Js[i]] - 1/Series[i, 3];
Y__bus[Js[i], Is[i]] := Y__bus[Js[i], Is[i]] - 1/Series[i, 3];
Y__bus[Js[i], Js[i]] := Y__bus[Js[i], Js[i]] + Series[i, 4] +
1/Series[i, 3];
end do:
Y__bus
(4.1)

Add shunt elements


> for i from 1 to N_sh do
Y__bus[Is[i], Is[i]] := Y__bus[Is[i], Is[i]] + Shunt[i, 2];
Y__bus[Js[i], Js[i]] := Y__bus[Js[i], Js[i]] + Shunt[i, 2];
end do:
Y__bus

(4.2)
(4.2)

Real and Reactive Power Injections


Real power flow function. In the function arguments, k is the bus number, v is the voltage magnitude
and d is the voltage phase.
> P := (k, v, d) -> add(v[k] * v[i] * abs(Y__bus[k, i]) * cos(ifelse
(Y__bus[k, i] <> 0, argument(Y__bus[k, i]), 0) + d[i] - d[k]),i =
1..N_bus):
Warning, (in P) `i` is implicitly declared local

Reactive power flow function


> Q := (k, v, d) -> -add(v[k] * v[i] * abs(Y__bus[k, i]) * sin
(ifelse(Y__bus[k, i] <> 0, argument(Y__bus[k, i]), 0) + d[i] - d
[k]),i = 1..N_bus):
Warning, (in Q) `i` is implicitly declared local

Solve the Load Flow Equation with fsolve


Generate the real power flow equations.
> real_power_eq := seq(Pb[i] = P(i, v, d), i in {2, 3, 4, 5})
(6.1)

Generate the reactive power flow equations


> reactive_power_eq := seq(Qb[i] = Q(i, v, d), i in {2, 4, 5})
(6.2)
(6.2)

v[1], d[1] and v[3] are known values (slack bus and PV-buses) and are substituted into the equation
system
> sys := eval({real_power_eq, reactive_power_eq}, {v[1] = 1.04, d[1]
= 0, v[3] = 1.02})
(6.3)

Numerically solve the real and reactive power flow equations.


> sys := fsolve(sys, {v[2] = 0.961, v[4] = 0.92, v[5] = 0.968, d[2]
= 0, d[3] = 0, d[4] = 0,d[5] = 0}, fulldigits)
(6.4)

Check the correctness of the solution


> eval([real_power_eq, reactive_power_eq],{v[1] = 1.04, d[1] = 0, v
[3] = 1.02} union sys)
(6.5)
(6.5)

Solve the Load Flow Equations with Newton-Raphson Iteration

Form the Jacobian Matrix


> Jac := Matrix(8, 8):
for k from 2 to N_bus do

for n from 2 to N_bus do


Jac[k - 1, n + N_bus - 2] := V[k] * abs(Y__bus[k, n]
) * cos(ifelse(Y__bus[k, n] <> 0, argument(Y__bus[k, n]), 0)) +
delta[n] - delta[k];
Jac[k - 1, k + N_bus - 2] := add(V[i] * abs(Y__bus
[k, i]) * cos(ifelse(Y__bus[k, i] <> 0, argument(Y__bus[k, i]), 0)
) + delta[i] - delta[k], i = 1..N_bus) + V[k] * abs(Y__bus[k, k])
* cos(argument(Y__bus[k, k])):
Jac[k + N_bus - 2, n + N_bus - 2] := -V[k] * abs(Y__bus[k,n]
)* sin(ifelse(Y__bus[k, n] <>0, argument(Y__bus[k, n]), 0)) +
delta[n] - delta[k]:
Jac[k + N_bus - 2, k + N_bus -2 ] := add(-V[i] * abs(Y__bus
[k,i]) * sin(ifelse(Y__bus[k, i] <> 0, argument(Y__bus[k, i]), 0))
+ delta[i] - delta[k], i = 1..N_bus) - V[k] * abs(Y__bus[k, k]) *
sin(argument(Y__bus[k, k])):
Jac[k - 1, n - 1] := -V[k] * V[n] * abs
(Y__bus[k, n]) * sin(ifelse(Y__bus[k, n] <> 0,argument(Y__bus[k,
n]),0)) + delta[i] - delta[k];
Jac[k - 1, k - 1] := add(V[k] * V[i] * abs
(Y__bus[k, i]) * sin(ifelse(Y__bus[k, i] <> 0, argument(Y__bus[k,
i]), 0)) + delta[i] - delta[k], i = 1..N_bus) - V[k]^2 * abs
(Y__bus[k, k]) * sin(argument(Y__bus[k, k]));
Jac[k + N_bus - 2, n - 1] := -V[k] * V[n] * abs
(Y__bus[k, n]) * cos(ifelse(Y__bus[k, n] <> 0, argument(Y__bus[k,
n]), 0) + delta[n] - delta[k]);
Jac[k + N_bus - 2, k - 1] := add(V[k] * V[i] * abs
(Y__bus[k, i]) *cos(ifelse(Y__bus[k, i] <> 0, argument(Y__bus[k,
i]),0) + delta[i] - delta[k]),i = 1..N_bus) - V[k]^2 * abs(Y__bus
[k, k]) * cos(argument(Y__bus[k, k]));

end do:
end do:
> for k from 2 to N_bus do
for n from 2 to N_bus do

Jac[k - 1, n + N_bus - 2] := ifelse(bus_type[n] =


"PV", 0, Jac[k - 1, n + N_bus - 2]);
Jac[k + N_bus - 2, n - 1] := ifelse(bus_type[k] =
"PV", 0, Jac[k + N_bus - 2, n - 1]):
Jac[k + N_bus - 2, n + N_bus - 2] := ifelse(bus_type[k] =
"PV", 0, Jac[k + N_bus - 2, n + N_bus - 2]):
Jac[k + N_bus - 2, n + N_bus - 2] := ifelse(bus_type[n] =
"PV", 0, Jac[k + N_bus - 2, n + N_bus - 2]):
Jac[k + N_bus - 2, k + N_bus - 2] := ifelse(bus_type[k] =
"PV", 1, Jac[k + N_bus - 2, k + N_bus - 2])

end do:
end do:

Hence the complete Jacobian matrix is


> Jac

(7.1.1)

Invert the Jacobian matrix


> Jinv := Jac^(-1)

(7.1.2)

Iterative Solution
Corrections of voltage and phase angle for the new iteration step
> Delta_V := (l, V, delta) -> add(Jinv[l + N_bus - 2, k - 1] * (Pb
[k] - P(k, V, delta)), k = 2..N_bus) + add(Jinv[l + N_bus - 2, k +
N_bus - 2] * ifelse(bus_type[k] = "PV", 0, Qb[k] - Q(k, V, delta)
),k = 2..N_bus)
Warning, (in Delta_V) `k` is implicitly declared local
(7.2.1)

> Delta_delta := (l, V, delta) -> add(Jinv[l - 1, k - 1] * (Pb[k] -


P(k, V, delta)), k = 2..N_bus) + add(Jinv[l - 1, k + N_bus - 2] *
ifelse(bus_type[k] = "PV", 0, Qb[k] - Q(k, V, delta)), k = 2..
N_bus)

(7.2.2)
Warning, (in Delta_delta) `k` is implicitly declared local
(7.2.2)

Maximum number of iterations


> Max_it := 6:

Acceleration coefficient
> lambda := 1:
> for Iter from 1 to Max_it do
for m from 2 to N_bus do
V[m] := V[m] + Delta_V(m, V, delta) * lambda:
delta[m] := delta[m] + Delta_delta(m, V, delta) * lambda:
end do:
end do:

Hence the bus voltage and phase angles are


> V, delta

(7.2.3)

These agree with the values calculated earlier with fsolve.

Analysis of Results
Power mismatch
> epsilon := add((Pb[m] - P(m, V, delta))^2 + ifelse(bus_type[m] =
"PV", 0, (Qb[m] - Q(m, V, delta))^2), m = 2..N_bus)^0.5
(8.1)

Real and reactive power of the slack bus


> Ps := P(1, V, delta) + P__L[1];
Qs := Q(1, V, delta) + Q__L[1]

(8.2)
Line losses for the second line are calculated as follows
> m := 2:
i := Is[m]:
j := Js[m]:
ys := 1/Series[m, 3];
ysh := Series[m, 4];

(8.3)
(8.3)
Power flow from sending to receiving terminal
> Pij := -V[i] * V[j] * abs(ys) * cos(argument(ys) + delta[j] -
delta[i]) + V[i]^2 * abs(ys) * cos(argument(ys)) + (V[i])^2 * abs
(ysh) * cos(argument(ysh))
(8.4)
Power from receiving to sending terminal
> Pji := -V[j] * V[i] * abs(ys) * cos(argument(ys) + delta[i] -
delta[j]) + V[j]^2 * abs(ys) * cos(argument(ys)) + V[j]^2 * abs
(ysh) * cos(argument(ysh))
(8.5)
Real power losses in the second line
> Ploss := Pij + Pji
(8.6)
Reactive power flow from sending to receiving terminal
> Qij := V[i] * V[j] * abs(ys) * sin(argument(ys) + delta[j] - delta
[i]) - V[i]^2 * abs(ys) * sin(argument(ys)) + (V[i])^2 * abs(ysh)
* sin(argument(ysh))
(8.7)
Reactive power flow from receiving to sending terminal
> Qji := V[i] * V[j] * abs(ys) * sin(argument(ys) + delta[i] - delta
[j]) - V[j]^2 * abs(ys) * sin(argument(ys)) + (V[j])^2 * abs(ysh)
* sin(argument(ysh))
(8.8)
Reactive power losses in the second line
> Qloss := Qij + Qji
(8.9)

You might also like