e2nIEE / pandapower
1
# -*- coding: utf-8 -*-
2

3
# Copyright (c) 2016-2021 by University of Kassel and Fraunhofer Institute for Energy Economics
4
# and Energy System Technology (IEE), Kassel. All rights reserved.
5

6

7 1
import numpy as np
8 1
from numpy import complex128
9 1
from pandapower.pypower.idx_bus import VM, VA,BASE_KV
10 1
from pandapower.pypower.idx_gen import PG, QG, GEN_BUS
11

12 1
from pandapower.auxiliary import _sum_by_group, sequence_to_phase, _sum_by_group_nvals, \
13
    I_from_SV_elementwise, S_from_VI_elementwise, SVabc_from_SV012
14

15 1
from pandapower.auxiliary import _sum_by_group
16 1
from pandapower.pypower.idx_bus import VM, VA
17 1
from pandapower.pypower.idx_gen import PG, QG
18

19

20 1
def _get_gen_results(net, ppc, bus_lookup_aranged, pq_bus):
21 1
    ac = net["_options"]["ac"]
22

23 1
    eg_end = sum(net['ext_grid'].in_service)
24 1
    gen_end = eg_end + len(net['gen'])
25

26 1
    if eg_end > 0:
27 1
        b, p, q = _get_ext_grid_results(net, ppc)
28
    else:
29 1
        b, p, q = [], [], []  # np.array([]), np.array([]), np.array([])
30

31
    # get results for gens
32 1
    if gen_end > eg_end:
33 1
        b, p, q = _get_pp_gen_results(net, ppc, b, p, q)
34

35 1
    if len(net.dcline) > 0:
36 1
        _get_dcline_results(net)
37 1
        b = np.hstack([b, net.dcline[["from_bus", "to_bus"]].values.flatten()])
38 1
        p = np.hstack([p, net.res_dcline[["p_from_mw", "p_to_mw"]].values.flatten()])
39 1
        q = np.hstack([q, net.res_dcline[["q_from_mvar", "q_to_mvar"]].values.flatten()])
40

41 1
    if not ac:
42 1
        q = np.zeros(len(p))
43 1
    b_sum, p_sum, q_sum = _sum_by_group(b, p, q)
44 1
    b = bus_lookup_aranged[b_sum.astype(int)]
45 1
    pq_bus[b, 0] -= p_sum
46 1
    pq_bus[b, 1] -= q_sum
47

48

49 1
def _get_gen_results_3ph(net, ppc0, ppc1, ppc2, bus_lookup_aranged, pq_bus):
50 1
    ac = net["_options"]["ac"]
51

52 1
    eg_end = len(net['ext_grid'])
53 1
    gen_end = eg_end + len(net['gen'][net['_is_elements']['gen']])
54

55 1
    b, pA, qA, pB, qB, pC, qC = _get_ext_grid_results_3ph(net, ppc0, ppc1, ppc2)
56

57
    # get results for gens
58 1
    if gen_end > eg_end:
59 0
        b, pA, qA, pB, qB, pC, qC = _get_pp_gen_results_3ph(net, ppc0, ppc1, ppc2, b, pA, qA, pB, qB, pC, qC)
60

61 1
    if not ac:
62 0
        qA, qB, qC = np.copy((np.zeros(len(pA)),)*3)
63

64 1
    b_pp, pA_sum, qA_sum, pB_sum, qB_sum, pC_sum, qC_sum = _sum_by_group_nvals(b.astype(int), pA, qA, pB, qB, pC, qC)
65 1
    b_ppc = bus_lookup_aranged[b_pp]
66 1
    pq_bus[b_ppc, 0] -= pA_sum
67 1
    pq_bus[b_ppc, 1] -= qA_sum
68 1
    pq_bus[b_ppc, 2] -= pB_sum
69 1
    pq_bus[b_ppc, 3] -= qB_sum
70 1
    pq_bus[b_ppc, 4] -= pC_sum
71 1
    pq_bus[b_ppc, 5] -= qC_sum
72

73

74 1
def _get_ext_grid_results(net, ppc):
75 1
    ac = net["_options"]["ac"]
76

77
    # get results for external grids
78 1
    eg_is_mask = net["_is_elements"]['ext_grid']
79 1
    ext_grid_lookup = net["_pd2ppc_lookups"]["ext_grid"]
80

81 1
    n_res_eg = len(net['ext_grid'])
82
    # indices of in service gens in the ppc
83 1
    eg_is_idx = net["ext_grid"].index.values[eg_is_mask]
84 1
    gen_idx_ppc = ext_grid_lookup[eg_is_idx]
85

86
    # read results from ppc for these buses
87 1
    p = np.zeros(n_res_eg)
88 1
    q = np.zeros(n_res_eg)
89 1
    p[eg_is_mask] = ppc["gen"][gen_idx_ppc, PG]
90
    # store result in net['res']
91 1
    net["res_ext_grid"]["p_mw"] = p
92

93
    # if ac PF q results are also available
94 1
    if ac:
95 1
        q[eg_is_mask] = ppc["gen"][gen_idx_ppc, QG]
96 1
        net["res_ext_grid"]["q_mvar"] = q
97

98
    # get bus values for pq_bus
99 1
    b = net['ext_grid'].bus.values
100
    # copy index for results
101 1
    net["res_ext_grid"].index = net['ext_grid'].index
102

103 1
    return b, p, q
104

105 1
def _get_ext_grid_results_3ph(net, ppc0, ppc1, ppc2):
106
    # get results for external grids
107 1
    eg_is_mask = net["_is_elements"]['ext_grid']
108 1
    ext_grid_lookup = net["_pd2ppc_lookups"]["ext_grid"]
109

110 1
    n_res_eg = len(net['ext_grid'])
111
    # indices of in service gens in the ppc
112 1
    eg_is_idx = net["ext_grid"].index.values[eg_is_mask]
113 1
    eg_idx_ppc = ext_grid_lookup[eg_is_idx]
114
    """ # 2 ext_grids Fix: Instead of the generator index, bus indices of the generators are used"""
115 1
    eg_bus_idx_ppc = np.real(ppc1["gen"][eg_idx_ppc, GEN_BUS]).astype(int)
116
    # read results from ppc for these buses
117 1
    V012 = np.array(np.zeros((3, n_res_eg)),dtype = np.complex128)
118 1
    V012[:, eg_is_idx] = np.array([ppc["bus"][eg_bus_idx_ppc, VM] * ppc["bus"][eg_bus_idx_ppc, BASE_KV]
119
                                      * np.exp(1j * np.deg2rad(ppc["bus"][eg_bus_idx_ppc, VA]))
120
                                      for ppc in [ppc0, ppc1, ppc2]])
121

122 1
    S012 = np.array(np.zeros((3, n_res_eg)),dtype = np.complex128)
123 1
    S012[:, eg_idx_ppc] = np.array([(ppc["gen"][eg_idx_ppc, PG] + 1j \
124
                                   * ppc["gen"][eg_idx_ppc, QG]) \
125
                                    for ppc in [ppc0, ppc1, ppc2]])
126

127 1
    Sabc, Vabc = SVabc_from_SV012(S012, V012/ np.sqrt(3), n_res=n_res_eg, idx=eg_idx_ppc)
128

129 1
    pA, pB, pC = map(lambda x: x.flatten(), np.real(Sabc))
130 1
    qA, qB, qC = map(lambda x: x.flatten(), np.imag(Sabc))
131

132
    # store result in net['res']
133 1
    net["res_ext_grid_3ph"]["p_a_mw"] = pA
134 1
    net["res_ext_grid_3ph"]["p_b_mw"] = pB
135 1
    net["res_ext_grid_3ph"]["p_c_mw"] = pC
136 1
    net["res_ext_grid_3ph"]["q_a_mvar"] = qA
137 1
    net["res_ext_grid_3ph"]["q_b_mvar"] = qB
138 1
    net["res_ext_grid_3ph"]["q_c_mvar"] = qC
139

140
    # get bus values for pq_bus
141 1
    b = net['ext_grid'].bus.values
142
    # copy index for results
143 1
    net["res_ext_grid_3ph"].index = net['ext_grid'].index
144

145 1
    return b, pA, qA, pB, qB, pC, qC
146

147

148 1
def _get_p_q_gen_results(net, ppc):
149 1
    gen_is = net["_is_elements"]["gen"]
150 1
    gen_lookup = net["_pd2ppc_lookups"]["gen"]
151 1
    gen_is_idx = np.array(net["gen"].index)[gen_is]
152
    # indices of in service gens in the ppc
153 1
    if np.any(gen_is):
154 1
        gen_idx_ppc = gen_lookup[gen_is_idx]
155
    else:
156 1
        gen_idx_ppc = []
157

158
    # read results from ppc for these buses
159 1
    n_res_gen = len(net['gen'])
160 1
    p_gen = np.zeros(n_res_gen)
161 1
    p_gen[gen_is] = ppc["gen"][gen_idx_ppc, PG]
162 1
    q_gen = None
163 1
    if net["_options"]["ac"]:
164 1
        q_gen = np.zeros(n_res_gen)
165 1
        q_gen[gen_is] = ppc["gen"][gen_idx_ppc, QG]
166 1
        net["res_gen"]["q_mvar"].values[:] = q_gen
167

168 1
    net["res_gen"]["p_mw"].values[:] = p_gen
169 1
    return p_gen, q_gen
170

171 1
def _get_p_q_gen_results_3ph(net, ppc0, ppc1, ppc2):
172 0
    _is_elements = net["_is_elements"]
173 0
    ac = net["_options"]["ac"]
174 0
    gen_is_mask = _is_elements['gen']
175 0
    gen_lookup = net["_pd2ppc_lookups"]["gen"]
176 0
    gen_is_idx = net["gen"].index[gen_is_mask]
177
    # indices of in service gens in the ppc
178 0
    if np.any(_is_elements["gen"]):
179 0
        gen_idx_ppc = gen_lookup[gen_is_idx]
180
    else:
181 0
        gen_idx_ppc = []
182

183
    # read results from ppc for these buses
184 0
    n_res_gen = len(net['gen'])
185 0
    gen_idx_ppc = gen_lookup[gen_is_idx]
186
    """ # 2 ext_grids Fix: Instead of the generator index, bus indices of the generators are used"""
187 0
    gen_bus_idx_ppc = np.real(ppc1["gen"][gen_idx_ppc, GEN_BUS]).astype(int)
188

189 0
    V012 = np.array(np.zeros((3, n_res_gen)))
190 0
    V012[:, gen_is_idx] = np.array([ppc["bus"][gen_bus_idx_ppc, VM]
191
                                      * np.exp(1j * np.deg2rad(ppc["bus"][gen_bus_idx_ppc, VA]))
192
                                      for ppc in [ppc0, ppc1, ppc2]])
193

194 0
    S012 = np.array(np.zeros((3, n_res_gen)))
195 0
    S012[:, gen_is_idx] = np.array(
196
        [-(ppc["gen"][gen_idx_ppc, PG] + 1j * ppc["gen"][gen_idx_ppc, QG]) for ppc in [ppc0, ppc1, ppc2]])
197 0
    I012 = np.array(np.zeros((3, n_res_gen)))
198 0
    I012[:, gen_is_idx] = I_from_SV_elementwise(S012[:, gen_is_idx], V012[:, gen_is_idx])
199

200 0
    Vabc = sequence_to_phase(V012)
201 0
    Iabc = sequence_to_phase(I012)
202 0
    Sabc = S_from_VI_elementwise(Vabc, Iabc) * 1e3
203 0
    pA, pB, pC = map(lambda x: x.flatten(), np.real(Sabc))
204 0
    qA, qB, qC = map(lambda x: x.flatten(), np.imag(Sabc))
205

206 0
    net["res_gen_3ph"]["p_a_mw"] = pA
207 0
    net["res_gen_3ph"]["p_b_mw"] = pB
208 0
    net["res_gen_3ph"]["p_c_mw"] = pC
209 0
    net["res_gen_3ph"]["q_a_mvar"] = qA
210 0
    net["res_gen_3ph"]["q_b_mvar"] = qB
211 0
    net["res_gen_3ph"]["q_c_mvar"] = qC
212

213 0
    return pA, qA, pB, qB, pC, qC
214

215

216

217 1
def _get_v_gen_resuts(net, ppc):
218
    # lookups for ppc
219 1
    bus_lookup = net["_pd2ppc_lookups"]["bus"]
220

221
    # in service gens
222 1
    gen_is = net["_is_elements"]['gen']
223 1
    bus_idx_ppc = bus_lookup[net["gen"]["bus"].values[gen_is]]
224

225 1
    n_res_gen = len(net['gen'])
226

227
    # voltage magnitudes
228 1
    v_pu = np.zeros(n_res_gen)
229 1
    v_pu[gen_is] = ppc["bus"][bus_idx_ppc][:, VM]
230

231
    # voltage angles
232 1
    v_a = np.zeros(n_res_gen)
233 1
    v_a[gen_is] = ppc["bus"][bus_idx_ppc][:, VA]
234

235 1
    net["res_gen"]["vm_pu"].values[:] = v_pu
236 1
    net["res_gen"]["va_degree"].values[:] = v_a
237 1
    return v_pu, v_a
238

239

240 1
def _get_v_gen_results_3ph(net, ppc0, ppc1, ppc2):
241
    # lookups for ppc
242 0
    bus_lookup = net["_pd2ppc_lookups"]["bus"]
243 0
    gen_lookup = net["_pd2ppc_lookups"]["gen"]
244

245
    # in service gens
246 0
    gen_is_mask = net["_is_elements"]['gen']
247 0
    gen_is_idx = net["gen"].index[gen_is_mask]
248 0
    bus_idx_ppc = bus_lookup[net["gen"]["bus"].values[gen_is_mask]]
249

250 0
    n_res_gen = len(net['gen'])
251 0
    gen_idx_ppc = gen_lookup[gen_is_idx]
252
    """ # 2 ext_grids Fix: Instead of the generator index, bus indices of the generators are used"""
253 0
    gen_bus_idx_ppc = np.real(ppc1["gen"][gen_idx_ppc, GEN_BUS]).astype(int)
254 0
    V012 = np.array(np.zeros((3, n_res_gen)))
255 0
    V012[:, gen_is_mask] = np.array([ppc["bus"][gen_bus_idx_ppc, VM]
256
                                      * np.exp(1j * np.deg2rad(ppc["bus"][gen_bus_idx_ppc, VA]))
257
                                      for ppc in [ppc0, ppc1, ppc2]])
258 0
    VABC = sequence_to_phase(V012)
259

260
    # voltage magnitudes
261 0
    vA_pu, vB_pu, vC_pu = np.copy((np.zeros(n_res_gen),) * 3)
262 0
    vA_pu[gen_idx_ppc] = np.abs(VABC[0, gen_idx_ppc])
263 0
    vB_pu[gen_idx_ppc] = np.abs(VABC[1, gen_idx_ppc])
264 0
    vC_pu[gen_idx_ppc] = np.abs(VABC[2, gen_idx_ppc])
265

266
    # voltage angles
267 0
    vA_a, vB_a, vC_a = np.copy((np.zeros(n_res_gen),) * 3)
268 0
    vA_a[gen_idx_ppc] = np.rad2deg(np.angle(VABC[0, gen_idx_ppc]))
269 0
    vB_a[gen_idx_ppc] = np.rad2deg(np.angle(VABC[1, gen_idx_ppc]))
270 0
    vC_a[gen_idx_ppc] = np.rad2deg(np.angle(VABC[2, gen_idx_ppc]))
271

272 0
    net["res_gen_3ph"]["vmA_pu"] = vA_pu
273 0
    net["res_gen_3ph"]["vmB_pu"] = vB_pu
274 0
    net["res_gen_3ph"]["vmC_pu"] = vC_pu
275 0
    net["res_gen_3ph"]["vaA_degree"] = vA_a
276 0
    net["res_gen_3ph"]["vaB_degree"] = vB_a
277 0
    net["res_gen_3ph"]["vaC_degree"] = vC_a
278 0
    return vA_pu, vA_a, vB_pu, vB_a, vC_pu, vC_a
279

280

281 1
def _get_pp_gen_results(net, ppc, b, p, q):
282 1
    p_gen, q_gen = _get_p_q_gen_results(net, ppc)
283 1
    _get_v_gen_resuts(net, ppc)
284

285 1
    b = np.hstack([b, net['gen'].bus.values])
286

287 1
    p = np.hstack([p, p_gen])
288 1
    if net["_options"]["ac"]:
289 1
        q = np.hstack([q, q_gen])
290

291 1
    return b, p, q
292

293 1
def _get_pp_gen_results_3ph(net, ppc0, ppc1, ppc2, b, pA, qA, pB, qB, pC, qC):
294 0
    pA_gen, qA_gen, pB_gen, qB_gen, pC_gen, qC_gen = _get_p_q_gen_results_3ph(net, ppc0, ppc1, ppc2)
295 0
    _get_v_gen_results_3ph(net, ppc0, ppc1, ppc2)
296

297 0
    ac = net["_options"]["ac"]
298

299 0
    net["res_gen_3ph"].index = net['gen'].index
300 0
    b = np.hstack([b, net['gen'].bus.values])
301

302 0
    pA = np.hstack([pA, pA_gen])
303 0
    pB = np.hstack([pB, pB_gen])
304 0
    pC = np.hstack([pC, pC_gen])
305 0
    if ac:
306 0
        qA = np.hstack([qA, qA_gen])
307 0
        qB = np.hstack([qB, qB_gen])
308 0
        qC = np.hstack([qC, qC_gen])
309

310 0
    return b, pA, qA, pB, qB, pC, qC
311

312 1
def _get_dcline_results(net):
313 1
    dc_gens = net.gen.index[(len(net.gen) - len(net.dcline) * 2):]
314 1
    from_gens = net.res_gen.loc[dc_gens[1::2]]
315 1
    to_gens = net.res_gen.loc[dc_gens[::2]]
316

317 1
    net.res_dcline.p_from_mw = - from_gens.p_mw.values
318 1
    net.res_dcline.p_to_mw = - to_gens.p_mw.values
319 1
    net.res_dcline.pl_mw = - (to_gens.p_mw.values + from_gens.p_mw.values)
320

321 1
    net.res_dcline.q_from_mvar = - from_gens.q_mvar.values
322 1
    net.res_dcline.q_to_mvar = - to_gens.q_mvar.values
323

324 1
    net.res_dcline.vm_from_pu = from_gens.vm_pu.values
325 1
    net.res_dcline.vm_to_pu = to_gens.vm_pu.values
326 1
    net.res_dcline.va_from_degree = from_gens.va_degree.values
327 1
    net.res_dcline.va_to_degree = to_gens.va_degree.values
328

329 1
    net.res_dcline.index = net.dcline.index

Read our documentation on viewing source code .

Loading