Sunteți pe pagina 1din 25

n-bus Power Flow Solver / State Estimator - Anthony S. Deese, Ph.D.... https://sites.google.com/site/anthonydeesephd/matlab-files/power-syst...

Matlab Resources >


Anthony S. Deese, Ph.D.
The College of New Jersey n-bus Power Flow Solver /
Assistant Professor, Department of
Electrical and Computer Engineering
State Estimator
Director, Smart Electric Power System
(SEPS) Laboratory % Anthony S. Deese, Ph.D.
deesea@tcnj.edu % The College of New Jersey
% Assistant Professor
www.anthonydeese.com % http:\\anthony.deese.googlepages.com
% deesea@tcnj.edu

% DESCRIPTION: This Matlab algorithm performs many


tasks associated with
% power system analysis. First, it has the ability to
perform both fully
% coupled and dc power flow analysis. Second, it has
the ability to create
% measurements (with user-defined error) to be used as
input for state
% estimation. Third, it has the ability to perform
state estimation -
% allowing the user to examine how the placement of
measurement devices as
% well as magnitude of distibution of measurement
error affect the
% discrepency between power flow and state estimation
results. In essence,
% it provides the user with a complete package for the
study of both power
% flow and state estimation in n-bus power systems.

close all
clear maplemex
pause(1)
clear all
pause(1)
clc
pause(1)
j = sqrt(-1);

% USER-DEFINED INPUT
******************************************************
%
************************************************************************
%
************************************************************************
%
************************************************************************
%
************************************************************************
Site Navigation
Curriculum Vitae % ACTION: Define bus characteristics below.
% column #1 = bus #
Smart Electric Power System
% column #2 = bus type ( 1 = slack, 2 = gen/PV, 3
Laboratory (SEPS) = load/PQ )
% column #3 = voltage magnitude (per unit)
OpenFlow Power System Simulation % column #4 = voltage angle (degrees)
Tool (Beta-Version) % ** note that columns 3 and 4 also provide
initial conditions for
Announcements % power flow analysis (they should be filled
Recent Conference Presentations in)
% column #5 = real power injection (per unit)
Recent Journal Papers % column #6 = reactive power injection (per unit)
% column #7 = valid pseudo-measurement ( 0 - no, 1
Pictures and Video - yes ), for state
TV, Radio, and Print % estimation only

Teaching (Undergrad) bus = [


ELC251: Electronics I 1 1 1 0 -98.76
ENG272: Differential Equations I -98.76 1; % slack
2 2 1 0 +1.00
ELC383: Power Electronics -98.76 1; % gen
3 2 1 0 +0.50
ELC470: Power Systems and -98.76 1; % compensator
Renewability 4 3 1 0 -0.10
-0.20 1; % load

1 of 25 08-03-2014 08:39
n-bus Power Flow Solver / State Estimator - Anthony S. Deese, Ph.D.... https://sites.google.com/site/anthonydeesephd/matlab-files/power-syst...

ENG212: Circuit Analysis 5 3 1 0 -0.20


+0.10 1;
% load
IDS470 / ENG470: Sustainable 6 2 1 0 -0.30
Engineering Europe -98.76 1; % gen
7 3 1 0 -0.15
Teaching (Graduate) +0.00 1; % load (bus 9)
8 3 1 0 +0.25
ECEP612: Economic Operation of
-0.10 1; % load (bus 10)
Power Systems 9 3 1 0 -0.35
-0.20 1; % load (bus 11)
EGMT515: Engineering Management
10 3 1 0 -0.45
Research -0.30 1; ]; % load (bus 12)
% bus no type magn. angle PInj
Artificial Neural Networks QInj mtype
Power System Analysis via Field
Programmable Analog Array (FPAA) % ACTION: Define the line impedances and
Smart House Technology admittances (per unit).
% column #1 = from bus #
Matlab Resources % column #2 = to bus #
% column #3 = line resistance (R)
n-bus Power Flow Solver / State % column #4 = line reactance (X)
Estimator % column #5 = type of measurement (0 = none, 1 =
from --> to, 2 = from
4-Bus Economic Dispatch Solver % --> to, 3 - both, for state estimation only
Dynamic Programming Algorithm % column #6 = complex power flow from 'from' to
'to' (calculated)
for Markov Decision Process % column #7 = complex power flow from 'to' to
IEEE Standard Power System Test 'from' (calculated)
Cases % NOTE: That the program does not respond well to
Lab Exercises parallel lines
% between two nodes. The user should combine
Tutorials these two paths into a
% single transmission line.
Desktop Wallpapers
Senior Design line = [

1 2 0.01 1.0 1; %
transmission line
1 5 0.02 0.9 1; %
transmission line
2 5 0.03 0.8 1; %
transmission line
2 3 0.04 0.7 1; %
transmission line
2 4 0.05 0.6 1; %
transmission line
3 4 0.06 0.5 1; %
transmission line
4 5 0.07 0.4 1; %
transmission line
%5 6 0.08 0.3 1; %
transmission line
4 7 0.09 0.2 1; %
transmission line
6 10 0.01 0.1 1; %
transmission line
6 9 0.02 0.2 1; %
transmission line
9 8 0.03 0.3 1; %
transmission line
2 8 0.04 0.4 1; % tie
line (normally-open)
1 10 0.05 0.5 1; %
tie-line (normally-open)
8 10 0.06 0.6 1; ]; %
tie-line (normally-open)
% from to R X mtype

% ACTION: Define stopping criterion for power flow


as well as state
% estimation.
power_flow_threshold = 0.01;
state_estimation_threshold = 0.01;

% ACTION: Define error to be injected into power


measurements.
meas_variance = 0.001;

% ACTION: Define whether full vs. dc power flow

2 of 25 08-03-2014 08:39
n-bus Power Flow Solver / State Estimator - Anthony S. Deese, Ph.D.... https://sites.google.com/site/anthonydeesephd/matlab-files/power-syst...

should be employed.
pf_type = 1; % 0 = full, 1 = dc

% ACTION: Defome whether power flow vs. power flow


and state estimation
% should be performed.
analysis_type = 1; % 0 = power flow only, 1 = both
(with state est)

% ACTION: Define voltage magnitude limits as well


as power flow limits.
Vmax = 1.05; % maximum bus voltage magnitude
Vmin = 0.95; % minimum bus voltage magnitude
Pmax = 0.25; % maximum line real power flow

% PRE-ANALYSIS
************************************************************
%
************************************************************************
%
************************************************************************
%
************************************************************************
%
************************************************************************

% ACTION: Initialize 'convergence' variable to


zero. If convergence =
% 1, then power flow has converged. If
convergence = 0, then power flo
% did not converge.
convergence = 0;

% ACTION: Initialize counters to zero.


n_slack = 0; % number of slack buses
n_gen = 0; % number of generators
n_load = 0; % number of loads

% ACTION: Calculate the number of slack buses,


generators, and loads
% within the system. Address all buses.
for k1 = 1:size(bus,1)

% ACTION: Increment counters based on bus


type.
if bus(k1,2) == 1
n_slack = n_slack + 1;
elseif bus(k1,2) == 2
n_gen = n_gen + 1;
elseif bus(k1,2) == 3
n_load = n_load + 1;
else
% ACTION: Display error message for
unrecognized bus type.
disp('FATAL ERROR: At least one bus exists
with unrecognized type (not 1, 2 or 3). Refer to
node...')
node = bus(k1,1)
input(' ')
end
end

% ACTION: Perform a check for any "islanded" buses


- to which no active
% transmission line is attached. The analysis
will not yield a valid
% solution with presence of such singularities.
for k1 = 1:size(bus,1)

% ACTION: Initialize "found" to zero. This


variable signifies
% whether a connection to bus k1 has been
found yet.
found = 0;

% ACTION: Scan all rows of line to find a


match.
for k2 = 1:size(line,1)

% ACTION: IF "match is found" THEN "set


found = 1"

3 of 25 08-03-2014 08:39
n-bus Power Flow Solver / State Estimator - Anthony S. Deese, Ph.D.... https://sites.google.com/site/anthonydeesephd/matlab-files/power-syst...

if bus(k1,1) == line(k2,1) || bus(k1,1) ==


line(k2,2)

% ACTION: Set "found" to one.


found = 1;
end
end

% ACTION: IF "no transmission line is found"


THEN "display error".
if found == 0

% ACTION: Display appropriate error.


disp('FATAL ERROR: There exists a bus to
which no active transmission line is attached. It is
identified below...')
node = bus(k1,1)
input(' ')
end
end

% ACTION: Perform a check to ensure that bus #1 is


a slack bus. This
% is an assumption the algorithm employs - and
must be true.
if bus(1,2) == 1
else
disp('FATAL ERROR: Bus #1 should be defined as
slack bus. Please make necessary changes.')
input(' ')
end

% ACTION: Sort bus and line matrices by first


columns (bus #).
bus = sortrows(bus);
line = sortrows(line);

% ACTION: Define symbolic / numerical values for


YBus matrix (and all
% associatd values).
% ** Ybus(:,:,1) = symbolic description
% ** Ybus(:,:,2) = numerical description

for k1 = 1:max(bus(:,1))
for k2 = 1:max(bus(:,1))

% ACTION: Define symbolic variables.


Ybus(k1,k2,1) =
sym(sprintf('Ybus%g%g',k1,k2));
angleYbus(k1,k2,1) =
sym(sprintf('angleYbus%g%g',k1,k2));
magYbus(k1,k2,1) =
sym(sprintf('magYbus%g%g',k1,k2));
Gik(k1,k2,1) =
sym(sprintf('Gik%g%g',k1,k2));
Bik(k1,k2,1) =
sym(sprintf('Bik%g%g',k1,k2));
end
end

% ACTION: Initialize second (aka. numerical) layer


of Ybus matrix.
Ybus(:,:,2) = 0*eye(max(bus(:,1)));

% ACTION: Define numerical values of Ybus(:,:,2).


for k1 = 1:size(line,1)

% ACTION: Define the from and to buses as well


as zline and yline.
fbus = line(k1,1);
tbus = line(k1,2);
zline = line(k1,3) + j*line(k1,4);
yline = 1/zline;

% ACTION: Define elements of YBus matrix


Ybus(fbus,fbus,2) = Ybus(fbus,fbus,2) + yline;
Ybus(fbus,tbus,2) = Ybus(fbus,tbus,2) - yline;
Ybus(tbus,fbus,2) = Ybus(tbus,fbus,2) - yline;
Ybus(tbus,tbus,2) = Ybus(tbus,tbus,2) + yline;
end

% ACTION: Continue to define numerical values.


for k1 = 1:size(bus,1)

4 of 25 08-03-2014 08:39
n-bus Power Flow Solver / State Estimator - Anthony S. Deese, Ph.D.... https://sites.google.com/site/anthonydeesephd/matlab-files/power-syst...

for k2 = 1:size(bus,1)

angleYbus(k1,k2,2) =
angle(double(Ybus(k1,k2,2)));
magYbus(k1,k2,2) =
abs(double(Ybus(k1,k2,2)));
end
end

% ACTION: Continue to define numerical values.


for k1 = 1:size(line,1)

fbus = line(k1,1);
tbus = line(k1,2);
zline = line(k1,3) + j*line(k1,4);
yline = 1/zline;

Gik(fbus,tbus,2) = real(yline);
Bik(fbus,tbus,2) = imag(yline);

Gik(tbus,fbus,2) = real(yline);
Bik(tbus,fbus,2) = imag(yline);

end

% ACTION: (DC) Initialize the constant Jacobian


matrices to be employed
% for dc power flow analysis only. They are
(essentially) composed of
% the susceptance values (B) for appropriate
buses.
dcJAng = 0*eye(n_load);
dcJMag = 0*eye(n_gen);

% ACTION: (DC) Initialize counters (missingk1_Ang,


missingk2_Ang,
% missingk1_Mag, missingk2_Mag). These counters
represet the missing
% rows and columns from the individual matrices.
missing_rows_Ang = 0;
missing_cols_Ang = 0;
missing_rows_Mag = 0;
missing_cols_Mag = 0;

% ACTION: (DC) Define elements of dcJMag.


for row = 1:size(bus,1)

% ACTION: Any row associated with a slack bus


or generator bus
% should be neglected from dcJMag.
if bus(row,2) == 1 || bus(row,2) == 2

% ACTION: Increment appropriate counters


by one.
missing_rows_Mag = missing_rows_Mag + 1;

% ACTION: Otherwise...
else

% ACTION: Initialize number of missing


columns to zero.
missing_cols_Mag = 0;

% ACTION: Examine all possible "column"


elements which fall
% within a given row.
for col = 1:size(bus,1)

% ACTION: Again, neglect any column


associated with a slack
% or generator bus.
if bus(col,2) == 1 || bus(col,2) == 2

% ACTION: Increment appropriate


counter by one.
missing_cols_Mag =
missing_cols_Mag + 1;

% ACTION: Otherwise...
else

% ACTION: Copy appropriate element


of YBus to dcJMag.

5 of 25 08-03-2014 08:39
n-bus Power Flow Solver / State Estimator - Anthony S. Deese, Ph.D.... https://sites.google.com/site/anthonydeesephd/matlab-files/power-syst...

dcJMag(row-missing_rows_Mag,col-
missing_cols_Mag) = imag(Ybus(row,col,2));

end
end
end
end

% ACTION: (DC) Define elements of dcJAng.


for row = 1:size(bus,1)

% ACTION: Any row associated with a slack bus


% should be neglected from dcJMag.
if bus(row,2) == 1

% ACTION: Increment appropriate counters


by one.
missing_rows_Ang = missing_rows_Ang + 1;

% ACTION: Otherwise...
else

% ACTION: Initialize number of missing


columns to zero.
missing_cols_Ang = 0;

% ACTION: Examine all possible "column"


elements which fall
% within a given row.
for col = 1:size(bus,1)

% ACTION: Again, neglect any column


associated with a slack
% bus.
if bus(col,2) == 1

% ACTION: Increment appropriate


counter by one.
missing_cols_Ang =
missing_cols_Ang + 1;

% ACTION: Otherwise...
else

% ACTION: Copy appropriate element


of YBus to dcJMag.
dcJAng(row-missing_rows_Ang,col-
missing_cols_Ang) = imag(Ybus(row,col,2));

end
end
end
end

% ACTION: (DC) Define the inverse of both dcJAbs


and dcJMag. Because
% these values do not change with iteration, there
is no need to invert
% them repeatedly. This is one major advantage of
dc power flow over
% the "full" implementation.
inv_dcJAng = inv(double(dcJAng));
inv_dcJMag = inv(double(dcJMag));

% ACTION: Check for any missing buses. In other


words, there should be
% no system consisting of bus #1, 2, 4, and #5
without #3. The user
% should redefine the input file appropariately.
for k1 = 1:size(bus,1)
if bus(k1,1) == k1
else
disp('FATAL ERROR: All buses should be
defined - at least one is missing. Refer to node...')
node = k1
input(' ')
end
end

% ACTION: Check buses with more tha one


definition.
for k1 = 1:size(bus,1)

6 of 25 08-03-2014 08:39
n-bus Power Flow Solver / State Estimator - Anthony S. Deese, Ph.D.... https://sites.google.com/site/anthonydeesephd/matlab-files/power-syst...

if k1 < size(bus,1)
if bus(k1,1) == bus(k1+1,1)

disp('FATAL ERROR: Problem exists with


bus array - one bus is defined multiple times. Refer
to node...')
node = k1
input(' ')
end
end
end

% ACTION: Check for symmetry of YBus. The loop is


also used to
% generate a "connection_matrix" which describes
the presence of
% transmission lines between certain buses.
for k1 = 1:size(bus,1)
for k2 = 1:size(bus,1)

% ACTION: IF "the value of symmetrical


elements match in Ybus
% matrix" THEN "no error is generated."
if Ybus(k1,k2,2) == Ybus(k2,k1,2)
else
input('FATAL ERROR: YBus matrix is not
symmetrical...')
end

% ACTION: Use the if statement below to


generate the
% appropriate value of
"connection_matrix."
if Ybus(k1,k2,2) == 0
connection_matrix(k1,k2) = 0;
else
connection_matrix(k1,k2) = 1;
end
end
end

% POWER FLOW ANALYSIS


*****************************************************
%
************************************************************************
%
************************************************************************
%
************************************************************************
%
************************************************************************

% ACTION: Define symbolic and numerical VARIABLES


required for ----------
% POWER FLOW ANALYSIS
-----------------------------------------------------

% ACTION: define symbolic / numerical values for


voltage magnitude
% and angle
% ** V = [ bus #, symbolic, value ]
% ** theta = [ bus #, symbolic, value ]
for k1 = 1:size(bus,1)

% ACTION: Declare symbolic variables.


V(k1,2) = sym(sprintf('V%g',bus(k1,1)));
theta(k1,2) =
sym(sprintf('theta%g',bus(k1,1)));

% ACTION: Define location.


V(k1,1) = k1;
theta(k1,1) = k1;

% ACTION: Define numerical values.


V(k1,3) = [ bus(k1,3) ];
theta(k1,3) = [ bus(k1,4) ];

end

% ACTION: Initialize counter k2. It is used in

7 of 25 08-03-2014 08:39
n-bus Power Flow Solver / State Estimator - Anthony S. Deese, Ph.D.... https://sites.google.com/site/anthonydeesephd/matlab-files/power-syst...

the loop below to


% define injections for all non-slack buses.
k2 = 1;

% ACTION: Define symbolic / numerical values for


PInj and QInj - the
% bus injections.
% ** Pinj = [ bus #, symbolic, value ]
% ** Qinj = [ bus #, symbolic, value ]
for k1 = 1:size(bus,1)

% IF "bus k1 is NOT slack bus" THEN


if bus(k1,2) ~= 1

% ACTION: Declare symbolic variables.


Pinj(k2,2) =
sym(sprintf('Pinj%g',bus(k1,1)));

% ACTION: Define location.


Pinj(k2,1) = bus(k1,1);

% ACTION: Define numerical value.


Pinj(k2,3) = bus(k1,5);

% ACTION: Increment counter.


k2 = k2+1;

end
end

% ACTION: Again, initialize k2 counter.


k2 = 1;

% ACTION: Repeat process above for reactive


injections.
for k1 = 1:size(bus,1)

% IF "bus k1 IS load bus" THEN


if bus(k1,2) == 3

% ACTION: Declare symbolic variables.


Qinj(k2,2) =
sym(sprintf('Qinj%g',bus(k1,1)));

% ACTION: Define location.


Qinj(k2,1) = bus(k1,1);

% ACTION: Define numerical value.


Qinj(k2,3) = bus(k1,6);

% ACTION: Increment counter.


k2 = k2+1;

end
end

% ACTION: Again, initialize k2 counter.


k2 = 1;

% ACTION: Define symbolic / numerical values for


state array.
% ** state = [ bus, type (0 - theta, 1 - mag),
symbolic, numerical)
for k1 = 1:size(bus,1)

% IF "bus k1 is NOT slack bus" THEN


if bus(k1,2) == 1
else

% ACTION: Declare symbolic variable


state(k2,3) =
sym(sprintf('theta%g',bus(k1,1)));

% ACTION: Define location and type


state(k2,1:2) = [ bus(k1,1) 0 ];

% ACTION: Define numerical values. It


will either be taken
% from the bus matrix of initialized to
zero.
for k3 = 1:size(bus,1)
if state(k2,1) == bus(k3,1)
state(k2,4) = bus(k3,4);

8 of 25 08-03-2014 08:39
n-bus Power Flow Solver / State Estimator - Anthony S. Deese, Ph.D.... https://sites.google.com/site/anthonydeesephd/matlab-files/power-syst...

else
state(k2,4) = 0;
end
end

% ACTION: Increment counter


k2 = k2+1;

end
end

% ACTION: Repeat process above for bus voltage


magnitudes.
for k1 = 1:size(bus,1)

% IF "bus k1 IS load bus" THEN


if bus(k1,2) == 3

% ACTION: Declare system states.


state(k2,3) =
sym(sprintf('V%g',bus(k1,1)));

% ACTION: Define location and type.


state(k2,1:2) = [ bus(k1,1) 1 ];

% ACTION: Define numerical values. It


will either be taken
% from the bus matrix of initialized to
one.
for k3 = 1:size(bus,1)
if state(k2,1) == bus(k3,1)
state(k2,4) = bus(k3,3);
else
state(k2,4) = 1;
end
end

% ACTION: Increment counter


k2 = k2+1;

end
end

% ACTION: Define the symbolic EQUATIONS / CONSTRAINTS


required for --------
% POWER FLOW ANALYSIS
-----------------------------------------------------
% e.g. measured - calculated power flow at bus i

% ACTION: Initialize counter k3.


k3 = 1;

% ACTION: Generate the real power flow functions


(Pi).
for k1 = 1:size(bus,1)

% IF (bus k1 DOES supply pseudo-measurement)


and (bus k1 is not
% slack bus) THEN
if bus(k1,2) ~= 1

% ACTION: Begin to define power flow


equation.
functPi(k3,1) = [ V(k1,2) * V(k1,2)*
magYbus(k1,k1,1) ] * cos( theta(k1,2) - theta(k1,2) -
angleYbus(k1,k1,1) );

% ACTION: Examine all other buses


(non-slack)
for k2 = 1:size(bus,1)

% IF (k1 is NOT equal to k2) THEN


if k1 ~= k2

% ACTION: Continue to define power


flow equation.
functPi(k3,1) = functPi(k3,1) + [
V(k1,2) * V(k2,2) * connection_matrix(k1,k2) *
magYbus(k1,k2,1) ] * cos( theta(k1,2) - theta(k2,2) -
angleYbus(k1,k2,1) );

9 of 25 08-03-2014 08:39
n-bus Power Flow Solver / State Estimator - Anthony S. Deese, Ph.D.... https://sites.google.com/site/anthonydeesephd/matlab-files/power-syst...

end
end

% ACTION: Define associated constraints.


Remember the
% constraint is agreement of sum of flows
at a given bus and
% the defined injection.
constPi(k3,1) = Pinj(k3,2) -
functPi(k3,1);

% ACTION: Increment counter.


k3 = k3 + 1;

end
end

% ACTION: Initialize counter.


k3 = 1;

% ACTION: Generate the reactive power flow


function (Qi).
for k1 = 1:size(bus,1)

% IF (bus k1 IS load bus) THEN


if bus(k1,2) == 3

% ACTION: Begin to define power flow


equation.
functQi(k3,1) = [ V(k1,2) * V(k1,2) *
magYbus(k1,k1,1) ] * sin( theta(k1,2) - theta(k1,2) -
angleYbus(k1,k1,1) );

% ACTION: Examine all other buses.


for k2 = 1:size(bus,1)

% IF (k1 != k2) THEN


if k1 ~= k2

% ACTION: Continue to define power


flow equation
functQi(k3,1) = functQi(k3,1) + [
V(k1,2) * V(k2,2) * connection_matrix(k1,k2) *
magYbus(k1,k2,1) ] * sin( theta(k1,2) - theta(k2,2) -
angleYbus(k1,k2,1) );
end
end

% ACTION: Define associated constraints.


Remember the
% constraint is agreement of sum of flows
at a given bus and
% the defined injection.
constQi(k3,1) = Qinj(k3,2) -
functQi(k3,1);

% ACTION: Increment counter.


k3 = k3 + 1;
end
end

% ACTION: Define symbolic ARRAY of CONSTRAINTS for


POWER FLOW ANALYSIS ----
% e.g. State Estimation Constraints (sec)

constPowerFlow(:,1) = [ constPi; constQi ];

% ACTION: Define symbolic JACOBIAN matrix for POWER


FLOW ANALYSIS ---------
% e.g. referred to as the J matrix

J(:,:,1) =
jacobian(constPowerFlow(:,1),state(:,3));

% ACTION: Perform ITERATIONS of POWER FLOW ANALYSIS


----------------------

% ACTION: Initialize mismatch.

10 of 25 08-03-2014 08:39
n-bus Power Flow Solver / State Estimator - Anthony S. Deese, Ph.D.... https://sites.google.com/site/anthonydeesephd/matlab-files/power-syst...

mismatch = 9999;

% ACTION: Initialize counter.


k1 = 1;

% ACTION: Initialize updated_state.


updated_state = state(:,4)*0;

% ACTION: Continue power flow analysis iterations


until either the
% mismatch falls below user-defined threshold, or
the number of
% iterations exceeds 25.
while ( abs(mismatch) > abs(power_flow_threshold)
) && ( k1 < 25 )

% ACTION: Display iteration number.


clc
power_flow_iteration = k1
disp('out of 25 iterations (max)')

% ACTION: Perform SUBSTITUTION for POWER FLOW


ANALYSIS ------------
% e.g. flat start (1 < 0)

J(:,:,2) = subs( J(:,:,1), V(:,2),


double( V(:,3) ));
J(:,:,2) = subs( J(:,:,2), theta(:,2),
double( theta(:,3) ));
J(:,:,2) = subs( J(:,:,2), magYbus(:,:,1),
double( magYbus(:,:,2) ));
J(:,:,2) = subs( J(:,:,2),
angleYbus(:,:,1), double( angleYbus(:,:,2) ));

J_record(:,:,k1) = J(:,:,2);

constPowerFlow(:,2) = subs(
constPowerFlow(:,1), V(:,2),
double( V(:,3) ));
constPowerFlow(:,2) = subs(
constPowerFlow(:,2), theta(:,2),
double( theta(:,3) ));
constPowerFlow(:,2) = subs(
constPowerFlow(:,2), magYbus(:,:,1),
double( magYbus(:,:,2) ));
constPowerFlow(:,2) = subs(
constPowerFlow(:,2), angleYbus(:,:,1),
double( angleYbus(:,:,2) ));
constPowerFlow(:,2) = subs(
constPowerFlow(:,2), Pinj(:,2),
double( Pinj(:,3) ));
constPowerFlow(:,2) = subs(
constPowerFlow(:,2), Qinj(:,2),
double( Qinj(:,3) ));

% ACTION: Record these mismatches.


constPowerFlow_record(:,k1) =
constPowerFlow(:,2);

% ACTION: Define mismatch.


if k1 > 2
mismatch =
max(abs(double(constPowerFlow(:,2))));
end

% ACTION: Define counter to keep track of


number of slack buses
% found and eliminated from Vnotslack.
n_missing = 0;

% ACTION: Remove slack bus from V, creating


Vnotslack. This array
% will be used to update voltage angles in dc
power flow ([B]-1/V)
for k2 = 1:size(V,1)

% ACTION: If bus k2 is slack bus, do not


copy corresponding
% element from V to Vnotslack.
if bus(k2,2) == 1

% ACTION: Increment counter.


n_missing = n_missing + 1;

11 of 25 08-03-2014 08:39
n-bus Power Flow Solver / State Estimator - Anthony S. Deese, Ph.D.... https://sites.google.com/site/anthonydeesephd/matlab-files/power-syst...

% ACTION: Otherwise, perform transfer.


else

% ACTION: Transfer, keeping in mind of


shift by n_missing.
Vnotslack(k2-n_missing,1) = V(k2,3);
end
end

% ACTION: perform UPDATE for POWER FLOW


ANALYSIS --------------------
% e.g. x(1) = -[J^-1]f + x(0)

if pf_type == 0

% ACTION: Employ "full" power flow update


expression.
updated_state =
-inv(double(J(:,:,2)))*constPowerFlow(:,2) +
state(:,4);

elseif pf_type == 1

% ACTION: Employ "dc" power flow update


expressions.
updated_state(1:n_load+n_gen) =
-double(inv_dcJAng) * [
double(constPowerFlow(1:n_load+n_gen,2)) ./
double(Vnotslack) ] + double(state(1:n_load+n_gen,4));

updated_state(n_gen+n_load+1:n_gen+2*n_load) =
-double(inv_dcJMag) * [
double(constPowerFlow(n_gen+n_load+1:n_gen+2*n_load,2))
./ double(state(n_gen+n_load+1:n_gen+2*n_load,4)) ] +
double(state(n_gen+n_load+1:n_gen+2*n_load,4));
else

% ACTION: Display error message for


unrecognized power flow
% type.
disp('FATAL ERROR: Unrecognized power flow
type - neither full nor dc.')
input(' ')
end

% ACTION: TRANSFER values from updated_state


to appropriate arrays
index(k1) = k1;
state_record(:,k1) = state(:,4);

% ACTION: Transfer to V and theta arrays.


for k2 = 1:size(state,1)
if state(k2,2) == 0
for k3 = 1:size(theta,1)

if state(k2,1) == theta(k3,1)

theta(k3,3) =
updated_state(k2);
end
end
elseif state(k2,2) == 1
for k3 = 1:size(V,1)

if state(k2,1) == V(k3,1)

V(k3,3) = updated_state(k2);
end
end
end
end

% ACTION: Transfer to state array.


state(:,4) = updated_state;

% ACTION: Increment k1. This allows power


flow analysis to move on
% to "next iteration."
k1 = k1+1;

end

12 of 25 08-03-2014 08:39
n-bus Power Flow Solver / State Estimator - Anthony S. Deese, Ph.D.... https://sites.google.com/site/anthonydeesephd/matlab-files/power-syst...

% POST-ANALYSIS
***********************************************************
%
************************************************************************
%
************************************************************************
%
************************************************************************
%
************************************************************************

% ACTION: CHECK for accuracy POWER FLOW RESULT


--------------------------
% ** this is done by comparison of injections and
line flows

% ACTION: Initialize counter k2.


k2 = 1;

% ACTION: Define the symbolic equations for flow


along all lines.
for k1 = 1:size(line,1)

% ACTION: Define 'from' bus and 'to' bus for


the k1-th line.
fbus = line(k1,1);
tbus = line(k1,2);

% ACTION: Define equation.


functPik(k2,3) = [ V(fbus,2)^2 *
Gik(fbus,tbus,1) ] - ( V(fbus,2)*V(tbus,2)*[
Gik(fbus,tbus,1)*cos(theta(fbus,2) - theta(tbus,2)) +
Bik(fbus,tbus,1)*sin(theta(fbus,2) - theta(tbus,2)) ]
);
functQik(k2,3) = [ -V(fbus,2)^2 *
Bik(fbus,tbus,1) ] - ( V(fbus,2)*V(tbus,2)*[
Gik(fbus,tbus,1)*sin(theta(fbus,2) - theta(tbus,2)) -
Bik(fbus,tbus,1)*cos(theta(fbus,2) - theta(tbus,2)) ]
);
functPik(k2+1,3) = [ V(tbus,2)^2 *
Gik(tbus,fbus,1) ] - ( V(tbus,2)*V(fbus,2)*[
Gik(tbus,fbus,1)*cos(theta(tbus,2) - theta(fbus,2)) +
Bik(tbus,fbus,1)*sin(theta(tbus,2) - theta(fbus,2)) ]
);
functQik(k2+1,3) = [ -V(tbus,2)^2 *
Bik(tbus,fbus,1) ] - ( V(tbus,2)*V(fbus,2)*[
Gik(tbus,fbus,1)*sin(theta(tbus,2) - theta(fbus,2)) -
Bik(tbus,fbus,1)*cos(theta(tbus,2) - theta(fbus,2)) ]
);

% ACTION: Define location.


functPik(k2,1:2) = [ fbus tbus ];
functPik(k2+1,1:2) = [ tbus fbus ];
functQik(k2,1:2) = [ fbus tbus ];
functQik(k2+1,1:2) = [ tbus fbus ];

% ACTION: Increment counter.


k2 = k2+2;

end

% ACTION: Perform substitution.


functPik(:,4) = subs( functPik(:,3), V(:,2),
double( V(:,3) ));
functPik(:,4) = subs( functPik(:,4),
theta(:,2), double( theta(:,3) ));
functPik(:,4) = subs( functPik(:,4),
Gik(:,:,1), double( Gik(:,:,2) ));
functPik(:,4) = subs( functPik(:,4),
Bik(:,:,1), double( Bik(:,:,2) ));

functQik(:,4) = subs( functQik(:,3), V(:,2),


double( V(:,3) ));
functQik(:,4) = subs( functQik(:,4),
theta(:,2), double( theta(:,3) ));
functQik(:,4) = subs( functQik(:,4),
Gik(:,:,1), double( Gik(:,:,2) ));
functQik(:,4) = subs( functQik(:,4),
Bik(:,:,1), double( Bik(:,:,2) ));

% ACTION: Calculate the bus flows from the

13 of 25 08-03-2014 08:39
n-bus Power Flow Solver / State Estimator - Anthony S. Deese, Ph.D.... https://sites.google.com/site/anthonydeesephd/matlab-files/power-syst...

individual line flows. Note


% that Pi = sum(Pik) for all k.
for k1 = 1:size(bus,1)

% ACTION: Initialize bus flows to zero.


Pflow(k1) = 0;
Qflow(k1) = 0;

% ACTION: Address all rows of functPik /


functQik. This
% corresponds to the real and reactive power
flow along all lines
% within the system.
for k2 = 1:size(functPik,1)

% ACTION: IF (the k1-th bus is equal to


the from_bus of the
% k2-th line) THEN...
if bus(k1,1) == functPik(k2,1)

% ACTION: Add the k1-k2 "line" flow to


the "bus" flow.
Pflow(k1) = Pflow(k1) +
functPik(k2,4);
Qflow(k1) = Qflow(k1) +
functQik(k2,4);
end
end
end

% ACTION: Address all rows of the bus matrix.


for k1 = 1:size(bus,1)

% ACTION: IF (bus k1 is not the slack bus)


THEN
if bus(k1,2) ~= 1

% ACTION: Calculate the mismatch between


real power injection
% and real power flow.
mismatchP(k1,1) = bus(k1,5) - Pflow(k1);

% IF (bus k1 is a load bus) THEN


if bus(k1,2) == 3

% ACTION: Calculate the mismatch


between reactive power
% injection and real power flow.
mismatchQ(k1,1) = bus(k1,6) -
Qflow(k1);
end
end
end

% IF (the total mismatch is less than user-defined


threshold) THEN
if ( abs(mismatch) < abs(power_flow_threshold) )

% ACTION: Set convergence variable to 1.


convergence = 1;

% ACTION: Display error message if significant


mismatch exists.
if pf_type == 0
if sum( abs(mismatchP))+sum(abs(mismatchQ)
) > power_flow_threshold

% ACTION: Display error.


input('FATAL ERROR: Although
convergence was achieved, calculated power flow does
not match user-defined injection. Final check
failed.')
end

% NOTE: That the threshold is slightly


increased if dc power flow
% is employed.
elseif pf_type == 1

if sum( abs(mismatchP))+sum(abs(mismatchQ)
) > 10*power_flow_threshold

% ACTION: Display error.

14 of 25 08-03-2014 08:39
n-bus Power Flow Solver / State Estimator - Anthony S. Deese, Ph.D.... https://sites.google.com/site/anthonydeesephd/matlab-files/power-syst...

input('FATAL ERROR: Although


convergence was achieved, calculated power flow does
not match user-defined injection. Final check
failed.')
end
end
else

% ACTION: Display warning messgae.


disp('WARNING: Power flow analysis did not
converge. Maximum number of iterations (25) reached.')
pause(5)
end

% GENERATE AND SAVE MEASUREMENTS


******************************************
%
************************************************************************
%
************************************************************************
%
************************************************************************
%
************************************************************************

% ACTION: Generate the measurement matrices (mbus


and mline). The
% makeup of these matrices is defined below.
for k1 = 1:size(line,1)
mline(k1,:) = [ line(k1,1) line(k1,2)
line(k1,3) line(k1,4) line(k1,5) ];
end

% ACTION: Address all rows of line (k1) as well as


functPik (k2)...
for k1 = 1:size(line,1)
for k2 = 1:size(functPik,1)

% IF (line k1 is same line and direction


as power measurement)
% THEN (record to 6 and 7th columns)
if ( mline(k1,1) == functPik(k2,1) ) && (
mline(k1,2) == functPik(k2,2) )

% ACTION: Save real and reactive power


flow measurements to
% mline with measurement error of
user-defined variance.
mline(k1,6) = functPik(k2,4) +
meas_variance * (rand()-0.5) * functPik(k2,4);
mline(k1,7) = functQik(k2,4) +
meas_variance * (rand()-0.5) * functQik(k2,4);

% IF (line k1 is the same line but


opposite direction as power
% measurement) THEN (record to 8th and 9th
columns)
elseif ( mline(k1,1) == functPik(k2,2) )
&& ( mline(k1,2) == functPik(k2,1) )

% ACTION: Save measurements of


opposite direction to mline.
mline(k1,8) = functPik(k2,4) +
meas_variance * (rand()-0.5) * functPik(k2,4);
mline(k1,9) = functQik(k2,4) +
meas_variance * (rand()-0.5) * functQik(k2,4);

end
end
end

% NOTE that for 'mline' matrix:


% column #1: from bus
% column #2: to bus
% column #3: line resistance (Rik)
% column #4: line reactance (Xik)
% column #5: measurement type
% (0 = none, 1 = from --> to, 2 = from -->
to, 3 - both)
% column #6: from --> to Pflow (with error)
% column #7: from --> to Qflow (with error)

15 of 25 08-03-2014 08:39
n-bus Power Flow Solver / State Estimator - Anthony S. Deese, Ph.D.... https://sites.google.com/site/anthonydeesephd/matlab-files/power-syst...

% column #8: to --> from Pflow (with error)


% column #9: to --> from Qflow (with error)

% ACTION: Address all measurements.


for k1 = 1:size(bus,1)

% ACTION: Record measurements of S to measS


array with error as
% defined by meas_variance.
mbus(k1,:) = [ bus(k1,1) bus(k1,2) bus(k1,3)
bus(k1,4) bus(k1,5)+meas_variance*
(rand()-0.5)*bus(k1,5) bus(k1,6)+meas_variance*
(rand()-0.5)*bus(k1,6) bus(k1,7)
V(k1,3)+meas_variance*(rand()-0.5)*V(k1,3)
theta(k1,3)+meas_variance*(rand()-0.5)*theta(k1,3) ];
end

% NOTE that for 'mbus' matrix:


% column #1: bus #
% column #2: type
% column #3: nominal |V| / initial condition
% column #4: nominal theta / initial condition
% column #5: Pinj
% column #6: Qinj
% column #7: measured |V|
% column #8: measured theta

% ACTION: Only delete and reload all files if


state estimation is to be
% performed.
if analysis_type == 1

% ACTION: Save all pertinent files.


save master mline mbus connection_matrix bus
line V theta Ybus magYbus angleYbus Gik Bik
state_estimation_threshold analysis_type Vmax Vmin
Pmax convergence

% ACTION: Clear memory (including maple


modules).
clear all
clear maplemex
clc

% ACTION: Load pertinent files again.


load master
end

% CALCULATE COST (from limit violations)


**********************************
%
************************************************************************
%
************************************************************************
%
************************************************************************
%
************************************************************************

% ACTION: IF (convergence == 0) THEN (cost is very


high / aka. 10^10)
if convergence == 0

% ACTION: Define cost to 10^10.


cost = 10^10;

% ACTION: Otherwise, quantify cost associated with


violation of various
% limits.
else

% ACTION: Initialize line flow violation cost.


line_violation_cost = 0;

% ACTION: Examine all rows of mline for line


flow limit violations.
for k1 = 1:size(mline,1)

% ACTION: Each row provides two real flows


- corresponding to the

16 of 25 08-03-2014 08:39
n-bus Power Flow Solver / State Estimator - Anthony S. Deese, Ph.D.... https://sites.google.com/site/anthonydeesephd/matlab-files/power-syst...

% different directions. Take the greater


of these two.
temp_Pflow =
max(abs(mline(k1,6)),abs(mline(k1,8)));

% ACTION: Determine whether this


temp_Pflow is greater than the maximum
% limit.
if temp_Pflow > Pmax

% ACTION: Calculate cost associated


with violation of line power
% flows.
line_violation_cost =
line_violation_cost + abs(temp_Pflow-Pmax)/abs(Pmax);
end
end

% ACTION: Initialize voltage magnitude


violation cost.
magn_violation_cost = 0;

% ACTION: Examine all rows of V for voltage


magnitude violations.
for k1 = 1:size(V,1)

% ACTION: Determine whether the voltage


magnitude violates the
% upper limit.
if ( double(abs(V(k1,3))) > abs(Vmax) )

% ACTION: Calculate cost associated


with violation of voltage
% magnitude limit.
magn_violation_cost =
magn_violation_cost + abs(V(k1)-Vmax)/abs(Vmax);

end

% ACTION: Determine whether the voltage


magnitude violates the
% lower limit.
if ( double(abs(V(k1,3))) < abs(Vmin) )

% ACTION: Calculate cost associated


with violation of voltage
% magnitude limit.
magn_violation_cost =
magn_violation_cost + abs(V(k1)-Vmin)/abs(Vmin);

end
end

% ACTION: Define cost as sum of voltage


magnitude and line flow
% violation components.
cost = magn_violation_cost +
line_violation_cost;
end

% ACTION: IF "analysis_type = 1" THEN "perform


state estimation"
if analysis_type == 0

clc
disp('Output of power flow analysis is shown
below (in per unit and radians)...')
power_flow_variables = transpose(state(:,3))
power_flow_values =
double(transpose(state(:,4)))

% ACTION: Initialize figure number.


figure_number = 0;

% ACTION: Only plot results if convergence is


achieved.
if convergence == 1

% ACTION: Plot results.


for k1 = 1:size(state_record,1)

% ACTION: Generate a new window for


every 9-subplots.

17 of 25 08-03-2014 08:39
n-bus Power Flow Solver / State Estimator - Anthony S. Deese, Ph.D.... https://sites.google.com/site/anthonydeesephd/matlab-files/power-syst...

if mod(k1-1,9) == 0

% ACTION: Increment figure_number


figure_number = figure_number + 1;
figure(figure_number)
end

% ACTION: Define subplot location.


subplot(3,3,mod(k1-1,9)+1)

% ACTION: Plot data.


if state(k1,2) == 0
plot( index,
360*state_record(k1,:)/(2*pi), 'o-' )
elseif state(k1,2) == 1
plot( index, state_record(k1,:),
'o-' )
end

% ACTION: Generate x-axis label.


xlabel('iteration #')

if state(k1,2) == 0
ylabel(sprintf('theta #%g
(deg)',double(state(k1,1))))
elseif state(k1,2) == 1
ylabel(sprintf('vmag #%g
(pu)',double(state(k1,1))))
end
end
end
break;
end

% PERFORM STATE ESTIMATION


************************************************
%
************************************************************************
%
************************************************************************
%
************************************************************************
%
************************************************************************

% ACTION: Define symbolic and numerical VARIABLES


required for ------------
% STATE ESTIMATION
--------------------------------------------------------

% ACTION: Initialize counter.


k2 = 1;

% ACTION: Define symbolic / numerical values for


measurements of Pik
% and Qik.
% ** measPik = [ line #, from bus, to bus,
symbolic, value ]
% ** measQik = [ line #, from bus, to bus,
symbolic, value ]
for k1 = 1:size(mline,1)

% ACTION: Define 'from bus' and 'to bus'.


fbus = mline(k1,1);
tbus = mline(k1,2);

% IF (measurement type is forward, from -->


to)
if mline(k1,5) == 1

% ACTION: Declare symbolic variables.

measPik(k2,4) =
sym(sprintf('measPik%g%g',fbus,tbus));
measQik(k2,4) =
sym(sprintf('measQik%g%g',fbus,tbus));

% ACTION: Define location.


measPik(k2,1:3) = [ k1 fbus tbus ];
measQik(k2,1:3) = [ k1 fbus tbus ];

18 of 25 08-03-2014 08:39
n-bus Power Flow Solver / State Estimator - Anthony S. Deese, Ph.D.... https://sites.google.com/site/anthonydeesephd/matlab-files/power-syst...

% ACTION: Define numerical values.


measPik(k2,5) = [ mline(k1,6) ];
measQik(k2,5) = [ mline(k1,7) ];

% ACTION: Increment counter k2.


k2 = k2+1;

% IF (measurement type is backward, to -->


from)
elseif mline(k1,5) == 2

% ACTION: Declare symbolic variables.

measPik(k2,4) =
sym(sprintf('measPik%g%g',tbus,fbus));
measQik(k2,4) =
sym(sprintf('measQik%g%g',tbus,fbus));

% ACTION: Define location.


measPik(k2,1:3) = [ k1 tbus fbus ];
measQik(k2,1:3) = [ k1 tbus fbus ];

% ACTION: Define numerical values.


measPik(k2,5) = [ mline(k1,8) ];
measQik(k2,5) = [ mline(k1,9) ];

% ACTION: Increment counter k2.


k2 = k2+1;

% IF (measurement type is bi-directional, from


--> to and to --> from)
elseif mline(k1,5) == 3

% ACTION: Perform same steps as above.


measPik(k2,4) =
sym(sprintf('measPik%g%g',fbus,tbus));
measPik(k2+1,4) =
sym(sprintf('measPik%g%g',tbus,fbus));

measQik(k2,4) =
sym(sprintf('measQik%g%g',fbus,tbus));
measQik(k2+1,4) =
sym(sprintf('measQik%g%g',tbus,fbus));

measPik(k2,1:3) = [ k1 fbus tbus ];


measPik(k2+1,1:3) = [ k1 tbus fbus ];

measQik(k2,1:3) = [ k1 fbus tbus ];


measQik(k2+1,1:3) = [ k1 tbus fbus ];

measPik(k2,5) = [ mline(k1,6) ];
measQik(k2,5) = [ mline(k1,7) ];

measPik(k2+1,5) = [ mline(k1,8) ];
measQik(k2+1,5) = [ mline(k1,9) ];

% ACTION: Increment counter k2.


k2 = k2+2;
end
end

% ACTION: Initialize counter k2.


k2 = 1;

% ACTION: Define symbolic / numerical values for


pseudo-measurements
% of Pi and Qi.
% ** pseudomeasPi = [ bus #, symbolic, value ]
% ** pseudomeasQi = [ bus #, symbolic, value ]
for k1 = 1:size(mbus,1)

% IF (bus k1 DOES supply pseudo-measurement)


AND (bus k1 is NOT
% slack bus) THEN
if ( mbus(k1,7) == 1 ) && ( mbus(k1,2) ~= 1 )

% ACTION: Declare symbolic variables.


pseudomeasPi(k2,2) =
sym(sprintf('pseudomeasPi%g',double(mbus(k1,1))));

% ACTION: Define location.


pseudomeasPi(k2,1) = mbus(k1,1);

19 of 25 08-03-2014 08:39
n-bus Power Flow Solver / State Estimator - Anthony S. Deese, Ph.D.... https://sites.google.com/site/anthonydeesephd/matlab-files/power-syst...

% ACTION: Define numerical value.


pseudomeasPi(k2,3) = mbus(k1,5);

% ACTION: Increment counter.


k2 = k2+1;
end
end

% ACTION: Initialize counter k2.


k2 = 1;

% ACTION: Repeat steps above for reactive power


pseudo-measurements.
for k1 = 1:size(mbus,1)

if ( mbus(k1,7) == 1 ) && ( mbus(k1,2) == 3 )

% ACTION: Declare symbolic variables.


pseudomeasQi(k2,2) =
sym(sprintf('pseudomeasQi%g',double(mbus(k1,1))));

% ACTION: Define location.


pseudomeasQi(k2,1) = mbus(k1,1);

% ACTION: Define numerical value.


pseudomeasQi(k2,3) = mbus(k1,6);

% ACTION: Increment counter.


k2 = k2+1;
end
end

% ACTION: Clear the state, for reload.


clear state

% ACTION: Initialize counter k2.


k2 = 1;

% ACTION: Define symbolic / numerical values for


state array
% ** state = [ bus, type (0 - theta, 1 - mag),
symbolic, numerical)
for k1 = 1:size(mbus,1)

% IF (bus k1 is NOT slack bus)


if mbus(k1,2) == 1
else

% ACTION: Declare symbolic variable.


state(k2,3) =
sym(sprintf('theta%g',double(mbus(k1,1))));

% ACTION: Define location and type.


state(k2,1:2) = [ mbus(k1,1) 0 ];

% ACTION: Define numerical values.


state(k2,4) = 0; % this is b/c FLAT START

% ACTION: Increment counter.


k2 = k2+1;
end
end

% ACTION: Repeat steps above for voltage magnitude


measurements.
for k1 = 1:size(mbus,1)

% IF (bus k1 is NOT slack bus)


if mbus(k1,2) == 1
else

% ACTION: Declare system states.


state(k2,3) =
sym(sprintf('V%g',double(mbus(k1,1))));

% ACTION: Define location and type.


state(k2,1:2) = [ mbus(k1,1) 1 ];

% ACTION: Define numerical values.


state(k2,4) = 1; % this is b/c FLAT START

% ACTION: Increment counter.


k2 = k2+1;

20 of 25 08-03-2014 08:39
n-bus Power Flow Solver / State Estimator - Anthony S. Deese, Ph.D.... https://sites.google.com/site/anthonydeesephd/matlab-files/power-syst...

end
end

% ACTION: Define the symbolic EQUATIONS / CONSTRAINTS


associated with -----
% MEASUREMENTS required for STATE ESTIMATION
------------------------------
% e.g. measured - calculated power flow along
line ik

% ACTION: Initialize counter k2.


k2 = 1;

% ACTION: Address all rows of mline.


for k1 = 1:size(mline,1)

% ACTION: Define 'from' bus and 'to' bus for


the k1-th line.
fbus = mline(k1,1);
tbus = mline(k1,2);

% IF (type = 1 define single direction


variables aka. forward) THEN
if mline(k1,5) == 1

% ACTION: Define power 'line' flow


equations.
functPik(k2,1) = [ V(fbus,2)^2 *
Gik(fbus,tbus,1) ] - ( V(fbus,2)*V(tbus,2)*[
Gik(fbus,tbus,1)*cos(theta(fbus,2) - theta(tbus,2)) +
Bik(fbus,tbus,1)*sin(theta(fbus,2) - theta(tbus,2)) ]
);
functQik(k2,1) = [ -V(fbus,2)^2 *
Bik(fbus,tbus,1) ] - ( V(fbus,2)*V(tbus,2)*[
Gik(fbus,tbus,1)*sin(theta(fbus,2) - theta(tbus,2)) -
Bik(fbus,tbus,1)*cos(theta(fbus,2) - theta(tbus,2)) ]
);

% ACTION: Define associated constraints.


constPik(k2,1) = measPik(k2,4) -
functPik(k2,1);
constQik(k2,1) = measQik(k2,4) -
functQik(k2,1);

% ACTION: Increment counter by one.


k2 = k2+1;

% IF (type = 2 define single direction


variables aka. backward)
elseif mline(k1,5) == 2

% ACTION: Define power 'line' flow


equations.
functPik(k2,1) = [ V(tbus,2)^2 *
Gik(tbus,fbus,1) ] - ( V(tbus,2)*V(fbus,2)*[
Gik(tbus,fbus,1)*cos(theta(tbus,2) - theta(fbus,2)) +
Bik(tbus,fbus,1)*sin(theta(tbus,2) - theta(fbus,2)) ]
);
functQik(k2,1) = [ -V(tbus,2)^2 *
Bik(tbus,fbus,1) ] - ( V(tbus,2)*V(fbus,2)*[
Gik(tbus,fbus,1)*sin(theta(tbus,2) - theta(fbus,2)) -
Bik(tbus,fbus,1)*cos(theta(tbus,2) - theta(fbus,2)) ]
);

% ACTION: Define associated constraints.


constPik(k2,1) = measPik(k2,4) -
functPik(k2,1);
constQik(k2,1) = measQik(k2,4) -
functQik(k2,1);

% ACTION: Increment counter by one.


k2 = k2+1;

% IF (type = 3 declare bi-directional


variables aka. forward / backward)
elseif mline(k1,5) == 3

% ACTION: Repeat steps above for


bi-directional measurements.
functPik(k2,1) = [ V(fbus,2)^2 *
Gik(fbus,tbus,1) ] - ( V(fbus,2)*V(tbus,2)*[

21 of 25 08-03-2014 08:39
n-bus Power Flow Solver / State Estimator - Anthony S. Deese, Ph.D.... https://sites.google.com/site/anthonydeesephd/matlab-files/power-syst...

Gik(fbus,tbus,1)*cos(theta(fbus,2) - theta(tbus,2)) +
Bik(fbus,tbus,1)*sin(theta(fbus,2) - theta(tbus,2)) ]
);
functQik(k2,1) = [ -V(fbus,2)^2 *
Bik(fbus,tbus,1) ] - ( V(fbus,2)*V(tbus,2)*[
Gik(fbus,tbus,1)*sin(theta(fbus,2) - theta(tbus,2)) -
Bik(fbus,tbus,1)*cos(theta(fbus,2) - theta(tbus,2)) ]
);
functPik(k2+1,1) = [ V(tbus,2)^2 *
Gik(tbus,fbus,1) ] - ( V(tbus,2)*V(fbus,2)*[
Gik(tbus,fbus,1)*cos(theta(tbus,2) - theta(fbus,2)) +
Bik(tbus,fbus,1)*sin(theta(tbus,2) - theta(fbus,2)) ]
);
functQik(k2+1,1) = [ -V(tbus,2)^2 *
Bik(tbus,fbus,1) ] - ( V(tbus,2)*V(fbus,2)*[
Gik(tbus,fbus,1)*sin(theta(tbus,2) - theta(fbus,2)) -
Bik(tbus,fbus,1)*cos(theta(tbus,2) - theta(fbus,2)) ]
);

constPik(k2,1) = measPik(k2,4) -
functPik(k2,1);
constQik(k2,1) = measQik(k2,4) -
functQik(k2,1);
constPik(k2+1,1) = measPik(k2,4) -
functPik(k2,1);
constQik(k2+1,1) = measQik(k2,4) -
functQik(k2,1);

k2 = k2+2;
end
end

% ACTION: Define the symbolic EQUATIONS / CONSTRAINTS


associated with ---
% PSEUDO-MEASUREMENTS required for STATE ESTIMATION
-----------------------
% e.g. measured - calculated power flow at bus i

% ACTION: Initialize counter.


k3 = 1;

% ACTION: Address all rows of mbus.


for k1 = 1:size(mbus,1)

% IF (bus k1 DOES supply pseudo-measurement)


AND (bus k1 is not
% slack bus) THEN...
if ( mbus(k1,7) == 1 ) && ( mbus(k1,2) ~= 1 )

% ACTION: Begin to define power flow


equation.
functPi(k3,1) = [ V(k1,2) * V(k1,2)*
magYbus(k1,k1,1) ] * cos( theta(k1,2) - theta(k1,2) -
angleYbus(k1,k1,1) );

% ACTION: Address all rows of mbus.


for k2 = 1:size(mbus,1)

% IF (k1 is NOT equal to k2) THEN...


if k1 ~= k2

% ACTION: Continue to define power


flow equation.
functPi(k3,1) = functPi(k3,1) + [
V(k1,2) * V(k2,2) * connection_matrix(k1,k2) *
magYbus(k1,k2,1) ] * cos( theta(k1,2) - theta(k2,2) -
angleYbus(k1,k2,1) );

end
end

% ACTION: Define associated constraints.


constPi(k3,1) = pseudomeasPi(k3,2) -
functPi(k3,1);

% ACTION: Increment counter.


k3 = k3 + 1;
end
end

% ACTION: initialize counter

22 of 25 08-03-2014 08:39
n-bus Power Flow Solver / State Estimator - Anthony S. Deese, Ph.D.... https://sites.google.com/site/anthonydeesephd/matlab-files/power-syst...

k3 = 1;

% ACTION: Address all rows of mbus.


for k1 = 1:size(mbus,1)

% IF (bus k1 DOES supply pseudo-measurement)


THEN...
if mbus(k1,7) == 1

% IF (bus k1 IS load bus) THEN...


if mbus(k1,2) == 3

% ACTION: Begin to define power flow


equation.
functQi(k3,1) = [ V(k1,2) * V(k1,2)*
magYbus(k1,k1,1) ] * sin( theta(k1,2) - theta(k1,2) -
angleYbus(k1,k1,1) );

% ACTION: Address all "other" buses.


for k2 = 1:size(mbus,1)

% IF (k1 is NOT equal to k2)


THEN...
if k1 ~= k2

% ACTION: Continue to define


power flow equation.
functQi(k3,1) = functQi(k3,1)
+ [ V(k1,2) * V(k2,2) * connection_matrix(k1,k2) *
magYbus(k1,k2,1) ] * sin( theta(k1,2) - theta(k2,2) -
angleYbus(k1,k2,1) );

end
end

% ACTION: Define associated


constraints.
constQi(k3,1) = pseudomeasQi(k3,2) -
functQi(k3,1);

% ACTION: Increment counter.


k3 = k3 + 1;
end
end
end

% ACTION: Define symbolic ARRAY of CONSTRAINTS for


STATE ESTIMATION -------
% e.g. State Estimation Constraints (sec)

constStateEstimation(:,1) = [ constPik; constPi;


constQik; constQi ];

% ACTION: Define symbolic JACOBIAN matrix for STATE


ESTIMATION ------------
% e.g. referred to as the H matrix

H(:,:,1) =
jacobian(constStateEstimation(:,1),state(:,3));

% ACTION: Initialize mismatch.


mismatch = 9999;

% ACTION: Initialize counter.


k1 = 1;

% ACTION: Continue iterations until either mismatch


falls below
% user-defined threshold or number of iterations
exceeds 25...
while ( abs(mismatch) >
abs(state_estimation_threshold) ) && ( k1 < 25 )

% ACTION: Define index.


index(k1) = k1;

% ACTION: Display iteration number.


clc
state_estimation_iteration = k1
disp(' out of 25 iterations (max)')

% ACTION: perform SUBSTITUTION for STATE

23 of 25 08-03-2014 08:39
n-bus Power Flow Solver / State Estimator - Anthony S. Deese, Ph.D.... https://sites.google.com/site/anthonydeesephd/matlab-files/power-syst...

ESTIMATION -----------------
% e.g. flat start (1 < 0)

constStateEstimation(:,2) = subs(
constStateEstimation(:,1), V(:,2),
double( V(:,3) ));
constStateEstimation(:,2) = subs(
constStateEstimation(:,2), theta(:,2),
double( theta(:,3) ));
constStateEstimation(:,2) = subs(
constStateEstimation(:,2), Gik(:,:,1),
double( Gik(:,:,2) ));
constStateEstimation(:,2) = subs(
constStateEstimation(:,2), Bik(:,:,1),
double( Bik(:,:,2) ));
constStateEstimation(:,2) = subs(
constStateEstimation(:,2), magYbus(:,:,1),
double( magYbus(:,:,2) ));
constStateEstimation(:,2) = subs(
constStateEstimation(:,2), angleYbus(:,:,1),
double( angleYbus(:,:,2) ));
constStateEstimation(:,2) = subs(
constStateEstimation(:,2), measPik(:,4),
double( measPik(:,5) ));
constStateEstimation(:,2) = subs(
constStateEstimation(:,2), measQik(:,4),
double( measQik(:,5) ));
constStateEstimation(:,2) = subs(
constStateEstimation(:,2), pseudomeasPi(:,2),
double( pseudomeasPi(:,3) ));
constStateEstimation(:,2) = subs(
constStateEstimation(:,2), pseudomeasQi(:,2),
double( pseudomeasQi(:,3) ));

H(:,:,2) = subs( H(:,:,1), V(:,2),


double( V(:,3) ));
H(:,:,2) = subs( H(:,:,2), theta(:,2),
double( theta(:,3) ));
H(:,:,2) = subs( H(:,:,2), Gik(:,:,1),
double( Gik(:,:,2) ));
H(:,:,2) = subs( H(:,:,2), Bik(:,:,1),
double( Bik(:,:,2) ));
H(:,:,2) = subs( H(:,:,2), magYbus(:,:,1),
double( magYbus(:,:,2) ));
H(:,:,2) = subs( H(:,:,2), angleYbus(:,:,1),
double( angleYbus(:,:,2) ));
H(:,:,2) = subs( H(:,:,2), measPik(:,4),
double( measPik(:,5) ));
H(:,:,2) = subs( H(:,:,2), measQik(:,4),
double( measQik(:,5) ));

% ACTION: Perform UPDATE for STATE ESTIMATION


------------------------

updated_state = -[ inv(
double(transpose(H(:,:,2))*H(:,:,2))
)*transpose(H(:,:,2))] * constStateEstimation(:,2) +
state(:,4);

% ACTION: Define mismatch.


if k1 > 2
mismatch =
max(abs(double(constStateEstimation(:,2))));
end

% ACTION: Record updates


--------------------------------------------

matrix_record(:,:,k1) = [ inv(
double(transpose(H(:,:,2))*H(:,:,2))
)*transpose(H(:,:,2))];
constStateEstimation_record(:,k1) =
constStateEstimation(:,2);
state_record(:,k1) = state(:,4);
mismatch_record(k1) = mismatch;

% ACTION: Transfer values from updated_state array


to theta and V.
for k2 = 1:size(state,1)
if state(k2,2) == 0
for k3 = 1:size(theta,1)
if state(k2,1) == theta(k3,1)
theta(k3,3) =

24 of 25 08-03-2014 08:39
n-bus Power Flow Solver / State Estimator - Anthony S. Deese, Ph.D.... https://sites.google.com/site/anthonydeesephd/matlab-files/power-syst...

updated_state(k2);
end
end
elseif state(k2,2) == 1
for k3 = 1:size(V,1)
if state(k2,1) == V(k3,1)
V(k3,3) = updated_state(k2);
end
end
end
end

% ACTION: Transfer to state array.


state(:,4) = updated_state;

% ACTION: Update k1.


k1 = k1+1;
end

% ACTION: IF "analysis_type = 1" THEN "perform


state estimation"
if analysis_type == 1
clc
disp('Output of state estimation is shown
below (in per unit and radians)...')
state_estiomation_variables =
transpose(state(:,3))
state_estimation_values =
double(transpose(state(:,4)))
end

% ACTION: Initialize figure #.


figure_number = 0;

% ACTION: Plot results.


for k1 = 1:size(state_record,1)

% ACTION: Generate a new window for every


9-subplots.
if mod(k1-1,9) == 0

% ACTION: Increment figure_number


figure_number = figure_number + 1;
figure(figure_number)
end

% ACTION: Define subplot location.


subplot(3,3,mod(k1-1,9)+1)

% ACTION: Plot data.


if state(k1,2) == 0
plot( index,
360*state_record(k1,:)/(2*pi), 'o-' )
elseif state(k1,2) == 1
plot( index, state_record(k1,:), 'o-' )
end

% ACTION: Generate x-axis label.


xlabel('iteration #')

if state(k1,2) == 0
ylabel(sprintf('theta #%g
(deg)',double(state(k1,1))))
elseif state(k1,2) == 1
ylabel(sprintf('vmag #%g
(pu)',double(state(k1,1))))
end
end

Sign in | Recent Site Activity | Report Abuse | Print Page | Remove Access | Powered By Google Sites

25 of 25 08-03-2014 08:39

S-ar putea să vă placă și