1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 """Computes partial derivatives of power injection w.r.t. voltage.
18 """
19
20 from numpy import conj, diag, asmatrix, asarray
21 from scipy.sparse import issparse, csr_matrix as sparse
22
23
25 """Computes partial derivatives of power injection w.r.t. voltage.
26
27 Returns two matrices containing partial derivatives of the complex bus
28 power injections w.r.t voltage magnitude and voltage angle respectively
29 (for all buses). If C{Ybus} is a sparse matrix, the return values will be
30 also. The following explains the expressions used to form the matrices::
31
32 S = diag(V) * conj(Ibus) = diag(conj(Ibus)) * V
33
34 Partials of V & Ibus w.r.t. voltage magnitudes::
35 dV/dVm = diag(V / abs(V))
36 dI/dVm = Ybus * dV/dVm = Ybus * diag(V / abs(V))
37
38 Partials of V & Ibus w.r.t. voltage angles::
39 dV/dVa = j * diag(V)
40 dI/dVa = Ybus * dV/dVa = Ybus * j * diag(V)
41
42 Partials of S w.r.t. voltage magnitudes::
43 dS/dVm = diag(V) * conj(dI/dVm) + diag(conj(Ibus)) * dV/dVm
44 = diag(V) * conj(Ybus * diag(V / abs(V)))
45 + conj(diag(Ibus)) * diag(V / abs(V))
46
47 Partials of S w.r.t. voltage angles::
48 dS/dVa = diag(V) * conj(dI/dVa) + diag(conj(Ibus)) * dV/dVa
49 = diag(V) * conj(Ybus * j * diag(V))
50 + conj(diag(Ibus)) * j * diag(V)
51 = -j * diag(V) * conj(Ybus * diag(V))
52 + conj(diag(Ibus)) * j * diag(V)
53 = j * diag(V) * conj(diag(Ibus) - Ybus * diag(V))
54
55 For more details on the derivations behind the derivative code used
56 in PYPOWER information, see:
57
58 [TN2] R. D. Zimmerman, "AC Power Flows, Generalized OPF Costs and
59 their Derivatives using Complex Matrix Notation", MATPOWER
60 Technical Note 2, February 2010.
61 U{http://www.pserc.cornell.edu/matpower/TN2-OPF-Derivatives.pdf}
62
63 @author: Ray Zimmerman (PSERC Cornell)
64 @author: Richard Lincoln
65 """
66 ib = range(len(V))
67
68 if issparse(Ybus):
69 Ibus = Ybus * V
70
71 diagV = sparse((V, (ib, ib)))
72 diagIbus = sparse((Ibus, (ib, ib)))
73 diagVnorm = sparse((V / abs(V), (ib, ib)))
74 else:
75 Ibus = Ybus * asmatrix(V).T
76
77 diagV = asmatrix(diag(V))
78 diagIbus = asmatrix(diag( asarray(Ibus).flatten() ))
79 diagVnorm = asmatrix(diag(V / abs(V)))
80
81 dS_dVm = diagV * conj(Ybus * diagVnorm) + conj(diagIbus) * diagVnorm
82 dS_dVa = 1j * diagV * conj(diagIbus - Ybus * diagV)
83
84 return dS_dVm, dS_dVa
85