-
Notifications
You must be signed in to change notification settings - Fork 2
/
vcpf.m
100 lines (98 loc) · 3.71 KB
/
vcpf.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
function [U, Sslack, Sg, Sf, St, iter] = vcpf(Uslack,NB,NL,f,Zbranch,Ybranch,Yd,Sd,gen_bus,Sg,Ug,gen_type,epsilon,iter_max)
%CALC_V_PQ_SUM Solves the power flow using the power summation method.
%
% [U, Sslack, Sg, Sf, St, iter] = vcpf(Uslack,NB,NL,f,Zbranch,Ybranch,Yd,Sd,gen_bus,Sg,Ug,gen_type,epsilon,iter_max)
%
% Solves for bus voltages, generator reactive power, branch active and
% reactive power flows and slack bus active and reactive power. The input
% data consist of slack bus voltage, number of buses and branches,
% vector "from bus" indices, branch impedance and shunt admittance,
% vector of bus shunt admittances and load demand, as well as vectors
% with indicies of PV buses with their active powers and specified voltages.
% It is assumed that the branches are ordered using the principle of
% oriented ordering: indicies of sending nodes are smaller then the indicies
% of the receiving nodes. The branch index is equal to the index of their
% receiving node. Branch addmittances are added in Yd and treated as constant
% admittance bus loads.
% The applied method is Voltage correction power flow (VCPF) taken from:
% D. Rajicic, R. Ackovski and R. Taleski, "Voltage correction power flow,"
% IEEE Transactions on Power Delivery, vol. 9, no. 2, pp. 1056-1062, Apr 1994.
% https://doi.org/10.1109/61.296308
%
% See also DIST_PF.
% initialize variables
U = Uslack * ones(NB,1);
Uold = U;
iter = 0;
finish = 0;
% Add artificial branch at the top of branches, so that the number of each
% branch equals the number of the receiving node
f = [0; f];
Zbranch = [0; Zbranch];
NL = NL + 1;
% Split generators into PQ type and PV type
gen_pq = find(gen_type == 1);
gen_pv = find(gen_type == 2);
pv = gen_bus(gen_pv);
Ug = Ug(gen_pv);
% For generators of type PQ add negative of their complex power to bus load
Sd(gen_bus(gen_pq)) = Sd(gen_bus(gen_pq)) - Sg(gen_pq);
% For generators of type PV add negative of their real power to bus load
Sd(gen_bus(gen_pv)) = Sd(gen_bus(gen_pv)) - real(Sg(gen_pv));
% Make impedance matrix for all PV buses
Zpv = make_zpv(pv,NB,NL,f,Zbranch);
if size(Zpv,1) > 0
Bpv = (imag(Zpv))^-1;
end
% Voltage Correction Power Flow
npv = length(pv);
Qpv = zeros(npv,1);
while finish == 0 && iter < iter_max
iter = iter + 1;
% Initial branch flows, equal to receiving node load (incl. shunts)
S = Sd + conj(Yd).*abs(U).^2;
St = S;
Sf = St;
% Backward sweep
for k = NL:-1:2
i = f(k);
Sf(k) = St(k) + Zbranch(k) * abs(St(k)/U(k))^2;
St(i) = St(i) + Sf(k);
end
% Forward sweep
for k = 2:NL
i = f(k);
U(k) = U(i) - Zbranch(k) * conj(Sf(k)/U(i));
end
% Check convergence
DU = abs(U - Uold);
if max(DU) > epsilon
Uold = U;
if ~isempty(pv)
% Calculate reactive power correction for PV generators
DE = (Ug./abs(U(pv))-1).*real(U(pv)); % Rajicic (VCPF)
DD = Bpv * DE;
DC = DD .* imag(U(pv))./real(U(pv));
% Make voltage correction
V_corr = make_vcorr(DC+1j*DD,pv,NB,NL,f,Zbranch);
U = U + V_corr;
DQ = DD .* abs(U(pv)).^2 ./ real(U(pv));
% Update reactive power for PV generators
Qpv = Qpv + DQ;
Sd(pv) = Sd(pv) - 1j*DQ;
end
else
finish = 1;
end
end
% Save generators reactive powers and branch flows
if ~isempty(gen_pv)
Sg(gen_pv) = real(Sg(gen_pv)) + 1j*Qpv;
end
Sslack = St(1);
Sf = Sf(2:end);
St = St(2:end);
f = f(2:end);
% Account for branch shunt power flows
Sf = Sf + conj(Ybranch) .* abs(U(f)).^2 / 2;
St = St - conj(Ybranch) .* abs(U(2:end)).^2 / 2;