1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 """Construct linear constraints for generator capability curves.
18 """
19
20 from numpy import array, linalg, zeros, arange, r_, c_
21 from numpy import flatnonzero as find
22 from scipy.sparse import csr_matrix as sparse
23
24 from idx_gen import PC1, PC2, QC1MIN, QC1MAX, QC2MIN, QC2MAX
25
26 from hasPQcap import hasPQcap
27
28
30 """Construct linear constraints for generator capability curves.
31
32 Constructs the parameters for the following linear constraints
33 implementing trapezoidal generator capability curves, where
34 C{Pg} and C{Qg} are the real and reactive generator injections::
35
36 Apqh * [Pg, Qg] <= ubpqh
37 Apql * [Pg, Qg] <= ubpql
38
39 C{data} constains additional information as shown below.
40
41 Example::
42 Apqh, ubpqh, Apql, ubpql, data = makeApq(baseMVA, gen)
43
44 data['h'] [Qc1max-Qc2max, Pc2-Pc1]
45 data['l'] [Qc2min-Qc1min, Pc1-Pc2]
46 data['ipqh'] indices of gens with general PQ cap curves (upper)
47 data['ipql'] indices of gens with general PQ cap curves (lower)
48
49 @author: Ray Zimmerman (PSERC Cornell)
50 @author: Carlos E. Murillo-Sanchez (PSERC Cornell & Universidad
51 Autonoma de Manizales)
52 @author: Richard Lincoln
53 """
54 data = {}
55
56 ng = gen.shape[0]
57
58
59
60
61 ipqh = find( hasPQcap(gen, 'U') )
62 ipql = find( hasPQcap(gen, 'L') )
63 npqh = ipqh.shape[0]
64 npql = ipql.shape[0]
65
66
67
68
69 if npqh > 0:
70 data["h"] = c_[gen[ipqh, QC1MAX] - gen[ipqh, QC2MAX],
71 gen[ipqh, PC2] - gen[ipqh, PC1]]
72 ubpqh = data["h"][:, 0] * gen[ipqh, PC1] + \
73 data["h"][:, 1] * gen[ipqh, QC1MAX]
74 for i in range(npqh):
75 tmp = linalg.norm(data["h"][i, :])
76 data["h"][i, :] = data["h"][i, :] / tmp
77 ubpqh[i] = ubpqh[i] / tmp
78 Apqh = sparse((data["h"].flatten('F'),
79 (r_[arange(npqh), arange(npqh)], r_[ipqh, ipqh+ng])),
80 (npqh, 2*ng))
81 ubpqh = ubpqh / baseMVA
82 else:
83 data["h"] = array([])
84 Apqh = zeros((0, 2*ng))
85 ubpqh = array([])
86
87
88 if npql > 0:
89 data["l"] = c_[gen[ipql, QC2MIN] - gen[ipql, QC1MIN],
90 gen[ipql, PC1] - gen[ipql, PC2]]
91 ubpql = data["l"][:, 0] * gen[ipql, PC1] + \
92 data["l"][:, 1] * gen[ipql, QC1MIN]
93 for i in range(npql):
94 tmp = linalg.norm(data["l"][i, :])
95 data["l"][i, :] = data["l"][i, :] / tmp
96 ubpql[i] = ubpql[i] / tmp
97 Apql = sparse((data["l"].flatten('F'),
98 (r_[arange(npql), arange(npql)], r_[ipql, ipql+ng])),
99 (npql, 2*ng))
100 ubpql = ubpql / baseMVA
101 else:
102 data["l"] = array([])
103 Apql = zeros((0, 2*ng))
104 ubpql = array([])
105
106 data["ipql"] = ipql
107 data["ipqh"] = ipqh
108
109 return Apqh, ubpqh, Apql, ubpql, data
110