ltbams 0.9.9__py3-none-any.whl → 1.0.2a1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (191) hide show
  1. ams/__init__.py +4 -11
  2. ams/_version.py +3 -3
  3. ams/cases/5bus/pjm5bus_demo.xlsx +0 -0
  4. ams/cases/5bus/pjm5bus_jumper.xlsx +0 -0
  5. ams/cases/5bus/pjm5bus_uced.json +1062 -0
  6. ams/cases/5bus/pjm5bus_uced.xlsx +0 -0
  7. ams/cases/5bus/pjm5bus_uced_esd1.xlsx +0 -0
  8. ams/cases/5bus/pjm5bus_uced_ev.xlsx +0 -0
  9. ams/cases/ieee123/ieee123.xlsx +0 -0
  10. ams/cases/ieee123/ieee123_regcv1.xlsx +0 -0
  11. ams/cases/ieee14/ieee14.json +1166 -0
  12. ams/cases/ieee14/ieee14.raw +92 -0
  13. ams/cases/ieee14/ieee14_conn.xlsx +0 -0
  14. ams/cases/ieee14/ieee14_uced.xlsx +0 -0
  15. ams/cases/ieee39/ieee39.xlsx +0 -0
  16. ams/cases/ieee39/ieee39_uced.xlsx +0 -0
  17. ams/cases/ieee39/ieee39_uced_esd1.xlsx +0 -0
  18. ams/cases/ieee39/ieee39_uced_pvd1.xlsx +0 -0
  19. ams/cases/ieee39/ieee39_uced_vis.xlsx +0 -0
  20. ams/cases/matpower/benchmark.json +1594 -0
  21. ams/cases/matpower/case118.m +787 -0
  22. ams/cases/matpower/case14.m +129 -0
  23. ams/cases/matpower/case300.m +1315 -0
  24. ams/cases/matpower/case39.m +205 -0
  25. ams/cases/matpower/case5.m +62 -0
  26. ams/cases/matpower/case_ACTIVSg2000.m +9460 -0
  27. ams/cases/npcc/npcc.m +644 -0
  28. ams/cases/npcc/npcc_uced.xlsx +0 -0
  29. ams/cases/pglib/pglib_opf_case39_epri__api.m +243 -0
  30. ams/cases/wecc/wecc.m +714 -0
  31. ams/cases/wecc/wecc_uced.xlsx +0 -0
  32. ams/cli.py +6 -0
  33. ams/core/__init__.py +2 -0
  34. ams/core/documenter.py +652 -0
  35. ams/core/matprocessor.py +782 -0
  36. ams/core/model.py +330 -0
  37. ams/core/param.py +322 -0
  38. ams/core/service.py +918 -0
  39. ams/core/symprocessor.py +224 -0
  40. ams/core/var.py +59 -0
  41. ams/extension/__init__.py +5 -0
  42. ams/extension/eva.py +401 -0
  43. ams/interface.py +1085 -0
  44. ams/io/__init__.py +133 -0
  45. ams/io/json.py +82 -0
  46. ams/io/matpower.py +406 -0
  47. ams/io/psse.py +6 -0
  48. ams/io/pypower.py +103 -0
  49. ams/io/xlsx.py +80 -0
  50. ams/main.py +81 -4
  51. ams/models/__init__.py +24 -0
  52. ams/models/area.py +40 -0
  53. ams/models/bus.py +52 -0
  54. ams/models/cost.py +169 -0
  55. ams/models/distributed/__init__.py +3 -0
  56. ams/models/distributed/esd1.py +71 -0
  57. ams/models/distributed/ev.py +60 -0
  58. ams/models/distributed/pvd1.py +67 -0
  59. ams/models/group.py +231 -0
  60. ams/models/info.py +26 -0
  61. ams/models/line.py +238 -0
  62. ams/models/renewable/__init__.py +5 -0
  63. ams/models/renewable/regc.py +119 -0
  64. ams/models/reserve.py +94 -0
  65. ams/models/shunt.py +14 -0
  66. ams/models/static/__init__.py +2 -0
  67. ams/models/static/gen.py +165 -0
  68. ams/models/static/pq.py +61 -0
  69. ams/models/timeslot.py +69 -0
  70. ams/models/zone.py +49 -0
  71. ams/opt/__init__.py +12 -0
  72. ams/opt/constraint.py +175 -0
  73. ams/opt/exprcalc.py +127 -0
  74. ams/opt/expression.py +188 -0
  75. ams/opt/objective.py +174 -0
  76. ams/opt/omodel.py +432 -0
  77. ams/opt/optzbase.py +192 -0
  78. ams/opt/param.py +156 -0
  79. ams/opt/var.py +233 -0
  80. ams/pypower/__init__.py +8 -0
  81. ams/pypower/_compat.py +9 -0
  82. ams/pypower/core/__init__.py +8 -0
  83. ams/pypower/core/pips.py +894 -0
  84. ams/pypower/core/ppoption.py +244 -0
  85. ams/pypower/core/ppver.py +18 -0
  86. ams/pypower/core/solver.py +2451 -0
  87. ams/pypower/eps.py +6 -0
  88. ams/pypower/idx.py +174 -0
  89. ams/pypower/io.py +604 -0
  90. ams/pypower/make/__init__.py +11 -0
  91. ams/pypower/make/matrices.py +665 -0
  92. ams/pypower/make/pdv.py +506 -0
  93. ams/pypower/routines/__init__.py +7 -0
  94. ams/pypower/routines/cpf.py +513 -0
  95. ams/pypower/routines/cpf_callbacks.py +114 -0
  96. ams/pypower/routines/opf.py +1803 -0
  97. ams/pypower/routines/opffcns.py +1946 -0
  98. ams/pypower/routines/pflow.py +852 -0
  99. ams/pypower/toggle.py +1098 -0
  100. ams/pypower/utils.py +293 -0
  101. ams/report.py +212 -50
  102. ams/routines/__init__.py +23 -0
  103. ams/routines/acopf.py +117 -0
  104. ams/routines/cpf.py +65 -0
  105. ams/routines/dcopf.py +241 -0
  106. ams/routines/dcpf.py +209 -0
  107. ams/routines/dcpf0.py +196 -0
  108. ams/routines/dopf.py +150 -0
  109. ams/routines/ed.py +312 -0
  110. ams/routines/pflow.py +255 -0
  111. ams/routines/pflow0.py +113 -0
  112. ams/routines/routine.py +1033 -0
  113. ams/routines/rted.py +519 -0
  114. ams/routines/type.py +160 -0
  115. ams/routines/uc.py +376 -0
  116. ams/shared.py +63 -9
  117. ams/system.py +61 -22
  118. ams/utils/__init__.py +3 -0
  119. ams/utils/misc.py +77 -0
  120. ams/utils/paths.py +257 -0
  121. docs/Makefile +21 -0
  122. docs/make.bat +35 -0
  123. docs/source/_templates/autosummary/base.rst +5 -0
  124. docs/source/_templates/autosummary/class.rst +35 -0
  125. docs/source/_templates/autosummary/module.rst +65 -0
  126. docs/source/_templates/autosummary/module_toctree.rst +66 -0
  127. docs/source/api.rst +102 -0
  128. docs/source/conf.py +203 -0
  129. docs/source/examples/index.rst +34 -0
  130. docs/source/genmodelref.py +61 -0
  131. docs/source/genroutineref.py +47 -0
  132. docs/source/getting_started/copyright.rst +20 -0
  133. docs/source/getting_started/formats/index.rst +20 -0
  134. docs/source/getting_started/formats/matpower.rst +183 -0
  135. docs/source/getting_started/formats/psse.rst +46 -0
  136. docs/source/getting_started/formats/pypower.rst +223 -0
  137. docs/source/getting_started/formats/xlsx.png +0 -0
  138. docs/source/getting_started/formats/xlsx.rst +23 -0
  139. docs/source/getting_started/index.rst +76 -0
  140. docs/source/getting_started/install.rst +234 -0
  141. docs/source/getting_started/overview.rst +26 -0
  142. docs/source/getting_started/testcase.rst +45 -0
  143. docs/source/getting_started/verification.rst +13 -0
  144. docs/source/images/curent.ico +0 -0
  145. docs/source/images/dcopf_time.png +0 -0
  146. docs/source/images/sponsors/CURENT_Logo_NameOnTrans.png +0 -0
  147. docs/source/images/sponsors/CURENT_Logo_Transparent.png +0 -0
  148. docs/source/images/sponsors/CURENT_Logo_Transparent_Name.png +0 -0
  149. docs/source/images/sponsors/doe.png +0 -0
  150. docs/source/index.rst +108 -0
  151. docs/source/modeling/example.rst +159 -0
  152. docs/source/modeling/index.rst +17 -0
  153. docs/source/modeling/model.rst +210 -0
  154. docs/source/modeling/routine.rst +122 -0
  155. docs/source/modeling/system.rst +51 -0
  156. docs/source/release-notes.rst +398 -0
  157. ltbams-1.0.2a1.dist-info/METADATA +210 -0
  158. ltbams-1.0.2a1.dist-info/RECORD +188 -0
  159. {ltbams-0.9.9.dist-info → ltbams-1.0.2a1.dist-info}/WHEEL +1 -1
  160. ltbams-1.0.2a1.dist-info/top_level.txt +3 -0
  161. tests/__init__.py +0 -0
  162. tests/test_1st_system.py +33 -0
  163. tests/test_addressing.py +40 -0
  164. tests/test_andes_mats.py +61 -0
  165. tests/test_case.py +266 -0
  166. tests/test_cli.py +34 -0
  167. tests/test_export_csv.py +89 -0
  168. tests/test_group.py +83 -0
  169. tests/test_interface.py +216 -0
  170. tests/test_io.py +32 -0
  171. tests/test_jumper.py +27 -0
  172. tests/test_known_good.py +267 -0
  173. tests/test_matp.py +437 -0
  174. tests/test_model.py +54 -0
  175. tests/test_omodel.py +119 -0
  176. tests/test_paths.py +22 -0
  177. tests/test_report.py +251 -0
  178. tests/test_repr.py +21 -0
  179. tests/test_routine.py +178 -0
  180. tests/test_rtn_dcopf.py +101 -0
  181. tests/test_rtn_dcpf.py +77 -0
  182. tests/test_rtn_ed.py +279 -0
  183. tests/test_rtn_pflow.py +219 -0
  184. tests/test_rtn_rted.py +273 -0
  185. tests/test_rtn_uc.py +248 -0
  186. tests/test_service.py +73 -0
  187. ltbams-0.9.9.dist-info/LICENSE +0 -692
  188. ltbams-0.9.9.dist-info/METADATA +0 -859
  189. ltbams-0.9.9.dist-info/RECORD +0 -14
  190. ltbams-0.9.9.dist-info/top_level.txt +0 -1
  191. {ltbams-0.9.9.dist-info → ltbams-1.0.2a1.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,506 @@
1
+ """
2
+ Make partial derivatives matrices w.r.t. voltage.
3
+ """
4
+
5
+ import logging # NOQA
6
+
7
+ import numpy as np # NOQA
8
+ import scipy.sparse as sp # NOQA
9
+ from scipy.sparse import csr_matrix as c_sparse # NOQA
10
+
11
+ from ams.pypower.idx import IDX # NOQA
12
+
13
+ logger = logging.getLogger(__name__)
14
+
15
+
16
+ def dSbus_dV(Ybus, V):
17
+ """
18
+ Computes partial derivatives of power injection w.r.t. voltage.
19
+
20
+ Returns two matrices containing partial derivatives of the complex bus
21
+ power injections w.r.t voltage magnitude and voltage angle respectively
22
+ (for all buses). If C{Ybus} is a c_sparse matrix, the return values will be
23
+ also. The following explains the expressions used to form the matrices::
24
+
25
+ S = diag(V) * conj(Ibus) = diag(conj(Ibus)) * V
26
+
27
+ Partials of V & Ibus w.r.t. voltage magnitudes::
28
+ dV/dVm = diag(V / abs(V))
29
+ dI/dVm = Ybus * dV/dVm = Ybus * diag(V / abs(V))
30
+
31
+ Partials of V & Ibus w.r.t. voltage angles::
32
+ dV/dVa = j * diag(V)
33
+ dI/dVa = Ybus * dV/dVa = Ybus * j * diag(V)
34
+
35
+ Partials of S w.r.t. voltage magnitudes::
36
+ dS/dVm = diag(V) * conj(dI/dVm) + diag(conj(Ibus)) * dV/dVm
37
+ = diag(V) * conj(Ybus * diag(V / abs(V)))
38
+ + conj(diag(Ibus)) * diag(V / abs(V))
39
+
40
+ Partials of S w.r.t. voltage angles::
41
+ dS/dVa = diag(V) * conj(dI/dVa) + diag(conj(Ibus)) * dV/dVa
42
+ = diag(V) * conj(Ybus * j * diag(V))
43
+ + conj(diag(Ibus)) * j * diag(V)
44
+ = -j * diag(V) * conj(Ybus * diag(V))
45
+ + conj(diag(Ibus)) * j * diag(V)
46
+ = j * diag(V) * conj(diag(Ibus) - Ybus * diag(V))
47
+
48
+ For more details on the derivations behind the derivative code used
49
+ in PYPOWER information, see:
50
+
51
+ [TN2] R. D. Zimmerman, "AC Power Flows, Generalized OPF Costs and
52
+ their Derivatives using Complex Matrix Notation", MATPOWER
53
+ Technical Note 2, February 2010.
54
+ U{http://www.pserc.cornell.edu/matpower/TN2-OPF-Derivatives.pdf}
55
+
56
+ @author: Ray Zimmerman (PSERC Cornell)
57
+ """
58
+ ib = range(len(V))
59
+
60
+ if sp.issparse(Ybus):
61
+ Ibus = Ybus * V
62
+
63
+ diagV = c_sparse((V, (ib, ib)))
64
+ diagIbus = c_sparse((Ibus, (ib, ib)))
65
+ diagVnorm = c_sparse((V / abs(V), (ib, ib)))
66
+ else:
67
+ Ibus = Ybus * np.asmatrix(V).T
68
+
69
+ diagV = np.asmatrix(np.diag(V))
70
+ diagIbus = np.asmatrix(np.diag(np.asarray(Ibus).flatten()))
71
+ diagVnorm = np.asmatrix(np.diag(V / abs(V)))
72
+
73
+ dS_dVm = diagV * np.conj(Ybus * diagVnorm) + np.conj(diagIbus) * diagVnorm
74
+ dS_dVa = 1j * diagV * np.conj(diagIbus - Ybus * diagV)
75
+
76
+ return dS_dVm, dS_dVa
77
+
78
+
79
+ def dIbr_dV(branch, Yf, Yt, V):
80
+ """Computes partial derivatives of branch currents w.r.t. voltage.
81
+
82
+ Returns four matrices containing partial derivatives of the complex
83
+ branch currents at "from" and "to" ends of each branch w.r.t voltage
84
+ magnitude and voltage angle respectively (for all buses). If C{Yf} is a
85
+ c_sparse matrix, the partial derivative matrices will be as well. Optionally
86
+ returns vectors containing the currents themselves. The following
87
+ explains the expressions used to form the matrices::
88
+
89
+ If = Yf * V
90
+
91
+ Partials of V, Vf & If w.r.t. voltage angles::
92
+ dV/dVa = j * diag(V)
93
+ dVf/dVa = c_sparse(range(nl), f, j*V(f)) = j * c_sparse(range(nl), f, V(f))
94
+ dIf/dVa = Yf * dV/dVa = Yf * j * diag(V)
95
+
96
+ Partials of V, Vf & If w.r.t. voltage magnitudes::
97
+ dV/dVm = diag(V / abs(V))
98
+ dVf/dVm = c_sparse(range(nl), f, V(f) / abs(V(f))
99
+ dIf/dVm = Yf * dV/dVm = Yf * diag(V / abs(V))
100
+
101
+ Derivations for "to" bus are similar.
102
+
103
+ @author: Ray Zimmerman (PSERC Cornell)
104
+ """
105
+ i = range(len(V))
106
+
107
+ Vnorm = V / abs(V)
108
+
109
+ if sp.issparse(Yf):
110
+ diagV = c_sparse((V, (i, i)))
111
+ diagVnorm = c_sparse((Vnorm, (i, i)))
112
+ else:
113
+ diagV = np.asmatrix(np.diag(V))
114
+ diagVnorm = np.asmatrix(np.diag(Vnorm))
115
+
116
+ dIf_dVa = Yf * 1j * diagV
117
+ dIf_dVm = Yf * diagVnorm
118
+ dIt_dVa = Yt * 1j * diagV
119
+ dIt_dVm = Yt * diagVnorm
120
+
121
+ # Compute currents.
122
+ if sp.issparse(Yf):
123
+ If = Yf * V
124
+ It = Yt * V
125
+ else:
126
+ If = np.asarray(Yf * np.asmatrix(V).T).flatten()
127
+ It = np.asarray(Yt * np.asmatrix(V).T).flatten()
128
+
129
+ return dIf_dVa, dIf_dVm, dIt_dVa, dIt_dVm, If, It
130
+
131
+
132
+ def dSbr_dV(branch, Yf, Yt, V):
133
+ """Computes partial derivatives of power flows w.r.t. voltage.
134
+
135
+ returns four matrices containing partial derivatives of the complex
136
+ branch power flows at "from" and "to" ends of each branch w.r.t voltage
137
+ magnitude and voltage angle respectively (for all buses). If C{Yf} is a
138
+ c_sparse matrix, the partial derivative matrices will be as well. Optionally
139
+ returns vectors containing the power flows themselves. The following
140
+ explains the expressions used to form the matrices::
141
+
142
+ If = Yf * V;
143
+ Sf = diag(Vf) * conj(If) = diag(conj(If)) * Vf
144
+
145
+ Partials of V, Vf & If w.r.t. voltage angles::
146
+ dV/dVa = j * diag(V)
147
+ dVf/dVa = c_sparse(range(nl), f, j*V(f)) = j * c_sparse(range(nl), f, V(f))
148
+ dIf/dVa = Yf * dV/dVa = Yf * j * diag(V)
149
+
150
+ Partials of V, Vf & If w.r.t. voltage magnitudes::
151
+ dV/dVm = diag(V / abs(V))
152
+ dVf/dVm = c_sparse(range(nl), f, V(f) / abs(V(f))
153
+ dIf/dVm = Yf * dV/dVm = Yf * diag(V / abs(V))
154
+
155
+ Partials of Sf w.r.t. voltage angles::
156
+ dSf/dVa = diag(Vf) * conj(dIf/dVa)
157
+ + diag(conj(If)) * dVf/dVa
158
+ = diag(Vf) * conj(Yf * j * diag(V))
159
+ + conj(diag(If)) * j * c_sparse(range(nl), f, V(f))
160
+ = -j * diag(Vf) * conj(Yf * diag(V))
161
+ + j * conj(diag(If)) * c_sparse(range(nl), f, V(f))
162
+ = j * (conj(diag(If)) * c_sparse(range(nl), f, V(f))
163
+ - diag(Vf) * conj(Yf * diag(V)))
164
+
165
+ Partials of Sf w.r.t. voltage magnitudes::
166
+ dSf/dVm = diag(Vf) * conj(dIf/dVm)
167
+ + diag(conj(If)) * dVf/dVm
168
+ = diag(Vf) * conj(Yf * diag(V / abs(V)))
169
+ + conj(diag(If)) * c_sparse(range(nl), f, V(f)/abs(V(f)))
170
+
171
+ Derivations for "to" bus are similar.
172
+
173
+ For more details on the derivations behind the derivative code used
174
+ in PYPOWER information, see:
175
+
176
+ [TN2] R. D. Zimmerman, "AC Power Flows, Generalized OPF Costs and
177
+ their Derivatives using Complex Matrix Notation", MATPOWER
178
+ Technical Note 2, February 2010.
179
+ U{http://www.pserc.cornell.edu/matpower/TN2-OPF-Derivatives.pdf}
180
+
181
+ @author: Ray Zimmerman (PSERC Cornell)
182
+ """
183
+ # define
184
+ f = branch[:, IDX.branch.F_BUS].astype(int) # list of "from" buses
185
+ t = branch[:, IDX.branch.T_BUS].astype(int) # list of "to" buses
186
+ nl = len(f)
187
+ nb = len(V)
188
+ il = np.arange(nl)
189
+ ib = np.arange(nb)
190
+
191
+ Vnorm = V / abs(V)
192
+
193
+ if sp.issparse(Yf):
194
+ # compute currents
195
+ If = Yf * V
196
+ It = Yt * V
197
+
198
+ diagVf = c_sparse((V[f], (il, il)))
199
+ diagIf = c_sparse((If, (il, il)))
200
+ diagVt = c_sparse((V[t], (il, il)))
201
+ diagIt = c_sparse((It, (il, il)))
202
+ diagV = c_sparse((V, (ib, ib)))
203
+ diagVnorm = c_sparse((Vnorm, (ib, ib)))
204
+
205
+ shape = (nl, nb)
206
+ # Partial derivative of S w.r.t voltage phase angle.
207
+ dSf_dVa = 1j * (np.conj(diagIf) *
208
+ c_sparse((V[f], (il, f)), shape) - diagVf * np.conj(Yf * diagV))
209
+
210
+ dSt_dVa = 1j * (np.conj(diagIt) *
211
+ c_sparse((V[t], (il, t)), shape) - diagVt * np.conj(Yt * diagV))
212
+
213
+ # Partial derivative of S w.r.t. voltage amplitude.
214
+ dSf_dVm = diagVf * np.conj(Yf * diagVnorm) + np.conj(diagIf) * \
215
+ c_sparse((Vnorm[f], (il, f)), shape)
216
+
217
+ dSt_dVm = diagVt * np.conj(Yt * diagVnorm) + np.conj(diagIt) * \
218
+ c_sparse((Vnorm[t], (il, t)), shape)
219
+ else: # dense version
220
+ # compute currents
221
+ If = np.asarray(Yf * np.asmatrix(V).T).flatten()
222
+ It = np.asarray(Yt * np.asmatrix(V).T).flatten()
223
+
224
+ diagVf = np.asmatrix(np.diag(V[f]))
225
+ diagIf = np.asmatrix(np.diag(If))
226
+ diagVt = np.asmatrix(np.diag(V[t]))
227
+ diagIt = np.asmatrix(np.diag(It))
228
+ diagV = np.asmatrix(np.diag(V))
229
+ diagVnorm = np.asmatrix(np.diag(Vnorm))
230
+ temp1 = np.asmatrix(np.zeros((nl, nb), complex))
231
+ temp2 = np.asmatrix(np.zeros((nl, nb), complex))
232
+ temp3 = np.asmatrix(np.zeros((nl, nb), complex))
233
+ temp4 = np.asmatrix(np.zeros((nl, nb), complex))
234
+ for i in range(nl):
235
+ fi, ti = f[i], t[i]
236
+ temp1[i, fi] = V[fi].item()
237
+ temp2[i, fi] = Vnorm[fi].item()
238
+ temp3[i, ti] = V[ti].item()
239
+ temp4[i, ti] = Vnorm[ti].item()
240
+
241
+ dSf_dVa = 1j * (np.conj(diagIf) * temp1 - diagVf * np.conj(Yf * diagV))
242
+ dSf_dVm = diagVf * np.conj(Yf * diagVnorm) + np.conj(diagIf) * temp2
243
+ dSt_dVa = 1j * (np.conj(diagIt) * temp3 - diagVt * np.conj(Yt * diagV))
244
+ dSt_dVm = diagVt * np.conj(Yt * diagVnorm) + np.conj(diagIt) * temp4
245
+
246
+ # Compute power flow vectors.
247
+ Sf = V[f] * np.conj(If)
248
+ St = V[t] * np.conj(It)
249
+
250
+ return dSf_dVa, dSf_dVm, dSt_dVa, dSt_dVm, Sf, St
251
+
252
+
253
+ def d2Sbus_dV2(Ybus, V, lam):
254
+ """Computes 2nd derivatives of power injection w.r.t. voltage.
255
+
256
+ Returns 4 matrices containing the partial derivatives w.r.t. voltage angle
257
+ and magnitude of the product of a vector C{lam} with the 1st partial
258
+ derivatives of the complex bus power injections. Takes sparse bus
259
+ admittance matrix C{Ybus}, voltage vector C{V} and C{nb x 1} vector of
260
+ multipliers C{lam}. Output matrices are sparse.
261
+
262
+ For more details on the derivations behind the derivative code used
263
+ in PYPOWER information, see:
264
+
265
+ [TN2] R. D. Zimmerman, I{"AC Power Flows, Generalized OPF Costs and
266
+ their Derivatives using Complex Matrix Notation"}, MATPOWER
267
+ Technical Note 2, February 2010.
268
+ U{http://www.pserc.cornell.edu/matpower/TN2-OPF-Derivatives.pdf}
269
+
270
+ @author: Ray Zimmerman (PSERC Cornell)
271
+ """
272
+ nb = len(V)
273
+ ib = np.arange(nb)
274
+ Ibus = Ybus * V
275
+ diaglam = c_sparse((lam, (ib, ib)))
276
+ diagV = c_sparse((V, (ib, ib)))
277
+
278
+ A = c_sparse((lam * V, (ib, ib)))
279
+ B = Ybus * diagV
280
+ C = A * np.conj(B)
281
+ D = Ybus.getH() * diagV
282
+ E = diagV.conj() * (D * diaglam - c_sparse((D * lam, (ib, ib))))
283
+ F = C - A * c_sparse((np.conj(Ibus), (ib, ib)))
284
+ G = c_sparse((np.ones(nb) / abs(V), (ib, ib)))
285
+
286
+ Gaa = E + F
287
+ Gva = 1j * G * (E - F)
288
+ Gav = Gva.T
289
+ Gvv = G * (C + C.T) * G
290
+
291
+ return Gaa, Gav, Gva, Gvv
292
+
293
+
294
+ def d2AIbr_dV2(dIbr_dVa, dIbr_dVm, Ibr, Ybr, V, lam):
295
+ """Computes 2nd derivatives of |complex current|**2 w.r.t. V.
296
+
297
+ Returns 4 matrices containing the partial derivatives w.r.t. voltage
298
+ angle and magnitude of the product of a vector C{lam} with the 1st partial
299
+ derivatives of the square of the magnitude of the branch currents.
300
+ Takes sparse first derivative matrices of complex flow, complex flow
301
+ vector, sparse branch admittance matrix C{Ybr}, voltage vector C{V} and
302
+ C{nl x 1} vector of multipliers C{lam}. Output matrices are sparse.
303
+
304
+ For more details on the derivations behind the derivative code used
305
+ in PYPOWER information, see:
306
+
307
+ [TN2] R. D. Zimmerman, I{"AC Power Flows, Generalized OPF Costs and
308
+ their Derivatives using Complex Matrix Notation"}, MATPOWER
309
+ Technical Note 2, February 2010.
310
+ U{http://www.pserc.cornell.edu/matpower/TN2-OPF-Derivatives.pdf}
311
+
312
+ @see: L{dIbr_dV}.
313
+
314
+ @author: Ray Zimmerman (PSERC Cornell)
315
+ """
316
+ # define
317
+ il = range(len(lam))
318
+
319
+ diaglam = c_sparse((lam, (il, il)))
320
+ diagIbr_conj = c_sparse((Ibr.conj(), (il, il)))
321
+
322
+ Iaa, Iav, Iva, Ivv = d2Ibr_dV2(Ybr, V, diagIbr_conj * lam)
323
+
324
+ Haa = 2 * (Iaa + dIbr_dVa.T * diaglam * dIbr_dVa.conj()).real
325
+ Hva = 2 * (Iva + dIbr_dVm.T * diaglam * dIbr_dVa.conj()).real
326
+ Hav = 2 * (Iav + dIbr_dVa.T * diaglam * dIbr_dVm.conj()).real
327
+ Hvv = 2 * (Ivv + dIbr_dVm.T * diaglam * dIbr_dVm.conj()).real
328
+
329
+ return Haa, Hav, Hva, Hvv
330
+
331
+
332
+ def d2ASbr_dV2(dSbr_dVa, dSbr_dVm, Sbr, Cbr, Ybr, V, lam):
333
+ """Computes 2nd derivatives of |complex power flow|**2 w.r.t. V.
334
+
335
+ Returns 4 matrices containing the partial derivatives w.r.t. voltage
336
+ angle and magnitude of the product of a vector C{lam} with the 1st partial
337
+ derivatives of the square of the magnitude of branch complex power flows.
338
+ Takes sparse first derivative matrices of complex flow, complex flow
339
+ vector, sparse connection matrix C{Cbr}, sparse branch admittance matrix
340
+ C{Ybr}, voltage vector C{V} and C{nl x 1} vector of multipliers C{lam}.
341
+ Output matrices are sparse.
342
+
343
+ For more details on the derivations behind the derivative code used
344
+ in PYPOWER information, see:
345
+
346
+ [TN2] R. D. Zimmerman, I{"AC Power Flows, Generalized OPF Costs and
347
+ their Derivatives using Complex Matrix Notation"}, MATPOWER
348
+ Technical Note 2, February 2010.
349
+ U{http://www.pserc.cornell.edu/matpower/TN2-OPF-Derivatives.pdf}
350
+
351
+ @see: L{dSbr_dV}
352
+
353
+ @author: Ray Zimmerman (PSERC Cornell)
354
+ """
355
+ il = range(len(lam))
356
+
357
+ diaglam = c_sparse((lam, (il, il)))
358
+ diagSbr_conj = c_sparse((Sbr.conj(), (il, il)))
359
+
360
+ Saa, Sav, Sva, Svv = d2Sbr_dV2(Cbr, Ybr, V, diagSbr_conj * lam)
361
+
362
+ Haa = 2 * (Saa + dSbr_dVa.T * diaglam * dSbr_dVa.conj()).real
363
+ Hva = 2 * (Sva + dSbr_dVm.T * diaglam * dSbr_dVa.conj()).real
364
+ Hav = 2 * (Sav + dSbr_dVa.T * diaglam * dSbr_dVm.conj()).real
365
+ Hvv = 2 * (Svv + dSbr_dVm.T * diaglam * dSbr_dVm.conj()).real
366
+
367
+ return Haa, Hav, Hva, Hvv
368
+
369
+
370
+ def d2Ibr_dV2(Ybr, V, lam):
371
+ """Computes 2nd derivatives of complex branch current w.r.t. voltage.
372
+
373
+ Returns 4 matrices containing the partial derivatives w.r.t. voltage
374
+ angle and magnitude of the product of a vector LAM with the 1st partial
375
+ derivatives of the complex branch currents. Takes sparse branch admittance
376
+ matrix C{Ybr}, voltage vector C{V} and C{nl x 1} vector of multipliers
377
+ C{lam}. Output matrices are sparse.
378
+
379
+ For more details on the derivations behind the derivative code used
380
+ in PYPOWER information, see:
381
+
382
+ [TN2] R. D. Zimmerman, I{"AC Power Flows, Generalized OPF Costs and
383
+ their Derivatives using Complex Matrix Notation"}, MATPOWER
384
+ Technical Note 2, February 2010.
385
+ U{http://www.pserc.cornell.edu/matpower/TN2-OPF-Derivatives.pdf}
386
+
387
+ @author: Ray Zimmerman (PSERC Cornell)
388
+ """
389
+ nb = len(V)
390
+ ib = np.arange(nb)
391
+ diaginvVm = c_sparse((np.ones(nb) / abs(V), (ib, ib)))
392
+
393
+ Haa = c_sparse((-(Ybr.T * lam) * V, (ib, ib)))
394
+ Hva = -1j * Haa * diaginvVm
395
+ Hav = Hva.copy()
396
+ Hvv = c_sparse((nb, nb))
397
+
398
+ return Haa, Hav, Hva, Hvv
399
+
400
+
401
+ def d2Sbr_dV2(Cbr, Ybr, V, lam):
402
+ """Computes 2nd derivatives of complex power flow w.r.t. voltage.
403
+
404
+ Returns 4 matrices containing the partial derivatives w.r.t. voltage angle
405
+ and magnitude of the product of a vector C{lam} with the 1st partial
406
+ derivatives of the complex branch power flows. Takes sparse connection
407
+ matrix C{Cbr}, sparse branch admittance matrix C{Ybr}, voltage vector C{V}
408
+ and C{nl x 1} vector of multipliers C{lam}. Output matrices are sparse.
409
+
410
+ For more details on the derivations behind the derivative code used
411
+ in PYPOWER information, see:
412
+
413
+ [TN2] R. D. Zimmerman, I{"AC Power Flows, Generalized OPF Costs and
414
+ their Derivatives using Complex Matrix Notation"}, MATPOWER
415
+ Technical Note 2, February 2010.
416
+ U{http://www.pserc.cornell.edu/matpower/TN2-OPF-Derivatives.pdf}
417
+
418
+ @author: Ray Zimmerman (PSERC Cornell)
419
+ """
420
+ nb = len(V)
421
+ nl = len(lam)
422
+ ib = range(nb)
423
+ il = range(nl)
424
+
425
+ diaglam = c_sparse((lam, (il, il)))
426
+ diagV = c_sparse((V, (ib, ib)))
427
+
428
+ A = Ybr.getH() * diaglam * Cbr
429
+ B = np.conj(diagV) * A * diagV
430
+ D = c_sparse(((A * V) * np.conj(V), (ib, ib)))
431
+ E = c_sparse(((A.T * np.conj(V) * V), (ib, ib)))
432
+ F = B + B.T
433
+ G = c_sparse((np.ones(nb) / abs(V), (ib, ib)))
434
+
435
+ Haa = F - D - E
436
+ Hva = 1j * G * (B - B.T - D + E)
437
+ Hav = Hva.T
438
+ Hvv = G * F * G
439
+
440
+ return Haa, Hav, Hva, Hvv
441
+
442
+
443
+ def dAbr_dV(dSf_dVa, dSf_dVm, dSt_dVa, dSt_dVm, Sf, St):
444
+ """Partial derivatives of squared flow magnitudes w.r.t voltage.
445
+
446
+ Returns four matrices containing partial derivatives of the square of
447
+ the branch flow magnitudes at "from" & "to" ends of each branch w.r.t
448
+ voltage magnitude and voltage angle respectively (for all buses), given
449
+ the flows and flow sensitivities. Flows could be complex current or
450
+ complex or real power. Notation below is based on complex power. The
451
+ following explains the expressions used to form the matrices:
452
+
453
+ Let Af refer to the square of the apparent power at the "from" end of
454
+ each branch::
455
+
456
+ Af = abs(Sf)**2
457
+ = Sf .* conj(Sf)
458
+ = Pf**2 + Qf**2
459
+
460
+ then ...
461
+
462
+ Partial w.r.t real power::
463
+ dAf/dPf = 2 * diag(Pf)
464
+
465
+ Partial w.r.t reactive power::
466
+ dAf/dQf = 2 * diag(Qf)
467
+
468
+ Partial w.r.t Vm & Va::
469
+ dAf/dVm = dAf/dPf * dPf/dVm + dAf/dQf * dQf/dVm
470
+ dAf/dVa = dAf/dPf * dPf/dVa + dAf/dQf * dQf/dVa
471
+
472
+ Derivations for "to" bus are similar.
473
+
474
+ For more details on the derivations behind the derivative code used
475
+ in PYPOWER information, see:
476
+
477
+ [TN2] R. D. Zimmerman, I{"AC Power Flows, Generalized OPF Costs and
478
+ their Derivatives using Complex Matrix Notation"}, MATPOWER
479
+ Technical Note 2, February 2010.
480
+ U{http://www.pserc.cornell.edu/matpower/TN2-OPF-Derivatives.pdf}
481
+
482
+ @return: The partial derivatives of the squared flow magnitudes w.r.t
483
+ voltage magnitude and voltage angle given the flows and flow
484
+ sensitivities. Flows could be complex current or complex or
485
+ real power.
486
+ @see: L{dIbr_dV}, L{dSbr_dV}
487
+
488
+ @author: Ray Zimmerman (PSERC Cornell)
489
+ """
490
+ il = range(len(Sf))
491
+
492
+ dAf_dPf = c_sparse((2 * Sf.real, (il, il)))
493
+ dAf_dQf = c_sparse((2 * Sf.imag, (il, il)))
494
+ dAt_dPt = c_sparse((2 * St.real, (il, il)))
495
+ dAt_dQt = c_sparse((2 * St.imag, (il, il)))
496
+
497
+ # Partial derivative of apparent power magnitude w.r.t voltage
498
+ # phase angle.
499
+ dAf_dVa = dAf_dPf * dSf_dVa.real + dAf_dQf * dSf_dVa.imag
500
+ dAt_dVa = dAt_dPt * dSt_dVa.real + dAt_dQt * dSt_dVa.imag
501
+ # Partial derivative of apparent power magnitude w.r.t. voltage
502
+ # amplitude.
503
+ dAf_dVm = dAf_dPf * dSf_dVm.real + dAf_dQf * dSf_dVm.imag
504
+ dAt_dVm = dAt_dPt * dSt_dVm.real + dAt_dQt * dSt_dVm.imag
505
+
506
+ return dAf_dVa, dAf_dVm, dAt_dVa, dAt_dVm
@@ -0,0 +1,7 @@
1
+ """
2
+ Module for PYPOWER routines.
3
+ """
4
+
5
+ from ams.pypower.routines.pflow import runpf # NOQA
6
+ from ams.pypower.routines.opf import runopf, runuopf # NOQA
7
+ from ams.pypower.routines.cpf import runcpf # NOQA