def _transformBlock(self, block, currentds): self._fe = {} for ds in block.component_map(ContinuousSet).itervalues(): if currentds is None or currentds is ds.cname(True): generate_finite_elements(ds, self._nfe[currentds]) if not ds.get_changed(): if len(ds) - 1 > self._nfe[currentds]: print("***WARNING: More finite elements were found in ContinuousSet "\ "'%s' than the number of finite elements specified in apply. "\ "The larger number of finite elements will be used." %(ds.cname(True))) self._nfe[ds.cname(True)] = len(ds) - 1 self._fe[ds.cname(True)] = sorted(ds) # Adding discretization information to the differentialset object itself # so that it can be accessed outside of the discretization object disc_info = ds.get_discretization_info() disc_info['nfe'] = self._nfe[ds.cname(True)] disc_info['scheme'] = self._scheme_name + ' Difference' # Maybe check to see if any of the ContinuousSets have been changed, # if they haven't then the model components need not be updated # or even iterated through for c in block.component_map().itervalues(): update_contset_indexed_component(c) for d in block.component_map(DerivativeVar).itervalues(): dsets = d.get_continuousset_list() for i in set(dsets): if currentds is None or i.cname(True) is currentds: oldexpr = d.get_derivative_expression() loc = d.get_state_var()._contset[i] count = dsets.count(i) if count >= 3: raise DAE_Error( "Error discretizing '%s' with respect to '%s'. Current implementation "\ "only allows for taking the first or second derivative with respect to "\ "a particular ContinuousSet" %(d.cname(True),i.cname(True))) scheme = self._scheme[count - 1] newexpr = create_partial_expression( scheme, oldexpr, i, loc) d.set_derivative_expression(newexpr) # Reclassify DerivativeVar if all indexing ContinuousSets have been discretized if d.is_fully_discretized(): add_discretization_equations(block, d) block.reclassify_component_type(d, Var) # Reclassify Integrals if all ContinuousSets have been discretized if block_fully_discretized(block): if block.contains_component(Integral): for i in block.component_map(Integral).itervalues(): i.reconstruct() block.reclassify_component_type(i, Expression) # If a model contains integrals they are most likely to appear in the objective # function which will need to be reconstructed after the model is discretized. for k in block.component_map(Objective).itervalues(): k.reconstruct()
def test_update_contset_indexed_component_piecewise_multiple(self): x = [0.0, 1.5, 3.0, 5.0] y = [1.1, -1.1, 2.0, 1.1] model = ConcreteModel() model.t = ContinuousSet(bounds=(0, 10)) model.s = Set(initialize=['A', 'B', 'C']) model.x = Var(model.s, model.t, bounds=(min(x), max(x))) model.y = Var(model.s, model.t) model.fx = Piecewise(model.s, model.t, model.y, model.x, pw_pts=x, pw_constr_type='EQ', f_rule=y) self.assertEqual(len(model.fx), 6) expansion_map = ComponentMap() generate_finite_elements(model.t, 5) update_contset_indexed_component(model.fx, expansion_map) self.assertEqual(len(model.fx), 18) self.assertEqual(len(model.fx['A', 2].SOS2_constraint), 3)
def _transformBlock(self, block, currentds): self._fe = {} for ds in block.component_map(ContinuousSet).itervalues(): if currentds is None or currentds == ds.cname(True): generate_finite_elements(ds,self._nfe[currentds]) if not ds.get_changed(): if len(ds)-1 > self._nfe[currentds]: print("***WARNING: More finite elements were found in ContinuousSet "\ "'%s' than the number of finite elements specified in apply. "\ "The larger number of finite elements will be used." %(ds.cname(True))) self._nfe[ds.cname(True)]=len(ds)-1 self._fe[ds.cname(True)]=sorted(ds) # Adding discretization information to the differentialset object itself # so that it can be accessed outside of the discretization object disc_info = ds.get_discretization_info() disc_info['nfe']=self._nfe[ds.cname(True)] disc_info['scheme']=self._scheme_name + ' Difference' # Maybe check to see if any of the ContinuousSets have been changed, # if they haven't then the model components need not be updated # or even iterated through for c in block.component_map().itervalues(): update_contset_indexed_component(c) for d in block.component_map(DerivativeVar).itervalues(): dsets = d.get_continuousset_list() for i in set(dsets): if currentds is None or i.cname(True) == currentds: oldexpr = d.get_derivative_expression() loc = d.get_state_var()._contset[i] count = dsets.count(i) if count >= 3: raise DAE_Error( "Error discretizing '%s' with respect to '%s'. Current implementation "\ "only allows for taking the first or second derivative with respect to "\ "a particular ContinuousSet" %(d.cname(True),i.cname(True))) scheme = self._scheme[count-1] newexpr = create_partial_expression(scheme,oldexpr,i,loc) d.set_derivative_expression(newexpr) # Reclassify DerivativeVar if all indexing ContinuousSets have been discretized if d.is_fully_discretized(): add_discretization_equations(block,d) block.reclassify_component_type(d,Var) # Reclassify Integrals if all ContinuousSets have been discretized if block_fully_discretized(block): if block.contains_component(Integral): for i in block.component_map(Integral).itervalues(): i.reconstruct() block.reclassify_component_type(i,Expression) # If a model contains integrals they are most likely to appear in the objective # function which will need to be reconstructed after the model is discretized. for k in block.component_map(Objective).itervalues(): k.reconstruct()
def test_update_contset_indexed_component_block_multiple2(self): model = ConcreteModel() model.t = ContinuousSet(bounds=(0, 10)) model.s1 = Set(initialize=['A', 'B', 'C']) model.s2 = Set(initialize=[('x1', 'x1'), ('x2', 'x2')]) def _block_rule(_b_, t, s1): m = _b_.model() b = Block() def _init(m, i, j): return j * 2 b.p1 = Param(m.s1, m.t, mutable=True, default=_init) b.v1 = Var(m.s1, m.t, initialize=5) b.v2 = Var(m.s2, m.t, initialize=2) b.v3 = Var(m.t, m.s2, initialize=1) def _con1(_b, si, ti): return _b.v1[si, ti] * _b.p1[si, ti] == _b.v1[si, t]**2 b.con1 = Constraint(m.s1, m.t, rule=_con1) def _con2(_b, i, j, ti): return _b.v2[i, j, ti] - _b.v3[ti, i, j] + _b.p1['A', ti] b.con2 = Expression(m.s2, m.t, rule=_con2) return b model.blk = Block(model.t, model.s1, rule=_block_rule) expansion_map = ComponentMap() self.assertTrue(len(model.blk), 6) generate_finite_elements(model.t, 5) missing_idx = set(model.blk._index) - set(iterkeys(model.blk._data)) model.blk._dae_missing_idx = missing_idx update_contset_indexed_component(model.blk, expansion_map) self.assertEqual(len(model.blk), 18) self.assertEqual(len(model.blk[10, 'C'].con1), 6) self.assertEqual(len(model.blk[2, 'B'].con1), 18) self.assertEqual(len(model.blk[10, 'C'].v2), 4) self.assertEqual(model.blk[2, 'A'].p1['A', 2], 4) self.assertEqual(model.blk[8, 'C'].p1['B', 6], 12) self.assertEqual(model.blk[4, 'B'].con1['B', 4](), 15) self.assertEqual(model.blk[6, 'A'].con1['C', 8](), 55) self.assertEqual(model.blk[0, 'A'].con2['x1', 'x1', 10](), 21) self.assertEqual(model.blk[4, 'C'].con2['x2', 'x2', 6](), 13)
def test_update_contset_indexed_component_block_single2(self): model = ConcreteModel() model.t = ContinuousSet(bounds=(0, 10)) def _block_rule(_b_, t): m = _b_.model() b = Block() b.s1 = Set(initialize=['A1', 'A2', 'A3']) def _init(m, j): return j * 2 b.p1 = Param(m.t, default=_init) b.v1 = Var(m.t, initialize=5) b.v2 = Var(m.t, initialize=2) b.v3 = Var(m.t, b.s1, initialize=1) def _con1(_b, ti): return _b.v1[ti] * _b.p1[ti] == _b.v1[t]**2 b.con1 = Constraint(m.t, rule=_con1) def _con2(_b, i, ti): return _b.v2[ti] - _b.v3[ti, i] + _b.p1[ti] b.con2 = Expression(b.s1, m.t, rule=_con2) return b model.blk = Block(model.t, rule=_block_rule) expansion_map = ComponentMap() self.assertTrue(len(model.blk), 2) generate_finite_elements(model.t, 5) missing_idx = set(model.blk._index) - set(iterkeys(model.blk._data)) model.blk._dae_missing_idx = missing_idx update_contset_indexed_component(model.blk, expansion_map) self.assertEqual(len(model.blk), 6) self.assertEqual(len(model.blk[10].con1), 2) self.assertEqual(len(model.blk[2].con1), 6) self.assertEqual(len(model.blk[10].v2), 2) self.assertEqual(model.blk[2].p1[2], 4) self.assertEqual(model.blk[8].p1[6], 12) self.assertEqual(model.blk[4].con1[4](), 15) self.assertEqual(model.blk[6].con1[8](), 55) self.assertEqual(model.blk[0].con2['A1', 10](), 21) self.assertEqual(model.blk[4].con2['A2', 6](), 13)
def test_update_contset_indexed_component_unsupported_single(self): m = ConcreteModel() m.t = ContinuousSet(bounds=(0, 10)) m.s = Set(m.t) generate_finite_elements(m.t, 5) expansion_map = ComponentMap() # Expected TypeError because Set is not a component that supports # indexing by a ContinuousSet with self.assertRaises(TypeError): update_contset_indexed_component(m.s, expansion_map)
def test_update_contset_indexed_component_expressions_single(self): m = ConcreteModel() m.t = ContinuousSet(bounds=(0, 10)) m.p = Param(m.t, default=3) m.v = Var(m.t, initialize=5) def _con1(m, i): return m.p[i] * m.v[i] m.con1 = Expression(m.t, rule=_con1) # Rules that iterate over a ContinuousSet implicitly are not updated # after the discretization def _con2(m): return sum(m.v[i] for i in m.t) m.con2 = Expression(rule=_con2) expansion_map = ComponentMap() generate_finite_elements(m.t, 5) update_contset_indexed_component(m.v, expansion_map) update_contset_indexed_component(m.p, expansion_map) update_contset_indexed_component(m.con1, expansion_map) update_contset_indexed_component(m.con2, expansion_map) self.assertTrue(len(m.con1) == 6) self.assertEqual(m.con1[2](), 15) self.assertEqual(m.con1[8](), 15) self.assertEqual(m.con2(), 10)
def test_update_contset_indexed_component_vars_multiple(self): m = ConcreteModel() m.t = ContinuousSet(bounds=(0, 10)) m.t2 = ContinuousSet(initialize=[1, 2, 3]) m.s = Set(initialize=[1, 2, 3]) m.s2 = Set(initialize=[(1, 1), (2, 2)]) m.v1 = Var(m.s, m.t, initialize=3) m.v2 = Var(m.s, m.t, m.t2, bounds=(4, 10), initialize={ (1, 0, 1): 22, (2, 10, 2): 22 }) def _init(m, i, j, k): return i m.v3 = Var(m.t, m.s2, bounds=(-5, 5), initialize=_init) m.v4 = Var(m.s, m.t2, initialize=7, dense=True) m.v5 = Var(m.s2) expansion_map = ComponentMap() generate_finite_elements(m.t, 5) update_contset_indexed_component(m.v1, expansion_map) update_contset_indexed_component(m.v2, expansion_map) update_contset_indexed_component(m.v3, expansion_map) update_contset_indexed_component(m.v4, expansion_map) update_contset_indexed_component(m.v5, expansion_map) self.assertTrue(len(m.v1) == 18) self.assertTrue(len(m.v2) == 54) self.assertTrue(len(m.v3) == 12) self.assertTrue(len(m.v4) == 9) self.assertTrue(value(m.v1[1, 4]) == 3) self.assertTrue(m.v1[2, 2].ub is None) self.assertTrue(m.v1[3, 8].lb is None) self.assertTrue(value(m.v2[1, 0, 1]) == 22) self.assertTrue(m.v2[1, 2, 1].value is None) self.assertTrue(m.v2[2, 4, 3].lb == 4) self.assertTrue(m.v2[3, 8, 1].ub == 10) self.assertTrue(value(m.v3[2, 2, 2]) == 2) self.assertTrue(m.v3[4, 1, 1].lb == -5) self.assertTrue(m.v3[8, 2, 2].ub == 5) self.assertTrue(value(m.v3[6, 1, 1]) == 6)
def test_update_contset_indexed_component_vars_single(self): m = ConcreteModel() m.t = ContinuousSet(bounds=(0, 10)) m.t2 = ContinuousSet(initialize=[1, 2, 3]) m.s = Set(initialize=[1, 2, 3]) m.v1 = Var(m.t, initialize=3) m.v2 = Var(m.t, bounds=(4, 10), initialize={0: 2, 10: 12}) def _init(m, i): return i m.v3 = Var(m.t, bounds=(-5, 5), initialize=_init) m.v4 = Var(m.s, initialize=7, dense=True) m.v5 = Var(m.t2, dense=True) expansion_map = ComponentMap() generate_finite_elements(m.t, 5) update_contset_indexed_component(m.v1, expansion_map) update_contset_indexed_component(m.v2, expansion_map) update_contset_indexed_component(m.v3, expansion_map) update_contset_indexed_component(m.v4, expansion_map) update_contset_indexed_component(m.v5, expansion_map) self.assertTrue(len(m.v1) == 6) self.assertTrue(len(m.v2) == 6) self.assertTrue(len(m.v3) == 6) self.assertTrue(len(m.v4) == 3) self.assertTrue(len(m.v5) == 3) self.assertTrue(value(m.v1[2]) == 3) self.assertTrue(m.v1[4].ub is None) self.assertTrue(m.v1[6].lb is None) self.assertTrue(m.v2[2].value is None) self.assertTrue(m.v2[4].lb == 4) self.assertTrue(m.v2[8].ub == 10) self.assertTrue(value(m.v2[0]) == 2) self.assertTrue(value(m.v3[2]) == 2) self.assertTrue(m.v3[4].lb == -5) self.assertTrue(m.v3[6].ub == 5) self.assertTrue(value(m.v3[8]) == 8)
def test_update_contset_indexed_component_other(self): m = ConcreteModel() m.t = ContinuousSet(bounds=(0, 10)) m.junk = Suffix() m.s = Set(initialize=[1, 2, 3]) m.v = Var(m.s) def _obj(m): return sum(m.v[i] for i in m.s) m.obj = Objective(rule=_obj) expansion_map = ComponentMap generate_finite_elements(m.t, 5) update_contset_indexed_component(m.junk, expansion_map) update_contset_indexed_component(m.s, expansion_map) update_contset_indexed_component(m.obj, expansion_map)
def test_update_contset_indexed_component_expressions_multiple(self): m = ConcreteModel() m.t = ContinuousSet(bounds=(0, 10)) m.t2 = ContinuousSet(initialize=[1, 2, 3]) m.s1 = Set(initialize=[1, 2, 3]) m.s2 = Set(initialize=[(1, 1), (2, 2)]) def _init(m, i, j): return j + i m.p1 = Param(m.s1, m.t, default=_init) m.v1 = Var(m.s1, m.t, initialize=5) m.v2 = Var(m.s2, m.t, initialize=2) m.v3 = Var(m.t2, m.s2, initialize=1) def _con1(m, si, ti): return m.v1[si, ti] * m.p1[si, ti] m.con1 = Expression(m.s1, m.t, rule=_con1) def _con2(m, i, j, ti): return m.v2[i, j, ti] + m.p1[1, ti] m.con2 = Expression(m.s2, m.t, rule=_con2) def _con3(m, i, ti, ti2, j, k): return m.v1[i, ti] - m.v3[ti2, j, k] * m.p1[i, ti] m.con3 = Expression(m.s1, m.t, m.t2, m.s2, rule=_con3) expansion_map = ComponentMap() generate_finite_elements(m.t, 5) update_contset_indexed_component(m.p1, expansion_map) update_contset_indexed_component(m.v1, expansion_map) update_contset_indexed_component(m.v2, expansion_map) update_contset_indexed_component(m.v3, expansion_map) update_contset_indexed_component(m.con1, expansion_map) update_contset_indexed_component(m.con2, expansion_map) update_contset_indexed_component(m.con3, expansion_map) self.assertTrue(len(m.con1) == 18) self.assertTrue(len(m.con2) == 12) self.assertTrue(len(m.con3) == 108) self.assertEqual(m.con1[1, 4](), 25) self.assertEqual(m.con1[2, 6](), 40) self.assertEqual(m.con1[3, 8](), 55) self.assertEqual(m.con2[1, 1, 2](), 5) self.assertEqual(m.con2[2, 2, 4](), 7) self.assertEqual(m.con2[1, 1, 8](), 11) self.assertEqual(m.con3[1, 2, 1, 1, 1](), 2) self.assertEqual(m.con3[1, 4, 1, 2, 2](), 0) self.assertEqual(m.con3[2, 6, 3, 1, 1](), -3) self.assertEqual(m.con3[3, 8, 2, 2, 2](), -6)
def _transformBlock(self, block, currentds): self._fe = {} for ds in itervalues(block.component_map(ContinuousSet)): if currentds is None or currentds == ds.name: generate_finite_elements(ds, self._nfe[currentds]) if not ds.get_changed(): if len(ds) - 1 > self._nfe[currentds]: print("***WARNING: More finite elements were found in differentialset "\ "'%s' than the number of finite elements specified in apply. "\ "The larger number of finite elements will be used." % (ds.name,)) self._nfe[ds.name] = len(ds) - 1 self._fe[ds.name] = sorted(ds) generate_colloc_points(ds, self._tau[currentds]) # Adding discretization information to the differentialset object itself # so that it can be accessed outside of the discretization object disc_info = ds.get_discretization_info() disc_info['nfe'] = self._nfe[ds.name] disc_info['ncp'] = self._ncp[currentds] disc_info['tau_points'] = self._tau[currentds] disc_info['adot'] = self._adot[currentds] disc_info['adotdot'] = self._adotdot[currentds] disc_info['afinal'] = self._afinal[currentds] disc_info['scheme'] = self._scheme_name for c in itervalues(block.component_map()): update_contset_indexed_component(c) for d in itervalues(block.component_map(DerivativeVar)): dsets = d.get_continuousset_list() for i in set(dsets): if currentds is None or i.name == currentds: oldexpr = d.get_derivative_expression() loc = d.get_state_var()._contset[i] count = dsets.count(i) if count >= 3: raise DAE_Error( "Error discretizing '%s' with respect to '%s'. Current implementation "\ "only allows for taking the first or second derivative with respect to "\ "a particular ContinuousSet" %s(d.name,i.name)) scheme = self._scheme[count - 1] # print("%s %s" % (i.name, scheme.__name__)) newexpr = create_partial_expression( scheme, oldexpr, i, loc) d.set_derivative_expression(newexpr) if self._scheme_name == 'LAGRANGE-LEGENDRE': add_continuity_equations(block, d, i, loc) # Reclassify DerivativeVar if all indexing ContinuousSets have been discretized if d.is_fully_discretized(): add_discretization_equations(block, d) block.reclassify_component_type(d, Var) # Reclassify Integrals if all ContinuousSets have been discretized if block_fully_discretized(block): if block.contains_component(Integral): for i in itervalues(block.component_map(Integral)): i.reconstruct() block.reclassify_component_type(i, Expression) # If a model contains integrals they are most likely to appear in the objective # function which will need to be reconstructed after the model is discretized. for k in itervalues(block.component_map(Objective)): k.reconstruct()
def _transformBlock(self, block, currentds): self._fe = {} for ds in itervalues(block.component_map(ContinuousSet)): if currentds is None or currentds == ds.name: generate_finite_elements(ds,self._nfe[currentds]) if not ds.get_changed(): if len(ds)-1 > self._nfe[currentds]: print("***WARNING: More finite elements were found in differentialset "\ "'%s' than the number of finite elements specified in apply. "\ "The larger number of finite elements will be used." % (ds.name,)) self._nfe[ds.name]=len(ds)-1 self._fe[ds.name]=sorted(ds) generate_colloc_points(ds,self._tau[currentds]) # Adding discretization information to the differentialset object itself # so that it can be accessed outside of the discretization object disc_info = ds.get_discretization_info() disc_info['nfe']=self._nfe[ds.name] disc_info['ncp']=self._ncp[currentds] disc_info['tau_points']=self._tau[currentds] disc_info['adot'] = self._adot[currentds] disc_info['adotdot'] = self._adotdot[currentds] disc_info['afinal'] = self._afinal[currentds] disc_info['scheme'] = self._scheme_name for c in itervalues(block.component_map()): update_contset_indexed_component(c) for d in itervalues(block.component_map(DerivativeVar)): dsets = d.get_continuousset_list() for i in set(dsets): if currentds is None or i.name == currentds: oldexpr = d.get_derivative_expression() loc = d.get_state_var()._contset[i] count = dsets.count(i) if count >= 3: raise DAE_Error( "Error discretizing '%s' with respect to '%s'. Current implementation "\ "only allows for taking the first or second derivative with respect to "\ "a particular ContinuousSet" %(d.name,i.name)) scheme = self._scheme[count-1] # print("%s %s" % (i.name, scheme.__name__)) newexpr = create_partial_expression(scheme,oldexpr,i,loc) d.set_derivative_expression(newexpr) if self._scheme_name == 'LAGRANGE-LEGENDRE': add_continuity_equations(block,d,i,loc) # Reclassify DerivativeVar if all indexing ContinuousSets have been discretized if d.is_fully_discretized(): add_discretization_equations(block,d) block.reclassify_component_type(d,Var) # Reclassify Integrals if all ContinuousSets have been discretized if block_fully_discretized(block): if block.contains_component(Integral): for i in itervalues(block.component_map(Integral)): i.reconstruct() block.reclassify_component_type(i,Expression) # If a model contains integrals they are most likely to appear in the objective # function which will need to be reconstructed after the model is discretized. for k in itervalues(block.component_map(Objective)): k.reconstruct()