def test_reverse_orientation_three_edges():
    pc_states = {
        'open': {
            (1, 2, 'A1'): 5,
            (2, 1, 'A2'): 0,
            (1, 3, 'B1'): 3,
            (3, 1, 'B2'): 0,
            (2, 3, 'C1'): 4,
            (3, 2, 'C2'): 5
        }
    }
    pc_edges = [(1, 2, 'A1'), (2, 1, 'A2'), (1, 3, 'B1'), (3, 1, 'B2'),
                (2, 3, 'C1'), (3, 2, 'C2')]
    pc = top.PlumbingComponent('threeway', pc_states, pc_edges)

    plumb = test.two_valve_setup(0.5, 0.2, 10, utils.CLOSED, 0.5, 0.2, 10,
                                 utils.CLOSED)

    mapping = {1: 3, 2: 4, 3: 5}
    plumb.add_component(pc, mapping, 'open')

    with pytest.raises(exceptions.InvalidComponentError) as err:
        plumb.reverse_orientation('threeway')
    assert str(err.value) == "Component must only have two edges to be automatically reversed.\n" +\
        "Consider adjusting direction manually."
def test_6():
    states = {
        'open': {
            (1, 2, 'A1'): 1,
            (2, 1, 'A2'): 1,
            (1, 3, 'B1'): utils.CLOSED,
            (3, 1, 'B2'): utils.CLOSED
        }
    }
    edges = [(1, 2, 'A1'), (2, 1, 'A2'), (1, 3, 'B1'), (3, 1, 'B2')]
    pc = top.PlumbingComponent('three', states, edges)
    mapping = {'three': {1: 1, 2: 2, 3: 3}}
    pressures = {1: (100, False), 2: (0, False), 3: (0, False)}

    steady_by = utils.s_to_micros(1)
    converged = {1: 50, 2: 50, 3: 0}

    step_plumb = top.PlumbingEngine({'three': pc}, mapping, pressures,
                                    {'three': 'open'})
    step_state = step_plumb.step(1e6)

    solve_plumb = top.PlumbingEngine({'three': pc}, mapping, pressures,
                                     {'three': 'open'})
    solve_state = solve_plumb.solve()

    len_plumb = top.PlumbingEngine({'three': pc}, mapping, pressures,
                                   {'three': 'open'})
    solve_len = len(len_plumb.solve(return_resolution=len_plumb.time_res))
    test.validate_plumbing_engine(step_plumb, solve_plumb, steady_by,
                                  converged, solve_state, step_state,
                                  solve_len, len_plumb.time_res)
Пример #3
0
def one_component_engine():
    states = {
        'open': {
            (1, 2, 'A1'): 1,
            (2, 1, 'A2'): 1
        },
        'closed': {
            (1, 2, 'A1'): top.CLOSED,
            (2, 1, 'A2'): top.CLOSED
        },
        'halfway_open': {
            (1, 2, 'A1'): 100,
            (2, 1, 'A2'): 100
        }
    }
    edges = [(1, 2, 'A1'), (2, 1, 'A2')]

    c1 = top.PlumbingComponent('c1', states, edges)

    mapping = {'c1': {1: 1, 2: 2}}

    pressures = {1: (100, False), 2: (0, False)}

    initial_states = {'c1': 'open'}

    return top.PlumbingEngine({'c1': c1}, mapping, pressures, initial_states)
    def parse_components(self):
        """Create and store components for plumbing engine."""
        for entry in self.package.components():
            name = entry['name']

            # extract edge list, plus dict of {edge name: edge tuple}
            edge_dict = extract_edges(entry)
            edge_list = []
            for edge in edge_dict.values():
                edge_list.extend(edge)

            # extract states dict {state_name: {edge: teq}} for each edge
            # in both directions
            states = {}
            for state_name, edges in entry['states'].items():
                edge_teqs = {}
                for edge_name, teqs in edges.items():
                    fwd_edge, back_edge = edge_dict[edge_name]

                    edge_teqs[fwd_edge] = teqs['fwd']
                    edge_teqs[back_edge] = teqs['back']
                states[state_name] = edge_teqs

            component = top.PlumbingComponent(name, states, edge_list)
            self.components[name] = component
def test_add_invalid_component():
    plumb = test.two_valve_setup(0.5, 0.2, 10, utils.CLOSED, 0.5, 0.2, 10,
                                 utils.CLOSED)

    wrong_node = 5
    pc_states = {
        'open': {
            (1, wrong_node, 'A1'): 0,
            (2, 1, 'A2'): 0
        },
        'closed': {
            (1, 2, 'A1'): 0,
            (2, 1, 'A2'): 0
        }
    }
    pc_edges = [(1, 2, 'A1'), (2, 1, 'A2')]
    invalid_pc = top.PlumbingComponent('valve', pc_states, pc_edges)

    assert not invalid_pc.is_valid()

    with pytest.raises(exceptions.BadInputError) as err:
        plumb.add_component(invalid_pc, {1: 3, 2: 4}, 'open')
    assert str(
        err.value
    ) == "Component not valid; all errors must be resolved before loading in."
def test_invalid_component():
    wrong_node = 5
    pc_states = {
        'open': {
            (1, wrong_node, 'A1'): 0,
            (2, 1, 'A2'): 0
        },
        'closed': {
            (1, 2, 'A1'): 0,
            (2, 1, 'A2'): 0
        }
    }
    pc_edges = [(1, 2, 'A1'), (2, 1, 'A2')]
    invalid_pc = top.PlumbingComponent('valve', pc_states, pc_edges)

    assert not invalid_pc.is_valid()

    plumb = top.PlumbingEngine()

    with pytest.raises(exceptions.BadInputError) as err:
        plumb.load_graph({'valve': invalid_pc}, {
            1: 1,
            2: 2
        }, {1: 100}, {'valve': 'open'})
    assert str(err.value) == "Node 1 not found in graph."

    assert not plumb.is_valid()
    assert len(plumb.errors()) == 2

    error = invalid.InvalidComponentName(
        "Component with name 'valve' is not valid;"
        " component cannot be loaded in until errors are resolved.", 'valve')
    assert error in plumb.errors()
Пример #7
0
def parallel_component_engine():
    states = {
        'static': {
            (1, 2, 'A1'): 1,
            (2, 1, 'A2'): 1
        },
    }
    edges = [(1, 2, 'A1'), (2, 1, 'A2')]

    c1 = top.PlumbingComponent('c1', states, edges)
    c2 = top.PlumbingComponent('c2', states, edges)

    mapping = {'c1': {1: 1, 2: 2}, 'c2': {1: 1, 2: 2}}
    pressures = {1: (0, False), 2: (0, False)}
    initial_states = {'c1': 'static', 'c2': 'static'}

    return top.PlumbingEngine({'c1': c1, 'c2': c2}, mapping, pressures, initial_states)
def create_component(s1v1, s1v2, s2v1, s2v2, name, key):
    pc_states = {
        'open': {
            (1, 2, key + '1'): s1v1,
            (2, 1, key + '2'): s1v2
        },
        'closed': {
            (1, 2, key + '1'): s2v1,
            (2, 1, key + '2'): s2v2
        }
    }
    pc_edges = [(1, 2, key + '1'), (2, 1, key + '2')]
    pc = top.PlumbingComponent(name, pc_states, pc_edges)
    return pc
Пример #9
0
def test_minimum_teq():
    normal_teq = 1
    teq_too_low = utils.micros_to_s(utils.TEQ_MIN) / 2
    states, edges = two_edge_states_edges(normal_teq, normal_teq, normal_teq,
                                          teq_too_low)
    pc = top.PlumbingComponent('valve', states, edges)

    assert not pc.is_valid()
    assert len(pc.errors()) == 1

    error = invalid.InvalidTeq(
        f'Provided teq value too low, minimum value is: {utils.micros_to_s(utils.TEQ_MIN)}s',
        'valve', 'closed', (2, 1, 'A2'), teq_too_low)
    assert error in pc.errors()
Пример #10
0
def test_invalid_keyword():
    normal_teq = 1
    wrong_keyword_teq = 'potato'
    states, edges = two_edge_states_edges(normal_teq, normal_teq, normal_teq,
                                          wrong_keyword_teq)
    pc = top.PlumbingComponent('valve', states, edges)

    assert not pc.is_valid()
    assert len(pc.errors()) == 1

    error = invalid.InvalidTeq(
        f"Invalid provided teq value ('potato'), accepted keyword is: '{utils.CLOSED}'",
        'valve', 'closed', (2, 1, 'A2'), wrong_keyword_teq)

    assert error in pc.errors()
Пример #11
0
def test_component_dicts_remain_unchanged():
    teq = 5
    pc_states, edges = two_edge_states_edges(teq, teq, teq, teq)
    _ = top.PlumbingComponent('valve', pc_states, edges)

    assert pc_states == two_edge_states_edges(teq, teq, teq, teq)[0]
    assert pc_states != {
        'open': {
            (1, 2, 'A1'): utils.teq_to_FC(teq),
            (2, 1, 'A2'): utils.teq_to_FC(teq)
        },
        'closed': {
            (1, 2, 'B1'): utils.teq_to_FC(teq),
            (2, 1, 'B2'): utils.teq_to_FC(teq)
        }
    }
def test_toggle_listing():
    plumb = test.two_valve_setup(0.5, 0.2, 10, utils.CLOSED, 0.5, 0.2, 10,
                                 utils.CLOSED)

    pc_states = {'open': {(1, 2, 'A1'): 0, (2, 1, 'A2'): 0}}
    pc_edges = [(1, 2, 'A1'), (2, 1, 'A2')]

    pc = top.PlumbingComponent('tank', pc_states, pc_edges)

    mapping = {1: 3, 2: 4}
    plumb.add_component(pc, mapping, 'open')

    toggles = plumb.list_toggles()

    assert len(toggles) == 2
    assert 'valve1' in toggles
    assert 'valve2' in toggles
    assert 'tank' not in toggles
Пример #13
0
def test_plumbing_component_setup():
    pc1_states, pc1_edges = two_edge_states_edges(0, 0, utils.CLOSED,
                                                  utils.CLOSED)
    pc1 = top.PlumbingComponent('valve1', pc1_states, pc1_edges)

    assert pc1.current_state is None
    assert list(pc1.component_graph.edges(keys=True)) == [(1, 2, 'A1'),
                                                          (2, 1, 'A2')]
    assert list(pc1.component_graph.nodes()) == [1, 2]
    assert pc1.states == {
        'open': {
            (1, 2, 'A1'): utils.FC_MAX,
            (2, 1, 'A2'): utils.FC_MAX
        },
        'closed': {
            (1, 2, 'A1'): 0,
            (2, 1, 'A2'): 0
        }
    }
    assert pc1.is_valid()
    assert not pc1.errors()
Пример #14
0
def test_duplicate_edges():
    states = {
        'open': {
            (1, 2, 'A1'): 0,
            (2, 1, 'A2'): 0
        },
        'closed': {
            (1, 2, 'A1'): 0,
            (2, 1, 'A2'): 0
        }
    }
    edge = (1, 2, 'A1')
    edges = [edge, edge, (2, 1, 'A2')]

    pc = top.PlumbingComponent('valve', states, edges)

    assert not pc.is_valid()

    error = invalid.InvalidComponentEdge(
        f"Duplicate edges '{edge}' found in edge list.", edge)
    assert error in pc.errors()
Пример #15
0
def test_edge_id_error():
    wrong_node = 5

    states = {
        'open': {
            (wrong_node, 2, 'A1'): 0,
            (2, 1, 'A2'): 0
        },
        'closed': {
            (1, 2, 'A1'): 0,
            (2, 1, 'A2'): 0
        }
    }
    edges = [(1, 2, 'A1'), (2, 1, 'A2')]

    pc = top.PlumbingComponent('valve', states, edges)

    assert not pc.is_valid()
    error = invalid.InvalidComponentEdge(
        f"Edge '({wrong_node}, 2, 'A1')' not found in provided edge list.",
        (wrong_node, 2, 'A1'))
    assert error in pc.errors()
Пример #16
0
def test_multiple_errors():
    normal_teq = 1
    teq_too_low = utils.micros_to_s(utils.TEQ_MIN) / 2
    wrong_keyword_teq = 'potato'
    states, edges = two_edge_states_edges(normal_teq, normal_teq, teq_too_low,
                                          wrong_keyword_teq)
    pc = top.PlumbingComponent('valve', states, edges)

    assert not pc.is_valid()
    assert len(pc.errors()) == 2

    error1 = invalid.InvalidTeq(
        f"Provided teq value too low, minimum value is: {utils.micros_to_s(utils.TEQ_MIN)}s",
        'valve', 'closed', (1, 2, 'A1'), teq_too_low)

    error2 = invalid.InvalidTeq(
        f"Invalid provided teq value ('{wrong_keyword_teq}'),"
        f" accepted keyword is: '{utils.CLOSED}'", 'valve', 'closed',
        (2, 1, 'A2'), wrong_keyword_teq)

    assert error1 in pc.errors()
    assert error2 in pc.errors()
def make_engine():
    states = {'static': {(1, 2, 'A1'): 1, (2, 1, 'A2'): 1}}
    edges = [(1, 2, 'A1'), (2, 1, 'A2')]

    mapping = {
        'c1': {
            1: 'atm',
            2: 1
        },
        'c2': {
            1: 1,
            2: 2
        },
        'c3': {
            1: 1,
            2: 2
        },
        'c4': {
            1: 2,
            2: 3
        },
        'c5': {
            1: 3,
            2: 'atm'
        },
        'c6': {
            1: 3,
            2: 4
        },
        'c7': {
            1: 4,
            2: 5
        },
        'c8': {
            1: 4,
            2: 5
        },
        'c9': {
            1: 5,
            2: 6
        },
        'c10': {
            1: 6,
            2: 'atm'
        },
        'c11': {
            1: 6,
            2: 'atm'
        },
        'c12': {
            1: 6,
            2: 'atm'
        }
    }

    pressures = {}
    for k1, v1 in mapping.items():
        for k2, v2 in v1.items():
            pressures[v2] = (0, False)

    component_dict = {
        k: top.PlumbingComponent(k, states, edges)
        for k in mapping.keys()
    }
    initial_states = {k: 'static' for k in mapping.keys()}

    return top.PlumbingEngine(component_dict, mapping, pressures,
                              initial_states)