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 .