コード例 #1
0
ファイル: dyn_utils.py プロジェクト: xiangyuy/idaes-pse
def deactivate_model_at(b, cset, pts, outlvl=idaeslog.NOTSET):
    """
    Finds any block or constraint in block b, indexed explicitly (and not 
    implicitly) by cset, and deactivates it at points specified. 
    Implicitly indexed components are excluded because one of their parent 
    blocks will be deactivated, so deactivating them too would be redundant.

    Args:
        b : Block to search
        cset : ContinuousSet of interest
        pts : Value or list of values, in ContinuousSet, to deactivate at

    Returns:
        A dictionary mapping points in pts to lists of
        component data that have been deactivated there
    """
    if not type(pts) is list:
        pts = [pts]
    for pt in pts:
        if not pt in cset:
            msg = str(pt) + ' is not in ContinuousSet ' + cset.name
            raise ValueError(msg)
    deactivated = {pt: [] for pt in pts}

    visited = set()
    for comp in b.component_objects([Block, Constraint], active=True):
        # Record components that have been visited in case component_objects
        # contains duplicates (due to references)
        if id(comp) in visited:
            continue
        visited.add(id(comp))

        if (is_explicitly_indexed_by(comp, cset)
                and not is_in_block_indexed_by(comp, cset)):
            info = get_index_set_except(comp, cset)
            non_cset_set = info['set_except']
            index_getter = info['index_getter']

            for non_cset_index in non_cset_set:
                for pt in pts:
                    index = index_getter(non_cset_index, pt)
                    try:
                        comp[index].deactivate()
                        deactivated[pt].append(comp[index])
                    except KeyError:
                        # except KeyError to allow Constraint/Block.Skip
                        msg = (comp.name + ' has no index ' + str(index))
                        init_log = idaeslog.getInitLogger(__name__, outlvl)
                        init_log.warning(msg)
                        continue

    return deactivated
コード例 #2
0
ファイル: dyn_utils.py プロジェクト: xiangyuy/idaes-pse
def get_derivatives_at(b, time, pts):
    """
    Finds derivatives with respect to time at points specified.
    No distinction made for multiple derivatives or mixed partials.

    Args:
        b : Block to search for derivatives
        time : ContinuousSet to look for derivatives with respect to
        pts : Value or list of values in time set at which to return 
              derivatives

    Returns
        Dictionary mapping time points to lists of derivatives
        at those points
    """
    if not type(pts) is list:
        pts = [pts]
    dvdict = {pt: [] for pt in pts}

    visited = set()
    for var in b.component_objects(Var):
        if id(var) in visited:
            continue
        visited.add(id(var))

        if not isinstance(var, DerivativeVar):
            continue
        if time not in ComponentSet(var.get_continuousset_list()):
            continue

        info = get_index_set_except(var, time)
        non_time_set = info['set_except']
        index_getter = info['index_getter']
        for pt in pts:
            for non_time_index in non_time_set:
                index = index_getter(non_time_index, pt)
                dvdict[pt].append(var[index])

    return dvdict
コード例 #3
0
ファイル: initialization.py プロジェクト: yuanzy97/pyomo
def get_inconsistent_initial_conditions(model,
                                        time,
                                        tol=1e-8,
                                        t0=None,
                                        allow_skip=True,
                                        suppress_warnings=False):
    """Finds constraints of the model that are implicitly or explicitly
    indexed by time and checks if they are consistent to within a tolerance
    at the initial value of time.

    Args:
        model: Model whose constraints to check
        time: Set whose initial condition will be checked
        tol: Maximum constraint violation
        t0: Point in time at which to check constraints

    Returns:
        List of constraint data objects that were found to be inconsistent.
    """
    if t0 is None:
        t0 = time.first()

    inconsistent = ComponentSet()
    for con in model.component_objects(Constraint, active=True):
        if not is_explicitly_indexed_by(con, time):
            continue
        if is_in_block_indexed_by(con, time):
            continue
        info = get_index_set_except(con, time)
        non_time_set = info['set_except']
        index_getter = info['index_getter']
        for non_time_index in non_time_set:
            index = index_getter(non_time_index, t0)
            try:
                condata = con[index]
            except KeyError:
                # To allow Constraint.Skip
                if not suppress_warnings:
                    print(index_warning(con.name, index))
                if not allow_skip:
                    raise
                continue
            if (value(condata.body) - value(condata.upper) > tol
                    or value(condata.lower) - value(condata.body) > tol):
                inconsistent.add(condata)

    for blk in model.component_objects(Block, active=True):
        # What if there are time-indexed blocks at multiple levels
        # of a hierarchy?
        # My preferred convention is to only check the first (highest-
        # level) time index, but distinguishing between different-level
        # time indices is an expensive operation.
        if not is_explicitly_indexed_by(blk, time):
            continue
        if is_in_block_indexed_by(blk, time):
            continue
        info = get_index_set_except(blk, time)
        non_time_set = info['set_except']
        index_getter = info['index_getter']
        for non_time_index in non_time_set:
            index = index_getter(non_time_index, t0)
            blkdata = blk[index]
            for condata in blkdata.component_data_objects(Constraint,
                                                          active=True):
                if (value(condata.body) - value(condata.upper) > tol
                        or value(condata.lower) - value(condata.body) > tol):
                    if condata in inconsistent:
                        raise ValueError(
                            '%s has already been visited. The only way this '
                            'should happen is if the model has nested time-'
                            'indexed blocks, which is not supported.')
                    inconsistent.add(condata)

    return list(inconsistent)
コード例 #4
0
ファイル: dyn_utils.py プロジェクト: xiangyuy/idaes-pse
def copy_values_at_time(fs_tgt,
                        fs_src,
                        t_target,
                        t_source,
                        copy_fixed=True,
                        outlvl=idaeslog.NOTSET):
    """
    Function to set the values of all (explicitly or implicitly) time-indexed 
    variables in a flowsheet to similar values (with the same name) but at 
    different points in time and (potentially) in different flowsheets.

    Args:
        fs_tgt : Target flowsheet, whose variables' values will get set
        fs_src : Source flowsheet, whose variables' values will be used to 
                 set those of the target flowsheet. Could be the target
                 flowsheet
        t_target : Target time point
        t_source : Source time point
        copy_fixed : Bool of whether or not to copy over fixed variables in 
                     target model 
        outlvl : IDAES logger output level

    Returns:
        None
    """
    time_target = fs_tgt.time
    var_visited = set()
    for var_target in fs_tgt.component_objects(Var):
        if id(var_target) in var_visited:
            continue
        var_visited.add(id(var_target))

        if not is_explicitly_indexed_by(var_target, time_target):
            continue
        n = var_target.index_set().dimen

        local_parent = fs_src

        varname = var_target.getname(fully_qualified=True, relative_to=fs_tgt)
        # Calling find_component here makes the assumption that varname does not
        # contain decimal indices.
        var_source = fs_src.find_component(varname)
        if var_source is None:
            # Log a warning
            msg = ('Warning copying values: ' + varname +
                   ' does not exist in source block ' + fs_src.name)
            init_log = idaeslog.getInitLogger(__name__, outlvl)
            init_log.warning(msg)
            continue

        if n == 1:
            if not copy_fixed and var_target[t_target].fixed:
                continue
            var_target[t_target].set_value(var_source[t_source].value)
        elif n >= 2:
            index_info = get_index_set_except(var_target, time_target)
            non_time_index_set = index_info['set_except']
            index_getter = index_info['index_getter']
            for non_time_index in non_time_index_set:
                source_index = index_getter(non_time_index, t_source)
                target_index = index_getter(non_time_index, t_target)
                if not copy_fixed and var_target[target_index].fixed:
                    continue
                var_target[target_index].set_value(
                    var_source[source_index].value)

    blk_visited = set()
    for blk_target in fs_tgt.component_objects(Block):
        if id(blk_target) in blk_visited:
            continue
        blk_visited.add(id(blk_target))

        if not is_explicitly_indexed_by(blk_target, time_target):
            continue
        n = blk_target.index_set().dimen

        blkname = blk_target.getname(fully_qualified=True, relative_to=fs_tgt)
        blk_source = fs_src.find_component(blkname)
        if blk_source is None:
            # log warning
            msg = ('Warning copying values: ' + blkname +
                   ' does not exist in source' + fs_src.name)
            init_log = idaeslog.getInitLogger(__name__, outlvl)
            init_log.warning(msg)
            continue

        if n == 1:
            target_index = t_target
            source_index = t_source

            var_visited = set()
            for var_target in blk_target[target_index].component_data_objects(
                    Var):
                if id(var_target) in var_visited:
                    continue
                var_visited.add(id(var_target))

                if not copy_fixed and var_target.fixed:
                    continue

                # Here, find_component will not work from BlockData object
                local_parent = blk_source[source_index]
                for r in path_from_block(var_target, blk_target[target_index]):
                    local_parent = getattr(local_parent, r[0])[r[1]]
                var_source = getattr(local_parent,
                                     var_target.parent_component().local_name)[
                                         var_target.index()]
                var_target.set_value(var_source.value)

        elif n >= 2:
            index_info = get_index_set_except(blk_target, time_target)
            non_time_index_set = index_info['set_except']
            index_getter = index_info['index_getter']
            for non_time_index in non_time_index_set:
                source_index = index_getter(non_time_index, t_source)
                target_index = index_getter(non_time_index, t_target)

                var_visited = set()
                for var_target in blk_target[
                        target_index].component_data_objects(Var):
                    if id(var_target) in var_visited:
                        continue
                    var_visited.add(id(var_target))

                    if not copy_fixed and var_target.fixed:
                        continue

                    local_parent = blk_source[source_index]
                    for r in path_from_block(var_target,
                                             blk_target[target_index]):
                        local_parent = getattr(local_parent, r[0])[r[1]]
                    var_source = getattr(
                        local_parent,
                        var_target.parent_component().local_name)[
                            var_target.index()]
                    var_target.set_value(var_source.value)
コード例 #5
0
    def test_get_index_set_except(self):
        '''
        Tests:
          For components indexed by 0, 1, 2, 3, 4 sets:
            get_index_set_except one, then two (if any) of those sets
            check two items that should be in set_except
            insert item(s) back into these sets via index_getter
        '''
        m = ConcreteModel()
        m.time = ContinuousSet(bounds=(0, 10))
        m.space = ContinuousSet(bounds=(0, 10))
        m.set1 = Set(initialize=['a', 'b', 'c'])
        m.set2 = Set(initialize=['d', 'e', 'f'])
        m.v = Var()
        m.v1 = Var(m.time)
        m.v2 = Var(m.time, m.space)
        m.v3 = Var(m.time, m.space, m.set1)
        m.v4 = Var(m.time, m.space, m.set1, m.set2)

        # Multi-dimensional set:
        m.set3 = Set(initialize=[('a', 1), ('b', 2)])
        m.v5 = Var(m.set3)
        m.v6 = Var(m.time, m.space, m.set3)
        m.v7 = Var(m.set3, m.space, m.time)

        disc = TransformationFactory('dae.collocation')
        disc.apply_to(m, wrt=m.time, nfe=5, ncp=2, scheme='LAGRANGE-RADAU')
        disc.apply_to(m, wrt=m.space, nfe=5, ncp=2, scheme='LAGRANGE-RADAU')

        # Want this to give a TypeError
        # info = get_index_set_except(m.v, m.time)

        # Indexed by one set
        info = get_index_set_except(m.v1, m.time)
        set_except = info['set_except']
        index_getter = info['index_getter']
        self.assertTrue(set_except == [None])
        # Variable is not indexed by anything except time
        # Test that index_getter returns only the new value given,
        # regardless of whether it was part of the set excluded (time):
        self.assertEqual(index_getter((), -1), -1)

        # Indexed by two sets
        info = get_index_set_except(m.v2, m.time)
        set_except = info['set_except']
        index_getter = info['index_getter']
        self.assertTrue(m.space[1] in set_except
                        and m.space.last() in set_except)
	# Here (2,) is the partial index, corresponding to space.
        # Can be provided as a scalar or tuple. 4, the time index,
        # should be inserted before (2,)
        self.assertEqual(index_getter((2,), 4), (4, 2))
        self.assertEqual(index_getter(2, 4), (4, 2))

        # Case where every set is "omitted," now for multiple sets
        info = get_index_set_except(m.v2, m.space, m.time)
        set_except = info['set_except']
        index_getter = info['index_getter']
        self.assertTrue(set_except == [None])
        # 5, 7 are the desired index values for space, time 
        # index_getter should put them in the right order for m.v2,
        # even if they are not valid indices for m.v2
        self.assertEqual(index_getter((), 5, 7), (7, 5))

        # Indexed by three sets
        info = get_index_set_except(m.v3, m.time)
        # In this case set_except is a product of the two non-time sets
        # indexing v3
        set_except = info['set_except']
        index_getter = info['index_getter']
        self.assertTrue((m.space[1], 'b') in set_except
                        and (m.space.last(), 'a') in set_except)
        # index_getter inserts a scalar index into an index of length 2
        self.assertEqual(index_getter((2, 'b'), 7), (7, 2, 'b'))

        info = get_index_set_except(m.v3, m.space, m.time)
        # Two sets omitted. Now set_except is just set1
        set_except = info['set_except']
        index_getter = info['index_getter']
        self.assertTrue('a' in set_except)
        # index_getter inserts the two new indices in the right order
        self.assertEqual(index_getter('b', 1.2, 1.1), (1.1, 1.2, 'b'))

        # Indexed by four sets
        info = get_index_set_except(m.v4, m.set1, m.space)
        # set_except is a product, and there are two indices to insert
        set_except = info['set_except']
        index_getter = info['index_getter']
        self.assertTrue((m.time[1], 'd') in set_except)
        self.assertEqual(index_getter((4, 'f'), 'b', 8), (4, 8, 'b', 'f'))
        
        # The intended usage of this function looks something like:
        index_set = m.v4.index_set()
        for partial_index in set_except:
            complete_index = index_getter(partial_index, 'a', m.space[2])
            self.assertTrue(complete_index in index_set)
            # Do something for every index of v4 at 'a' and space[2]

        # Indexed by a multi-dimensional set
        info = get_index_set_except(m.v5, m.set3)
        set_except = info['set_except']
        index_getter = info['index_getter']
        self.assertEqual(set_except, [None])
        self.assertEqual(index_getter((), ('a', 1)), ('a', 1))

        info = get_index_set_except(m.v6, m.set3, m.time)
        set_except = info['set_except']
        index_getter = info['index_getter']
        self.assertTrue(m.space[1] in set_except)
        self.assertEqual(index_getter(m.space[1], ('b', 2), m.time[1]),
                (m.time[1], m.space[1], 'b', 2))

        info = get_index_set_except(m.v7, m.time)
        set_except = info['set_except']
        index_getter = info['index_getter']
        self.assertIn(('a', 1, m.space[1]), set_except)
        self.assertEqual(index_getter(('a', 1, m.space[1]), m.time[1]),
                         ('a', 1, m.space[1], m.time[1]))

        m.v8 = Var(m.time, m.set3, m.time)
        with self.assertRaises(ValueError):
            info = get_index_set_except(m.v8, m.time)
        with self.assertRaises(ValueError):
            info = get_index_set_except(m.v8, m.space)