def test_for_line_with_zero_length(net): tb.replace_zero_branches_with_switches(net, elements=('line', ), zero_impedance=False) assert 'REPLACEMENT_line_0' in net.switch.name.values assert ~net.line.in_service.at[0] assert 'REPLACEMENT_line_2' not in net.switch.name.values
def test_line_with_zero_impediance(net): # test for line with zero impedance tb.replace_zero_branches_with_switches(net, elements=('line', ), zero_length=False) assert 'REPLACEMENT_line_1' not in net.switch.name.values assert 'REPLACEMENT_line_2' in net.switch.name.values
def test_in_service_only(net): tb.replace_zero_branches_with_switches(net, elements=('line', )) assert len(net.switch.loc[net.switch.name == 'REPLACEMENT_line_0']) == 1 tb.replace_zero_branches_with_switches(net, elements=('line', ), in_service_only=False) assert len(net.switch.loc[net.switch.name == 'REPLACEMENT_line_0']) == 2 assert ~net.switch.closed.at[2]
def test_impedance(net): tb.replace_zero_branches_with_switches(net, elements=('impedance', ), zero_length=False, zero_impedance=True, in_service_only=True) assert 'REPLACEMENT_impedance_0' not in net.switch.name.values assert 'REPLACEMENT_impedance_1' in net.switch.name.values assert 'REPLACEMENT_impedance_2' not in net.switch.name.values
def test_all(net): tb.replace_zero_branches_with_switches(net, elements=('impedance', 'line'), zero_length=True, zero_impedance=True, in_service_only=True) assert 'REPLACEMENT_impedance_1' in net.switch.name.values assert 'REPLACEMENT_line_0' in net.switch.name.values assert 'REPLACEMENT_line_2' in net.switch.name.values assert ~net.line.in_service.at[0] assert net.line.in_service.at[1] assert ~net.line.in_service.at[2] assert 'REPLACEMENT_impedance_0' not in net.switch.name.values assert 'REPLACEMENT_impedance_2' not in net.switch.name.values assert 'REPLACEMENT_line_1' not in net.switch.name.values assert net.impedance.in_service.at[0] assert ~net.impedance.in_service.at[1] assert net.impedance.in_service.at[2]
def test_drop(net): tb.replace_zero_branches_with_switches(net, elements=('line', 'impedance'), drop_affected=True) assert len(net.line) == 1 assert len(net.impedance) == 2
def test_replace_zero_branches_with_switches(): net = pp.create_empty_network() bus0 = pp.create_bus(net, vn_kv=0.4) bus1 = pp.create_bus(net, vn_kv=0.4) bus2 = pp.create_bus(net, vn_kv=0.4) bus3 = pp.create_bus(net, vn_kv=0.4) bus4 = pp.create_bus(net, vn_kv=0.4) bus5 = pp.create_bus(net, vn_kv=0.4) bus6 = pp.create_bus(net, vn_kv=0.4) pp.create_ext_grid(net, bus0, vm_pu=0.4) line0 = pp.create_line(net, bus0, bus1, length_km=0, std_type="NAYY 4x50 SE") line1 = pp.create_line_from_parameters(net, bus2, bus3, length_km=1, r_ohm_per_km=0, x_ohm_per_km=0.1, c_nf_per_km=0, max_i_ka=1) line2 = pp.create_line_from_parameters(net, bus3, bus4, length_km=1, r_ohm_per_km=0, x_ohm_per_km=0, c_nf_per_km=0, max_i_ka=1) impedance0 = pp.create_impedance(net, bus1, bus2, 0.01, 0.01, sn_kva=1e5) impedance1 = pp.create_impedance(net, bus4, bus5, 0, 0, sn_kva=1e5) impedance2 = pp.create_impedance(net, bus5, bus6, 0, 0, rtf_pu=0.1, sn_kva=1e5) # test for line with zero length tb.replace_zero_branches_with_switches(net, elements=('line', ), zero_length=True, zero_impedance=False, in_service_only=True) assert 'REPLACEMENT_line_0' in net.switch.name.values assert ~net.line.in_service.at[0] # test for in_service_only tb.replace_zero_branches_with_switches(net, elements=('line', ), zero_length=True, zero_impedance=False, in_service_only=True) assert len(net.switch.loc[net.switch.name == 'REPLACEMENT_line_0']) == 1 tb.replace_zero_branches_with_switches(net, elements=('line', ), zero_length=True, zero_impedance=False, in_service_only=False) assert len(net.switch.loc[net.switch.name == 'REPLACEMENT_line_0']) == 2 assert ~net.switch.closed.at[1] # test for line with zero impedance tb.replace_zero_branches_with_switches(net, elements=('line', ), zero_length=False, zero_impedance=True, in_service_only=True) assert 'REPLACEMENT_line_1' not in net.switch.name.values assert 'REPLACEMENT_line_2' in net.switch.name.values # test for impedance tb.replace_zero_branches_with_switches(net, elements=('impedance', ), zero_length=False, zero_impedance=True, in_service_only=True) assert 'REPLACEMENT_impedance_0' not in net.switch.name.values assert 'REPLACEMENT_impedance_1' in net.switch.name.values assert 'REPLACEMENT_impedance_2' not in net.switch.name.values # now run everything altogether net.switch.drop(net.switch.index, inplace=True) net.line.loc[:, 'in_service'] = True net.impedance.loc[:, 'in_service'] = True tb.replace_zero_branches_with_switches(net, elements=('impedance', 'line'), zero_length=True, zero_impedance=True, in_service_only=True) assert 'REPLACEMENT_impedance_1' in net.switch.name.values assert 'REPLACEMENT_line_0' in net.switch.name.values assert 'REPLACEMENT_line_2' in net.switch.name.values assert ~net.line.in_service.at[0] assert net.line.in_service.at[1] assert ~net.line.in_service.at[2] assert 'REPLACEMENT_impedance_0' not in net.switch.name.values assert 'REPLACEMENT_impedance_2' not in net.switch.name.values assert 'REPLACEMENT_line_1' not in net.switch.name.values assert net.impedance.in_service.at[0] assert ~net.impedance.in_service.at[1] assert net.impedance.in_service.at[2]
def validate_pf_conversion(net, is_unbalanced=False, **kwargs): """ Trys to run a Loadflow with the converted pandapower network. If the loadflow converges, \ PowerFactory and pandapower loadflow results will be compared. Note that a pf validation can \ only be done if there are pf results available. INPUT: - **net** (PandapowerNetwork) - converted pandapower network OUTPUT: - **all_diffs** (list) - returns a list with the difference in all validated values. If all values are zero -> results are equal """ logger.debug('starting verification') toolbox.replace_zero_branches_with_switches(net) pf_results = _get_pf_results(net, is_unbalanced=is_unbalanced) if "controller" not in net.keys() or len(net.controller) == 0: try: for arg in 'trafo_model check_connectivity'.split(): if arg in kwargs: kwargs.pop(arg) if is_unbalanced: logger.info("running pandapower 3ph loadflow") pp.runpp_3ph(net, trafo_model="t", check_connectivity=True, **kwargs) else: logger.info("running pandapower loadflow") pp.runpp(net, trafo_model="t", check_connectivity=True, **kwargs) except Exception as err: logger.error('pandapower load flow failed: %s' % err, exc_info=True) diagnostic(net) raise err else: import pandapower.control as control try: control.run_control(net, max_iter=50, trafo_model="t", check_connectivity=True, **kwargs) except Exception as err: logger.error('pandapower load flow with converter failed: %s' % err) diagnostic(net) raise err all_diffs = dict() logger.info('pandapower net converged: %s' % net.converged) _set_pf_results(net, pf_results, is_unbalanced=is_unbalanced) net.bus.name.fillna("", inplace=True) only_in_pandapower = set(net.bus[net.bus.name.str.endswith("_aux")].index) | \ set(net.bus[net.bus.type == "ls"].index) in_both = set(net.bus.index) - only_in_pandapower pf_closed = pf_results['pf_switch_status'] wrong_switches = net.res_switch.loc[pf_closed != net.switch.loc[ pf_closed.index, 'closed']].index.values if 'res_switch' in net.keys() else [] if len(net.switch) > 0: logger.info('%d switches are wrong: %s' % (len(wrong_switches), wrong_switches)) if len(net.trafo3w[net.trafo3w.in_service]) > 0: trafo3w_idx = net.trafo3w.query('in_service').index trafo3w_diff = net.res_trafo3w.loc[ trafo3w_idx].pf_loading - net.res_trafo3w.loc[ trafo3w_idx].loading_percent trafo3w_id = abs(trafo3w_diff).idxmax() logger.info( "Maximum trafo3w loading difference between pandapower and powerfactory: %.1f " "percent at trafo3w %d (%s)" % (max(abs(trafo3w_diff)), trafo3w_id, net.trafo3w.at[trafo3w_id, 'name'])) all_diffs["trafo3w_diff"] = trafo3w_diff if len(net.sgen[net.sgen.in_service]) > 0: logger.debug('verifying sgen') sgen_p_diff = net.res_sgen.pf_p.replace(np.nan, 0) - net.res_sgen.p_mw sgen_q_diff = net.res_sgen.pf_q.replace(np.nan, 0) - net.res_sgen.q_mvar sgen_p_diff_is = net.res_sgen.pf_p.replace(np.nan, 0) * net.sgen.loc[ net.res_sgen.index, 'in_service'] - net.res_sgen.p_mw sgen_q_diff_is = net.res_sgen.pf_q.replace(np.nan, 0) * net.sgen.loc[ net.res_sgen.index, 'in_service'] - net.res_sgen.q_mvar logger.info( "Maximum sgen active power difference between pandapower and powerfactory: " "%.1f MW, in service only: %.1f MW" % (max(abs(sgen_p_diff)), max(abs(sgen_p_diff_is)))) logger.info( "Maximum sgen reactive power difference between pandapower and powerfactory: " "%.1f Mvar, in service only: %.1f Mvar" % (max(abs(sgen_q_diff)), max(abs(sgen_q_diff_is)))) all_diffs["sgen_p_diff_is"] = sgen_p_diff_is all_diffs["sgen_q_diff_is"] = sgen_q_diff_is if len(net.gen[net.gen.in_service]) > 0: logger.debug('verifying gen') gen_p_diff = net.res_gen.pf_p.replace(np.nan, 0) - net.res_gen.p_mw gen_q_diff = net.res_gen.pf_q.replace(np.nan, 0) - net.res_gen.q_mvar gen_p_diff_is = net.res_gen.pf_p.replace(np.nan, 0) * net.gen.loc[ net.res_gen.index, 'in_service'] - net.res_gen.p_mw gen_q_diff_is = net.res_gen.pf_q.replace(np.nan, 0) * net.gen.loc[ net.res_gen.index, 'in_service'] - net.res_gen.q_mvar logger.info( "Maximum gen active power difference between pandapower and powerfactory: " "%.1f MW, in service only: %.1f MW" % (max(abs(gen_p_diff)), max(abs(gen_p_diff_is)))) logger.info( "Maximum gen reactive power difference between pandapower and powerfactory: " "%.1f Mvar, in service only: %.1f Mvar" % (max(abs(gen_q_diff)), max(abs(gen_q_diff_is)))) all_diffs["gen_p_diff_is"] = gen_p_diff_is all_diffs["gen_q_diff_is"] = gen_q_diff_is if len(net.ward[net.ward.in_service]) > 0: logger.debug('verifying ward') ward_p_diff = net.res_ward.pf_p.replace(np.nan, 0) - net.res_ward.p_mw ward_q_diff = net.res_ward.pf_q.replace(np.nan, 0) - net.res_ward.q_mvar ward_p_diff_is = net.res_ward.pf_p.replace(np.nan, 0) * net.ward.loc[ net.res_ward.index, 'in_service'] - net.res_ward.p_mw ward_q_diff_is = net.res_ward.pf_q.replace(np.nan, 0) * net.ward.loc[ net.res_ward.index, 'in_service'] - net.res_ward.q_mvar logger.info( "Maximum ward active power difference between pandapower and powerfactory: " "%.1f MW, in service only: %.1f MW" % (max(abs(ward_p_diff)), max(abs(ward_p_diff_is)))) logger.info( "Maximum ward reactive power difference between pandapower and powerfactory: " "%.1f Mvar, in service only: %.1f Mvar" % (max(abs(ward_q_diff)), max(abs(ward_q_diff_is)))) all_diffs["ward_p_diff_is"] = ward_p_diff_is all_diffs["ward_q_diff_is"] = ward_q_diff_is if is_unbalanced: _validate_pf_conversion_unbalanced(net, in_both, all_diffs) else: _validate_pf_conversion_balanced(net, in_both, all_diffs) return all_diffs