Exemple #1
0
    def test_context(self):
        m = self.model()

        comp = m.b.v2[1, 0]
        context = m.b
        sets = ComponentSet((m.time, ))
        _slice = slice_component_along_sets(comp, sets)
        # Context makes no difference in resulting slice here.
        self.assertEqual(_slice, m.b.v2[:, 0])

        comp = m.b.b2[1, 0].v2[1, 'a']
        context = m.b.b2[1, 0]
        sets = ComponentSet((m.time, ))
        _slice = slice_component_along_sets(comp, sets, context=context)
        # Here, context does make a difference
        self.assertEqual(_slice, m.b.b2[1, 0].v2[:, 'a'])

        comp = m.b.b2[1, 0].v1['a']
        context = m.b.b2[1, 0]
        sets = ComponentSet((m.time, ))
        _slice = slice_component_along_sets(comp, sets, context=context)
        self.assertIs(_slice, m.b.b2[1, 0].v1['a'])

        sets = ComponentSet((m.comp, ))
        _slice = slice_component_along_sets(comp, sets, context=context)
        self.assertEqual(_slice, m.b.b2[1, 0].v1[:])

        context = m.b.b2
        sets = ComponentSet((m.time, m.comp))
        _slice = slice_component_along_sets(comp, sets, context=context)
        self.assertEqual(_slice, m.b.b2[:, 0].v1[:])
Exemple #2
0
def expand_data_over_space(m, time, space, data):
    """
    data maps time/space cuids to values.
    We get a data object from the cuid, then generate slices
    over time only at every point in space.
    """
    sets = (time, )
    t0 = next(iter(time))
    new_data = {}
    for name, value in data.items():
        var = m.find_component(name)
        if var is None:
            # Steady model won't have accumulation variables
            assert "accumulation" in name
            continue
        factor_sets = list(var.index_set().subsets())
        if var.is_indexed() and len(factor_sets) == 2:
            # Assume our var is indexed by time, then space.
            for x in space:
                cuid = ComponentUID(
                    slice_component_along_sets(var[t0, x], sets))
                new_data[str(cuid)] = value
        else:
            new_data[name] = value
    return new_data
Exemple #3
0
    def test_cuid_of_slice(self):
        m = pyo.ConcreteModel()
        m.s1 = pyo.Set(initialize=["a", "b"])
        m.s2 = pyo.Set(initialize=["c", "d"])
        m.b = pyo.Block(m.s1)
        for i in m.s1:
            m.b[i].v = pyo.Var(m.s2)
        slice_ = slice_component_along_sets(m.b["a"].v["c"],
                                            ComponentSet((m.s1, )))
        cuid = pyo.ComponentUID(slice_)
        self.assertEqual(str(cuid), "b[*].v[c]")

        slice_ = slice_component_along_sets(m.b["a"].v[("c", )],
                                            ComponentSet((m.s1, )))
        cuid = pyo.ComponentUID(slice_)
        self.assertEqual(str(cuid), "b[*].v[c]")
Exemple #4
0
def get_time_indexed_cuid(var, sets=None, dereference=None):
    """
    Arguments
    ---------
    var:
        Object to process
    time: Set
        Set to use if slicing a vardata object
    dereference: None or int
        Number of times we may access referent attribute to recover a
        "base component" from a reference.

    """
    # TODO: Does this function have a good name?
    # Should this function be generalized beyond a single indexing set?
    # Is allowing dereference to be an integer worth the confusion it might
    # add?
    if dereference is None:
        # Does this branch make sense? If given an unattached component,
        # we dereference, otherwise we don't dereference.
        remaining_dereferences = int(var.parent_block() is None)
    else:
        remaining_dereferences = int(dereference)
    if var.is_indexed():
        if var.is_reference() and remaining_dereferences:
            remaining_dereferences -= 1
            referent = var.referent
            if isinstance(referent, IndexedComponent_slice):
                return ComponentUID(referent)
            else:
                # If dereference is None, we propagate None, dereferencing
                # until we either reach a component attached to a block
                # or reach a non-reference component.
                dereference = dereference if dereference is None else\
                        remaining_dereferences
                # NOTE: Calling this function recursively
                return get_time_indexed_cuid(referent,
                                             time,
                                             dereference=dereference)
        else:
            # Assume that var is indexed only by time
            # TODO: Get appropriate slice for indexing set.
            # TODO: Should we call slice_component_along_sets here as well?
            # To cover the case of b[t0].var, where var is indexed
            # by a set we care about, and we also care about time...
            # But then maybe we should slice only the sets we care about...
            # Don't want to do anything with these sets unless we're
            # presented with a vardata...
            #index = tuple(
            #    get_slice_for_set(s) for s in var.index_set().subsets()
            #)
            index = get_slice_for_set(var.index_set())
            return ComponentUID(var[:])
    else:
        if sets is None:
            raise ValueError(
                "A ComponentData %s was provided but no set. We need to know\n"
                "what set this component should be indexed by." % var.name)
        slice_ = slice_component_along_sets(var, sets)
        return ComponentUID(slice_)
Exemple #5
0
def get_max_values_from_steady(m):
    time = m.fs.time
    assert len(time) == 1
    t0 = next(iter(time))
    gas_length = m.fs.MB.gas_phase.length_domain
    solid_length = m.fs.MB.solid_phase.length_domain
    sets = (time, gas_length, solid_length)
    sets_list, comps_list = flatten_components_along_sets(m, sets, pyo.Var)
    for sets, comps in zip(sets_list, comps_list):
        if len(sets) == 2 and sets[0] is time and sets[1] is gas_length:
            gas_comps = comps
        elif len(sets) == 2 and sets[0] is time and sets[1] is solid_length:
            solid_comps = comps
    variables = gas_comps + solid_comps
    max_values = ComponentMap(
        (
            var,
            max(abs(data.value) for data in var.values()
                if data.value is not None),
        )
        for var in variables
    )

    # Maps time indexed vars to their max values over space
    max_values_time = {}
    for var in variables:
        for x in gas_length:
            sliced = slice_component_along_sets(var[t0, x], (time,))
            max_values_time[str(pyo.ComponentUID(sliced))] = max_values[var]

    return max_values_time
Exemple #6
0
    def test_with_tuple_of_sets(self):
        m = pyo.ConcreteModel()
        m.s1 = pyo.Set(initialize=[1, 2, 3])
        m.s2 = pyo.Set(initialize=[1, 2, 3])
        m.v = pyo.Var(m.s1, m.s2)
        sets = (m.s1, )
        slice_ = slice_component_along_sets(m.v[1, 2], sets)

        # These tests are essentially the same, but we run the CUID test
        # first as it gives a nicer error message.
        self.assertEqual(str(pyo.ComponentUID(slice_)), "v[*,2]")
        self.assertEqual(slice_, m.v[:, 2])
Exemple #7
0
    def test_none_dimen(self):
        m = self.model()

        comp = m.b.b2[1, 0].vn
        sets = ComponentSet((m.d_none, ))
        _slice = slice_component_along_sets(comp, sets)
        self.assertIs(_slice, m.b.b2[1, 0].vn)

        comp = m.b.b2[1, 0].vn[1, 'd', 3, 'a', 1]
        sets = ComponentSet((m.d_2, m.time))
        _slice = slice_component_along_sets(comp, sets)
        self.assertEqual(_slice, m.b.b2[:, 0].vn[:, 'd', 3, :, :])

        sets = ComponentSet((m.d_none, m.d_2))
        _slice = slice_component_along_sets(comp, sets)
        self.assertEqual(_slice, m.b.b2[1, 0].vn[1, ..., :, :])

        comp = m.b.bn['c', 1, 10, 'a', 1].v3[1, 0, 1]
        sets = ComponentSet((m.d_none, m.time))
        _slice = slice_component_along_sets(comp, sets)
        self.assertEqual(_slice, m.b.bn[..., 'a', 1].v3[:, 0, :])

        comp = m.b.bn['c', 1, 10, 'a', 1].vn[1, 'd', 3, 'b', 2]
        sets = ComponentSet((m.d_none, ))
        _slice = slice_component_along_sets(comp, sets)
        self.assertEqual(_slice, m.b.bn[..., 'a', 1].vn[1, ..., 'b', 2])

        sets = ComponentSet((m.d_none, m.d_2))
        _slice = slice_component_along_sets(comp, sets)
        self.assertEqual(_slice, m.b.bn[..., :, :].vn[1, ..., :, :])

        comp = m.b.bn['c', 1, 10, 'a', 1].vn[1, 'd', 3, 'b', 2]
        context = m.b.bn['c', 1, 10, 'a', 1]
        sets = ComponentSet((m.d_none, ))
        _slice = slice_component_along_sets(comp, sets, context=context)
        self.assertEqual(_slice, m.b.bn['c', 1, 10, 'a', 1].vn[1, ..., 'b', 2])

        sets = ComponentSet((m.d_none, m.d_2))
        _slice = slice_component_along_sets(comp, sets, context=context)
        self.assertEqual(_slice, m.b.bn['c', 1, 10, 'a', 1].vn[1, ..., :, :])

        context = m.b.bn
        sets = ComponentSet((m.d_none, ))
        _slice = slice_component_along_sets(comp, sets, context=context)
        self.assertEqual(_slice, m.b.bn[..., 'a', 1].vn[1, ..., 'b', 2])
Exemple #8
0
    def test_no_context(self):
        m = self.model()

        comp = m.b.v0
        sets = ComponentSet((m.time, m.space))
        _slice = slice_component_along_sets(comp, sets)
        # Use `assertIs` when the "slice" is actually just a component.
        self.assertIs(_slice, m.b.v0)

        comp = m.b.v1[1]
        sets = ComponentSet((m.time, m.space))
        _slice = slice_component_along_sets(comp, sets)
        self.assertEqual(_slice, m.b.v1[:])

        comp = m.b.v2[1, 0]
        sets = ComponentSet((m.time, m.space))
        _slice = slice_component_along_sets(comp, sets)
        self.assertEqual(_slice, m.b.v2[:, :])

        comp = m.b.b2[1, 0].v1['a']
        sets = ComponentSet((m.time, m.space))
        _slice = slice_component_along_sets(comp, sets)
        self.assertEqual(_slice, m.b.b2[:, :].v1['a'])

        comp = m.b.b2[1, 0].v1
        sets = ComponentSet((m.time, m.space))
        _slice = slice_component_along_sets(comp, sets)
        self.assertEqual(_slice, m.b.b2[:, :].v1)

        comp = m.b.b2[1, 0].v2[1, 'a']
        sets = ComponentSet((m.time, ))
        _slice = slice_component_along_sets(comp, sets)
        self.assertEqual(_slice, m.b.b2[:, 0].v2[:, 'a'])

        comp = m.b.bn['c', 1, 10, 'a', 1].v3[1, 0, 1]
        sets = ComponentSet((m.time, ))
        _slice = slice_component_along_sets(comp, sets)
        self.assertEqual(_slice, m.b.bn['c', 1, 10, 'a', 1].v3[:, 0, :])
Exemple #9
0
    def __init__(self,
                 plant_model=None,
                 plant_time_set=None,
                 controller_model=None,
                 controller_time_set=None,
                 inputs_at_t0=None,
                 measurements=None,
                 sample_time=None,
                 **kwargs):
        """
        Measurements must be defined in the controller model.
        Inputs must be defined in the plant model.
        """
        # To find components in a model given a name,
        # modulo the index of some set:
        # i.   slice the component along the set
        # ii.  create a cuid from that slice
        # iii. get a reference to the slice from the cuid on the new model
        # iv.  access the reference at the index you want (optional)
        self.measurement_cuids = [
            ComponentUID(
                slice_component_along_sets(comp, (controller_time_set, )))
            for comp in measurements
        ]
        self.input_cuids = [
            ComponentUID(slice_component_along_sets(comp, (plant_time_set, )))
            for comp in inputs_at_t0
        ]

        p_t0 = plant_time_set.first()
        init_plant_measurements = [
            cuid.find_component_on(plant_model)[p_t0]
            for cuid in self.measurement_cuids
        ]

        self.plant = DynamicBlock(
            model=plant_model,
            time=plant_time_set,
            inputs=inputs_at_t0,
            measurements=init_plant_measurements,
        )
        self.plant.construct()

        # Here we repeat essentially the same "find component"
        # procedure as above.
        c_t0 = controller_time_set.first()
        init_controller_inputs = [
            cuid.find_component_on(controller_model)[c_t0]
            for cuid in self.input_cuids
        ]
        self.controller = ControllerBlock(
            model=controller_model,
            time=controller_time_set,
            inputs=init_controller_inputs,
            measurements=measurements,
        )
        self.controller.construct()

        if sample_time is not None:
            self.controller.set_sample_time(sample_time)
            self.plant.set_sample_time(sample_time)
            self.sample_time = sample_time