Exemple #1
0
    def test_generate_dont_fix_inputs_with_fixed_var(self):
        m = _make_simple_model()
        m.v4.fix()
        subs = [
                ([m.con1], [m.v1]),
                ([m.con2, m.con3], [m.v2, m.v3]),
                ]
        other_vars = [
                [m.v2, m.v3],
                [m.v1],
                ]
        for i, (block, inputs) in enumerate(generate_subsystem_blocks(subs)):
            self.assertIs(block.model(), block)
            var_set = ComponentSet(subs[i][1])
            con_set = ComponentSet(subs[i][0])
            input_set = ComponentSet(other_vars[i])
            
            self.assertEqual(len(var_set), len(block.vars))
            self.assertEqual(len(con_set), len(block.cons))
            self.assertEqual(len(input_set), len(inputs))
            self.assertTrue(all(var in var_set for var in block.vars[:]))
            self.assertTrue(all(con in con_set for con in block.cons[:]))
            self.assertTrue(all(var in input_set for var in inputs))
            self.assertFalse(m.v1.fixed)
            self.assertFalse(m.v2.fixed)
            self.assertFalse(m.v3.fixed)
            self.assertTrue(m.v4.fixed)

        self.assertFalse(m.v1.fixed)
        self.assertFalse(m.v2.fixed)
        self.assertFalse(m.v3.fixed)
        self.assertTrue(m.v4.fixed)
Exemple #2
0
    def test_generate_subsystems_with_fixed_var(self):
        m = _make_simple_model()
        m.v4.fix()
        subs = [
                ([m.con1], [m.v1]),
                ([m.con2, m.con3], [m.v2, m.v3]),
                ]
        other_vars = [
                [m.v2, m.v3],
                [m.v1],
                ]
        for i, (block, inputs) in enumerate(generate_subsystem_blocks(subs)):
            inputs = list(block.input_vars.values())
            with TemporarySubsystemManager(to_fix=inputs):
                self.assertIs(block.model(), block)
                var_set = ComponentSet(subs[i][1])
                con_set = ComponentSet(subs[i][0])
                input_set = ComponentSet(other_vars[i])

                self.assertEqual(len(var_set), len(block.vars))
                self.assertEqual(len(con_set), len(block.cons))
                self.assertEqual(len(input_set), len(inputs))
                self.assertTrue(all(var in var_set for var in block.vars[:]))
                self.assertTrue(all(con in con_set for con in block.cons[:]))
                self.assertTrue(all(var in input_set for var in inputs))
                self.assertTrue(all(var.fixed for var in inputs))
                self.assertFalse(any(var.fixed for var in block.vars[:]))

        # Test that we have properly unfixed variables, except variables
        # that were already fixed.
        self.assertFalse(m.v1.fixed)
        self.assertFalse(m.v2.fixed)
        self.assertFalse(m.v3.fixed)
        self.assertTrue(m.v4.fixed)
Exemple #3
0
    def test_generate_subsystems_include_fixed_var(self):
        m = _make_simple_model()
        m.v4.fix()
        subsystems = [
                ([m.con1], [m.v1]),
                ([m.con2, m.con3], [m.v2, m.v3]),
                ]
        other_vars = [
                [m.v2, m.v3, m.v4],
                [m.v1, m.v4],
                ]
        for i, (block, inputs) in enumerate(generate_subsystem_blocks(
            subsystems,
            include_fixed=True,
            )):
            with TemporarySubsystemManager(to_fix=inputs):
                self.assertIs(block.model(), block)
                var_set = ComponentSet(subsystems[i][1])
                con_set = ComponentSet(subsystems[i][0])
                input_set = ComponentSet(other_vars[i])
                
                self.assertEqual(len(var_set), len(block.vars))
                self.assertEqual(len(con_set), len(block.cons))
                self.assertEqual(len(input_set), len(block.input_vars))
                self.assertTrue(all(var in var_set for var in block.vars[:]))
                self.assertTrue(all(con in con_set for con in block.cons[:]))
                self.assertTrue(all(var in input_set for var in inputs))
                self.assertTrue(all(var.fixed for var in inputs))
                self.assertFalse(any(var.fixed for var in block.vars[:]))

        self.assertFalse(m.v1.fixed)
        self.assertFalse(m.v2.fixed)
        self.assertFalse(m.v3.fixed)
        self.assertTrue(m.v4.fixed)
Exemple #4
0
    def test_generate_subsystems_without_fixed_var(self):
        m = _make_simple_model()
        subs = [
                ([m.con1], [m.v1, m.v4]),
                ([m.con2, m.con3], [m.v2, m.v3]),
                ]
        other_vars = [
                [m.v2, m.v3],
                [m.v1, m.v4],
                ]
        for i, (block, inputs) in enumerate(generate_subsystem_blocks(subs)):
            with TemporarySubsystemManager(to_fix=inputs):
                self.assertIs(block.model(), block)
                var_set = ComponentSet(subs[i][1])
                con_set = ComponentSet(subs[i][0])
                input_set = ComponentSet(other_vars[i])
                
                self.assertEqual(len(var_set), len(block.vars))
                self.assertEqual(len(con_set), len(block.cons))
                self.assertEqual(len(input_set), len(block.input_vars))
                self.assertTrue(all(var in var_set for var in block.vars[:]))
                self.assertTrue(all(con in con_set for con in block.cons[:]))
                self.assertTrue(all(var in input_set for var in inputs))
                self.assertTrue(all(var.fixed for var in inputs))
                self.assertFalse(any(var.fixed for var in block.vars[:]))

        # Test that we have properly unfixed variables
        self.assertFalse(any(var.fixed for var in
            m.component_data_objects(pyo.Var)))
Exemple #5
0
    def test_generate_subsystems_with_exception(self):
        m = _make_simple_model()
        subs = [
                ([m.con1], [m.v1, m.v4]),
                ([m.con2, m.con3], [m.v2, m.v3]),
                ]
        other_vars = [
                [m.v2, m.v3],
                [m.v1, m.v4],
                ]
        with self.assertRaises(RuntimeError):
            for i, (block, inputs) in enumerate(generate_subsystem_blocks(subs)):
                with TemporarySubsystemManager(to_fix=inputs):
                    self.assertTrue(all(var.fixed for var in inputs))
                    self.assertFalse(any(var.fixed for var in block.vars[:]))
                    if i == 1:
                        raise RuntimeError()

        # Test that we have properly unfixed variables
        self.assertFalse(any(var.fixed for var in
            m.component_data_objects(pyo.Var)))
Exemple #6
0
def generate_strongly_connected_components(
    constraints,
    variables=None,
    include_fixed=False,
):
    """ Performs a block triangularization of the incidence matrix
    of the provided constraints and variables, and yields a block that
    contains the constraints and variables of each diagonal block
    (strongly connected component).

    Arguments
    ---------
    constraints: List of Pyomo constraint data objects
        Constraints used to generate strongly connected components.
    variables: List of Pyomo variable data objects
        Variables that may participate in strongly connected components.
        If not provided, all variables in the constraints will be used.
    include_fixed: Bool
        Indicates whether fixed variables will be included when
        identifying variables in constraints.

    Yields
    ------
    Blocks containing the variables and constraints of every strongly
    connected component, in a topological order, as well as the
    "input variables" for that block

    """
    if variables is None:
        var_set = ComponentSet()
        variables = []
        for con in constraints:
            for var in identify_variables(
                    con.expr,
                    include_fixed=include_fixed,
            ):
                if var not in var_set:
                    variables.append(var)
                    var_set.add(var)

    assert len(variables) == len(constraints)
    igraph = IncidenceGraphInterface()
    var_block_map, con_block_map = igraph.block_triangularize(
        variables=variables,
        constraints=constraints,
    )
    blocks = set(var_block_map.values())
    n_blocks = len(blocks)
    var_blocks = [[] for b in range(n_blocks)]
    con_blocks = [[] for b in range(n_blocks)]
    for var, b in var_block_map.items():
        var_blocks[b].append(var)
    for con, b in con_block_map.items():
        con_blocks[b].append(con)
    subsets = list(zip(con_blocks, var_blocks))
    for block, inputs in generate_subsystem_blocks(
            subsets,
            include_fixed=include_fixed,
    ):
        # TODO: How does len scale for reference-to-list?
        assert len(block.vars) == len(block.cons)
        yield (block, inputs)
Exemple #7
0
def generate_time_blocks(m, time):
    subsystems = get_subsystems_along_time(m, time)
    for block, inputs in generate_subsystem_blocks(subsystems):
        yield block, inputs
Exemple #8
0
def generate_time_element_blocks(
    m,
    time,
    skip_partition=False,
    flatten_vars=None,
    flatten_cons=None,
    time_subsystems=None,
):
    with TIMER.context("flatten"):
        if flatten_vars is None:
            scalar_vars, dae_vars = flatten_dae_components(m, time, Var)
        else:
            scalar_vars, dae_vars = flatten_vars
        if flatten_cons is None:
            scalar_cons, dae_cons = flatten_dae_components(m, time, Constraint)
        else:
            scalar_cons, dae_cons = flatten_cons
    with TIMER.context("get time subsystems"):
        # We repeat the above flattening in this function...
        if time_subsystems is None:
            subsystems = get_subsystems_along_time(
                m,
                time,
                flatten_vars=(scalar_vars, dae_vars),
                flatten_cons=(scalar_cons, dae_cons),
            )
        else:
            subsystems = time_subsystems
    if not skip_partition:
        # If we know our time-subsystems are all independent, as is
        # the case in a discretization that only involves adjacent
        # time points, then we can skip this expensive partition step.
        with TIMER.context("partition"):
            partition = partition_independent_subsystems(subsystems)
    else:
        partition = [[i] for i in range(len(subsystems))]
    time_partition = [[time.at(i + 1) for i in subset] for subset in partition]

    combined_subsystems = [(
        [con for i in subset for con in subsystems[i][0]],
        [var for i in subset for var in subsystems[i][1]],
    ) for subset in partition]
    TIMER.start("subsystem blocks")
    for i, (block, inputs) in enumerate(
            generate_subsystem_blocks(combined_subsystems)):
        TIMER.stop("subsystem blocks")
        t_points = time_partition[i]
        assert len(block.vars) == len(block.cons)
        if i != 0:
            # Initialize with results of previous solve
            # TODO: Should initialize happen in a separate function?
            for var in dae_vars:
                # The time required to look up the vardata objects
                # in these references is actually showing up in a
                # profile. TODO: Potentially refactor to use
                # dicts: time -> vardata here... (Note that this
                # caches valid time points, as opposed to references)
                vlatest = var[latest]
                for t in t_points:
                    var_t = var[t]
                    if not var_t.fixed:
                        var_t.set_value(vlatest.value)
        yield block, inputs
        # I don't think t_points can be empty. TODO: is this correct?
        latest = t_points[-1]

        if i != len(combined_subsystems) - 1:
            # Small hack so we can profile generate_subsystem_blocks
            # in this loop
            TIMER.start("subsystem blocks")