예제 #1
0
파일: test_misc.py 프로젝트: vova292/pyomo
    def test_get_index_information(self):
        m = ConcreteModel()
        m.t = ContinuousSet(bounds=(0, 10))
        m.x = ContinuousSet(bounds=(0, 10))
        m.s = Set(initialize=['a', 'b', 'c'])
        m.v = Var(m.t, m.x, m.s, initialize=1)
        m.v2 = Var(m.t, m.s, initialize=1)

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

        info = get_index_information(m.v, m.t)
        nts = info['non_ds']
        index_getter = info['index function']

        self.assertEqual(len(nts), 33)
        self.assertTrue(m.x in nts.set_tuple)
        self.assertTrue(m.s in nts.set_tuple)
        self.assertEqual(index_getter((8.0, 'a'), 1, 0), (2.0, 8.0, 'a'))

        info = get_index_information(m.v2, m.t)
        nts = info['non_ds']
        index_getter = info['index function']

        self.assertEqual(len(nts), 3)
        self.assertTrue(m.s is nts)
        self.assertEqual(index_getter('a', 1, 0), (2.0, 'a'))
예제 #2
0
    def reduce_collocation_points(self,
                                  instance,
                                  var=None,
                                  ncp=None,
                                  contset=None):
        """
        This method will add additional constraints to a model to reduce the
        number of free collocation points (degrees of freedom) for a particular
        variable.

        Parameters
        ----------
        instance : Pyomo model
            The discretized Pyomo model to add constraints to

        var : ``pyomo.environ.Var``
            The Pyomo variable for which the degrees of freedom will be reduced

        ncp : int
            The new number of free collocation points for `var`. Must be
            less that the number of collocation points used in discretizing
            the model.

        contset : ``pyomo.dae.ContinuousSet``
            The :py:class:`ContinuousSet<pyomo.dae.ContinuousSet>` that was
            discretized and for which the `var` will have a reduced number
            of degrees of freedom

        """
        if contset is None:
            raise TypeError("A continuous set must be specified using the "
                            "keyword 'contset'")
        if contset.ctype is not ContinuousSet:
            raise TypeError("The component specified using the 'contset' "
                            "keyword must be a ContinuousSet")
        ds = contset

        if len(self._ncp) == 0:
            raise RuntimeError("This method should only be called after using "
                               "the apply() method to discretize the model")
        elif None in self._ncp:
            tot_ncp = self._ncp[None]
        elif ds.name in self._ncp:
            tot_ncp = self._ncp[ds.name]
        else:
            raise ValueError("ContinuousSet '%s' has not been discretized, "
                             "please call the apply_to() method with this "
                             "ContinuousSet to discretize it before calling "
                             "this method" % ds.name)

        if var is None:
            raise TypeError("A variable must be specified")
        if var.ctype is not Var:
            raise TypeError("The component specified using the 'var' keyword "
                            "must be a variable")

        if ncp is None:
            raise TypeError(
                "The number of collocation points must be specified")
        if ncp <= 0:
            raise ValueError(
                "The number of collocation points must be at least 1")
        if ncp > tot_ncp:
            raise ValueError("The number of collocation points used to "
                             "interpolate an individual variable must be less "
                             "than the number used to discretize the original "
                             "model")
        if ncp == tot_ncp:
            # Nothing to be done
            return instance

        # Check to see if the continuousset is an indexing set of the variable
        if var.dim() == 0:
            raise IndexError("ContinuousSet '%s' is not an indexing set of"
                             " the variable '%s'" % (ds.name, var.name))
        varidx = var.index_set()
        if not hasattr(varidx, 'set_tuple'):
            if ds is not varidx:
                raise IndexError("ContinuousSet '%s' is not an indexing set of"
                                 " the variable '%s'" % (ds.name, var.name))
        elif ds not in varidx.set_tuple:
            raise IndexError("ContinuousSet '%s' is not an indexing set of the"
                             " variable '%s'" % (ds.name, var.name))

        if var.name in self._reduced_cp:
            temp = self._reduced_cp[var.name]
            if ds.name in temp:
                raise RuntimeError("Variable '%s' has already been constrained"
                                   " to a reduced number of collocation points"
                                   " over ContinuousSet '%s'.")
            else:
                temp[ds.name] = ncp
        else:
            self._reduced_cp[var.name] = {ds.name: ncp}

        # TODO: Use unique_component_name for this
        list_name = var.local_name + "_interpolation_constraints"

        instance.add_component(list_name, ConstraintList())
        conlist = instance.find_component(list_name)

        t = list(ds)
        fe = ds._fe
        info = get_index_information(var, ds)
        tmpidx = info['non_ds']
        idx = info['index function']

        # Iterate over non_ds indices
        for n in tmpidx:
            # Iterate over finite elements
            for i in range(0, len(fe) - 1):
                # Iterate over collocation points
                for k in range(1, tot_ncp - ncp + 1):
                    if ncp == 1:
                        # Constant over each finite element
                        conlist.add(
                            var[idx(n, i, k)] == var[idx(n, i, tot_ncp)])
                    else:
                        tmp = ds.ord(fe[i]) - 1
                        tmp2 = ds.ord(fe[i + 1]) - 1
                        ti = t[tmp + k]
                        tfit = t[tmp2 - ncp + 1:tmp2 + 1]
                        coeff = self._interpolation_coeffs(ti, tfit)
                        conlist.add(var[idx(n, i, k)] == sum(
                            var[idx(n, i, j)] * next(coeff)
                            for j in range(tot_ncp - ncp + 1, tot_ncp + 1)))

        return instance
예제 #3
0
    def reduce_collocation_points(self,
                                  instance,
                                  var=None,
                                  ncp=None,
                                  contset=None):
        """
        This method will add additional constraints to a model if some
        of the Variables are specified as having less collocation points
        than the default
        """
        if contset is None:
            raise TypeError(
                "A continuous set must be specified using the keyword 'contset'"
            )
        if contset.type() is not ContinuousSet:
            raise TypeError("The component specified using the 'contset' keyword "\
                "must be a differential set")
        ds = instance.find_component(contset.cname(True))
        if ds is None:
            raise ValueError("ContinuousSet '%s' is not a valid component of the discretized "\
                "model instance" %(contset.cname(True)))

        if len(self._ncp) == 0:
            raise RuntimeError("This method should only be called after using the apply() method "\
                "to discretize the model")
        elif None in self._ncp:
            tot_ncp = self._ncp[None]
        elif ds.cname(True) in self._ncp:
            tot_ncp = self._ncp[ds.cname(True)]
        else:
            raise ValueError("ContinuousSet '%s' has not been discretized yet, please call "\
                "the apply() method with this ContinuousSet to discretize it before calling "\
                "this method" %s(ds.cname(True)))

        if var is None:
            raise TypeError("A variable must be specified")
        if var.type() is not Var:
            raise TypeError("The component specified using the 'var' keyword "\
                "must be a variable")
        tmpvar = instance.find_component(var.cname(True))
        if tmpvar is None:
            raise ValueError("Variable '%s' is not a valid component of the discretized "\
                "model instance" %(var.cname(True)))

        var = tmpvar

        if ncp is None:
            raise TypeError(
                "The number of collocation points must be specified")
        if ncp <= 0:
            raise ValueError(
                "The number of collocation points must be at least 1")
        if ncp > tot_ncp:
            raise ValueError("The number of collocation points used to interpolate "\
                "an individual variable must be less than the number used to discretize "\
                "the original model")
        if ncp == tot_ncp:
            # Nothing to be done
            return instance

        # Check to see if the continuousset is an indexing set of the variable
        if var.dim() == 1:
            if ds not in var._index:
                raise IndexError("ContinuousSet '%s' is not an indexing set of the variable '%s'"\
                    % (ds.name,var.cname(True)))
        elif ds not in var._index_set:
            raise IndexError("ContinuousSet '%s' is not an indexing set of the variable '%s'"\
                % (ds.name,var.name))

        if var.cname(True) in self._reduced_cp:
            temp = self._reduced_cp[var.cname(True)]
            if ds.cname(True) in temp:
                raise RuntimeError("Variable '%s' has already been constrained to a reduced "\
                    "number of collocation points over ContinuousSet '%s'.")
            else:
                temp[ds.name] = ncp
        else:
            self._reduced_cp[var.name] = {ds.name: ncp}

        list_name = var.name + "_interpolation_constraints"

        instance.add_component(list_name, ConstraintList())
        conlist = instance.find_component(list_name)

        t = sorted(ds)
        fe = ds._fe
        info = get_index_information(var, ds)
        tmpidx = info['non_ds']
        idx = info['index function']

        # Iterate over non_ds indices
        for n in tmpidx:
            # Iterate over finite elements
            for i in xrange(0, len(fe) - 1):
                # Iterate over collocation points
                for k in xrange(1, tot_ncp - ncp + 1):
                    if ncp == 1:
                        # Constant over each finite element
                        conlist.add(
                            var[idx(n, i, k)] == var[idx(n, i, tot_ncp)])
                    else:
                        tmp = t.index(fe[i])
                        tmp2 = t.index(fe[i + 1])
                        ti = t[tmp + k]
                        tfit = t[tmp2 - ncp + 1:tmp2 + 1]
                        coeff = self._interpolation_coeffs(ti, tfit)
                        conlist.add(var[idx(n, i, k)] == sum(
                            var[idx(n, i, j)] * coeff.next()
                            for j in xrange(tot_ncp - ncp + 1, tot_ncp + 1)))

        return instance
예제 #4
0
파일: colloc.py 프로젝트: Pyomo/pyomo
    def reduce_collocation_points(self, instance, var=None, ncp=None,
                                  contset=None):
        """
        This method will add additional constraints to a model to reduce the
        number of free collocation points (degrees of freedom) for a particular
        variable.

        Parameters
        ----------
        instance : Pyomo model
            The discretized Pyomo model to add constraints to

        var : ``pyomo.environ.Var``
            The Pyomo variable for which the degrees of freedom will be reduced

        ncp : int
            The new number of free collocation points for `var`. Must be
            less that the number of collocation points used in discretizing
            the model.

        contset : ``pyomo.dae.ContinuousSet``
            The :py:class:`ContinuousSet<pyomo.dae.ContinuousSet>` that was
            discretized and for which the `var` will have a reduced number
            of degrees of freedom

        """
        if contset is None:
            raise TypeError("A continuous set must be specified using the "
                            "keyword 'contset'")
        if contset.type() is not ContinuousSet:
            raise TypeError("The component specified using the 'contset' "
                            "keyword must be a ContinuousSet")
        ds = contset

        if len(self._ncp) == 0:
            raise RuntimeError("This method should only be called after using "
                               "the apply() method to discretize the model")
        elif None in self._ncp:
            tot_ncp = self._ncp[None]
        elif ds.name in self._ncp:
            tot_ncp = self._ncp[ds.name]
        else:
            raise ValueError("ContinuousSet '%s' has not been discretized, "
                             "please call the apply_to() method with this "
                             "ContinuousSet to discretize it before calling "
                             "this method" % ds.name)

        if var is None:
            raise TypeError("A variable must be specified")
        if var.type() is not Var:
            raise TypeError("The component specified using the 'var' keyword "
                            "must be a variable")

        if ncp is None:
            raise TypeError(
                "The number of collocation points must be specified")
        if ncp <= 0:
            raise ValueError(
                "The number of collocation points must be at least 1")
        if ncp > tot_ncp:
            raise ValueError("The number of collocation points used to "
                             "interpolate an individual variable must be less "
                             "than the number used to discretize the original "
                             "model")
        if ncp == tot_ncp:
            # Nothing to be done
            return instance

        # Check to see if the continuousset is an indexing set of the variable
        if var.dim() == 0:
            raise IndexError("ContinuousSet '%s' is not an indexing set of"
                             " the variable '%s'" % (ds.name, var.name))
        elif var.dim() == 1:
            if ds not in var._index:
                raise IndexError("ContinuousSet '%s' is not an indexing set of"
                                 " the variable '%s'" % (ds.name, var.name))
        elif ds not in var._implicit_subsets:
            raise IndexError("ContinuousSet '%s' is not an indexing set of the"
                             " variable '%s'" % (ds.name, var.name))

        if var.name in self._reduced_cp:
            temp = self._reduced_cp[var.name]
            if ds.name in temp:
                raise RuntimeError("Variable '%s' has already been constrained"
                                   " to a reduced number of collocation points"
                                   " over ContinuousSet '%s'.")
            else:
                temp[ds.name] = ncp
        else:
            self._reduced_cp[var.name] = {ds.name: ncp}

        # TODO: Use unique_component_name for this
        list_name = var.local_name + "_interpolation_constraints"

        instance.add_component(list_name, ConstraintList())
        conlist = instance.find_component(list_name)

        t = sorted(ds)
        fe = ds._fe
        info = get_index_information(var, ds)
        tmpidx = info['non_ds']
        idx = info['index function']

        # Iterate over non_ds indices
        for n in tmpidx:
            # Iterate over finite elements
            for i in xrange(0, len(fe) - 1):
                # Iterate over collocation points
                for k in xrange(1, tot_ncp - ncp + 1):
                    if ncp == 1:
                        # Constant over each finite element
                        conlist.add(var[idx(n, i, k)] ==
                                    var[idx(n, i, tot_ncp)])
                    else:
                        tmp = t.index(fe[i])
                        tmp2 = t.index(fe[i + 1])
                        ti = t[tmp + k]
                        tfit = t[tmp2 - ncp + 1:tmp2 + 1]
                        coeff = self._interpolation_coeffs(ti, tfit)
                        conlist.add(var[idx(n, i, k)] ==
                                    sum(var[idx(n, i, j)] * next(coeff)
                                        for j in xrange(tot_ncp - ncp + 1,
                                                        tot_ncp + 1)))

        return instance
예제 #5
0
파일: colloc.py 프로젝트: Juanlu001/pyomo
    def reduce_collocation_points(self, instance, var=None, ncp=None, contset=None):
        """
        This method will add additional constraints to a model if some
        of the Variables are specified as having less collocation points
        than the default
        """
        if contset is None:
            raise TypeError("A continuous set must be specified using the keyword 'contset'")
        if contset.type() is not ContinuousSet:
            raise TypeError("The component specified using the 'contset' keyword "\
                "must be a differential set")
        ds = instance.find_component(contset.cname(True))
        if ds is None:
            raise ValueError("ContinuousSet '%s' is not a valid component of the discretized "\
                "model instance" %(contset.cname(True)))

        if len(self._ncp) == 0:
            raise RuntimeError("This method should only be called after using the apply() method "\
                "to discretize the model")
        elif None in self._ncp:
            tot_ncp = self._ncp[None]
        elif ds.cname(True) in self._ncp:
            tot_ncp = self._ncp[ds.cname(True)]
        else:
            raise ValueError("ContinuousSet '%s' has not been discretized yet, please call "\
                "the apply() method with this ContinuousSet to discretize it before calling "\
                "this method" %s(ds.cname(True)))

        if var is None:
            raise TypeError("A variable must be specified")
        if var.type() is not Var:
            raise TypeError("The component specified using the 'var' keyword "\
                "must be a variable")
        tmpvar = instance.find_component(var.cname(True))
        if tmpvar is None:
            raise ValueError("Variable '%s' is not a valid component of the discretized "\
                "model instance" %(var.cname(True)))

        var = tmpvar

        if ncp is None:
            raise TypeError("The number of collocation points must be specified")
        if ncp <= 0:
            raise ValueError("The number of collocation points must be at least 1")
        if ncp > tot_ncp:
            raise ValueError("The number of collocation points used to interpolate "\
                "an individual variable must be less than the number used to discretize "\
                "the original model")
        if ncp == tot_ncp:
            # Nothing to be done
            return instance

        # Check to see if the continuousset is an indexing set of the variable
        if var.dim() == 1:
            if ds not in var._index:
                raise IndexError("ContinuousSet '%s' is not an indexing set of the variable '%s'"\
                    % (ds.name,var.cname(True)))
        elif ds not in var._index_set:
            raise IndexError("ContinuousSet '%s' is not an indexing set of the variable '%s'"\
                % (ds.name,var.name))

        if var.cname(True) in self._reduced_cp:
            temp = self._reduced_cp[var.cname(True)]
            if ds.cname(True) in temp:
                raise RuntimeError("Variable '%s' has already been constrained to a reduced "\
                    "number of collocation points over ContinuousSet '%s'.")
            else:
                temp[ds.name]=ncp
        else:
            self._reduced_cp[var.name] = {ds.name:ncp}                
        
        list_name = var.name+"_interpolation_constraints"
        
        instance.add_component(list_name,ConstraintList())
        conlist = instance.find_component(list_name)

        t = sorted(ds)
        fe = ds._fe
        info = get_index_information(var,ds)
        tmpidx = info['non_ds']
        idx = info['index function']

        # Iterate over non_ds indices
        for n in tmpidx:
            # Iterate over finite elements
            for i in xrange(0,len(fe)-1):
                # Iterate over collocation points
                for k in xrange(1,tot_ncp-ncp+1):
                    if ncp == 1:
                        # Constant over each finite element
                        conlist.add(var[idx(n,i,k)]==var[idx(n,i,tot_ncp)])
                    else:
                        tmp = t.index(fe[i])
                        tmp2 = t.index(fe[i+1])
                        ti = t[tmp+k]
                        tfit = t[tmp2-ncp+1:tmp2+1]
                        coeff = self._interpolation_coeffs(ti,tfit)
                        conlist.add(var[idx(n,i,k)]== sum(var[idx(n,i,j)]*coeff.next() for j in xrange(tot_ncp-ncp+1,tot_ncp+1)))

        return instance