예제 #1
0
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)
예제 #2
0
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_remove_branches_with_loop_elements(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
    nbranches_org = len(branches)
    remove_branches_with_loop_elements(branches, nodes)
    for branch in branches:
        assert branch.name_from != branch.name_to
    validate_topology(nodes, branches)
    print(
        f'Removed {nbranches_org - len(branches)} branches, {len(branches)} branches left.'
    )
def test_assign_nodes_to_ring_0(
        branches_generators_nodes_preprocessed_merged,
        branches_generators_nodes_preprocessed_nonmerged):

    for switch in range(2):
        if switch == 0:
            branches_generators_nodes = branches_generators_nodes_preprocessed_merged
        else:
            branches_generators_nodes = branches_generators_nodes_preprocessed_nonmerged

        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
        countries = branches_generators_nodes.settings.countries

        validate_topology(nodes, branches)

        for country in countries:
            if country == 'XX':
                continue
            n_nodes_in_country = len(
                [n for n in nodes if n.country == country])
            n_branches_in_country = len(
                [b for b in branches if b.country == country])
            print(
                f'Connecting for country {country} with {n_nodes_in_country} nodes and '
                f'{n_branches_in_country} branches:')

            assign_nodes_to_ring_0(nodes, branches, country)

            n_nodes_in_ring_0 = len([node for node in nodes if node.ring == 0])
            print(f"Ring 0 initialised with {n_nodes_in_ring_0} nodes.")
            cntry_nodes_non_conn = [
                n for n in nodes if n.country == country and n.ring != 0
            ]
            for n in cntry_nodes_non_conn:
                print(f"Warning : {n.name} is not connected to {country}")
            conn_nodes_non_cntry = [
                n for n in nodes if n.ring == 0 and n.country != country
            ]
            for n in conn_nodes_non_cntry:
                print(
                    f"Warning : {n.name} is connected to {country} but belongs to {n.country}"
                )
            assert len(conn_nodes_non_cntry) == 0

            reset_connectivity(branches, nodes)  # only for testing
예제 #6
0
def branches_generators_nodes(name_file_settings):
    BGN = collections.namedtuple('BranchesGeneratorsNodes',
                                 'name branches generators nodes settings')

    name = name_file_settings.name
    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)
    validate_topology(nodes, branches)

    return BGN(name, branches, generators, nodes, settings)
예제 #7
0
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_apply_couplers_on_branches(branches_generators_nodes):
    if branches_generators_nodes.branches is None:
        print('Branches None, most likely because file not found')
        return

    branches_generators_nodes.settings.do_merge_couplers = True
    branches = branches_generators_nodes.branches
    generators = branches_generators_nodes.generators
    nodes = branches_generators_nodes.nodes

    validate_topology(nodes, branches)

    couplers = [b for b in branches if b.type == BranchTypeEnum.Coupler]
    n_nodes = len(nodes)
    n_couplers = len(couplers)
    n_branches = len(branches)

    dict_couplers = create_coupler_mapping(couplers)
    apply_couplers_on_branches_and_generators(branches, generators, nodes)

    validate_topology(nodes, branches)

    n_nodes_after = len(nodes)
    n_branches_after = len(branches)
    set_replaced_branches = set(dict_couplers.keys()) - set(
        dict_couplers.values())
    for branch in branches:
        assert branch.name_from not in set_replaced_branches
        assert branch.name_to not in set_replaced_branches
    print(
        f'{n_couplers} couplers applied on a total of {n_nodes} nodes and {n_branches} branches'
    )
    print(
        f'After application, left with {n_nodes_after} nodes and {n_branches_after} branches'
    )
    print_examples(branches_generators_nodes.name, couplers, 'Bus bar coupler')
    print_stats([tr.impedance for tr in couplers], "Impedance")
    print_stats([tr.PATL for tr in couplers], "PATL")