You are on page 1of 19

Simulation and Analysis of Power Systems and Power Electronics in MATLAB

Montreal, lecture 1, Wednesday September 13, 2000

A Power Flow in Matlab


© 1999, 2000 Fernando L. Alvarado
This section describes the development and extension of a basic power flow program in Matlab.
To the extent feasible, complex vector operations are used, even for the calculation of the
Jacobian matrix1.

The problem
The main problem of interest in power system analysis is the solution of the so-called power flow
(or load flow) problem. The assumptions for the basic power flow problem are:
• A passive linear network of admittances describes the transmission grid. The nodal
admittance matrix Y-bus (denoted by Y) characterizes the behavior of the nodal voltages to
nodal current injections. The components of Y are complex numbers of the form
Yij = g ij + jbij . There are n nodes in the network. The dimension of Y is n by n.
• Every node can have active and reactive generation and active and reactive demand, each
represented as a complex number. The complete set of generation injections for the network
is denoted by the vector Sg, and the demands by the vector Sd, each a vector of dimension n.
• Every node (or bus) is classified as either a PV or a PQ node. For a PV node, the voltage
magnitude and the net power injection are fixed, while the generation Q is a variable. For a
PQ node, both the active and reactive net power injections are fixed (either positive or
negative).
• One node (usually a PV node) is designated as the angle reference for all voltages. At least
one node (usually the same PV node) is designated as a node where the net injection P is not
specified but rather determined as a variable. Thus, in this node both voltage magnitude and
angle are known. The node is called the slack node. When multiple nodes are designated as
slack nodes, some means for resolving the uncertainty as to which node picks up the “slack”
is necessary.
The following complex equations must be satisfied at every node in the network, no exceptions:

S g − S d = V i* ( YiV )

where i* denotes element-wise product of two vectors (using Matlab notation), and * as a
superscript denotes the complex conjugate. The dot i denotes the ordinary dot product of a
matrix times a vector.
Since at least one voltage V is known (and possibly many magnitudes of several other voltages),
this means that only a subset of these equations is solved as a simultaneous set. In particular, the
equations that are selected for a simultaneous solution are:
• The real and reactive parts of these equations for all PQ nodes.
• The real-only part of the above equations for all PV nodes excluding the slack.
Likewise, the only variables of immediate interest are:

1
The key idea used for the vectorization of Jacobian computations is based on work by Christopher
DeMarco of the University of Wisconsin.

© 1999 F. Alvarado 1 Power flow


Simulation and Analysis of Power Systems and Power Electronics in MATLAB
Montreal, lecture 1, Wednesday September 13, 2000
• The voltage magnitudes and angles (or real and imaginary parts of the voltages) for all PQ
nodes.
• The voltage angles at all PV nodes.
All other variables (such as Q at PV nodes or P and Q at the slack node) can be determined after
the fact from the above equation.
There are situations where the explicit rectangular form of the power flow equations is more
desirable than the concise complex vectorized version above. For these situations, the following

 
∆Pi = − Pi + | Vi |  ∑ | V j | g ij cos(δ i − δ j ) + ∑ | V j | bij sin(δ i − δ j )
 j∈αˆ i j ∈α i 
 
∆Qi = −Qi + | Vi |  ∑ | V j | g ij sin(δ i − δ j ) − ∑ | V j | bij cos(δ i − δ j )
 j∈α i j∈αˆ i 
is the set of power flow equations of interest:
where gij and boj are the real and imaginary components of the entries of the nodal admittance
matrix, δi is the angle of Vi, αi denotes all neighbors or node i excluding i itself, and α^ i denotes
the neighbors of i including i itself.
In matrix form, these equations can be expressed as:

∆S = S d − S g + V i* ( Y iV )
*

and from here the Jacobian can be determined from:

F I + I .*F dV I
*
dS
d | V| GH JK GH d V JK
= V.*
dI
dV
*

dS F dI I F dV IJ
*

= V.*G J + I .*G
H dδ K H dδ K
*


where:
I = YV

© 1999 F. Alvarado 2 Power flow


Simulation and Analysis of Power Systems and Power Electronics in MATLAB
Montreal, lecture 1, Wednesday September 13, 2000
Building Y-bus (vectorized version)
The following vectorized code builds the Y-bus matrix:
function Ybus=bldybus(S)
% bldybus.m Build the y-bus matrices
Ybus=sparse(S.Bus.n,S.Bus.n);
YL=[];
if isfield(S.Bus,'G'),
YL=S.Bus.G;
end
if isfield(S.Bus,'B'),
YL=YL+i*S.Bus.B;
end
if ~isempty(YL),
Ybus=Ybus+diag(sparse(YL));
end
n=S.Bus.n;
Y11=(1./S.Branch.Z+(i*S.Branch.B)/2).*S.Branch.Status;
Ybus=Ybus+sparse(S.Branch.From,S.Branch.From,Y11,n,n);
Y12=(-1./(S.Branch.TAP.*S.Branch.Z)).*S.Branch.Status;
Ybus=Ybus+sparse(S.Branch.From,S.Branch.To,Y12,n,n);
Y21=(-1./(conj(S.Branch.TAP).*S.Branch.Z)).*S.Branch.Status;
Ybus=Ybus+sparse(S.Branch.To,S.Branch.From,Y21,n,n);
Y22=(1./((abs(S.Branch.TAP).^2).*S.Branch.Z)+(i*S.Branch.B)/2).*S.Branch.Stat
us;
Ybus=Ybus+sparse(S.Branch.To,S.Branch.To,Y22,n,n);
if isfield(S.Branch,'YI'),
Ybus=Ybus+sparse(S.Branch.From,S.Branch.From,S.Branch.YI,n,n);
end
if isfield(S.Branch,'YJ'),
Ybus=Ybus+sparse(S.Branch.To,S.Branch.To,S.Branch.YJ,n,n);
end
if isfield(S,'Shunt'),
Ybus=Ybus+sparse(S.Shunt.I,S.Shunt.I,i*S.Shunt.BINIT,n,n);
end;

The main code


The code to solve the power flow problem is:
function S=mpflow(S)
% Save as mpflow.m file
if nargin<1, S=readcf; end
S.Ybus=bldybus(S); % Build the Y-bus matrix
S.snet= sparse(S.Machine.BusRef,1,S.Machine.MW+j*S.Machine.MVAR,S.Bus.n,1)...
-sparse(S.Load.BusRef,1,S.Load.MW+j*S.Load.MVAR,S.Bus.n,1);
S=pfsolve(S);
if S.mismatch>0.001,
disp('Power flow failed to converge');
else
disp('Power flow solved');
end;

This code is virtually self-explanatory:


• The data are read from the common format file using the readcf.m function. This code is
listed in the appendix. The result of reading this information is stored in several tables: The Z
table contains branch data, the L table contains load data and the A table contains generator
data. In addition, the slack bus(es), generation bus(es) and load bus(es) are identified.

© 1999 F. Alvarado 3 Power flow


Simulation and Analysis of Power Systems and Power Electronics in MATLAB
Montreal, lecture 1, Wednesday September 13, 2000
• The appropriate matrices are constructed using the bldybus.m function, also available as a
p-code file.
• Some data conversion is performed (the solver assumes that net injections are used and does
not distinguish between the positive power delivered to loads and the negative power
delivered by generators).
• The solver is called. It returns the complex voltages at every bus, and also the mismatch or
maximum error.
• The user is given an indication of completion.
The main routine within this code if pfsolve.m. While we have only provided the p-code for
this routine, it is useful to examine a simplified version of this routine:

© 1999 F. Alvarado 4 Power flow


Simulation and Analysis of Power Systems and Power Electronics in MATLAB
Montreal, lecture 1, Wednesday September 13, 2000
function S=pfsolve(S)
% This routine solves the power flow problem using a Newton-Raphson
1 % iteration with full Jacobian update at every iteration.
% Originally developed by Professor Christopher DeMarco, 1997
% and expanded by Fernando Alvarado 1998, 1999
%
% Compute initial mismatch
2 MAXITER=15; n=S.Bus.n;
vbus=S.Bus.Voltages;
S.mismatch = Inf; % pick off largest component of relevant mismatch
% Newton-Raphson Iteration
3 S.itcnt = 0;
while S.mismatch > .0001
10 fullmiss = pfmiss(S); 4
rmiss=[real(fullmiss(S.PVlist));real(fullmiss(S.PQlist)); ...
imag(fullmiss(S.PQlist))];
S.mismatch = max(abs(rmiss)); 6
[dsdd, dsdv] = pflowjac(S.Ybus,vbus);
7
% dsdd and dsdv are composed of all (complex) partial derivatives
% rjac is a selection from these
rjac = [ ...
real(dsdd(S.PVlist,S.PVlist)) real(dsdd(S.PVlist,S.PQlist)) ...
real(dsdv(S.PVlist,S.PQlist)); ...
real(dsdd(S.PQlist,S.PVlist)) real(dsdd(S.PQlist,S.PQlist)) ...
real(dsdv(S.PQlist,S.PQlist)); ...
imag(dsdd(S.PQlist,S.PVlist)) imag(dsdd(S.PQlist,S.PQlist)) ...
imag(dsdv(S.PQlist,S.PQlist)) ];
x=[angle(vbus(S.PVlist))*pi/180;
angle(vbus(S.PQlist))*pi/180;
8 abs(vbus(S.PQlist))];
dx = -rjac\rmiss; % Here is the actual update
5 del=angle(vbus);
vmag=abs(vbus);
n1=length(S.PVlist); n2=n1+length(S.PQlist); n3=length(dx);
del(S.PVlist)=del(S.PVlist)+dx(1:n1);
del(S.PQlist)=del(S.PQlist)+dx((n1+1):n2); 9
vmag(S.PQlist)=vmag(S.PQlist)+dx((n2+1):n3);
vbus=vmag.*exp(j*del);
11 S.itcnt=S.itcnt+1;
if (S.itcnt > MAXITER)|((S.itcnt>3)&(S.mismatch>100)),
S.itcnt=Inf;
break;
end;
end
if (S.itcnt<=MAXITER),
S.Bus.Voltages=vbus;
disp([int2str(S.itcnt) ' iterations']);
end

The following comments apply to this code:


1. The implementation of the idea of using a single vectorized complex computation to obtain a
complex Jacobian matrix from which the real Jacobian is extracted originated with Professor
Christopher DeMarco of the University of Wisconsin in Madison.
2. The input voltages are used as the default value of the output voltages in case the routine
terminates prematurely due to convergence or other difficulties.
3. The norm of the error (mismatch) is used to determine convergence tolerance is the infinite
norm (largest error).

© 1999 F. Alvarado 5 Power flow


Simulation and Analysis of Power Systems and Power Electronics in MATLAB
Montreal, lecture 1, Wednesday September 13, 2000
4. The tolerance for this error is fixed at 0.0001, a suitable value for most applications. Normal
termination is based on the mismatch being smaller that this value.
5. Although most computations are done in complex mode, it is still necessary to have available
vectors with the polar representation of the voltages.
6. This is where the complex version of the complete Jacobian is computed.
7. This is where the real portion of the Jacobian of interest to us is extracted.
8. This is the main computational step: the solution of the simultaneous sparse linear equations.
9. This is where the correction is added to the previous solution value.
10. The mismatch fullmiss is computed for all buses, but only the portion of interest to us
rmiss is extracted.
11. The solution also can terminate by exceeding the maximum allowed number of iterations,.

Extending the power flow


The code above simply solves the basic power flow with no limits and finds the voltages and
angles at every node. After this is done, there are generally a number of additional computations
of interest. Some of these are described next.

Flows and overloads


The real objective of solving a power flow is quite often to find the individual line flows in the
network, and most particularly, to find whether there are any overloaded lines under the presumed
conditions. While developing the code for doing this computation using for and while loops is
straightforward. This section illustrates how to write this code in a vectorized manner. The
following code determines and displays every flow in every line in the network, identifies any
overloads, and displays a list of overloaded lines.
function [Sflow,iOvld]=flows(S)
% Calculate all the line flows and report overloads
Vf=S.Bus.Voltages;
Sflow=(Vf(S.Branch.From,1)-Vf(S.Branch.To,1))./S.Branch.Z+ ...
Vf(S.Branch.From,1).*(j*S.Branch.B/2);
iOvld=find((S.Branch.Status.*abs(Sflow))>S.Branch.RateValue);

The following comments apply to this code:


1. The computations of all flows is done is one single vectorized line of code.
2. An even better way to do this is to use the concept of the flow admittance matrix Yflow (not
illustrated).
3. The find function finds all overloads in a vectorized manner.

Penalty factors
The following code illustrates the construction of the loss penalty factors in accordance with the
Transposed Jacobian method (Alvarado 1979):

© 1999 F. Alvarado 6 Power flow


Simulation and Analysis of Power Systems and Power Electronics in MATLAB
Montreal, lecture 1, Wednesday September 13, 2000
Function beta=penalty(S)
% Construct the penalty factors
[dSdd,dSdv]=pflowjac(S.Ybus,S.Bus.Voltages);
Jac=[real(dSdd) real(dSdv); imag(dSdd) imag(dSdv)];
[n1,n2]=size(Jac);
Jacr=Jac(2:n1,2:n2); % Assuming the slack bus is bus 1
rhs=-Jac(1,2:n2)';
beta=[1; Jacr'\rhs];
disp('Beta');
disp(full(reshape(beta,n2/2,2)));

The following comments apply to this code:


1. The same Jacobian computation routine as in the power flow is used. In fact, it is possible to
save this Jacobian re-computation and just use the last Jacobian from the solution itself.
2. As before, real and imaginary parts of this complex Jacobian are extracted. Unlike the
previous case, however, all entries of the Jacobian are used. This assumes that no buses are
holding voltage constant.
3. The slack bus row and column are then excluded. In this simple version, the slack bus must
be node 1.
4. The right hand side corresponds to the row of the omitted slack bus active power.
5. The solution involves the use of the transposed reduced Jacobian.
6. The reshape function permits a more elegant display of the computed beta inverse penalty
factors.

© 1999 F. Alvarado 7 Power flow


Simulation and Analysis of Power Systems and Power Electronics in MATLAB
Montreal, lecture 1, Wednesday September 13, 2000

Using the power flow


We now illustrate the use of the above code to solve several simple power flow cases. Consider
the case illustrated below, from Wood and Wollenberg:

Bus3
Bus2

Bus6
Bus1
Bus5

Bus4
The common format data for this case is (save it as 6bus.cf):
Wood and Wollenberg test case
BUS DATA FOLLOWS
1 BUS1 1 1 3 1.0500 0.00 0.00 0.00 100.00 .00 100.00
2 BUS2 1 1 2 1.0500 0.00 0.00 0.00 50.00 .00 100.00
3 BUS3 1 1 2 1.0700 0.00 0.00 0.00 60.00 .00 100.00
4 BUS4 1 1 0 1.0000 0.00 70.00 70.00 .00
5 BUS5 1 1 0 1.0000 0.00 70.00 70.00 .00
6 BUS6 1 1 0 1.0000 0.00 70.00 70.00 .00
-999
BRANCH DATA FOLLOWS
1 2 1 1 1 0 .100000 .200000 .020000 100
1 4 1 1 1 0 .050000 .200000 .020000 100
1 5 1 1 1 0 .080000 .300000 .030000 100
2 3 1 1 1 0 .050000 .250000 .030000 100
2 4 1 1 1 0 .050000 .100000 .010000 100
2 5 1 1 1 0 .100000 .300000 .020000 100
2 6 1 1 1 0 .070000 .200000 .025000 100
3 5 1 1 1 0 .120000 .260000 .025000 100
3 6 1 1 1 0 .020000 .100000 .010000 100
4 5 1 1 1 0 .200000 .400000 .040000 100
5 6 1 1 1 0 .100000 .300000 .030000 100
-999
INTERCHANGE DATA FOLLOWS
-9
TIE LINE DATA FOLLOWS
-999
LOSS ZONE DATA FOLLOWS
-99
END OF DATA

Because of width restrictions, the “desired voltage” field generally supplied with PV type buses
has been excluded in the above data. However, the desired voltage magnitude for these buses is

© 1999 F. Alvarado 8 Power flow


Simulation and Analysis of Power Systems and Power Electronics in MATLAB
Montreal, lecture 1, Wednesday September 13, 2000
listed in the voltage magnitude field. Execution of the above power flow with this data as input
yields the following:
» fname='6bus';
» mpflow;
mpflow (c)1997 F. Alvarado and C. DeMarco
2 iterations
Power flow solved
» mis
mis =
1.4496e-006
» VV
VV =
(1,1) 1.0500
(2,1) 1.0478- 0.0682i
(3,1) 1.0669- 0.0809i
(4,1) 0.9838- 0.0719i
(5,1) 0.9756- 0.0892i
(6,1) 0.9960- 0.1042i
» rect2pol(VV)
ans =
(1,1) 1.0500
(2,1) 1.0500- 3.7248i
(3,1) 1.0700- 4.3340i
(4,1) 0.9864- 4.1788i
(5,1) 0.9797- 5.2240i
(6,1) 1.0014- 5.9705i

The following comments apply:


1. The output from the code is minimal. The final mismatch and the VV output had to be
manually extracted after the solution ended.
2. The final mismatch is quite small.
3. The rect2pol function gives the output as complex numbers, but the interpretation is that
the real part of the numbers is the magnitude of VV and the imaginary part is the angle in
degrees.
If, in addition, we execute the flows.m script:
» flows
Flows:
1 2 0.2773 0.1381 -1.0000 0.3098 1.0000
1 4 0.4161 -0.2164 -1.0000 0.4691 1.0000
1 5 0.3393 -0.1418 -1.0000 0.3678 1.0000
2 3 0.0349 0.0991 -1.0000 0.1051 1.0000
2 4 0.2856 -0.4919 -1.0000 0.5688 1.0000
2 5 0.1358 -0.1851 -1.0000 0.2296 1.0000
2 6 0.2417 -0.1615 -1.0000 0.2907 1.0000
3 5 0.1611 -0.2641 -1.0000 0.3094 1.0000
3 6 0.3609 -0.6319 -1.0000 0.7277 1.0000
4 5 0.0443 0.0206 -1.0000 0.0488 1.0000
5 6 0.0258 0.0908 -1.0000 0.0944 1.0000
Overloaded lines:
None

The columns here correspond to: the terminal nodes, the active and reactive flows, the minimum
limit, the flow, and the maximum limit. There are no overloaded lines in this case.
And if, in addition, we execute the penalty.m script we obtain:

© 1999 F. Alvarado 9 Power flow


Simulation and Analysis of Power Systems and Power Electronics in MATLAB
Montreal, lecture 1, Wednesday September 13, 2000
» penalty
Beta
1.0000 -0.1590
1.0154 -0.1777
1.0188 -0.1792
1.0289 -0.1460
1.0331 -0.1504
1.0264 -0.1702

The first column entries are the inverses of the penalty factors for the active powers at every node
in the network. The second column entries are the corresponding factors for the reactive powers.

The Fast Decoupled power flow


Approximations to the Jacobian slow down convergence, but do not change the solution. The
Fast Decoupled power flow uses the same mismatch equations, but approximates the Jacobian in
several ways:
• Conductances G are neglected.
• Voltage magnitudes are assumed to be 1pu.
• Voltage angles are small. Terms containing cosines are replaced by 1, terms containing sines
are set to zero.
The result of these approximations is a Jacobian that is decoupled, requires no trigonometric
computations, and remains constant from iteration to iteration.

The DC load flow


Approximations to the energy balance (or mismatch) equations do alter the solution. However,
there are many cases where a fast, non-iterative linear solution is adequate for estimation
purposes. In these cases, the “DC power flow” can be used. The same approximations as for the
Fast Decoupled power flow are used, but these approximations are applied to the mismatch
equations. The end result is that since all voltages are assumed to be unity, the only quantities
that remains to be estimated are the angles. These can be estimated from:
P = Bθ
Here B refers to the imaginary part of the Y-bus matrix. Solving for θ requires a single linear
solution. Once the angles are known, the flows (or the changes in flows) can be estimated. The
DC power flow is not particularly accurate, but it is being used in many aspects of the deregulated
electric power industry because of its linear non-iterative behavior.

Exercises
1. Create a front end for the power flow that allows you to remove any line and re-run the power
flow conveniently, and determine any overloads in the new case.
2. Add code to the flows.m script to display the overloads as a sorted list, largest percentage
overload first. Use the absolute values of the flow currents at either end.
3. Modify the code to calculate the Q injections at PV nodes, and to change these nodes to PQ
type if a limit is encountered.
4. Assuming all generator costs are the same and that there are no limits to any generator (other
than perhaps a minimum of zero), use the penalty factors above to re-dispatch generation to
minimize operating costs by minimizing system losses. The voltage at the slack generator

© 1999 F. Alvarado 10 Power flow


Simulation and Analysis of Power Systems and Power Electronics in MATLAB
Montreal, lecture 1, Wednesday September 13, 2000
must stay at 1pu. Hint: this will occur when the penalty factors for all the Qs are zero, and
the penalty factors for all the Ps are unity.
5. Write a script using the above code to determine the maximum increase possible in the
demands in the network before an overload occurs. Assume that for every MW of demand
increase in the load there is a corresponding MW increase in the supply, which is distributed
among the generators in direct proportion to their size. Increase only the P component of
every demand, in direct proportion to their size. Report the total system demand value at
which the overload occurs.

© 1999 F. Alvarado 11 Power flow


Simulation and Analysis of Power Systems and Power Electronics in MATLAB
Montreal, lecture 1, Wednesday September 13, 2000

Appendix A: Supporting routines


This appendix lists sufficient versions of the necessary supporting routines, without commentary.
The following code computes the mismatch:
function nmiss = pfmiss(S)
% Form the vector of complex power mismatches.
% Usage: nmiss = pfmiss(Y,vb,s_net_inject)
% Arguments: complex bus admittance matrix, Y;
% vector of complex bus voltage phasors, vb;
% vector of complex bus power demand (net),
% S.snet; (note that s_net_inject will be
% negative at buses demanding power)
% Returns: a full complex n-vector of power mismatches.
% Power LEAVING the bus is positive
% Comments: Note that we return ALL mismatches at EVERY bus.
ib=S.Ybus*S.Bus.Voltages;
nmiss = S.Bus.Voltages.*conj(ib)-S.snet;

The following code computes the Jacobian:


function [dSdd,dSdv] = pflowjac(Y,vb)
% Construct the power flow Jacobian matrix in complex form
% Usage: [dSdd,dSdv] = pflowjac(Y,vb)
% Arguments: complex bus admittance matrix, Y;
% vector of complex bus voltage phasors, vb.
% Returns: Two full, complex nxn matrices of partial derivatives;
% dSdd = partial of complex power w.r.t. delta;
% dSdv = partial of complex power w.r.t. voltage magnitude.
% Comments: We return ALL the partial derivatives of power absorbed at EVERY
% bus with respect to EVERY voltage magnitude and phase angle.
% The operation of this routine is transparent if one recognizes that:
% S = diag(vb)*conj(ib) = diag(conj(ib))*vb;
% hence:
% dS/d(delta) = diag(vb)*conj(d(ib)/d(delta))+diag(conj(ib))*d(vb)/d(delta)
% dS/d(vmag) = diag(vb)*conj(d(ib)/d(vmag))+diag(conj(ib))*d(vb)/d(vmag)
% This routine was developed by Chris DeMarco of the University of Wisconsin
ib=Y*vb;
dSdd=j*diag(conj(ib).*vb)-j*diag(vb)*conj(Y)*diag(conj(vb));
dSdv=diag(conj(ib).*(vb./abs(vb)))+diag(vb)*conj(Y)*diag(conj(vb)./abs(vb));

© 1999 F. Alvarado 12 Power flow


Simulation and Analysis of Power Systems and Power Electronics in MATLAB
Montreal, lecture 1, Wednesday September 13, 2000

The following code is a utility function scanint.m:


function i=scanint(s,beg,last,default),
% Function to read an integer from a designated field
if nargin<4, default=0; end;
i=default;
[dummy,ns]=size(s);
if ns<beg, return; end;
if last<beg, return; end;
last=min(last,ns);
if isspace(s(beg:last)), return; end;
i=sscanf(s(beg:last),'%d');
return;

The following is the code for scanreal.m:


function i=scanreal(s,beg,last,default),
% Function to read a real from a designated field
if nargin<4, default=0; end;
i=default;
[dummy,ns]=size(s);
if ns<beg, return; end;
if last<beg, return; end;
last=min(last,ns);
if isspace(s(beg:last)), return; end;
i=sscanf(s(beg:last),'%f');
return;

The next portion of code is the code necessary to read a common format file into a structure:
function S=readcf(fname)
% readcf.m
% Read the common format file and create a data dictionary structure
if nargin<1, [fname,pname]=uigetfile('*.cf'); fname=[pname fname]; end
S.Misc.BaseMVA=100;
fcf=fopen(fname,'r'); % Open common format file
s=fgetl(fcf);
while strcmp(s(1:min(3,length(s))),'BUS')~=1, % Find the start of bus data
s=fgetl(fcf);
end
s=fgetl(fcf);
while s(1)=='%', s=fgetl(fcf); end;
nL=0; ng=0; n=0;
S.PQlist=[]; S.SlackList=[]; S.BlackList=[]; S.PVlist=[];
S.Bus.Voltages=sparse(n,1);
S.Interch.I=[];
S.Interch.areaCount=zeros(100,1);
while strcmp(s(1:4),'-999')~=1,
n=n+1;
Pg=scanreal(s,59,67);
Qg=scanreal(s,68,75);
Pd=scanreal(s,41,49);
Qd=scanreal(s,50,58);
S.Bus.busType(n,1)=sscanf(s(26),'%d');
if (s(26)=='1') | (s(26)=='2') | (s(26)=='3')
if s(26)=='3', S.SlackList=[S.SlackList n];
else, S.PVlist=[S.PVlist n];
end;
else
S.PQlist=[S.PQlist n];
end;
bus=scanint(s,1,5);
S.Bus.Number(n,1)=bus;

© 1999 F. Alvarado 13 Power flow


Simulation and Analysis of Power Systems and Power Electronics in MATLAB
Montreal, lecture 1, Wednesday September 13, 2000
S.Bus.Name{n}=s(6:17);
S.newBus(bus)=n;
S.Machine.newGen(bus,1)=0;
if (Pg~=0) | (Qg~=0) | (s(26)=='3') | (s(26)=='2'),
ng=ng+1;
S.Machine.newGen(bus,1)=ng;
S.Machine.BusRef(ng,1)=bus; % Generation bus number
S.Machine.MW(ng,1)=Pg/S.Misc.BaseMVA; % Active Power Generation (actual)
S.Machine.MVAR(ng,1)=Qg/S.Misc.BaseMVA; % Reactive Power Generation
S.Machine.Status(ng,1)=1;
end
if (Pd~=0) | (Qd~=0),
nL=nL+1;
newLoad(bus,1)=nL;
S.Load.BusRef(nL,1)=bus; % Load bus number
S.Load.MW(nL,1)=Pd/S.Misc.BaseMVA; % Net active power load
S.Load.MVAR(nL,1)=Qd/S.Misc.BaseMVA; % Net reactive power load
S.Load.Status(nL,1)=1;
end;
S.Bus.Generation(n,1)=(Pg+j*Qg)/S.Misc.BaseMVA;
S.Bus.Load(n,1)=(Pd+j*Qd)/S.Misc.BaseMVA;
S.Bus.Voltages(n,1)=scanreal(s,28,33,1)* ...
exp(sqrt(-1)*scanreal(s,34,40)*pi/180);
S.Bus.area(n,1)=sscanf(s(19:20),'%d'); % Now this is numeric, +1
S.Bus.Zone(n,:)=s(21:23);
S.Bus.KV(n,1)=scanreal(s,77,83);
if S.Machine.newGen(bus),
S.Machine.MinOperatingVolt(ng,1)=scanreal(s,85,90);
S.Machine.MaxOperatingVolt(ng,1)=scanreal(s,85,90);
S.Machine.MaxQOutput(ng,1)=scanreal(s,91,98)/S.Misc.BaseMVA;
S.Machine.MinQOutput(ng,1)=scanreal(s,99,106)/S.Misc.BaseMVA;
S.Machine.ControlledBusRef(ng,1)=scanreal(s,124,128);
end
S.Bus.G(n,1)=scanreal(s,107,114);
S.Bus.B(n,1)=scanreal(s,115,122);
s=fgetl(fcf);
while s(1)=='%', s=fgetl(fcf); end;
end;
minArea=min(S.Bus.area);
dArea=1-minArea;
S.Interch.areaCount=sparse(S.Bus.area+dArea,1,1);

while ~strcmp(s(1:3),'BRA'), s=fgetl(fcf); end


s=fgetl(fcf);
while s(1)=='%', s=fgetl(fcf); end;
nn=0;
while ~strcmp(s(1:4),'-999'),
nn=nn+1;
S.Branch.To(nn,1)=S.newBus(scanint(s,1,5));
S.Branch.From(nn,1)=S.newBus(scanint(s,6,10));
R=scanreal(s,20,29); % Resistance
X=scanreal(s,30,40); % Reactance
S.Branch.Z(nn,1)=R+j*X;
S.Branch.B(nn,1)=scanreal(s,41,49); % Line Charging
S.Branch.RateValue(nn,1)=scanreal(s,51,55)/S.Misc.BaseMVA;
S.Branch.Type(nn,1)=scanint(s,19,19); % Type
if S.Branch.Type(nn,1), % If dealing with a transformer
tap=scanreal(s,77,82);
alpha=scanreal(s,84,90)*pi/180;
S.Branch.TAP(nn,1)=tap.*exp(j*alpha);
else
S.Branch.TAP(nn,1)=1;
end;

© 1999 F. Alvarado 14 Power flow


Simulation and Analysis of Power Systems and Power Electronics in MATLAB
Montreal, lecture 1, Wednesday September 13, 2000
s=fgetl(fcf); % Next line
while s(1)=='%', s=fgetl(fcf); end; % Skip comments
end
S.Branch.YI=zeros(nn,1);
S.Branch.YJ=zeros(nn,1);
S.Branch.Status=ones(nn,1);
kzero=find(S.Branch.RateValue==0); % No zero ratings permitted
S.Branch.RateValue(kzero)=Inf;

while ~strcmp(s(1:3),'INT'),
s=fgetl(fcf);
end
s=fgetl(fcf);
while s(1)=='%', s=fgetl(fcf); end;
nInterch=0;
while ~strcmp(s(1:2),'-9'),
nInterch=nInterch+1;
S.Interch.I(nInterch,1)=scanint(s,1,2);
S.Interch.ControlGenRef(nInterch,1)=scanint(s,3,7);
S.Interch.SchedNetMW(nInterch,1)=scanreal(s,21,29)/S.Misc.BaseMVA;
s=fgetl(fcf);
while s(1)=='%', s=fgetl(fcf); end;
end
fclose(fcf);
S.Machine.BusRef=S.newBus(S.Machine.BusRef)'; % Use internal bus numbers
S.Load.BusRef=S.newBus(S.Load.BusRef)'; % "
ky=find(S.Machine.ControlledBusRef); % "
kx=S.Machine.ControlledBusRef(ky);
S.Machine.ControlledBusRef(ky)=S.newBus(kx);
S.Bus.n=length(S.Bus.Voltages);
S.Branch.nn=length(S.Branch.From);
S.Bus.area=S.Bus.area+dArea;

© 1999 F. Alvarado 15 Power flow


Simulation and Analysis of Power Systems and Power Electronics in MATLAB
Montreal, lecture 1, Wednesday September 13, 2000

Appendix B: Brief description of the common format for solved power flow
data interchange

Taken from “Common Data Format for the Exchange of Solved Load Flow Data,” Working
Group on a Common Format for the Exchange of Solved Load Flow Data, _IEEE Transactions
on Power Apparatus and Systems, Vol. PAS-92, No. 6, November/December 1973, pp. 1916-
1925. Only the “tape” format (with lines of up to 128 characters) is described here.
The data is organized into sections with section headers and terminated with numeric flags
(usually –9 or –999). Data items are entered in specific columns. Mandatory items are indicated.
No blank items are allowed for mandatory items (note: most program will, nevertheless, default
some blank items). Floating point items should have explicit decimal point. No implicit decimal
points are used.
Data type codes:
A - Alphanumeric (no special characters)
I – Integer
F - Floating point
* - Mandatory item
TAPE
First line is the title, it also contains the Base MVA, usually 100
BUS DATA FOLLOWS
Columns 1- 4 Bus number (I) *
Columns 7-17 Name (A) (left justified) *
Columns 19-20 Load flow area number (I) Don't use zero! *
Columns 21-23 Loss zone number (I)
Columns 25-26 Type (I) *
0 - Unregulated (load, PQ)
1 - Hold MVAR generation within voltage limits, (PQ)
2 - Hold voltage within VAR limits (gen, PV)
3 - Hold voltage and angle (swing, V-Theta)
Columns 28-33 Final voltage magnitude, p.u. (F) *
Columns 34-40 Final angle, degrees (F) *
Columns 41-49 Load MW (F) *
Columns 50-59 Load MVAR (F) *
Columns 60-67 Generation MW (F) *
Columns 68-75 Generation MVAR (F) *
Columns 77-83 Base KV (F)
Columns 85-90 Desired volts (pu) (F)
Columns 91-98 Maximum MVAR or voltage limit (F)
Columns 99-106 Minimum MVAR or voltage limit (F)
Columns 107-114 Shunt conductance G (per unit) (F) *
Columns 115-122 Shunt susceptance B (per unit) (F) *
Columns 124-127 Remote controlled bus number
–999
BRANCH DATA FOLLOWS
Columns 1- 4 Tap bus number (I) *
For transformers or phase shifters, the non-unity tap side
Columns 6- 9 Z bus number (I) *
For transformers and phase shifters, the device impedance side.
Columns 11-12 Load flow area (I)
Columns 13-14 Loss zone (I)
Column 17 Circuit (I) * (Use 1 for single lines)
Column 19 Type (I) *
0 - Transmission line
1 - Fixed tap
2 - Variable tap for voltage control (TCUL, LTC)
3 - Variable tap (turns ratio) for MVAR control
4 - Variable phase angle for MW control (phase shifter)

© 1999 F. Alvarado 16 Power flow


Simulation and Analysis of Power Systems and Power Electronics in MATLAB
Montreal, lecture 1, Wednesday September 13, 2000
Columns 20-29 Branch resistance R, per unit (F) *
Columns 30-40 Branch reactance X, per unit (F) * No zero impedance lines
Columns 41-50 Line charging B, per unit (F) * (total line charging, +B)
Columns 51-55 Line MVA rating No 1 (I) Left justify!
Columns 57-61 Line MVA rating No 2 (I) Left justify!
Columns 63-67 Line MVA rating No 3 (I) Left justify!
Columns 69-72 Control bus number
Column 74 Side (I)
0 - Controlled bus is one of the terminals
1 - Controlled bus is near the tap side
2 - Controlled bus is near the impedance side (Z bus)
Columns 77-82 Transformer final turns ratio (F)
Columns 84-90 Transformer (phase shifter) final angle (F)
Columns 91-97 Minimum tap or phase shift (F)
Columns 98-104 Maximum tap or phase shift (F)
Columns 106-111 Step size (F)
Columns 113-119 Minimum voltage, MVAR or MW limit (F)
Columns 120-126 Maximum voltage, MVAR or MW limit (F)
-999
LOSS ZONES FOLLOWS
Columns 1- 3 Loss zone number (I)
Columns 5-16 Loss zone name (A)
-99
INTERCHANGE DATA FOLLOWS
Columns 1- 2 Area number (I) no zeros! *
Columns 4- 7 Interchange slack bus number (I) *
Columns 9-20 Alternate swing bus name (A)
Columns 21-28 Area interchange export, MW (F) (+ = out) *
Columns 30-35 Area interchange tolerance, MW (F) *
Columns 38-43 Area code (abbreviated name) (A) *
Columns 46-75 Area name (A)
-9
TIE LINES FOLLOW
Columns 1- 4 Metered bus number (I)
Columns 7-8 Metered area number (I)
Columns 11-14 Non-metered bus number (I)
Columns 17-18 Non-metered area number (I)
Column 21 Circuit number
–999

© 1999 F. Alvarado 17 Power flow


Simulation and Analysis of Power Systems and Power Electronics in MATLAB
Montreal, lecture 1, Wednesday September 13, 2000

Appendix D: Sample data for a 30 bus system


04/16/97 EE 456 100.0 1961 W EE 456 30 Bus Test Case
BUS DATA FOLLOWS 30 ITEMS
1 Glen Lyn 132 1 1 3 1.0700 0.00 0.00 0.00 170.60 3.45 0.0 1.0700 0.00 0.00 0.0 0.0000 1
2 Claytor 132 1 1 2 1.0500 -3.19 21.70 12.70 40.00 -8.26 0.0 1.0500 40.00 -10.00 0.0 0.0000 2
3 Kumis 132 1 1 0 1.0402 -5.03 2.40 1.20 0.00 0.00 0.0 0.0000 0.00 0.00 0.0 0.0000 0
4 Hancock 132 1 1 0 1.0328 -6.17 7.60 1.60 0.00 0.00 0.0 0.0000 0.00 0.00 0.0 0.0000 0
5 Fieldale 132 1 1 2 1.0500 -8.87 94.20 19.00 40.00 44.83 0.0 1.0500 900.00 -900.00 0.0 0.0000 5
6 Roanoke 132 1 1 0 1.0380 -7.19 0.00 0.00 0.00 0.00 0.0 0.0000 0.00 0.00 0.0 0.0000 0
7 Blaine 132 1 1 0 1.0354 -8.36 22.80 10.90 0.00 0.00 0.0 0.0000 0.00 0.00 0.0 0.0000 0
8 Reusens 132 1 1 2 1.0500 -7.28 30.00 30.00 40.00 61.48 0.0 1.0500 900.00 -900.00 0.0 0.0000 8
9 Roanoke 1.0 1 1 0 1.0501 -10.25 0.00 0.00 0.00 0.00 0.0 0.0000 0.00 0.00 0.0 0.0000 0
10 Roanoke 33 1 1 0 1.0454 -11.89 5.80 2.00 0.00 0.00 0.0 0.0000 0.00 0.00 0.0 0.1900 0
11 Roanoke 11 1 1 2 1.0501 -10.25 0.00 0.00 0.00 0.00 0.0 1.0820 0.00 0.00 0.0 0.0000 11
12 Hancock 33 1 1 0 1.0559 -11.40 11.20 7.50 0.00 0.00 0.0 0.0000 0.00 0.00 0.0 0.0000 0
13 Hancock 11 1 1 2 1.0559 -11.40 0.00 0.00 0.00 0.00 0.0 1.0710 0.00 0.00 0.0 0.0000 13
14 Bus 14 33 1 1 0 1.0416 -12.25 6.20 1.60 0.00 0.00 0.0 0.0000 0.00 0.00 0.0 0.0000 0
15 Bus 15 33 1 1 0 1.0377 -12.32 8.20 2.50 0.00 0.00 0.0 0.0000 0.00 0.00 0.0 0.0000 0
16 Bus 16 33 1 1 0 1.0440 -11.87 3.50 1.80 0.00 0.00 0.0 0.0000 0.00 0.00 0.0 0.0000 0
17 Bus 17 33 1 1 0 1.0399 -12.09 9.00 5.80 0.00 0.00 0.0 0.0000 0.00 0.00 0.0 0.0000 0
18 Bus 18 33 1 1 0 1.0283 -12.86 3.20 0.90 0.00 0.00 0.0 0.0000 0.00 0.00 0.0 0.0000 0
19 Bus 19 33 1 1 0 1.0258 -12.99 9.50 3.40 0.00 0.00 0.0 0.0000 0.00 0.00 0.0 0.0000 0
20 Bus 20 33 1 1 0 1.0299 -12.77 2.20 0.70 0.00 0.00 0.0 0.0000 0.00 0.00 0.0 0.0000 0
21 Bus 21 33 1 1 0 1.0339 -12.33 17.50 11.20 0.00 0.00 0.0 0.0000 0.00 0.00 0.0 0.0000 0
22 Bus 22 33 1 1 0 1.0347 -12.32 0.00 0.00 0.00 0.00 0.0 0.0000 0.00 0.00 0.0 0.0000 0
23 Bus 23 33 1 1 0 1.0294 -12.64 3.20 1.60 0.00 0.00 0.0 0.0000 0.00 0.00 0.0 0.0000 0
24 Bus 24 33 1 1 0 1.0267 -12.72 8.70 6.70 0.00 0.00 0.0 0.0000 0.00 0.00 0.0 0.0430 0
25 Bus 25 33 1 1 0 1.0327 -12.23 0.00 0.00 0.00 0.00 0.0 0.0000 0.00 0.00 0.0 0.0000 0
26 Bus 26 33 1 1 0 1.0152 -12.64 3.50 2.30 0.00 0.00 0.0 0.0000 0.00 0.00 0.0 0.0000 0
27 Cloverdle 33 1 1 0 1.0448 -11.67 0.00 0.00 0.00 0.00 0.0 0.0000 0.00 0.00 0.0 0.0000 0
28 Cloverdle132 1 1 0 1.0362 -7.65 0.00 0.00 0.00 0.00 0.0 0.0000 0.00 0.00 0.0 0.0000 0
29 Bus 29 33 1 1 0 1.0254 -12.85 2.40 0.90 0.00 0.00 0.0 0.0000 0.00 0.00 0.0 0.0000 0
30 Bus 30 33 1 1 0 1.0143 -13.69 10.60 1.90 0.00 0.00 0.0 0.0000 0.00 0.00 0.0 0.0000 0
-999
BRANCH DATA FOLLOWS 42 ITEMS
1 2 1 1 1 0 0.038400 0.115000 0.026400 125 137 0 0 0 0.0000 0.0 0.0000 0.0000 0.0000 0.0 0.0
1 2 1 1 1 0 0.038400 0.115000 0.026400 125 137 0 0 0 0.0000 0.0 0.0000 0.0000 0.0000 0.0 0.0
1 3 1 1 1 0 0.045200 0.165200 0.040800 85 90 0 0 0 0.0000 0.0 0.0000 0.0000 0.0000 0.0 0.0
2 4 1 1 1 0 0.057000 0.173700 0.036800 70 75 0 0 0 0.0000 0.0 0.0000 0.0000 0.0000 0.0 0.0
3 4 1 1 1 0 0.013200 0.037900 0.008400 85 90 0 0 0 0.0000 0.0 0.0000 0.0000 0.0000 0.0 0.0
2 5 1 1 1 0 0.047200 0.198300 0.041800 70 75 0 0 0 0.0000 0.0 0.0000 0.0000 0.0000 0.0 0.0
2 6 1 1 1 0 0.058100 0.176300 0.037400 70 75 0 0 0 0.0000 0.0 0.0000 0.0000 0.0000 0.0 0.0
4 6 1 1 1 0 0.011900 0.041400 0.009000 85 90 0 0 0 0.0000 0.0 0.0000 0.0000 0.0000 0.0 0.0
5 7 1 1 1 0 0.046000 0.116000 0.020400 70 75 0 0 0 0.0000 0.0 0.0000 0.0000 0.0000 0.0 0.0

© 1999 F. Alvarado 18 Power flow


Simulation and Analysis of Power Systems and Power Electronics in MATLAB
Montreal, lecture 1, Wednesday September 13, 2000

6 7 1 1 1 0 0.026700 0.082000 0.017000 85 90 0 0 0 0.0000 0.0 0.0000 0.0000 0.0000 0.0 0.0
6 8 1 1 1 0 0.012000 0.042000 0.009000 45 50 0 0 0 0.0000 0.0 0.0000 0.0000 0.0000 0.0 0.0
6 9 1 1 1 1 0.000000 0.208000 0.000000 65 70 0 0 0 0.9780 0.0 0.0000 0.0000 0.0000 0.0 0.0
6 10 1 1 1 0 0.000000 0.556000 0.000000 45 50 0 0 0 0.0000 0.0 0.0000 0.0000 0.0000 0.0 0.0
9 11 1 1 1 1 0.000000 0.208000 0.000000 0 0 0 0 0 1.0000 0.0 0.0000 0.0000 0.0000 0.0 0.0
9 10 1 1 1 1 0.000000 0.110000 0.000000 65 70 0 0 0 1.0000 0.0 0.0000 0.0000 0.0000 0.0 0.0
4 12 1 1 1 1 0.000000 0.256000 0.000000 65 70 0 0 0 0.9320 0.0 0.0000 0.0000 0.0000 0.0 0.0
12 13 1 1 1 1 0.000000 0.140000 0.000000 0 0 0 0 0 1.0000 0.0 0.0000 0.0000 0.0000 0.0 0.0
12 14 1 1 1 0 0.123100 0.255900 0.000000 30 33 0 0 0 0.0000 0.0 0.0000 0.0000 0.0000 0.0 0.0
12 15 1 1 1 0 0.066200 0.130400 0.000000 30 33 0 0 0 0.0000 0.0 0.0000 0.0000 0.0000 0.0 0.0
12 16 1 1 1 0 0.094500 0.198700 0.000000 30 33 0 0 0 0.0000 0.0 0.0000 0.0000 0.0000 0.0 0.0
14 15 1 1 1 0 0.221000 0.199700 0.000000 30 33 0 0 0 0.0000 0.0 0.0000 0.0000 0.0000 0.0 0.0
16 17 1 1 1 0 0.052400 0.192300 0.000000 30 33 0 0 0 0.0000 0.0 0.0000 0.0000 0.0000 0.0 0.0
15 18 1 1 1 0 0.107300 0.218500 0.000000 30 33 0 0 0 0.0000 0.0 0.0000 0.0000 0.0000 0.0 0.0
18 19 1 1 1 0 0.063900 0.129200 0.000000 30 33 0 0 0 0.0000 0.0 0.0000 0.0000 0.0000 0.0 0.0
19 20 1 1 1 0 0.034000 0.068000 0.000000 30 33 0 0 0 0.0000 0.0 0.0000 0.0000 0.0000 0.0 0.0
10 20 1 1 1 0 0.093600 0.209000 0.000000 30 33 0 0 0 0.0000 0.0 0.0000 0.0000 0.0000 0.0 0.0
10 17 1 1 1 0 0.032400 0.084500 0.000000 30 33 0 0 0 0.0000 0.0 0.0000 0.0000 0.0000 0.0 0.0
10 21 1 1 1 0 0.034800 0.074900 0.000000 30 33 0 0 0 0.0000 0.0 0.0000 0.0000 0.0000 0.0 0.0
10 22 1 1 1 0 0.072700 0.149900 0.000000 30 33 0 0 0 0.0000 0.0 0.0000 0.0000 0.0000 0.0 0.0
21 22 1 1 1 0 0.011600 0.023600 0.000000 30 33 0 0 0 0.0000 0.0 0.0000 0.0000 0.0000 0.0 0.0
15 23 1 1 1 0 0.100000 0.202000 0.000000 30 33 0 0 0 0.0000 0.0 0.0000 0.0000 0.0000 0.0 0.0
22 24 1 1 1 0 0.115000 0.179000 0.000000 30 33 0 0 0 0.0000 0.0 0.0000 0.0000 0.0000 0.0 0.0
23 24 1 1 1 0 0.132000 0.270000 0.000000 30 33 0 0 0 0.0000 0.0 0.0000 0.0000 0.0000 0.0 0.0
24 25 1 1 1 0 0.188500 0.329200 0.000000 30 33 0 0 0 0.0000 0.0 0.0000 0.0000 0.0000 0.0 0.0
25 26 1 1 1 0 0.254400 0.380000 0.000000 30 33 0 0 0 0.0000 0.0 0.0000 0.0000 0.0000 0.0 0.0
25 27 1 1 1 0 0.109300 0.208700 0.000000 30 33 0 0 0 0.0000 0.0 0.0000 0.0000 0.0000 0.0 0.0
28 27 1 1 1 1 0.000000 0.396000 0.000000 40 45 0 0 0 0.9680 0.0 0.0000 0.0000 0.0000 0.0 0.0
27 29 1 1 1 0 0.219800 0.415300 0.000000 30 33 0 0 0 0.0000 0.0 0.0000 0.0000 0.0000 0.0 0.0
27 30 1 1 1 0 0.320200 0.602700 0.000000 30 33 0 0 0 0.0000 0.0 0.0000 0.0000 0.0000 0.0 0.0
29 30 1 1 1 0 0.239900 0.453300 0.000000 30 33 0 0 0 0.0000 0.0 0.0000 0.0000 0.0000 0.0 0.0
8 28 1 1 1 0 0.063600 0.200000 0.042800 40 45 0 0 0 0.0000 0.0 0.0000 0.0000 0.0000 0.0 0.0
6 28 1 1 1 0 0.016900 0.059900 0.013000 40 45 0 0 0 0.0000 0.0 0.0000 0.0000 0.0000 0.0 0.0
-999
LOSS ZONES FOLLOWS 0 ITEMS
-99
INTERCHANGE DATA FOLLOWS 1 ITEMS
-999
TIE LINES FOLLOWS 0 ITEMS
-999
END OF DATA

© 1999 F. Alvarado 19 Power flow