Exemplo n.º 1
0
    def test_perfect_matching(self):
        model = make_gas_expansion_model()

        # These are the variables and constraints of the square,
        # nonsingular subsystem
        variables = []
        variables.extend(model.P.values())
        variables.extend(model.T[i] for i in model.streams
                         if i != model.streams.first())
        variables.extend(model.rho[i] for i in model.streams
                         if i != model.streams.first())
        variables.extend(model.F[i] for i in model.streams
                         if i != model.streams.first())

        constraints = list(model.component_data_objects(pyo.Constraint))

        imat = get_structural_incidence_matrix(variables, constraints)
        con_idx_map = ComponentMap((c, i) for i, c in enumerate(constraints))

        n_var = len(variables)
        matching = maximum_matching(imat)
        matching = ComponentMap(
            (c, variables[matching[con_idx_map[c]]]) for c in constraints)
        values = ComponentSet(matching.values())
        self.assertEqual(len(matching), n_var)
        self.assertEqual(len(values), n_var)

        # The subset of variables and equations we have identified
        # do not have a unique perfect matching. But we at least know
        # this much.
        self.assertIs(matching[model.ideal_gas[0]], model.P[0])
Exemplo n.º 2
0
    def test_rectangular_system(self):
        N_model = 2
        m = make_gas_expansion_model(N_model)
        variables = list(m.component_data_objects(pyo.Var))
        constraints = list(m.component_data_objects(pyo.Constraint))

        imat = get_structural_incidence_matrix(variables, constraints)
        M, N = imat.shape
        self.assertEqual(M, 4 * N_model + 1)
        self.assertEqual(N, 4 * (N_model + 1))

        row_partition, col_partition = dulmage_mendelsohn(imat)

        # No unmatched constraints
        self.assertEqual(row_partition[0], [])
        self.assertEqual(row_partition[1], [])

        # All constraints are matched with potentially unmatched variables
        matched_con_set = set(range(len(constraints)))
        self.assertEqual(set(row_partition[2]), matched_con_set)

        # 3 unmatched variables
        self.assertEqual(len(col_partition[0]), 3)
        # All variables are potentially unmatched
        potentially_unmatched = col_partition[0] + col_partition[1]
        potentially_unmatched_set = set(range(len(variables)))
        self.assertEqual(set(potentially_unmatched), potentially_unmatched_set)
Exemplo n.º 3
0
    def test_square_well_posed_model(self):
        N = 4
        m = make_gas_expansion_model(N)
        m.F[0].fix()
        m.rho[0].fix()
        m.T[0].fix()

        variables = [
            v for v in m.component_data_objects(pyo.Var) if not v.fixed
        ]
        constraints = list(m.component_data_objects(pyo.Constraint))
        imat = get_structural_incidence_matrix(variables, constraints)

        N, M = imat.shape
        self.assertEqual(N, M)

        row_partition, col_partition = dulmage_mendelsohn(imat)

        # Unmatched, reachable-from-unmatched, and matched-with-reachable
        # subsets are all empty.
        self.assertEqual(len(row_partition[0]), 0)
        self.assertEqual(len(row_partition[1]), 0)
        self.assertEqual(len(row_partition[2]), 0)
        self.assertEqual(len(col_partition[0]), 0)
        self.assertEqual(len(col_partition[1]), 0)
        self.assertEqual(len(col_partition[2]), 0)

        # All nodes belong to the "well-determined" subset
        self.assertEqual(len(row_partition[3]), M)
        self.assertEqual(len(col_partition[3]), N)
Exemplo n.º 4
0
    def test_incidence_matrix(self):
        N = 5
        model = make_gas_expansion_model(N)
        all_vars = list(model.component_data_objects(pyo.Var))
        all_cons = list(model.component_data_objects(pyo.Constraint))
        imat = get_structural_incidence_matrix(all_vars, all_cons)
        n_var = 4 * (N + 1)
        n_con = 4 * N + 1
        self.assertEqual(imat.shape, (n_con, n_var))

        var_idx_map = ComponentMap((v, i) for i, v in enumerate(all_vars))
        con_idx_map = ComponentMap((c, i) for i, c in enumerate(all_cons))

        # Map constraints to the variables they contain.
        csr_map = ComponentMap()
        csr_map.update((model.mbal[i],
                        ComponentSet([
                            model.F[i],
                            model.F[i - 1],
                            model.rho[i],
                            model.rho[i - 1],
                        ])) for i in model.streams
                       if i != model.streams.first())
        csr_map.update((model.ebal[i],
                        ComponentSet([
                            model.F[i],
                            model.F[i - 1],
                            model.rho[i],
                            model.rho[i - 1],
                            model.T[i],
                            model.T[i - 1],
                        ])) for i in model.streams
                       if i != model.streams.first())
        csr_map.update((model.expansion[i],
                        ComponentSet([
                            model.rho[i],
                            model.rho[i - 1],
                            model.P[i],
                            model.P[i - 1],
                        ])) for i in model.streams
                       if i != model.streams.first())
        csr_map.update((model.ideal_gas[i],
                        ComponentSet([
                            model.P[i],
                            model.rho[i],
                            model.T[i],
                        ])) for i in model.streams)

        # Want to test that the columns have the rows we expect.
        i = model.streams.first()
        for i, j, e in zip(imat.row, imat.col, imat.data):
            con = all_cons[i]
            var = all_vars[j]
            self.assertIn(var, csr_map[con])
            csr_map[con].remove(var)
            self.assertEqual(e, 1.0)
        # And no additional rows
        for con in csr_map:
            self.assertEqual(len(csr_map[con]), 0)
Exemplo n.º 5
0
    def test_incidence_graph(self):
        m = make_degenerate_solid_phase_model()
        variables = list(m.component_data_objects(pyo.Var))
        constraints = list(m.component_data_objects(pyo.Constraint))
        graph = get_incidence_graph(variables, constraints)
        matrix = get_structural_incidence_matrix(variables, constraints)
        from_matrix = from_biadjacency_matrix(matrix)

        self.assertEqual(graph.nodes, from_matrix.nodes)
        self.assertEqual(graph.edges, from_matrix.edges)
Exemplo n.º 6
0
    def test_imperfect_matching(self):
        model = make_gas_expansion_model()
        all_vars = list(model.component_data_objects(pyo.Var))
        all_cons = list(model.component_data_objects(pyo.Constraint))
        imat = get_structural_incidence_matrix(all_vars, all_cons)

        n_eqn = len(all_cons)
        matching = maximum_matching(imat)
        values = set(matching.values())
        self.assertEqual(len(matching), n_eqn)
        self.assertEqual(len(values), n_eqn)
Exemplo n.º 7
0
    def test_triangularize(self):
        N = 5
        model = make_gas_expansion_model(N)

        # These are the variables and constraints of the square,
        # nonsingular subsystem
        variables = []
        variables.extend(model.P.values())
        variables.extend(model.T[i] for i in model.streams
                         if i != model.streams.first())
        variables.extend(model.rho[i] for i in model.streams
                         if i != model.streams.first())
        variables.extend(model.F[i] for i in model.streams
                         if i != model.streams.first())

        constraints = list(model.component_data_objects(pyo.Constraint))

        imat = get_structural_incidence_matrix(variables, constraints)
        con_idx_map = ComponentMap((c, i) for i, c in enumerate(constraints))
        var_idx_map = ComponentMap((v, i) for i, v in enumerate(variables))

        row_block_map, col_block_map = block_triangularize(imat)
        var_block_map = ComponentMap(
            (v, col_block_map[var_idx_map[v]]) for v in variables)
        con_block_map = ComponentMap(
            (c, row_block_map[con_idx_map[c]]) for c in constraints)

        var_values = set(var_block_map.values())
        con_values = set(con_block_map.values())
        self.assertEqual(len(var_values), N + 1)
        self.assertEqual(len(con_values), N + 1)

        self.assertEqual(var_block_map[model.P[0]], 0)

        for i in model.streams:
            if i != model.streams.first():
                self.assertEqual(var_block_map[model.rho[i]], i)
                self.assertEqual(var_block_map[model.T[i]], i)
                self.assertEqual(var_block_map[model.P[i]], i)
                self.assertEqual(var_block_map[model.F[i]], i)

                self.assertEqual(con_block_map[model.ideal_gas[i]], i)
                self.assertEqual(con_block_map[model.expansion[i]], i)
                self.assertEqual(con_block_map[model.mbal[i]], i)
                self.assertEqual(con_block_map[model.ebal[i]], i)
Exemplo n.º 8
0
    def test_rectangular_model(self):
        m = make_dynamic_model()

        m.height[0].fix()

        variables = [
            v for v in m.component_data_objects(pyo.Var) if not v.fixed
        ]
        constraints = list(m.component_data_objects(pyo.Constraint))

        imat = get_structural_incidence_matrix(variables, constraints)
        M, N = imat.shape
        var_idx_map = ComponentMap((v, i) for i, v in enumerate(variables))
        con_idx_map = ComponentMap((c, i) for i, c in enumerate(constraints))

        row_partition, col_partition = dulmage_mendelsohn(imat)

        # No unmatched rows
        self.assertEqual(row_partition[0], [])
        self.assertEqual(row_partition[1], [])

        # Assert that the square subsystem contains the components we expect
        self.assertEqual(len(row_partition[3]), 1)
        self.assertEqual(row_partition[3][0], con_idx_map[m.flow_out_eqn[0]])

        self.assertEqual(len(col_partition[3]), 1)
        self.assertEqual(col_partition[3][0], var_idx_map[m.flow_out[0]])

        # Assert that underdetermined subsystem contains the components
        # we expect

        # Rows matched with potentially unmatched columns
        self.assertEqual(len(row_partition[2]), M - 1)
        row_indices = set(
            [i for i in range(M) if i != con_idx_map[m.flow_out_eqn[0]]])
        self.assertEqual(set(row_partition[2]), row_indices)

        # Potentially unmatched columns
        self.assertEqual(len(col_partition[0]), N - M)
        self.assertEqual(len(col_partition[1]), M - 1)
        potentially_unmatched = col_partition[0] + col_partition[1]
        col_indices = set(
            [i for i in range(N) if i != var_idx_map[m.flow_out[0]]])
        self.assertEqual(set(potentially_unmatched), col_indices)
Exemplo n.º 9
0
    def test_square_ill_posed_model(self):
        N = 1
        m = make_gas_expansion_model(N)
        m.P[0].fix()
        m.rho[0].fix()
        m.T[0].fix()

        variables = [
            v for v in m.component_data_objects(pyo.Var) if not v.fixed
        ]
        constraints = list(m.component_data_objects(pyo.Constraint))
        imat = get_structural_incidence_matrix(variables, constraints)

        var_idx_map = ComponentMap((v, i) for i, v in enumerate(variables))
        con_idx_map = ComponentMap((c, i) for i, c in enumerate(constraints))

        N, M = imat.shape
        self.assertEqual(N, M)

        row_partition, col_partition = dulmage_mendelsohn(imat)

        # Only unmatched constraint is ideal_gas[0]
        unmatched_rows = [con_idx_map[m.ideal_gas[0]]]
        self.assertEqual(row_partition[0], unmatched_rows)
        # No other constraints can possibly be unmatched.
        self.assertEqual(row_partition[1], [])
        # The potentially unmatched variables have four constraints
        # between them
        matched_con_set = set(con_idx_map[con] for con in constraints
                              if con is not m.ideal_gas[0])
        self.assertEqual(set(row_partition[2]), matched_con_set)

        # All variables are potentially unmatched
        potentially_unmatched_set = set(range(len(variables)))
        potentially_unmatched = col_partition[0] + col_partition[1]
        self.assertEqual(set(potentially_unmatched), potentially_unmatched_set)