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'))
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
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
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
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