@@ -9,30 +9,40 @@ function acpf!(ps::Caseps;
9
9
nodes = ps. bus[:,:ID ]
10
10
br_status = ps. branch[:,:status ]
11
11
links = ps. branch[br_status, [:from , :to ]]
12
- graphNos = FindSubsGraphs (nodes,links)
12
+ graphNos, linkNos = FindSubGraphs (nodes,links)
13
13
Vmag = ps. bus[:Vmag ] # note that Vmag and theta are passed by reference, so they are in fact the same as ps.bus[:Vmag] and ps.bus[:Vang]
14
- ps. bus[:Vang ] = 0.0
15
- theta = convert (Array, ps. bus[:Vang ])
14
+ ps. bus[:, : Vang ] = 0.0
15
+ theta = ps. bus[:Vang ]
16
16
n_subgraph = maximum (graphNos)
17
- one_converge_flag = false
17
+ Ybus, Yf, Yt = getYbus (ps)
18
+ Sbus, Sd, Sg = getSbus (ps)
19
+ Sd = sum (Sd,2 )
20
+ D = ps. bus_i[ps. shunt[:,:bus ]]
21
+ Sd_bus = zeros (Complex{Float64},nBus); Sd_bus[D] = Sd
22
+ F = ps. bus_i[ps. branch[:,:from ]]
23
+ T = ps. bus_i[ps. branch[:,:to ]]
24
+ not_converged = Int64[] # list of the islands that did not converge
18
25
for i = 1 : n_subgraph
26
+ # find buses in this island
19
27
busi_sub = find (graphNos .== i)
28
+ # find branches in this island
29
+ bri_sub = find (linkNos .== i)
20
30
mismatch, x0, ix_Vmag_sub, ix_theta_sub, pq_sub, ref_sub =
21
31
init_mismatch (ps, busi_sub, verbose, PartFactFlag, PartFact, PolarFlag)
22
32
# # Solve power flow
23
33
# newton-raphson
24
- x, converged = nrsolve (mismatch, x0, verbose= verbose, linesearch= " exact" );
34
+ x, converged = nrsolve (mismatch, x0, verbose= verbose, linesearch= " exact" )
25
35
26
36
if converged
27
- one_converge_flag = true # just check if at least one converged
28
37
# save the results
29
38
if PolarFlag
30
- idx = [busi_sub][pq_sub]
31
- Vmag[idx] = x[ix_Vmag_sub]
32
- idx = [busi_sub][! ref_sub]
33
- theta[idx] = x[ix_theta_sub]
34
- idx = [busi_sub][ref_sub]
35
- theta[idx] = 0
39
+ Vmag_sub = Vmag[busi_sub]
40
+ Vmag_sub[pq_sub] = x[ix_Vmag_sub]
41
+ Vmag[busi_sub] = Vmag_sub # this updates ps.bus[:,:Vmag]
42
+ theta_sub = theta[busi_sub]
43
+ theta_sub[! ref_sub] = x[ix_theta_sub]
44
+ theta_sub[ref_sub] = 0.
45
+ theta[busi_sub] = theta_sub # this updates ps.bus[:,:Vang]
36
46
else
37
47
# ignore this for now
38
48
#=
@@ -44,57 +54,72 @@ function acpf!(ps::Caseps;
44
54
theta = atan(f./e)
45
55
=#
46
56
end
47
- elseif verbose
48
- println (" Power flow did not converge on island $i of $n_subgraph ." )
49
- end
50
- end
51
- if one_converge_flag
52
- # make sure that only the converged islands have updated data!
53
-
54
- # voltage results
55
- V = Vmag.* exp (im* theta)
56
- D = ps. bus_i[ps. shunt[:,:bus ]]
57
- Ybus, Yf, Yt = getYbus (ps)
58
- Sbus, Sd, Sg = getSbus (ps)
59
- Sd = sum (Sd,2 )
60
- Sd_bus = zeros (Complex{Float64},nBus); Sd_bus[D] = Sd
61
- # branch results
62
- If = Yf* V # branch status is accounted for in Yf
63
- It = Yt* V # branch status is accounted for in Yt
64
- F = ps. bus_i[ps. branch[:,:from ]]
65
- T = ps. bus_i[ps. branch[:,:to ]]
66
- Sf = V[F] .* conj (If)
67
- St = V[T] .* conj (It)
68
- ps. branch[:,:ImagF ] = abs (If)
69
- ps. branch[:,:ImagT ] = abs (It)
70
- ps. branch[:,:Pf ] = real (Sf) * ps. baseMVA
71
- ps. branch[:,:Qf ] = imag (Sf) * ps. baseMVA
72
- ps. branch[:,:Pt ] = real (St) * ps. baseMVA
73
- ps. branch[:,:Qt ] = imag (St) * ps. baseMVA
74
- # update ps.gen
75
- Sg_bus = V.* conj (Ybus* V) + Sd_bus
76
- Pg_bus = real (Sg_bus)
77
- Qg_bus = imag (Sg_bus)
78
- for gi = 1 : size (ps. gen,1 )
79
- gen_bus = ps. gen[gi,1 ]
80
- gen_bus_i = ps. bus_i[gen_bus]
81
- if Vmag[gen_bus_i] == 0
82
- ps. gen[gi,:P ] = 0
83
- ps. gen[gi,:Q ] = 0
84
- else
85
- gens_at_bus = ps. gen[:,1 ] .== gen_bus
86
- if sum (gens_at_bus) == 1
87
- Pg_ratio = 1
57
+ # update results in ps only for this island
58
+ V_sub = Vmag_sub.* exp (im* theta_sub)
59
+ V = zeros (Complex{Float64},nBus)
60
+ V[busi_sub] = V_sub
61
+ V_sub = Vmag_sub.* exp (im* theta_sub)
62
+ Yf_sub = Yf[bri_sub,busi_sub]
63
+ Yt_sub = Yt[bri_sub,busi_sub]
64
+ If_sub = Yf_sub* V_sub
65
+ It_sub = Yt_sub* V_sub
66
+ F_sub = F[bri_sub]
67
+ Sf_sub = V[F_sub] .* conj (If_sub)
68
+ T_sub = T[bri_sub]
69
+ St_sub = V[T_sub] .* conj (It_sub)
70
+ ps. branch[bri_sub,:ImagF ] = abs (If_sub)
71
+ ps. branch[bri_sub,:ImagT ] = abs (It_sub)
72
+ ps. branch[bri_sub,:Pf ] = real (Sf_sub) * ps. baseMVA
73
+ ps. branch[bri_sub,:Qf ] = imag (Sf_sub) * ps. baseMVA
74
+ ps. branch[bri_sub,:Pt ] = real (St_sub) * ps. baseMVA
75
+ ps. branch[bri_sub,:Qt ] = imag (St_sub) * ps. baseMVA
76
+ # update ps.gen
77
+ Ybus_sub = Ybus[busi_sub,busi_sub]
78
+ Sg_bus_sub = V_sub.* conj (Ybus_sub* V_sub) + Sd_bus[busi_sub]
79
+ Pg_bus_sub = real (Sg_bus_sub)
80
+ Qg_bus_sub = imag (Sg_bus_sub)
81
+ gen_busID = ps. gen[:,:bus ]
82
+ gen_busi = ps. bus_i[gen_busID]
83
+ for (j,this_bus_i) = enumerate (busi_sub)
84
+ gi = (gen_busi .== this_bus_i)
85
+ if V[this_bus_i] == 0.
86
+ ps. gen[gi,:P ] = 0.
87
+ ps. gen[gi,:Q ] = 0.
88
88
else
89
- Pg_ratio = ps. gen[gi,:Pmax ]/ sum (ps. gen[gens_at_bus,:Pmax ])
89
+ if sum (gi) == 1
90
+ Pg_ratio = 1
91
+ else
92
+ Pg_ratio = ps. gen[gi,:Pmax ]/ sum (ps. gen[gi,:Pmax ])
93
+ end
94
+ ps. gen[gi,:P ] = Pg_bus_sub[j] * Pg_ratio * ps. baseMVA
95
+ ps. gen[gi,:Q ] = Qg_bus_sub[j] * Pg_ratio * ps. baseMVA
90
96
end
91
- ps. gen[gi,:P ] = Pg_bus[gen_bus_i] * Pg_ratio * ps. baseMVA
92
- ps. gen[gi,:Q ] = Qg_bus[gen_bus_i] * Pg_ratio * ps. baseMVA
93
97
end
94
- end
98
+ else
99
+ if verbose
100
+ println (" Power flow did not converge on island $i of $n_subgraph ." )
101
+ end
102
+ not_converged = [not_converged, i]
103
+ # update ps with 0 values for non-converged islands
104
+ Vmag[busi_sub] = 0.
105
+ theta[busi_sub] = 0.
106
+ ps. branch[bri_sub,:ImagF ] = 0.
107
+ ps. branch[bri_sub,:ImagT ] = 0.
108
+ ps. branch[bri_sub,:Pf ] = 0.
109
+ ps. branch[bri_sub,:Qf ] = 0.
110
+ ps. branch[bri_sub,:Pt ] = 0.
111
+ ps. branch[bri_sub,:Qt ] = 0.
112
+ gen_busID = ps. gen[:,:bus ]
113
+ gen_busi = ps. bus_i[gen_busID]
114
+ for j = busi_sub
115
+ gi = (gen_busi .== j)
116
+ ps. gen[gi,:P ] = 0.
117
+ ps. gen[gi,:Q ] = 0.
118
+ end
119
+ end
95
120
end
96
121
97
- return
122
+ return not_converged
98
123
99
124
#=
100
125
# solve the unconstrained optimization problem 1/2 * g(x)' * g(x) using levenberg-marquardt
0 commit comments