def test_set_branch_country_onoff_merge(do_merge_couplers, branches_generators_nodes): if branches_generators_nodes.branches is None: print('Branches None, most likely because file not found') return name, branches, generators, nodes, settings = branches_generators_nodes if do_merge_couplers: apply_couplers_on_branches_and_generators(branches, generators, nodes) else: convert_couplers_to_lines(branches) merge_tie_lines(branches, nodes) remove_branches_with_loop_elements(branches, nodes) assert all([b.country is not None for b in branches]) assert all([n.country is not None for n in nodes]) neg = ' ' if do_merge_couplers else ' not ' nxnodes = len([n for n in nodes if n.country == 'X']) ntiebranches = len([b for b in branches if b.country == 'TIE']) print( f'{nxnodes} x-nodes, {ntiebranches} tie-lines ({nxnodes/len(nodes)*100:.1f} pct of nodes, ' f'{ntiebranches/len(branches)*100:.1f} pct of branches)') print_list_occurrence(f'Nodes per country when couplers are{neg}merged', [n.country for n in nodes]) print_list_occurrence(f'Branches per country when couplers are{neg}merged', [b.country for b in branches])
def test_repeated_topology_buildup(settings): """Test to catch a strange bug when trying to cycle through a number of countries when building up did destroy the code. Disabled for full PSSE model for time reasons""" # noinspection PyUnusedLocal logger = logging.getLogger('') if settings.settings_name != SettingsEnum.PSSETest: return True for country in settings.countries: logging.debug(f'test for country {country}:') try: file_contents = open_file(settings) except FileNotFoundError: print(f'\n{settings.input_file_name} not found, skipping test for that file.') return branches, gens, nodes = read_grid(file_contents, settings) nodes = create_nodes_and_update_branches_with_node_info(branches) set_node_country(nodes, settings) validate_topology(nodes, branches) merge_tie_lines(branches, nodes) validate_topology(nodes, branches)
def create_and_preprocess_topology(branches, generators, nodes, country, settings): t0 = time.clock() if settings.do_merge_couplers: apply_couplers_on_branches_and_generators(branches, generators, nodes) else: convert_couplers_to_lines(branches) merge_tie_lines(branches, nodes) remove_branches_with_loop_elements(branches, nodes) validate_topology(nodes, branches) n_branch_with_neg_imp = len([branch for branch in branches if branch.impedance < 0]) logging.info(f"{n_branch_with_neg_imp} branches have negative impedance.") assign_nodes_to_ring_0(nodes, branches, country) assign_nodes_to_other_rings(nodes) nodes, branches = remove_non_connected_nodes_and_branches(nodes) connect_generators_to_nodes(nodes, generators) validate_topology(nodes, branches, generators) logging.info(f"Topology determined in {round(time.clock() - t0, 3)} seconds.") return branches, nodes
def test_merge_tie_lines(branches_generators_nodes): if branches_generators_nodes.branches is None: print('Branches None, most likely because file not found') return branches = branches_generators_nodes.branches nodes = branches_generators_nodes.nodes validate_topology(nodes, branches) n_x_nodes = len([node for node in nodes if node.is_x_node()]) # to account for x_nodes with more than 2 branches: n_redundant_branches = sum( [max(len(node.branches) - 2, 0) for node in nodes if node.is_x_node()]) if n_x_nodes > 0: x_node = [node for node in nodes if node.is_x_node()][0] branch_names = (x_node.branches[0].name_branch, x_node.branches[1].name_branch) branch_node_0 = [ n for n in [x_node.branches[0].node_from, x_node.branches[0].node_to] if n != x_node ] branch_node_1 = [ n for n in [x_node.branches[1].node_from, x_node.branches[1].node_to] if n != x_node ] branch_imps = (x_node.branches[0].impedance, x_node.branches[1].impedance) branch_PATLs = (x_node.branches[0].PATL, x_node.branches[1].PATL) n_nodes = len(nodes) n_branches = len(branches) merge_tie_lines(branches, nodes) assert len([node for node in nodes if node.is_x_node()]) == 0 assert len(nodes) == n_nodes - n_x_nodes # for each x-node, two branches replaced by 1, and correct for redundant branches: assert len(branches) == n_branches - n_x_nodes - n_redundant_branches if n_x_nodes > 0: print( f"Pre merge: {x_node.name} with branches {branch_names}, impedances {branch_imps}, " f"and PATLs {branch_PATLs} - between nodes {branch_node_0[0].name} and " f"{branch_node_1[0].name}.") # noinspection PyUnboundLocalVariable new_branch = [ b for b in branches if (branch_node_0[0] in (b.node_from, b.node_to)) and ( branch_node_1[0] in (b.node_from, b.node_to)) ][0] print( f"Post merge: branch {new_branch.name_branch} with impedance " f"{new_branch.impedance:.5} and PATL {new_branch.PATL:.5} between " f"{new_branch.name_from} and {new_branch.name_to}.")
def test_get_most_connected_node(branches_generators_nodes): if branches_generators_nodes.branches is None: print('Branches None, most likely because file not found') return branches = branches_generators_nodes.branches nodes = branches_generators_nodes.nodes merge_tie_lines(branches, nodes) countries = branches_generators_nodes.settings.countries for country in countries: mc_node = get_most_connected_node(nodes, country) if mc_node is None: continue print(f"In {country}, the most connected node is {mc_node.name} with " f"{len(mc_node.branches)} branches.")
def branches_generators_nodes_preprocessed_nonmerged(name_file_settings): BGN = collections.namedtuple('BranchesGeneratorsNodes', 'name branches generators nodes settings') name = f'{name_file_settings.name}_nonmergedcouplers' file_contents = name_file_settings.file settings = name_file_settings.settings if file_contents is None: return BGN(name, None, None, None, settings) branches, generators, nodes = read_grid(file_contents, settings) convert_couplers_to_lines(branches) merge_tie_lines(branches, nodes) remove_branches_with_loop_elements(branches, nodes) validate_topology(nodes, branches) return BGN(name, branches, generators, nodes, settings)
def test_remove_non_connected_nodes_and_branches(branches_generators_nodes): if branches_generators_nodes.branches is None: print('Branches None, most likely because file not found') return branches = branches_generators_nodes.branches nodes = branches_generators_nodes.nodes merge_tie_lines(branches, nodes) # To limit time use of test, only sample first 5 countries countries = branches_generators_nodes.settings.countries[:5] for country in countries: if country == 'XX': continue assign_nodes_to_ring_0(nodes, branches, country) assign_nodes_to_other_rings(nodes) n_nodes = len(nodes) n_branches = len(branches) nodes_new, branches_new = remove_non_connected_nodes_and_branches( nodes) assert len([n for n in nodes_new if not n.connected]) == 0, \ f"Non-connected nodes in node set for {country}." assert len([b for b in branches_new if not b.node_from.connected]) == 0, \ f"Branches with non-connected nodes in node set for {country}." assert len([b for b in branches_new if not b.node_to.connected]) == 0, \ f"Branches with non-connected nodes in node set for {country}." print( f"{(1 - len(nodes_new)/n_nodes)*100:.1f}% of nodes removed, ", f"{(1 - len(branches_new)/n_branches)*100:.1f}% of branches removed" ) # test for a too high (3 pct is a bit random treshold) number of elements lost assert (1 - len(nodes_new) / n_nodes) * 100 < 3 assert (1 - len(branches_new) / n_branches) * 100 < 3 reset_connectivity(branches, nodes) # only for testing