forked from MATPOWER/matpower
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathnewtonpf.m
137 lines (120 loc) · 4.2 KB
/
newtonpf.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
function [V, converged, i] = newtonpf(Ybus, Sbus, V0, ref, pv, pq, mpopt)
%NEWTONPF Solves the power flow using a full Newton's method.
% [V, CONVERGED, I] = NEWTONPF(YBUS, SBUS, V0, REF, PV, PQ, MPOPT)
% solves for bus voltages given the full system admittance matrix (for
% all buses), the complex bus power injection vector (for all buses),
% the initial vector of complex bus voltages, and column vectors with
% the lists of bus indices for the swing bus, PV buses, and PQ buses,
% respectively. The bus voltage vector contains the set point for
% generator (including ref bus) buses, and the reference angle of the
% swing bus, as well as an initial guess for remaining magnitudes and
% angles. MPOPT is a MATPOWER options struct which can be used to
% set the termination tolerance, maximum number of iterations, and
% output options (see MPOPTION for details). Uses default options if
% this parameter is not given. Returns the final complex voltages, a
% flag which indicates whether it converged or not, and the number of
% iterations performed.
%
% See also RUNPF.
% MATPOWER
% Copyright (c) 1996-2017, Power Systems Engineering Research Center (PSERC)
% by Ray Zimmerman, PSERC Cornell
%
% This file is part of MATPOWER.
% Covered by the 3-clause BSD License (see LICENSE file for details).
% See http://www.pserc.cornell.edu/matpower/ for more info.
%% default arguments
if nargin < 7
mpopt = mpoption;
end
%% options
tol = mpopt.pf.tol;
max_it = mpopt.pf.nr.max_it;
lin_solver = mpopt.pf.nr.lin_solver;
%% initialize
converged = 0;
i = 0;
V = V0;
Va = angle(V);
Vm = abs(V);
%% set up indexing for updating V
npv = length(pv);
npq = length(pq);
j1 = 1; j2 = npv; %% j1:j2 - V angle of pv buses
j3 = j2 + 1; j4 = j2 + npq; %% j3:j4 - V angle of pq buses
j5 = j4 + 1; j6 = j4 + npq; %% j5:j6 - V mag of pq buses
%% evaluate F(x0)
mis = V .* conj(Ybus * V) - Sbus(Vm);
F = [ real(mis([pv; pq]));
imag(mis(pq)) ];
%% check tolerance
normF = norm(F, inf);
if mpopt.verbose > 1
fprintf('\n it max P & Q mismatch (p.u.)');
fprintf('\n---- ---------------------------');
fprintf('\n%3d %10.3e', i, normF);
end
if normF < tol
converged = 1;
if mpopt.verbose > 1
fprintf('\nConverged!\n');
end
end
%% attempt to pick fastest linear solver, if not specified
if isempty(lin_solver)
nx = length(F);
if nx <= 10 || (nx <= 2000 && have_fcn('octave'))
lin_solver = '\'; %% default \ operator
else %% MATLAB and nx > 10 or Octave and nx > 2000
lin_solver = 'LU3'; %% LU decomp with 3 output args, AMD ordering
end
end
%% do Newton iterations
while (~converged && i < max_it)
%% update iteration counter
i = i + 1;
%% evaluate Jacobian
[dSbus_dVm, dSbus_dVa] = dSbus_dV(Ybus, V);
[dummy, neg_dSd_dVm] = Sbus(Vm);
dSbus_dVm = dSbus_dVm - neg_dSd_dVm;
j11 = real(dSbus_dVa([pv; pq], [pv; pq]));
j12 = real(dSbus_dVm([pv; pq], pq));
j21 = imag(dSbus_dVa(pq, [pv; pq]));
j22 = imag(dSbus_dVm(pq, pq));
J = [ j11 j12;
j21 j22; ];
%% compute update step
dx = mplinsolve(J, -F, lin_solver);
%% update voltage
if npv
Va(pv) = Va(pv) + dx(j1:j2); %for PV bus only angle is unknown
end
if npq
Va(pq) = Va(pq) + dx(j3:j4); %for PQ buses both voltage
Vm(pq) = Vm(pq) + dx(j5:j6); %angle and magnitude are unknown
end
V = Vm .* exp(1j * Va);
Vm = abs(V); %% update Vm and Va again in case
Va = angle(V); %% we wrapped around with a negative Vm
%% evalute F(x)
mis = V .* conj(Ybus * V) - Sbus(Vm);
F = [ real(mis(pv));
real(mis(pq));
imag(mis(pq)) ];
%% check for convergence
normF = norm(F, inf);
if mpopt.verbose > 1
fprintf('\n%3d %10.3e', i, normF);
end
if normF < tol
converged = 1;
if mpopt.verbose
fprintf('\nNewton''s method power flow converged in %d iterations.\n', i);
end
end
end
if mpopt.verbose
if ~converged
fprintf('\nNewton''s method power flow did not converge in %d iterations.\n', i);
end
end