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 ```import pandas as pd ``` 10 1 ```from pandapower.auxiliary import _sum_by_group, sequence_to_phase, _sum_by_group_nvals ``` 11 1 ```from pandapower.pypower.idx_bus import VM, VA, PD, QD, LAM_P, LAM_Q, BASE_KV,NONE ``` 12 13 1 ```from pandapower.pypower.idx_gen import PG, QG ``` 14 1 ```from pandapower.build_bus import _get_motor_pq, _get_symmetric_pq_of_unsymetric_element ``` 15 16 17 1 ```def _set_buses_out_of_service(ppc): ``` 18 19 1 ``` disco = np.where(ppc["bus"][:, 1] == NONE)[0] ``` 20 1 ``` ppc["bus"][disco, VM] = np.nan ``` 21 1 ``` ppc["bus"][disco, VA] = np.nan ``` 22 1 ``` ppc["bus"][disco, PD] = 0 ``` 23 1 ``` ppc["bus"][disco, QD] = 0 ``` 24 25 26 1 ```def _get_bus_v_results(net, ppc, suffix=None): ``` 27 1 ``` ac = net["_options"]["ac"] ``` 28 1 ``` bus_idx = _get_bus_idx(net) ``` 29 30 1 ``` res_table = "res_bus" if suffix is None else "res_bus%s" % suffix ``` 31 1 ``` if ac: ``` 32 1 ``` net[res_table]["vm_pu"] = ppc["bus"][bus_idx][:, VM] ``` 33 ``` # voltage angles ``` 34 1 ``` net[res_table]["va_degree"] = ppc["bus"][bus_idx][:, VA] ``` 35 36 37 1 ```def _get_bus_v_results_3ph(net, ppc0, ppc1, ppc2): ``` 38 1 ``` ac = net["_options"]["ac"] ``` 39 1 ``` V012_pu = _V012_from_ppc012(net, ppc0, ppc1, ppc2) ``` 40 ``` # Uncomment for results in kV instead of pu ``` 41 ``` # bus_base_kv = ppc0["bus"][:,BASE_KV]/np.sqrt(3) ``` 42 ``` # V012_pu = V012_pu*bus_base_kv ``` 43 44 1 ``` Vabc_pu = sequence_to_phase(V012_pu) ``` 45 46 1 ``` if ac: ``` 47 1 ``` net["res_bus_3ph"]["vm_a_pu"] = np.abs(Vabc_pu[0, :].flatten()) ``` 48 1 ``` net["res_bus_3ph"]["vm_b_pu"] = np.abs(Vabc_pu[1, :].flatten()) ``` 49 1 ``` net["res_bus_3ph"]["vm_c_pu"] = np.abs(Vabc_pu[2, :].flatten()) ``` 50 ``` # voltage angles ``` 51 1 ``` net["res_bus_3ph"]["va_a_degree"] = np.angle(Vabc_pu[0, :].flatten())*180/np.pi ``` 52 1 ``` net["res_bus_3ph"]["va_b_degree"] = np.angle(Vabc_pu[1, :].flatten())*180/np.pi ``` 53 1 ``` net["res_bus_3ph"]["va_c_degree"] = np.angle(Vabc_pu[2, :].flatten())*180/np.pi ``` 54 1 ``` net["res_bus_3ph"]["unbalance_percent"] = np.abs(V012_pu[2, :]/V012_pu[1, :])*100 ``` 55 1 ``` net["res_bus_3ph"].index = net["bus"].index ``` 56 57 58 1 ```def _V012_from_ppc012(net, ppc0, ppc1, ppc2): ``` 59 1 ``` bus_idx = _get_bus_idx(net) ``` 60 1 ``` V012_pu = np.zeros((3, len(bus_idx)), dtype=complex128) ``` 61 1 ``` V012_pu[0, :] = ppc0["bus"][bus_idx][:, VM] * np.exp(1j * np.deg2rad(ppc0["bus"][bus_idx][:, VA])) ``` 62 1 ``` V012_pu[1, :] = ppc1["bus"][bus_idx][:, VM] * np.exp(1j * np.deg2rad(ppc1["bus"][bus_idx][:, VA])) ``` 63 1 ``` V012_pu[2, :] = ppc2["bus"][bus_idx][:, VM] * np.exp(1j * np.deg2rad(ppc2["bus"][bus_idx][:, VA])) ``` 64 1 ``` return V012_pu ``` 65 66 67 1 ```def _get_bus_idx(net): ``` 68 1 ``` bus_lookup = net["_pd2ppc_lookups"]["bus"] ``` 69 1 ``` ppi = net["bus"].index.values ``` 70 1 ``` bus_idx = bus_lookup[ppi] ``` 71 1 ``` return bus_idx ``` 72 73 74 1 ```def _get_opf_marginal_prices(net, ppc): ``` 75 1 ``` bus_idx = _get_bus_idx(net) ``` 76 1 ``` net["res_bus"]["lam_p"] = ppc["bus"][bus_idx][:, LAM_P] ``` 77 1 ``` net["res_bus"]["lam_q"] = ppc["bus"][bus_idx][:, LAM_Q] ``` 78 79 80 1 ```def _get_bus_results(net, ppc, bus_pq): ``` 81 1 ``` ac = net["_options"]["ac"] ``` 82 1 ``` mode = net["_options"]["mode"] ``` 83 84 ``` # write sum of p and q values to bus ``` 85 1 ``` net["res_bus"]["p_mw"].values[:] = bus_pq[:, 0] ``` 86 1 ``` if ac: ``` 87 1 ``` net["res_bus"]["q_mvar"].values[:] = bus_pq[:, 1] ``` 88 89 ``` # opf variables ``` 90 1 ``` if mode == "opf": ``` 91 1 ``` _get_opf_marginal_prices(net, ppc) ``` 92 93 ``` # update index in res bus bus ``` 94 1 ``` net["res_bus"].index = net["bus"].index ``` 95 96 97 1 ```def _get_bus_results_3ph(net, bus_pq): ``` 98 1 ``` ac = net["_options"]["ac"] ``` 99 100 ``` # write sum of p and q values to bus ``` 101 1 ``` net["res_bus_3ph"]["p_a_mw"] = bus_pq[:, 0] ``` 102 1 ``` net["res_bus_3ph"]["p_b_mw"] = bus_pq[:, 2] ``` 103 1 ``` net["res_bus_3ph"]["p_c_mw"] = bus_pq[:, 4] ``` 104 1 ``` if ac: ``` 105 1 ``` net["res_bus_3ph"]["q_a_mvar"] = bus_pq[:, 1] ``` 106 1 ``` net["res_bus_3ph"]["q_b_mvar"] = bus_pq[:, 3] ``` 107 1 ``` net["res_bus_3ph"]["q_c_mvar"] = bus_pq[:, 5] ``` 108 109 ``` # Todo: OPF ``` 110 111 ``` # update index in res bus bus ``` 112 ``` # net["res_bus"].index = net["bus"].index ``` 113 1 ``` net["res_bus_3ph"].index = net["bus"].index ``` 114 115 1 ```def write_voltage_dependend_load_results(net, p, q, b): ``` 116 1 ``` l = net["load"] ``` 117 1 ``` _is_elements = net["_is_elements"] ``` 118 119 1 ``` if len(l) > 0: ``` 120 1 ``` load_is = _is_elements["load"] ``` 121 1 ``` scaling = l["scaling"].values ``` 122 1 ``` bus_lookup = net["_pd2ppc_lookups"]["bus"] ``` 123 1 ``` lidx = bus_lookup[l["bus"].values] ``` 124 125 1 ``` voltage_depend_loads = net["_options"]["voltage_depend_loads"] ``` 126 127 1 ``` cz = l["const_z_percent"].values / 100. ``` 128 1 ``` ci = l["const_i_percent"].values / 100. ``` 129 1 ``` cp = 1. - (cz + ci) ``` 130 131 ``` # constant power ``` 132 1 ``` pl = l["p_mw"].values * scaling * load_is * cp ``` 133 1 ``` net["res_load"]["p_mw"] = pl ``` 134 1 ``` p = np.hstack([p, pl]) ``` 135 136 1 ``` ql = l["q_mvar"].values * scaling * load_is * cp ``` 137 1 ``` net["res_load"]["q_mvar"] = ql ``` 138 1 ``` q = np.hstack([q, ql]) ``` 139 140 1 ``` b = np.hstack([b, l["bus"].values]) ``` 141 142 1 ``` if voltage_depend_loads: ``` 143 ``` # constant impedance and constant current ``` 144 1 ``` vm_l = net["_ppc"]["bus"][lidx, 7] ``` 145 1 ``` volt_depend = ci * vm_l + cz * vm_l ** 2 ``` 146 1 ``` pl = l["p_mw"].values * scaling * load_is * volt_depend ``` 147 1 ``` net["res_load"]["p_mw"] += pl ``` 148 1 ``` p = np.hstack([p, pl]) ``` 149 150 1 ``` ql = l["q_mvar"].values * scaling * load_is * volt_depend ``` 151 1 ``` net["res_load"]["q_mvar"] += ql ``` 152 1 ``` q = np.hstack([q, ql]) ``` 153 154 1 ``` b = np.hstack([b, l["bus"].values]) ``` 155 1 ``` return p, q, b ``` 156 157 158 1 ```def write_pq_results_to_element(net, ppc, element, suffix=None): ``` 159 ``` """ ``` 160 ``` get p_mw and q_mvar for a specific pq element ("load", "sgen"...). ``` 161 ``` This function basically writes values element table to res_element table ``` 162 ``` :param net: pandapower net ``` 163 ``` :param element: element name (str) ``` 164 ``` :return: ``` 165 ``` """ ``` 166 ``` # info from net ``` 167 1 ``` _is_elements = net["_is_elements"] ``` 168 1 ``` ac = net["_options"]["ac"] ``` 169 170 ``` # info element ``` 171 1 ``` el_data = net[element] ``` 172 1 ``` res_ = "res_%s" % element ``` 173 1 ``` if suffix is not None: ``` 174 1 ``` res_ += "_%s"%suffix ``` 175 1 ``` ctrl_ = "%s_controllable" % element ``` 176 177 1 ``` is_controllable = False ``` 178 1 ``` if ctrl_ in _is_elements: ``` 179 1 ``` controlled_elements = net[element][net._is_elements[ctrl_]].index ``` 180 1 ``` gen_idx = net._pd2ppc_lookups[ctrl_][controlled_elements] ``` 181 1 ``` gen_sign = 1 if element == "sgen" else -1 ``` 182 1 ``` is_controllable = True ``` 183 184 1 ``` if element == "motor": ``` 185 1 ``` p_mw, q_mvar = _get_motor_pq(net) ``` 186 1 ``` net[res_]["p_mw"].values[:] = p_mw ``` 187 1 ``` net[res_]["q_mvar"].values[:] = q_mvar ``` 188 1 ``` return net ``` 189 1 ``` elif element.startswith("asymmetric"): ``` 190 1 ``` p_mw, q_mvar = _get_symmetric_pq_of_unsymetric_element(net, element) ``` 191 1 ``` net[res_]["p_mw"].values[:] = p_mw ``` 192 1 ``` net[res_]["q_mvar"].values[:] = q_mvar ``` 193 1 ``` return net ``` 194 195 ``` # Wards and xwards have different names in their element table, but not in res table. Also no scaling -> Fix... ``` 196 1 ``` p_mw = "ps_mw" if element in ["ward", "xward"] else "p_mw" ``` 197 1 ``` q_mvar = "qs_mvar" if element in ["ward", "xward"] else "q_mvar" ``` 198 1 ``` scaling = el_data["scaling"].values if element not in ["ward", "xward"] else 1.0 ``` 199 200 1 ``` element_in_service = _is_elements[element] ``` 201 202 ``` # P result in mw to element ``` 203 1 ``` net[res_]["p_mw"].values[:] = el_data[p_mw].values * scaling * element_in_service ``` 204 1 ``` if is_controllable: ``` 205 1 ``` net[res_]["p_mw"].loc[controlled_elements] = ppc["gen"][gen_idx, PG] * gen_sign ``` 206 207 1 ``` if ac: ``` 208 ``` # Q result in mvar to element ``` 209 1 ``` net[res_]["q_mvar"].values[:] = el_data[q_mvar].values * scaling * element_in_service ``` 210 1 ``` if is_controllable: ``` 211 1 ``` net[res_]["q_mvar"].loc[controlled_elements] = ppc["gen"][gen_idx, QG] * gen_sign ``` 212 1 ``` return net ``` 213 214 215 1 ```def write_pq_results_to_element_3ph(net, element): ``` 216 ``` """ ``` 217 ``` get p_mw and q_mvar for a specific pq element ("load", "sgen"...). ``` 218 ``` This function basically writes values element table to res_element table ``` 219 220 ``` :param net: pandapower net ``` 221 ``` :param element: element name (str) ``` 222 ``` :return: ``` 223 ``` """ ``` 224 225 ``` # info from net ``` 226 1 ``` _is_elements = net["_is_elements"] ``` 227 1 ``` ac = net["_options"]["ac"] ``` 228 229 ``` # info element ``` 230 1 ``` el_data = net[element] ``` 231 1 ``` res_ = "res_" + element+"_3ph" ``` 232 233 1 ``` scaling = el_data["scaling"].values ``` 234 235 1 ``` element_in_service = _is_elements[element] ``` 236 237 1 ``` net[res_]["p_a_mw"] = pd.Series((el_data["p_mw"].values/3)\ ``` 238 ``` * scaling * element_in_service) if element in[ "load","sgen"] else\ ``` 239 ``` pd.Series(el_data["p_a_mw"].values * scaling * element_in_service) ``` 240 241 1 ``` net[res_]["p_b_mw"] = pd.Series((el_data["p_mw"].values/3) \ ``` 242 ``` * scaling * element_in_service)if element in[ "load","sgen"] else\ ``` 243 ``` pd.Series(el_data["p_b_mw"].values * scaling * element_in_service) ``` 244 245 1 ``` net[res_]["p_c_mw"] = pd.Series((el_data["p_mw"].values/3) \ ``` 246 ``` * scaling * element_in_service) if element in[ "load","sgen"] else\ ``` 247 ``` pd.Series(el_data["p_c_mw"].values * scaling * element_in_service) ``` 248 1 ``` if ac: ``` 249 ``` # Q result in kvar to element ``` 250 1 ``` net[res_]["q_a_mvar"] = pd.Series((el_data["q_mvar"].values/3)\ ``` 251 ``` * scaling * element_in_service) if element in[ "load","sgen"] else\ ``` 252 ``` pd.Series(el_data["q_a_mvar"].values * scaling * element_in_service) ``` 253 254 1 ``` net[res_]["q_b_mvar"] = pd.Series((el_data["q_mvar"].values/3)\ ``` 255 ``` * scaling * element_in_service) if element in[ "load","sgen"] else\ ``` 256 ``` pd.Series(el_data["q_b_mvar"].values * scaling * element_in_service) ``` 257 258 1 ``` net[res_]["q_c_mvar"] = pd.Series((el_data["q_mvar"].values/3)\ ``` 259 ``` * scaling * element_in_service) if element in[ "load","sgen"] else\ ``` 260 ``` pd.Series(el_data["q_c_mvar"].values * scaling * element_in_service) ``` 261 262 ``` # update index of result table ``` 263 1 ``` net[res_].index = net[element].index ``` 264 1 ``` return net ``` 265 266 267 1 ```def get_p_q_b(net, element, suffix=None): ``` 268 1 ``` ac = net["_options"]["ac"] ``` 269 1 ``` res_ = "res_" + element ``` 270 1 ``` if suffix != None: ``` 271 1 ``` res_ += "_%s"%suffix ``` 272 273 ``` # bus values are needed for stacking ``` 274 1 ``` b = net[element]["bus"].values ``` 275 1 ``` p = net[res_]["p_mw"] ``` 276 1 ``` q = net[res_]["q_mvar"] if ac else np.zeros_like(p) ``` 277 1 ``` return p, q, b ``` 278 279 1 ```def get_p_q_b_3ph(net, element): ``` 280 1 ``` ac = net["_options"]["ac"] ``` 281 1 ``` res_ = "res_" + element+"_3ph" ``` 282 283 ``` # bus values are needed for stacking ``` 284 1 ``` b = net[element]["bus"].values ``` 285 1 ``` pA = net[res_]["p_a_mw"] ``` 286 1 ``` pB = net[res_]["p_b_mw"] ``` 287 1 ``` pC = net[res_]["p_c_mw"] ``` 288 1 ``` qA = net[res_]["q_a_mvar"] if ac else np.zeros_like(pA) ``` 289 1 ``` qB = net[res_]["q_b_mvar"] if ac else np.zeros_like(pB) ``` 290 1 ``` qC = net[res_]["q_c_mvar"] if ac else np.zeros_like(pC) ``` 291 1 ``` return pA, qA, pB, qB, pC, qC, b ``` 292 293 294 1 ```def _get_p_q_results(net, ppc, bus_lookup_aranged): ``` 295 1 ``` bus_pq = np.zeros(shape=(len(net["bus"].index), 2), dtype=np.float) ``` 296 1 ``` b, p, q = np.array([]), np.array([]), np.array([]) ``` 297 298 1 ``` ac = net["_options"]["ac"] ``` 299 1 ``` elements = ["load", "motor", "sgen", "storage", "ward", "xward", ``` 300 ``` "asymmetric_load", "asymmetric_sgen"] ``` 301 302 1 ``` if net["_options"]["voltage_depend_loads"] and ac: ``` 303 ``` # voltage dependend loads need special treatment here ``` 304 305 1 ``` p, q, b = write_voltage_dependend_load_results(net, p, q, b) ``` 306 1 ``` elements.remove("load") ``` 307 308 1 ``` for element in elements: ``` 309 1 ``` if len(net[element]): ``` 310 1 ``` write_pq_results_to_element(net, ppc, element) ``` 311 1 ``` p_el, q_el, bus_el = get_p_q_b(net, element) ``` 312 1 ``` if element.endswith("sgen"): ``` 313 1 ``` p = np.hstack([p, -p_el]) ``` 314 1 ``` q = np.hstack([q, -q_el]) ``` 315 ``` else: ``` 316 1 ``` p = np.hstack([p, p_el]) ``` 317 1 ``` q = np.hstack([q, q_el]) ``` 318 1 ``` b = np.hstack([b, bus_el]) ``` 319 320 1 ``` if not ac: ``` 321 1 ``` q = np.zeros(len(p)) ``` 322 323 ``` # sum pq results from every element to be written to net['bus'] later on ``` 324 1 ``` b_pp, vp, vq = _sum_by_group(b.astype(int), p, q) ``` 325 1 ``` b_ppc = bus_lookup_aranged[b_pp] ``` 326 1 ``` bus_pq[b_ppc, 0] = vp ``` 327 1 ``` bus_pq[b_ppc, 1] = vq ``` 328 1 ``` return bus_pq ``` 329 330 1 ```def _get_p_q_results_3ph(net, bus_lookup_aranged): ``` 331 ``` # results to be filled (bus, p in kw, q in kvar) ``` 332 1 ``` bus_pq = np.zeros(shape=(len(net["bus"].index), 6), dtype=np.float) ``` 333 1 ``` b, pA, pB, pC, qA, qB, qC = np.array([]), np.array([]), np.array([]), np.array([]), \ ``` 334 ``` np.array([]), np.array([]), np.array([]) ``` 335 336 1 ``` ac = net["_options"]["ac"] ``` 337 ``` # Todo: Voltage dependent loads ``` 338 1 ``` elements = ["storage", "sgen", "load"] ``` 339 1 ``` elements_3ph = ["asymmetric_load", "asymmetric_sgen"] ``` 340 1 ``` for element in elements: ``` 341 1 ``` sign = -1 if element in ['sgen','asymmetric_sgen'] else 1 ``` 342 1 ``` if len(net[element]): ``` 343 1 ``` write_pq_results_to_element(net, net._ppc1, element, suffix="3ph") ``` 344 1 ``` p_el, q_el, bus_el = get_p_q_b(net, element, suffix="3ph") ``` 345 1 ``` pA = np.hstack([pA, sign * p_el/3]) ``` 346 1 ``` pB = np.hstack([pB, sign * p_el/3]) ``` 347 1 ``` pC = np.hstack([pC, sign * p_el/3]) ``` 348 1 ``` qA = np.hstack([qA, sign * q_el/3 if ac else np.zeros(len(p_el/3))]) ``` 349 1 ``` qB = np.hstack([qB, sign * q_el/3 if ac else np.zeros(len(p_el/3))]) ``` 350 1 ``` qC = np.hstack([qC, sign * q_el/3 if ac else np.zeros(len(p_el/3))]) ``` 351 1 ``` b = np.hstack([b, bus_el]) ``` 352 1 ``` for element in elements_3ph: ``` 353 1 ``` sign = -1 if element in ['sgen','asymmetric_sgen'] else 1 ``` 354 1 ``` if len(net[element]): ``` 355 1 ``` write_pq_results_to_element_3ph(net, element) ``` 356 1 ``` p_el_A, q_el_A, p_el_B, q_el_B, p_el_C, q_el_C, bus_el = get_p_q_b_3ph(net, element) ``` 357 1 ``` pA = np.hstack([pA, sign * p_el_A]) ``` 358 1 ``` pB = np.hstack([pB, sign * p_el_B]) ``` 359 1 ``` pC = np.hstack([pC, sign * p_el_C]) ``` 360 1 ``` qA = np.hstack([qA, sign * q_el_A if ac else np.zeros(len(p_el_A))]) ``` 361 1 ``` qB = np.hstack([qB, sign * q_el_B if ac else np.zeros(len(p_el_B))]) ``` 362 1 ``` qC = np.hstack([qC, sign * q_el_C if ac else np.zeros(len(p_el_C))]) ``` 363 1 ``` b = np.hstack([b, bus_el]) ``` 364 365 ``` # sum pq results from every element to be written to net['bus'] later on ``` 366 1 ``` b_pp, vp_A, vq_A, vp_B, vq_B, vp_C, vq_C = _sum_by_group_nvals(b.astype(int), pA, qA, pB, qB, pC, qC) ``` 367 1 ``` b_ppc = bus_lookup_aranged[b_pp] ``` 368 1 ``` bus_pq[b_ppc, 0] = vp_A ``` 369 1 ``` bus_pq[b_ppc, 1] = vq_A ``` 370 1 ``` bus_pq[b_ppc, 2] = vp_B ``` 371 1 ``` bus_pq[b_ppc, 3] = vq_B ``` 372 1 ``` bus_pq[b_ppc, 4] = vp_C ``` 373 1 ``` bus_pq[b_ppc, 5] = vq_C ``` 374 1 ``` return bus_pq ``` 375 376 1 ```def _get_shunt_results(net, ppc, bus_lookup_aranged, bus_pq): ``` 377 1 ``` ac = net["_options"]["ac"] ``` 378 379 1 ``` b, p, q = np.array([]), np.array([]), np.array([]) ``` 380 1 ``` _is_elements = net["_is_elements"] ``` 381 1 ``` bus_lookup = net["_pd2ppc_lookups"]["bus"] ``` 382 383 1 ``` s = net["shunt"] ``` 384 1 ``` if len(s) > 0: ``` 385 1 ``` sidx = bus_lookup[s["bus"].values] ``` 386 1 ``` shunt_is = _is_elements["shunt"] ``` 387 1 ``` u_shunt = ppc["bus"][sidx, VM] ``` 388 1 ``` step = s["step"] ``` 389 1 ``` v_ratio = (ppc["bus"][sidx, BASE_KV] / net["shunt"]["vn_kv"].values) ** 2 ``` 390 1 ``` u_shunt = np.nan_to_num(u_shunt) ``` 391 1 ``` p_shunt = u_shunt ** 2 * net["shunt"]["p_mw"].values * shunt_is * v_ratio * step ``` 392 1 ``` net["res_shunt"]["p_mw"].values[:] = p_shunt ``` 393 1 ``` p = np.hstack([p, p_shunt]) ``` 394 1 ``` if ac: ``` 395 1 ``` net["res_shunt"]["vm_pu"].values[:] = u_shunt ``` 396 1 ``` q_shunt = u_shunt ** 2 * net["shunt"]["q_mvar"].values * shunt_is * v_ratio * step ``` 397 1 ``` net["res_shunt"]["q_mvar"].values[:] = q_shunt ``` 398 1 ``` q = np.hstack([q, q_shunt]) ``` 399 1 ``` b = np.hstack([b, s["bus"].values]) ``` 400 401 1 ``` w = net["ward"] ``` 402 1 ``` if len(w) > 0: ``` 403 1 ``` widx = bus_lookup[w["bus"].values] ``` 404 1 ``` ward_is = _is_elements["ward"] ``` 405 1 ``` u_ward = ppc["bus"][widx, VM] ``` 406 1 ``` u_ward = np.nan_to_num(u_ward) ``` 407 1 ``` p_ward = u_ward ** 2 * net["ward"]["pz_mw"].values * ward_is ``` 408 1 ``` net["res_ward"]["p_mw"].values[:] = net["res_ward"]["p_mw"].values + p_ward ``` 409 1 ``` p = np.hstack([p, p_ward]) ``` 410 1 ``` if ac: ``` 411 1 ``` net["res_ward"]["vm_pu"].values[:] = u_ward ``` 412 1 ``` q_ward = u_ward ** 2 * net["ward"]["qz_mvar"].values * ward_is ``` 413 1 ``` net["res_ward"]["q_mvar"].values[:] = net["res_ward"]["q_mvar"].values + q_ward ``` 414 1 ``` q = np.hstack([q, q_ward]) ``` 415 1 ``` b = np.hstack([b, w["bus"].values]) ``` 416 417 1 ``` xw = net["xward"] ``` 418 1 ``` if len(xw) > 0: ``` 419 1 ``` widx = bus_lookup[xw["bus"].values] ``` 420 1 ``` xward_is = _is_elements["xward"] ``` 421 1 ``` u_xward = ppc["bus"][widx, VM] ``` 422 1 ``` u_xward = np.nan_to_num(u_xward) ``` 423 1 ``` p_xward = u_xward ** 2 * net["xward"]["pz_mw"].values * xward_is ``` 424 1 ``` net["res_xward"]["p_mw"].values[:] = net["res_xward"]["p_mw"].values + p_xward ``` 425 1 ``` p = np.hstack([p, p_xward]) ``` 426 1 ``` if ac: ``` 427 1 ``` net["res_xward"]["vm_pu"].values[:] = u_xward ``` 428 1 ``` q_xward = u_xward ** 2 * net["xward"]["qz_mvar"].values * xward_is ``` 429 1 ``` net["res_xward"]["q_mvar"].values[:] = net["res_xward"]["q_mvar"].values + q_xward ``` 430 1 ``` q = np.hstack([q, q_xward]) ``` 431 1 ``` b = np.hstack([b, xw["bus"].values]) ``` 432 433 1 ``` if not ac: ``` 434 1 ``` q = np.zeros(len(p)) ``` 435 1 ``` b_pp, vp, vq = _sum_by_group(b.astype(int), p, q) ``` 436 1 ``` b_ppc = bus_lookup_aranged[b_pp] ``` 437 438 1 ``` bus_pq[b_ppc, 0] += vp ``` 439 1 ``` if ac: ``` 440 1 ``` bus_pq[b_ppc, 1] += vq ```

Read our documentation on viewing source code .