def two_valve_setup_fixed(vAs1_1, vAs1_2, vAs2_1, vAs2_2, vBs1_1, vBs1_2,
                          vBs2_1, vBs2_2):
    pc1 = create_component(vAs1_1, vAs1_2, vAs2_1, vAs2_2, 'valve1', 'A')
    pc2 = create_component(vBs1_1, vBs1_2, vBs2_1, vBs2_2, 'valve2', 'B')

    component_mapping = {'valve1': {1: 1, 2: 2}, 'valve2': {1: 2, 2: 3}}

    pressures = {3: (100, True)}
    default_states = {'valve1': 'closed', 'valve2': 'open'}
    plumb = top.PlumbingEngine({
        'valve1': pc1,
        'valve2': pc2
    }, component_mapping, pressures, default_states)

    return plumb
def test_missing_node_pressure():
    wrong_node_name = 4
    pc1 = test.create_component(0, 0, 0, 0, 'valve1', 'A')
    pc2 = test.create_component(0, 0, 0, 0, 'valve2', 'B')

    component_mapping = {'valve1': {1: 1, 2: 2}, 'valve2': {1: 2, 2: 3}}

    pressures = {wrong_node_name: (100, False), 2: (100, False)}
    default_states = {'valve1': 'closed', 'valve2': 'open'}
    with pytest.raises(exceptions.BadInputError) as err:
        _ = top.PlumbingEngine({
            'valve1': pc1,
            'valve2': pc2
        }, component_mapping, pressures, default_states)
    assert str(err.value) == f"Node {wrong_node_name} not found in graph."
def test_5():
    pc = test.create_component(1, utils.CLOSED, utils.CLOSED, utils.CLOSED,
                               'check', 'A')
    mapping = {'check': {1: 1, 2: 2}}
    pressures = {1: (100, False)}
    default_states = {'check': 'open'}

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

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

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

    len_plumb = top.PlumbingEngine({'check': pc}, mapping, pressures,
                                   default_states)
    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)
예제 #4
0
def one_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)

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

    return top.PlumbingEngine({'c1': c1}, mapping, pressures, initial_states)
def test_list_functions():
    pc1 = test.create_component(0.5, 0.2, 10, utils.CLOSED, 'valve1', 'A')
    pc2 = test.create_component(0.5, 0.2, 10, utils.CLOSED, 'valve2', 'B')

    component_mapping = {
        'valve1': {
            1: 1,
            2: 2
        },
        'valve2': {
            1: 2,
            2: 3
        }
    }

    negative_pressure = -50
    pressures = {3: (negative_pressure, False)}
    default_states = {'valve1': 'closed', 'valve2': 'open'}
    plumb = top.PlumbingEngine(
        {'valve1': pc1, 'valve2': pc2}, component_mapping, pressures, default_states)

    assert plumb.edges() == [
        (1, 2, 'valve1.A1', {'FC': utils.teq_to_FC(utils.s_to_micros(10))}),
        (2, 1, 'valve1.A2', {'FC': 0}),
        (2, 3, 'valve2.B1', {'FC': utils.teq_to_FC(utils.s_to_micros(0.5))}),
        (3, 2, 'valve2.B2', {'FC': utils.teq_to_FC(utils.s_to_micros(0.2))})
    ]

    assert plumb.edges(data=False) == [
        (1, 2, 'valve1.A1'),
        (2, 1, 'valve1.A2'),
        (2, 3, 'valve2.B1'),
        (3, 2, 'valve2.B2')
    ]

    # Pressure at node 3 will be 0, since the provided one was invalid
    assert plumb.nodes() == [
        (1, {'body': top.GenericNode(0)}),
        (2, {'body': top.GenericNode(0)}),
        (3, {'body': top.GenericNode(0)}),
    ]

    assert plumb.nodes(data=False) == [1, 2, 3]

    assert plumb.errors() == {
        invalid.InvalidNodePressure(f"Negative pressure {negative_pressure} not allowed.", 3)
    }
def test_wrong_node_mapping():
    proper_node_name = 1
    wrong_node_name = 5
    pc1 = test.create_component(0, 0, 0, 0, 'valve1', 'A')
    pc2 = test.create_component(0, 0, 0, 0, 'valve2', 'B')

    component_mapping = {
        'valve1': {
            wrong_node_name: 1,
            2: 8
        },
        'valve2': {
            1: 8,
            2: 3
        }
    }

    pressures = {3: (100, False)}
    default_states = {'valve1': 'closed', 'valve2': 'open'}
    plumb = top.PlumbingEngine({
        'valve1': pc1,
        'valve2': pc2
    }, component_mapping, pressures, default_states)

    assert not plumb.is_valid()

    # Since the node name is wrong in the mapping, an error should be added
    # every time the mapping dict is accessed to find the matching graph node.
    # This translates to twice (once per component) when populating the main graph,
    # and twice (once per component) when assigning initial states by component,
    # since the component node stored in the component's states dict needs to be
    # translated into a main graph node. So 4 errors total, but they're identical
    # so we should get one original error and one multi-error note.
    assert len(plumb.errors()) == 2

    error = invalid.InvalidComponentNode(
        f"Component 'valve1', node {proper_node_name} not found in mapping dict.",
        'valve1', proper_node_name)

    duplicate_error = invalid.DuplicateError(
        invalid.multi_error_msg(
            f"Component 'valve1', node {proper_node_name} not found in mapping dict."
        ), error)

    assert error in plumb.errors()
    assert duplicate_error in plumb.errors()
def test_invalid_engine():
    wrong_component_name = 'potato'
    pc1 = test.create_component(0, 0, 0, 0, 'valve1', 'A')
    pc2 = test.create_component(0, 0, 0, 0, 'valve2', 'B')

    component_mapping = {'valve1': {1: 1, 2: 2}, 'valve2': {1: 2, 2: 3}}

    pressures = {3: (100, False)}
    default_states = {'valve1': 'closed', 'valve2': 'open'}
    plumb = top.PlumbingEngine({
        wrong_component_name: pc1,
        'valve2': pc2
    }, component_mapping, pressures, default_states)

    assert not plumb.is_valid()
    with pytest.raises(exceptions.InvalidEngineError) as err:
        plumb.step(5)
    assert str(
        err.value
    ) == "Step() cannot be called on an invalid engine. Check for errors."
def test_add_to_empty():
    plumb = top.PlumbingEngine()
    pc = test.create_component(2, utils.CLOSED, 0, 0, 'valve', 'A')

    mapping = {1: 1, 2: 2}

    plumb.add_component(pc, mapping, 'open', {1: (20, False)})

    assert plumb.is_valid()
    assert plumb.time_res == utils.DEFAULT_TIME_RESOLUTION_MICROS
    assert plumb.edges() == [(1, 2, 'valve.A1', {
        'FC': utils.teq_to_FC(utils.s_to_micros(2))
    }), (2, 1, 'valve.A2', {
        'FC': 0
    })]
    assert plumb.nodes() == [(1, {
        'body': top.GenericNode(20)
    }), (2, {
        'body': top.GenericNode(0)
    })]
    assert plumb.current_state('valve') == 'open'
def test_missing_initial_state():
    wrong_component_name = 'potato'
    proper_component_name = 'valve1'
    pc1 = test.create_component(0, 0, 0, 0, 'valve1', 'A')
    pc2 = test.create_component(0, 0, 0, 0, 'valve2', 'B')

    component_mapping = {'valve1': {1: 1, 2: 2}, 'valve2': {1: 2, 2: 3}}

    pressures = {3: (100, False)}
    default_states = {wrong_component_name: 'closed', 'valve2': 'open'}
    plumb = top.PlumbingEngine({
        'valve1': pc1,
        'valve2': pc2
    }, component_mapping, pressures, default_states)

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

    error = invalid.InvalidComponentName(
        f"Component '{proper_component_name}' state not found in initial states dict.",
        proper_component_name)

    assert error in plumb.errors()
def test_load_errorless_graph():
    wrong_component_name = 'potato'
    pc1 = test.create_component(0, 0, 0, 0, 'valve1', 'A')
    pc2 = test.create_component(0, 0, 0, 0, 'valve2', 'B')

    component_mapping = {'valve1': {1: 1, 2: 2}, 'valve2': {1: 2, 2: 3}}

    pressures = {3: (100, False)}
    default_states = {'valve1': 'closed', 'valve2': 'open'}
    plumb = top.PlumbingEngine({
        wrong_component_name: pc1,
        'valve2': pc2
    }, component_mapping, pressures, default_states)

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

    error1 = invalid.InvalidComponentName(
        f"Component with name '{wrong_component_name}' not found in mapping dict.",
        wrong_component_name)

    error2 = invalid.InvalidComponentName(
        f"Component '{wrong_component_name}' state not found in initial states dict.",
        wrong_component_name)

    assert error1 in plumb.errors()
    assert error2 in plumb.errors()

    plumb0 = test.two_valve_setup(0.5, 0.2, 10, utils.CLOSED, 0.5, 0.2, 10,
                                  utils.CLOSED)
    pressures = {3: (100, False)}
    default_states = {'valve1': 'closed', 'valve2': 'open'}

    plumb.load_graph(plumb0.component_dict, plumb0.mapping, pressures,
                     default_states)

    assert plumb.is_valid()
def test_engine_dicts_remain_unchanged():
    pc1 = test.create_component(0, 0, 0, 0, 'valve1', 'A')
    pc2 = test.create_component(0, 0, 0, 0, 'valve2', 'B')

    component_mapping = {'valve1': {1: 1, 2: 2}, 'valve2': {1: 2, 2: 3}}
    pressures = {3: (100, False)}
    default_states = {'valve1': 'closed', 'valve2': 'open'}
    component_dict = {'valve1': pc1, 'valve2': pc2}
    _ = top.PlumbingEngine(component_dict, component_mapping, pressures,
                           default_states)

    assert component_mapping == {
        'valve1': {
            1: 1,
            2: 2
        },
        'valve2': {
            1: 2,
            2: 3
        }
    }
    assert pressures == {3: (100, False)}
    assert default_states == {'valve1': 'closed', 'valve2': 'open'}
    assert component_dict == {'valve1': pc1, 'valve2': pc2}
def test_empty_graph():
    plumb = top.PlumbingEngine()

    assert plumb.time_res == utils.DEFAULT_TIME_RESOLUTION_MICROS
    assert not plumb.edges()
    assert not plumb.nodes()
예제 #13
0
 def make_engine(self):
     """Create the plumbing engine from the provided input."""
     plumb = top.PlumbingEngine(self.components, self.mapping,
                                self.initial_pressures, self.initial_states)
     return plumb
def test_empty_engine():
    plumb = top.PlumbingEngine()
    with pytest.raises(exceptions.InvalidEngineError) as err:
        plumb.step(5)

    assert str(err.value) == "Step() cannot be called on an empty engine."
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)