Example #1
0
    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()
Example #2
0
    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)
Example #3
0
    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()
Example #4
0
    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)
Example #5
0
    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)
Example #6
0
    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)
Example #7
0
    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)
Example #8
0
    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)
Example #9
0
    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)
Example #10
0
    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)
Example #11
0
    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)
Example #12
0
    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()
Example #13
0
    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()