def _pd2ppc_recycle(net, sequence, recycle): key = "_ppc" if sequence is None else "_ppc%d" % sequence if not recycle or not net.get(key, None): return _pd2ppc(net, sequence=sequence) ppc = net[key] ppc["success"] = False ppc["iterations"] = 0. ppc["et"] = 0. if "bus_pq" in recycle and recycle["bus_pq"]: # update pq values in bus _calc_pq_elements_and_add_on_ppc(net, ppc, sequence=sequence) # if "trafo" in recycle and recycle["trafo"]: # # update trafo in branch and Ybus # lookup = net._pd2ppc_lookups["branch"] # if "trafo" in lookup: # _calc_trafo_parameter(net, ppc) # if "trafo3w" in lookup: # _calc_trafo3w_parameter(net, ppc) if "gen" in recycle and recycle["gen"]: # updates the ppc["gen"] part _build_gen_ppc(net, ppc) ppc["gen"] = np.nan_to_num(ppc["gen"]) ppci = _ppc2ppci(ppc, net) ppci["internal"] = net[key]["internal"] net[key] = ppc return ppc, ppci
def _update_nr_variables(self): """ This function updates the stored NR variables for the powerflow, depending on the defined controllers for the time series calculation example: If only PQ updates are needed -> only pq values (in ppci.bus[:,PD]...) are updated If taps of trafos are updated -> Ybus must be recalculated Todo implement stuff for the controllers you use... @return: """ ### PQ Updates if self.update_pq: # update P, Q values _calc_pq_elements_and_add_on_ppc(self.net, self.ppci) # adds P and Q for shunts, wards and xwards (to PQ nodes) # Todo: update shunts # _calc_shunts_and_add_on_ppc(self.net, self.ppci) ### Ybus recalculation if self.update_trafo: # update branch SHIFT entries for transformers (if tap changed) self.update_trafos() if "ybus_handler" in self.net: logger.error( "Ybus update by trafo tap controller and ybus_handler is not possible simultaneously" ) if "ybus_handler" in self.net: self.Ybus, self.Yf, self.Yt = self.net["ybus_handler"].get_y()
def _update_ppc(net): """ Updates P, Q values of the ppc with changed values from net @param _is_elements: @return: """ # select elements in service (time consuming, so we do it once) net["_is_elements"] = aux._select_is_elements_numba(net) recycle = net["_options"]["recycle"] # get the old ppc and lookup ppc = net["_ppc"] ppci = copy.deepcopy(ppc) # adds P and Q for loads / sgens in ppc['bus'] (PQ nodes) _calc_pq_elements_and_add_on_ppc(net, ppc) # adds P and Q for shunts, wards and xwards (to PQ nodes) _calc_shunts_and_add_on_ppc(net, ppc) # updates values for gen _update_gen_ppc(net, ppc) # check if any generators connected to the same bus have different voltage setpoints _check_voltage_setpoints_at_same_bus(ppc) if not recycle["Ybus"]: # updates trafo and trafo3w values _update_trafo_trafo3w_ppc(net, ppc) # get OOS buses and place them at the end of the bus array (so that: 3 # (REF), 2 (PV), 1 (PQ), 4 (OOS)) oos_busses = ppc['bus'][:, BUS_TYPE] == NONE # there are no OOS busses in the ppci ppci['bus'] = ppc['bus'][~oos_busses] # select in service elements from ppc and put them in ppci brs = ppc["internal"]["branch_is"] gs = ppc["internal"]["gen_is"] ppci["branch"] = ppc["branch"][brs] ppci["gen"] = ppc["gen"][gs] return ppc, ppci
def _pd2ppc(net, sequence=None): """ Converter Flow: 1. Create an empty pypower datatructure 2. Calculate loads and write the bus matrix 3. Build the gen (Infeeder)- Matrix 4. Calculate the line parameter and the transformer parameter, and fill it in the branch matrix. Order: 1st: Line values, 2nd: Trafo values 5. if opf: make opf objective (gencost) 6. convert internal ppci format for pypower powerflow / opf without out of service elements and rearanged buses INPUT: **net** - The pandapower format network **sequence** - Used for three phase analysis ( 0 - Zero Sequence 1 - Positive Sequence 2 - Negative Sequence ) OUTPUT: **ppc** - The simple matpower format network. Which consists of: ppc = { "baseMVA": 1., *float* "version": 2, *int* "bus": np.array([], dtype=float), "branch": np.array([], dtype=np.complex128), "gen": np.array([], dtype=float), "gencost" = np.array([], dtype=float), only for OPF "internal": { "Ybus": np.array([], dtype=np.complex128) , "Yf": np.array([], dtype=np.complex128) , "Yt": np.array([], dtype=np.complex128) , "branch_is": np.array([], dtype=bool) , "gen_is": np.array([], dtype=bool) } **ppci** - The "internal" pypower format network for PF calculations """ # select elements in service (time consuming, so we do it once) net["_is_elements"] = aux._select_is_elements_numba(net, sequence=sequence) # Gets network configurations mode = net["_options"]["mode"] check_connectivity = net["_options"]["check_connectivity"] calculate_voltage_angles = net["_options"]["calculate_voltage_angles"] ppc = _init_ppc(net, mode=mode, sequence=sequence) # generate ppc['bus'] and the bus lookup _build_bus_ppc(net, ppc) if sequence == 0: from pandapower.pd2ppc_zero import _add_ext_grid_sc_impedance_zero, _build_branch_ppc_zero # Adds external grid impedance for 3ph and sc calculations in ppc0 _add_ext_grid_sc_impedance_zero(net, ppc) # Calculates ppc0 branch impedances from branch elements _build_branch_ppc_zero(net, ppc) else: # Calculates ppc1/ppc2 branch impedances from branch elements _build_branch_ppc(net, ppc) # Adds P and Q for loads / sgens in ppc['bus'] (PQ nodes) if mode == "sc": _add_gen_impedances_ppc(net, ppc) _add_motor_impedances_ppc(net, ppc) else: _calc_pq_elements_and_add_on_ppc(net, ppc, sequence=sequence) # adds P and Q for shunts, wards and xwards (to PQ nodes) _calc_shunts_and_add_on_ppc(net, ppc) # adds auxilary buses for open switches at branches _switch_branches(net, ppc) # Adds auxilary buses for in service lines with out of service buses. # Also deactivates lines if they are connected to two out of service buses _branches_with_oos_buses(net, ppc) if check_connectivity: if sequence in [None, 1, 2]: # sets islands (multiple isolated nodes) out of service if "opf" in mode: net["_isolated_buses"], _, _ = aux._check_connectivity_opf(ppc) else: net["_isolated_buses"], _, _ = aux._check_connectivity(ppc) net["_is_elements_final"] = aux._select_is_elements_numba( net, net._isolated_buses, sequence) else: ppc["bus"][net._isolated_buses, BUS_TYPE] = NONE net["_is_elements"] = net["_is_elements_final"] else: # sets buses out of service, which aren't connected to branches / REF buses aux._set_isolated_buses_out_of_service(net, ppc) _build_gen_ppc(net, ppc) if "pf" in mode: _check_for_reference_bus(ppc) aux._replace_nans_with_default_limits(net, ppc) # generates "internal" ppci format (for powerflow calc) # from "external" ppc format and updates the bus lookup # Note: Also reorders buses and gens in ppc ppci = _ppc2ppci(ppc, net) if mode == "pf": # check if any generators connected to the same bus have different voltage setpoints _check_voltage_setpoints_at_same_bus(ppc) if calculate_voltage_angles: _check_voltage_angles_at_same_bus(net, ppci) if mode == "opf": # make opf objective ppci = _make_objective(ppci, net) return ppc, ppci
def _pd2ppc(net): """ Converter Flow: 1. Create an empty pypower datatructure 2. Calculate loads and write the bus matrix 3. Build the gen (Infeeder)- Matrix 4. Calculate the line parameter and the transformer parameter, and fill it in the branch matrix. Order: 1st: Line values, 2nd: Trafo values 5. if opf: make opf objective (gencost) 6. convert internal ppci format for pypower powerflow / opf without out of service elements and rearanged buses INPUT: **net** - The pandapower format network OUTPUT: **ppc** - The simple matpower format network. Which consists of: ppc = { "baseMVA": 1., *float* "version": 2, *int* "bus": np.array([], dtype=float), "branch": np.array([], dtype=np.complex128), "gen": np.array([], dtype=float), "gencost" = np.array([], dtype=float), only for OPF "internal": { "Ybus": np.array([], dtype=np.complex128) , "Yf": np.array([], dtype=np.complex128) , "Yt": np.array([], dtype=np.complex128) , "branch_is": np.array([], dtype=bool) , "gen_is": np.array([], dtype=bool) } **ppci** - The "internal" pypower format network for PF calculations """ # select elements in service (time consuming, so we do it once) net["_is_elements"] = aux._select_is_elements_numba(net) # get options mode = net["_options"]["mode"] check_connectivity = net["_options"]["check_connectivity"] calculate_voltage_angles = net["_options"]["calculate_voltage_angles"] ppc = _init_ppc(net, mode=mode) # generate ppc['bus'] and the bus lookup _build_bus_ppc(net, ppc) # generate ppc['branch'] and directly generates branch values _build_branch_ppc(net, ppc) # adds P and Q for loads / sgens in ppc['bus'] (PQ nodes) if mode == "sc": _add_gen_impedances_ppc(net, ppc) _add_motor_impedances_ppc(net, ppc) else: _calc_pq_elements_and_add_on_ppc(net, ppc) # adds P and Q for shunts, wards and xwards (to PQ nodes) _calc_shunts_and_add_on_ppc(net, ppc) # adds auxilary buses for open switches at branches _switch_branches(net, ppc) # add auxilary buses for out of service buses at in service lines. # Also sets lines out of service if they are connected to two out of service buses _branches_with_oos_buses(net, ppc) if check_connectivity: # sets islands (multiple isolated nodes) out of service if "opf" in mode: isolated_nodes, _, _ = aux._check_connectivity_opf(ppc) else: isolated_nodes, _, _ = aux._check_connectivity(ppc) net["_is_elements"] = aux._select_is_elements_numba( net, isolated_nodes) # sets buses out of service, which aren't connected to branches / REF buses aux._set_isolated_buses_out_of_service(net, ppc) _build_gen_ppc(net, ppc) if "pf" in mode: _check_for_reference_bus(ppc) aux._replace_nans_with_default_limits(net, ppc) # generates "internal" ppci format (for powerflow calc) from "external" ppc format and updates the bus lookup # Note: Also reorders buses and gens in ppc ppci = _ppc2ppci(ppc, net) if mode == "pf": # check if any generators connected to the same bus have different voltage setpoints _check_voltage_setpoints_at_same_bus(ppc) if calculate_voltage_angles: _check_voltage_angles_at_same_bus(net, ppci) if mode == "opf": # make opf objective ppci = _make_objective(ppci, net) return ppc, ppci