Ejemplo n.º 1
0
def makeTwoTermIndexedDisjunction_BoundedVars():
    """Two-term indexed disjunction.
    Adds nothing to above--exists for historic reasons"""
    m = ConcreteModel()
    m.s = Set(initialize=[1, 2, 3])
    m.a = Var(m.s, bounds=(-100, 100))

    def disjunct_rule(d, s, flag):
        m = d.model()
        if flag:
            d.c = Constraint(expr=m.a[s] >= 6)
        else:
            d.c = Constraint(expr=m.a[s] <= 3)
    m.disjunct = Disjunct(m.s, [0, 1], rule=disjunct_rule)

    def disjunction_rule(m, s):
        return [m.disjunct[s, flag] for flag in [0, 1]]
    m.disjunction = Disjunction(m.s, rule=disjunction_rule)
    return m
Ejemplo n.º 2
0
def makeTwoTermMultiIndexedDisjunction():
    """Two-term indexed disjunction with tuple indices"""
    m = ConcreteModel()
    m.s = Set(initialize=[1, 2])
    m.t = Set(initialize=['A', 'B'])
    m.a = Var(m.s, m.t, bounds=(2, 7))

    def d_rule(disjunct, flag, s, t):
        m = disjunct.model()
        if flag:
            disjunct.c = Constraint(expr=m.a[s, t] == 0)
        else:
            disjunct.c = Constraint(expr=m.a[s, t] >= 5)
    m.disjunct = Disjunct([0, 1], m.s, m.t, rule=d_rule)

    def disj_rule(m, s, t):
        return [m.disjunct[0, s, t], m.disjunct[1, s, t]]
    m.disjunction = Disjunction(m.s, m.t, rule=disj_rule)
    return m
Ejemplo n.º 3
0
def makeNonQuadraticNonlinearGDP():
    """We use this in testing between steps--Needed non-quadratic and not 
    additively separable constraint expressions on a Disjunct."""
    m = ConcreteModel()
    m.I = RangeSet(1, 4)
    m.I1 = RangeSet(1, 2)
    m.I2 = RangeSet(3, 4)
    m.x = Var(m.I, bounds=(-2, 6))

    # sum of 4-norms...
    m.disjunction = Disjunction(
        expr=[[sum(m.x[i]**4 for i in m.I1)**(1/4) + \
               sum(m.x[i]**4 for i in m.I2)**(1/4) <= 1],
              [sum((3 - m.x[i])**4 for i in m.I1)**(1/4) +
               sum((3 - m.x[i])**4 for i in m.I2)**(1/4) <= 1]])

    m.obj = Objective(expr=m.x[2] - m.x[1], sense=maximize)

    return m
Ejemplo n.º 4
0
def makeTwoTermIndexedDisjunction():
    """Two-term indexed disjunction"""
    m = ConcreteModel()
    m.A = Set(initialize=[1, 2, 3])
    m.B = Set(initialize=['a', 'b'])
    m.x = Var(m.A, bounds=(-10, 10))

    def disjunct_rule(d, i, k):
        m = d.model()
        if k == 'a':
            d.cons_a = Constraint(expr=m.x[i] >= 5)
        if k == 'b':
            d.cons_b = Constraint(expr=m.x[i] <= 0)
    m.disjunct = Disjunct(m.A, m.B, rule=disjunct_rule)

    def disj_rule(m, i):
        return [m.disjunct[i, k] for k in m.B]
    m.disjunction = Disjunction(m.A, rule=disj_rule)
    return m
Ejemplo n.º 5
0
 def test_GDP_integer_vars_infeasible(self):
     m = ConcreteModel()
     m.x = Var(bounds=(0, 1))
     m.y = Var(domain=Integers, bounds=(0, 5))
     m.d = Disjunction(expr=[[
         m.x >= m.y, m.y >= 3.5
     ],
     [
         m.x >= m.y, m.y >= 2.5
     ]])
     m.o = Objective(expr=m.x)
     res = SolverFactory('gdpopt').solve(
         m, strategy='GLOA',
         mip_solver=mip_solver,
         nlp_solver=nlp_solver,
         minlp_solver=minlp_solver
     )
     self.assertEqual(res.solver.termination_condition,
                      TerminationCondition.infeasible)
Ejemplo n.º 6
0
 def test_solve_linear_GDP_unbounded(self):
     m = ConcreteModel()
     m.GDPopt_utils = Block()
     m.x = Var(bounds=(-1, 10))
     m.y = Var(bounds=(2, 3))
     m.z = Var()
     m.d = Disjunction(expr=[[m.x + m.y >= 5], [m.x - m.y <= 3]])
     m.o = Objective(expr=m.z)
     m.GDPopt_utils.variable_list = [m.x, m.y, m.z]
     m.GDPopt_utils.disjunct_list = [
         m.d._autodisjuncts[0], m.d._autodisjuncts[1]
     ]
     output = StringIO()
     with LoggingIntercept(output, 'pyomo.contrib.gdpopt', logging.WARNING):
         solve_linear_GDP(m, GDPoptSolveData(),
                          GDPoptSolver.CONFIG(dict(mip_solver=mip_solver)))
         self.assertIn(
             "Linear GDP was unbounded. Resolving with arbitrary bound values",
             output.getvalue().strip())
Ejemplo n.º 7
0
def makeNestedDisjunctions():
    m = ConcreteModel()
    m.x = Var(bounds=(-9, 9))
    m.z = Var(bounds=(0, 10))
    m.a = Var(bounds=(0, 23))

    def disjunct_rule(disjunct, flag):
        m = disjunct.model()
        if flag:
            def innerdisj_rule(disjunct, flag):
                m = disjunct.model()
                if flag:
                    disjunct.c = Constraint(expr=m.z >= 5)
                else:
                    disjunct.c = Constraint(expr=m.z == 0)
            disjunct.innerdisjunct = Disjunct([0, 1], rule=innerdisj_rule)

            @disjunct.Disjunction([0])
            def innerdisjunction(b, i):
                return [b.innerdisjunct[0], b.innerdisjunct[1]]
            disjunct.c = Constraint(expr=m.a <= 2)
        else:
            disjunct.c = Constraint(expr=m.x == 2)
    m.disjunct = Disjunct([0, 1], rule=disjunct_rule)
    # I want a SimpleDisjunct with a disjunction in it too

    def simpledisj_rule(disjunct):
        m = disjunct.model()

        @disjunct.Disjunct()
        def innerdisjunct0(disjunct):
            disjunct.c = Constraint(expr=m.x <= 2)

        @disjunct.Disjunct()
        def innerdisjunct1(disjunct):
            disjunct.c = Constraint(expr=m.x >= 4)

        disjunct.innerdisjunction = Disjunction(
            expr=[disjunct.innerdisjunct0, disjunct.innerdisjunct1])
    m.simpledisjunct = Disjunct(rule=simpledisj_rule)
    m.disjunction = Disjunction(
        expr=[m.simpledisjunct, m.disjunct[0], m.disjunct[1]])
    return m
Ejemplo n.º 8
0
def makeThreeTermIndexedDisj():
    m = ConcreteModel()
    m.s = Set(initialize=[1, 2])
    m.a = Var(m.s, bounds=(2, 7))

    def d_rule(disjunct, flag, s):
        m = disjunct.model()
        if flag == 0:
            disjunct.c = Constraint(expr=m.a[s] == 0)
        elif flag == 1:
            disjunct.c = Constraint(expr=m.a[s] >= 5)
        else:
            disjunct.c = Constraint(expr=inequality(2, m.a[s], 4))
    m.disjunct = Disjunct([0, 1, 2], m.s, rule=d_rule)

    def disj_rule(m, s):
        return [m.disjunct[0, s], m.disjunct[1, s], m.disjunct[2, s]]
    m.disjunction = Disjunction(m.s, rule=disj_rule)
    return m
Ejemplo n.º 9
0
 def test_induced_linear_in_disjunct(self):
     m = ConcreteModel()
     m.x = Var([0], bounds=(-3, 8))
     m.y = Var(RangeSet(2), domain=Binary)
     m.logical = ConstraintList()
     m.logical.add(expr=m.y[1] + m.y[2] == 1)
     m.v = Var([1])
     m.v[1].setlb(-2)
     m.v[1].setub(7)
     m.bilinear_outside = Constraint(expr=m.x[0] * m.v[1] >= 2)
     m.disjctn = Disjunction(
         expr=[[m.x[0] * m.v[1] == 3, 2 * m.x[0] == m.y[1] +
                m.y[2]], [m.x[0] * m.v[1] == 4]])
     TransformationFactory('contrib.induced_linearity').apply_to(m)
     self.assertEqual(
         m.disjctn.disjuncts[0].constraint[1].body.polynomial_degree(), 1)
     self.assertEqual(m.bilinear_outside.body.polynomial_degree(), 2)
     self.assertEqual(
         m.disjctn.disjuncts[1].constraint[1].body.polynomial_degree(), 2)
Ejemplo n.º 10
0
def build_model():
    m = ConcreteModel()
    m.x1 = Var(domain=NonNegativeReals, bounds=(0, 8))
    m.x2 = Var(domain=NonNegativeReals, bounds=(0, 8))
    m.c = Var(domain=NonNegativeReals, bounds=(1, 3))

    m.y1 = Disjunct()
    m.y2 = Disjunct()
    m.y3 = Disjunct()
    m.y1.constr1 = Constraint(expr=m.x1**2 + m.x2**2 - 1 <= 0)
    m.y1.constr2 = Constraint(expr=m.c == 2)
    m.y2.constr1 = Constraint(expr=(m.x1 - 4)**2 + (m.x2 - 1)**2 - 1 <= 0)
    m.y2.constr2 = Constraint(expr=m.c == 1)
    m.y3.constr1 = Constraint(expr=(m.x1 - 2)**2 + (m.x2 - 4)**2 - 1 <= 0)
    m.y3.constr2 = Constraint(expr=m.c == 3)
    m.GPD123 = Disjunction(expr=[m.y1, m.y2, m.y3])

    m.obj = Objective(expr=(m.x1 - 3)**2 + (m.x2 - 2)**2 + m.c, sense=minimize)

    return m
Ejemplo n.º 11
0
def makeThreeTermDisjunctionWithOneVarInOneDisjunct():
    """This is to make sure hull doesn't create more disaggregated variables 
    than it needs to: Here, x only appears in the first Disjunct, so we only 
    need two copies: one as usual for that disjunct and then one other that is 
    free if either of the second two Disjuncts is active and 0 otherwise.
    """
    m = ConcreteModel()
    m.x = Var(bounds=(-2,8))
    m.y = Var(bounds=(3,4))
    m.d1 = Disjunct()
    m.d1.c1 = Constraint(expr=m.x <= 3)
    m.d1.c2 = Constraint(expr=m.y >= 3.5)
    m.d2 = Disjunct()
    m.d2.c1 = Constraint(expr=m.y >= 3.7)
    m.d3 = Disjunct()
    m.d3.c1 = Constraint(expr=m.y >= 3.9)

    m.disjunction = Disjunction(expr=[m.d1, m.d2, m.d3])

    return m
Ejemplo n.º 12
0
def makeTwoTermDisj_BlockOnDisj():
    m = ConcreteModel()
    m.x = Var(bounds=(0, 1000))
    m.y = Var(bounds=(0, 800))

    def disj_rule(d, flag):
        m = d.model()
        if flag:
            d.b = Block()
            d.b.c = Constraint(expr=m.x == 0)
            d.add_component('b.c', Constraint(expr=m.y >= 9))
            d.b.anotherblock = Block()
            d.b.anotherblock.c = Constraint(expr=m.y >= 11)
            d.bb = Block([1])
            d.bb[1].c = Constraint(expr=m.x == 0)
        else:
            d.c = Constraint(expr=m.x >= 80)
    m.evil = Disjunct([0, 1], rule=disj_rule)
    m.disjunction = Disjunction(expr=[m.evil[0], m.evil[1]])
    return m
Ejemplo n.º 13
0
def makeTwoTermDisj_Nonlinear():
    """Single two-term disjunction which has all of ==, <=, and >= and 
    one nonlinear constraint.
    """
    m = ConcreteModel()
    m.w = Var(bounds=(2, 7))
    m.x = Var(bounds=(1, 8))
    m.y = Var(bounds=(-10, -3))

    def d_rule(disjunct, flag):
        m = disjunct.model()
        if flag:
            disjunct.c1 = Constraint(expr=m.x >= 2)
            disjunct.c2 = Constraint(expr=m.w == 3)
            disjunct.c3 = Constraint(expr=(1, m.x, 3))
        else:
            disjunct.c = Constraint(expr=m.x + m.y**2 <= 14)
    m.d = Disjunct([0, 1], rule=d_rule)
    m.disjunction = Disjunction(expr=[m.d[0], m.d[1]])
    return m
Ejemplo n.º 14
0
 def test_subproblem_preprocessing_encounters_trivial_constraints(self):
     m = ConcreteModel()
     m.x = Var(bounds=(0, 10))
     m.z = Var(bounds=(-10, 10))
     m.disjunction = Disjunction(expr=[[m.x == 0, m.z >= 4], 
                                       [m.x + m.z <= 0]])
     m.cons = Constraint(expr=m.x*m.z <= 0)
     m.obj = Objective(expr=-m.z)
     m.disjunction.disjuncts[0].indicator_var.fix(True)
     m.disjunction.disjuncts[1].indicator_var.fix(False)
     SolverFactory('gdpopt').solve(m, strategy='RIC', mip_solver=mip_solver,
                                   nlp_solver=nlp_solver,
                                   init_strategy='fix_disjuncts')
     # The real test is that this doesn't throw an error when we preprocess
     # to solve the first subproblem (in the initialization). The nonlinear
     # constraint becomes trivial, which we need to make sure is handled
     # correctly.
     self.assertEqual(value(m.x), 0)
     self.assertEqual(value(m.z), 10)
     self.assertTrue(value(m.disjunction.disjuncts[0].indicator_var))
     self.assertFalse(value(m.disjunction.disjuncts[1].indicator_var))
Ejemplo n.º 15
0
    def test_deactivate_without_fixing_indicator(self):
        m = ConcreteModel()
        m.x = Var()
        m.d1 = Disjunct()
        m.d1.constraint = Constraint(expr=m.x <= 0)
        m.d = Disjunction(expr=[m.d1, m.x >= 1, m.x >= 5])
        d2 = m.d.disjuncts[1].parent_component()
        self.assertEqual(len(m.component_map(Disjunction)), 1)
        self.assertEqual(len(m.component_map(Disjunct)), 2)
        self.assertIsNot(m.d1, d2)

        self.assertTrue(m.d1.active)
        self.assertTrue(d2.active)
        self.assertTrue(m.d.disjuncts[0].active)
        self.assertTrue(m.d.disjuncts[1].active)
        self.assertTrue(m.d.disjuncts[2].active)
        self.assertFalse(m.d.disjuncts[0].indicator_var.is_fixed())
        self.assertFalse(m.d.disjuncts[1].indicator_var.is_fixed())
        self.assertFalse(m.d.disjuncts[2].indicator_var.is_fixed())

        m.d.disjuncts[0]._deactivate_without_fixing_indicator()
        self.assertFalse(m.d1.active)
        self.assertTrue(d2.active)
        self.assertFalse(m.d.disjuncts[0].active)
        self.assertTrue(m.d.disjuncts[1].active)
        self.assertTrue(m.d.disjuncts[2].active)
        self.assertFalse(m.d.disjuncts[0].indicator_var.is_fixed())
        self.assertFalse(m.d.disjuncts[1].indicator_var.is_fixed())
        self.assertFalse(m.d.disjuncts[2].indicator_var.is_fixed())

        m.d.disjuncts[1]._deactivate_without_fixing_indicator()
        self.assertFalse(m.d1.active)
        self.assertTrue(d2.active)
        self.assertFalse(m.d.disjuncts[0].active)
        self.assertFalse(m.d.disjuncts[1].active)
        self.assertTrue(m.d.disjuncts[2].active)
        self.assertFalse(m.d.disjuncts[0].indicator_var.is_fixed())
        self.assertFalse(m.d.disjuncts[1].indicator_var.is_fixed())
        self.assertFalse(m.d.disjuncts[2].indicator_var.is_fixed())
Ejemplo n.º 16
0
    def test_assert_units_consistent_all_components(self):
        # test all scalar components consistent
        u = units
        m = self._create_model_and_vars()
        m.obj = Objective(expr=m.dx/m.t - m.vx)
        m.con = Constraint(expr=m.dx/m.t == m.vx)
        # vars already added
        m.exp = Expression(expr=m.dx/m.t - m.vx)
        m.suff = Suffix(direction=Suffix.LOCAL)
        # params already added
        # sets already added
        m.rs = RangeSet(5)
        m.disj1 = Disjunct()
        m.disj1.constraint = Constraint(expr=m.dx/m.t <= m.vx)
        m.disj2 = Disjunct()
        m.disj2.constraint = Constraint(expr=m.dx/m.t <= m.vx)
        m.disjn = Disjunction(expr=[m.disj1, m.disj2])
        # block tested as part of model
        m.extfn = ExternalFunction(python_callback_function, units=u.m/u.s, arg_units=[u.m, u.s])
        m.conext = Constraint(expr=m.extfn(m.dx, m.t) - m.vx==0)
        m.cset = ContinuousSet(bounds=(0,1))
        m.svar = Var(m.cset, units=u.m)
        m.dvar = DerivativeVar(sVar=m.svar, units=u.m/u.s)
        def prt1_rule(m):
            return {'avar': m.dx}
        def prt2_rule(m):
            return {'avar': m.dy}
        m.prt1 = Port(rule=prt1_rule)
        m.prt2 = Port(rule=prt2_rule)
        def arcrule(m):
            return dict(source=m.prt1, destination=m.prt2)
        m.arc = Arc(rule=arcrule)

        # complementarities do not work yet
        # The expression system removes the u.m since it is multiplied by zero.
        # We need to change the units_container to allow 0 when comparing units 
        # m.compl = Complementarity(expr=complements(m.dx/m.t >= m.vx, m.dx == 0*u.m))

        assert_units_consistent(m)
Ejemplo n.º 17
0
def makeTwoTermDisj_boxes():
    m = ConcreteModel()
    m.x = Var(bounds=(0, 5))
    m.y = Var(bounds=(0, 5))

    def d_rule(disjunct, flag):
        m = disjunct.model()
        if flag:
            disjunct.c1 = Constraint(expr=inequality(1, m.x, 2))
            disjunct.c2 = Constraint(expr=inequality(3, m.y, 4))
        else:
            disjunct.c1 = Constraint(expr=inequality(3, m.x, 4))
            disjunct.c2 = Constraint(expr=inequality(1, m.y, 2))

    m.d = Disjunct([0, 1], rule=d_rule)

    def disj_rule(m):
        return [m.d[0], m.d[1]]

    m.disjunction = Disjunction(rule=disj_rule)
    m.obj = Objective(expr=m.x + 2 * m.y)
    return m
Ejemplo n.º 18
0
def makeTwoTermDisj_BlockOnDisj():
    """SimpleDisjunction where one of the Disjuncts contains three different 
    blocks: two simple and one indexed"""
    m = ConcreteModel()
    m.x = Var(bounds=(0, 1000))
    m.y = Var(bounds=(0, 800))

    def disj_rule(d, flag):
        m = d.model()
        if flag:
            d.b = Block()
            d.b.c = Constraint(expr=m.x == 0)
            d.add_component('b.c', Constraint(expr=m.y >= 9))
            d.b.anotherblock = Block()
            d.b.anotherblock.c = Constraint(expr=m.y >= 11)
            d.bb = Block([1])
            d.bb[1].c = Constraint(expr=m.x == 0)
        else:
            d.c = Constraint(expr=m.x >= 80)
    m.evil = Disjunct([0, 1], rule=disj_rule)
    m.disjunction = Disjunction(expr=[m.evil[0], m.evil[1]])
    return m
Ejemplo n.º 19
0
    def test_reclassify_deactivated_disjuncts(self):
        m = ConcreteModel()
        m.d = Disjunct([1, 2, 3])
        m.disjunction = Disjunction(expr=[m.d[1], m.d[2], m.d[3]])
        m.d[1].deactivate()
        m.d[2].indicator_var = True
        m.d[3].indicator_var = False

        TransformationFactory('gdp.fix_disjuncts').apply_to(m)

        self.assertTrue(m.d[1].indicator_var.fixed)
        self.assertFalse(value(m.d[1].indicator_var))
        self.assertFalse(m.d[1].active)
        self.assertEqual(m.d[1].ctype, Block)

        self.assertTrue(m.d[2].indicator_var.fixed)
        self.assertTrue(value(m.d[2].indicator_var))
        self.assertTrue(m.d[2].active)
        self.assertTrue(m.d[3].indicator_var.fixed)
        self.assertFalse(value(m.d[3].indicator_var))
        self.assertFalse(m.d[3].active)
        self.assertEqual(m.d[1].ctype, Block)
        self.assertEqual(m.d[2].ctype, Block)
Ejemplo n.º 20
0
def localVar():
    """Two-term disjunction which declares a local variable y on one of the 
    disjuncts, which is used in the objective function as well.

    Used to test that we will treat y as global in the transformations, 
    despite where it is declared.
    """
    # y appears in a global constraint and a single disjunct.
    m = ConcreteModel()
    m.x = Var(bounds=(0, 3))

    m.disj1 = Disjunct()
    m.disj1.cons = Constraint(expr=m.x >= 1)

    m.disj2 = Disjunct()
    m.disj2.y = Var(bounds=(1, 3))
    m.disj2.cons = Constraint(expr=m.x + m.disj2.y == 3)

    m.disjunction = Disjunction(expr=[m.disj1, m.disj2])

    # This makes y global actually... But in disguise.
    m.objective = Objective(expr=m.x + m.disj2.y)
    return m
Ejemplo n.º 21
0
def makeTwoTermDisj_IndexedConstraints():
    m = ConcreteModel()
    m.s = Set(initialize=[1, 2])
    m.a = Var(m.s)
    m.b = Block()

    def disj1_rule(disjunct):
        m = disjunct.model()

        def c_rule(d, s):
            return m.a[s] == 0
        disjunct.c = Constraint(m.s, rule=c_rule)
    m.b.simpledisj1 = Disjunct(rule=disj1_rule)

    def disj2_rule(disjunct):
        m = disjunct.model()

        def c_rule(d, s):
            return m.a[s] <= 3
        disjunct.c = Constraint(m.s, rule=c_rule)
    m.b.simpledisj2 = Disjunct(rule=disj2_rule)
    m.b.disjunction = Disjunction(expr=[m.b.simpledisj1, m.b.simpledisj2])
    return m
Ejemplo n.º 22
0
    def makeModel():
        m = ConcreteModel()
        m.x = Var(bounds=(0, 5))
        m.y = Var(bounds=(0, 5))

        def d_rule(disjunct, flag):
            m = disjunct.model()
            if flag:
                disjunct.c1 = Constraint(expr=1 <= m.x <= 2)
                disjunct.c2 = Constraint(expr=3 <= m.y <= 4)
            else:
                disjunct.c1 = Constraint(expr=3 <= m.x <= 4)
                disjunct.c2 = Constraint(expr=1 <= m.y <= 2)

        m.d = Disjunct([0, 1], rule=d_rule)

        def disj_rule(m):
            return [m.d[0], m.d[1]]

        m.disjunction = Disjunction(rule=disj_rule)

        m.obj = Objective(expr=m.x + 2 * m.y)
        return m
Ejemplo n.º 23
0
def makeDuplicatedNestedDisjunction():
    m = ConcreteModel()
    m.x = Var(bounds=(0, 8))

    def outerdisj_rule(d, flag):
        m = d.model()
        if flag:
            def innerdisj_rule(d, flag):
                m = d.model()
                if flag:
                    d.c = Constraint(expr=m.x >= 2)
                else:
                    d.c = Constraint(expr=m.x == 0)
            d.innerdisjunct = Disjunct([0, 1], rule=innerdisj_rule)
            d.innerdisjunction = Disjunction(expr=[d.innerdisjunct[0],
                                                   d.innerdisjunct[1]])
            d.duplicateddisjunction = Disjunction(expr=[d.innerdisjunct[0],
                                                        d.innerdisjunct[1]])
        else:
            d.c = Constraint(expr=m.x == 8)
    m.outerdisjunct = Disjunct([0, 1], rule=outerdisj_rule)
    m.disjunction = Disjunction(expr=[m.outerdisjunct[0],
                                      m.outerdisjunct[1]])
    return m
Ejemplo n.º 24
0
 def _apply_to(self, instance, **kwds):
     # TODO: This data should be stored differently.  We cannot nest this transformation with itself
     if getattr(instance, 'bilinear_data_', None) is None:
         instance.bilinear_data_ = Block()
         instance.bilinear_data_.cache = {}
         instance.bilinear_data_.vlist = VarList()
         instance.bilinear_data_.vlist_boolean = []
         instance.bilinear_data_.IDX = Set()
         instance.bilinear_data_.disjuncts_   = Disjunct(instance.bilinear_data_.IDX*[0,1])
         instance.bilinear_data_.disjunction_data = {}
         instance.bilinear_data_.o_expr = {}
         instance.bilinear_data_.c_body = {}
     #
     # Iterate over all blocks
     #
     for block in instance.block_data_objects(
             active=True, sort=SortComponents.deterministic ):
         self._transformBlock(block, instance)
     #
     # WEH: I wish I had a DisjunctList and DisjunctionList object...
     #
     def rule(block, i):
         return instance.bilinear_data_.disjunction_data[i]
     instance.bilinear_data_.disjunction_ = Disjunction(instance.bilinear_data_.IDX, rule=rule)
Ejemplo n.º 25
0
m.D2 = Disjunct(
    m.I, m.t)  # case where level in next tank is at or above inlet height
for t in m.t:
    for i in range(1, Ntank):
        disj = m.D2[i, t]
        disj.high_level = Constraint(expr=m.L[i + 1, t] >= m.H[i + 1])
        disj.high_dynamics = Constraint(expr=m.delL[i, t] == m.L[i, t] -
                                        (m.L[i + 1, t] - m.H[i + 1]))
        m.BigM[disj.high_level] = 0.3


def _disjunction_rule(m, i, t):
    return [m.D1[i, t], m.D2[i, t]]


m.djcn = Disjunction(m.I, m.t, rule=_disjunction_rule)

# add rate of change constraints to valve opening problem


@m.ConstraintList()
def RoC(m):
    t = 0
    for tplus in m.t:
        if tplus > 0:
            for i in m.I:
                yield (m.w[i, tplus] - m.w[i, t])**2 <= 0.04
            yield (m.w0[tplus] - m.w0[t])**2 <= 0.04
            t = tplus

Ejemplo n.º 26
0
def build_model(use_cafaro_approximation, num_stages):
    """Build the model."""
    m = common.build_model(use_cafaro_approximation, num_stages)

    # list of tuples (num_modules, module_size)
    configurations_list = []
    for size in m.module_sizes:
        configs = [(i + 1, size) for i in range(m.max_num_modules[size])]
        configurations_list += configs

    # Map of config indx: (# modules, module size)
    m.configurations_map = {(k + 1): v
                            for k, v in enumerate(configurations_list)}

    m.module_index_set = RangeSet(len(configurations_list))

    m.module_config_active = Var(
        m.valid_matches,
        m.stages,
        m.module_index_set,
        doc="Binary for if which module configuration is active for a match.",
        domain=Binary,
        initialize=0)

    @m.Param(m.module_index_set, doc="Area of each configuration")
    def module_area(m, indx):
        num_modules, size = m.configurations_map[indx]
        return num_modules * size

    @m.Param(m.valid_matches,
             m.module_index_set,
             doc="Area cost for each modular configuration.")
    def modular_size_cost(m, hot, cold, indx):
        num_modules, size = m.configurations_map[indx]
        return num_modules * m.module_area_cost[hot, cold, size]

    @m.Param(m.valid_matches,
             m.module_index_set,
             doc="Fixed cost for each modular exchanger size.")
    def modular_fixed_cost(m, hot, cold, indx):
        num_modules, size = m.configurations_map[indx]
        return num_modules * m.module_fixed_unit_cost

    m.LMTD_discretize = Var(m.hot_streams,
                            m.cold_streams,
                            m.stages,
                            m.module_index_set,
                            doc="Discretized log mean temperature difference",
                            bounds=(0, 500),
                            initialize=0)

    for hot, cold, stg in m.valid_matches * m.stages:
        disj = m.exchanger_exists[hot, cold, stg]
        disj.choose_one_config = Constraint(expr=sum(
            m.module_config_active[hot, cold, stg, indx]
            for indx in m.module_index_set) == 1)

        disj.exchanger_area_cost = Constraint(
            expr=m.exchanger_area_cost[stg, hot, cold] * 1E-3 == sum(
                m.modular_size_cost[hot, cold, indx] * 1E-3 *
                m.module_config_active[hot, cold, stg, indx]
                for indx in m.module_index_set))
        disj.exchanger_fixed_cost = Constraint(
            expr=m.exchanger_fixed_cost[stg, hot, cold] == sum(
                m.modular_fixed_cost[hot, cold, indx] * 1E-3 *
                m.module_config_active[hot, cold, stg, indx]
                for indx in m.module_index_set))

        disj.discretize_area = Constraint(
            expr=m.exchanger_area[stg, hot, cold] == sum(
                m.module_area[indx] *
                m.module_config_active[hot, cold, stg, indx]
                for indx in m.module_index_set))

        disj.discretized_LMTD = Constraint(expr=m.LMTD[hot, cold, stg] == sum(
            m.LMTD_discretize[hot, cold, stg, indx]
            for indx in m.module_index_set))

        @disj.Constraint(m.module_index_set)
        def discretized_LMTD_LB(disj, indx):
            return (m.LMTD[hot, cold, stg].lb *
                    m.module_config_active[hot, cold, stg, indx]
                    ) <= m.LMTD_discretize[hot, cold, stg, indx]

        @disj.Constraint(m.module_index_set)
        def discretized_LMTD_UB(disj, indx):
            return m.LMTD_discretize[hot, cold, stg, indx] <= (
                m.LMTD[hot, cold, stg].ub *
                m.module_config_active[hot, cold, stg, indx])

        disj.exchanger_required_area = Constraint(
            expr=m.U[hot, cold] *
            sum(m.module_area[indx] * m.LMTD_discretize[hot, cold, stg, indx]
                for indx in m.module_index_set) >= m.heat_exchanged[hot, cold,
                                                                    stg])

    @m.Disjunct(m.module_sizes)
    def module_type(disj, size):
        """Disjunct for selection of one module type."""
        @disj.Constraint(m.valid_matches, m.stages, m.module_index_set)
        def no_other_module_types(_, hot, cold, stg, indx):
            # num_modules, size = configurations_map[indx]
            if m.configurations_map[indx][1] != size:
                return m.module_config_active[hot, cold, stg, indx] == 0
            else:
                return Constraint.NoConstraint

        # disj.no_other_module_types = Constraint(
        #     expr=sum(
        #         m.module_config_active[hot, cold, stg, indx]
        #         for indx in m.module_index_set
        #         if m.configurations_map[indx][1] != size) == 0
        # )

    m.select_one_module_type = Disjunction(
        expr=[m.module_type[area] for area in m.module_sizes])

    return m
Ejemplo n.º 27
0
def build_model(use_cafaro_approximation, num_stages):
    """Build the model."""
    m = common.build_model(use_cafaro_approximation, num_stages)

    m.possible_sizes = Set(initialize=[10 * (i + 1) for i in range(50)])
    m.module_size_active = Var(
        m.valid_matches,
        m.stages,
        m.possible_sizes,
        doc="Total area of modular exchangers for each match.",
        domain=Binary,
        initialize=0)

    num_modules_required = {}
    for size in m.possible_sizes:
        # For each possible size, calculate the number of exchangers of each
        # area required to satisfy that size.
        # Use progressively smaller exchangers to satisfy the size
        remaining_size = size
        module_sizes = sorted(m.module_sizes, reverse=True)
        for area in module_sizes:
            num_modules_required[size, area] = remaining_size // area
            remaining_size = remaining_size % area

    @m.Param(m.valid_matches,
             m.possible_sizes,
             m.module_sizes,
             doc="Number of exchangers of each area required to "
             "yield a certain total size.")
    def modular_num_exchangers(m, hot, cold, size, area):
        return num_modules_required[size, area]

    @m.Param(m.valid_matches,
             m.possible_sizes,
             doc="Area cost for each modular exchanger size.")
    def modular_size_cost(m, hot, cold, size):
        return sum(m.modular_num_exchangers[hot, cold, size, area] *
                   m.module_area_cost[hot, cold, area]
                   for area in m.module_sizes)

    @m.Param(m.valid_matches,
             m.possible_sizes,
             doc="Fixed cost for each modular exchanger size.")
    def modular_fixed_cost(m, hot, cold, size):
        return sum(m.modular_num_exchangers[hot, cold, size, area] *
                   m.module_fixed_unit_cost for area in m.module_sizes)

    m.LMTD_discretize = Var(m.hot_streams,
                            m.cold_streams,
                            m.stages,
                            m.possible_sizes,
                            doc="Discretized log mean temperature difference",
                            bounds=(0, 500),
                            initialize=0)

    for hot, cold, stg in m.valid_matches * m.stages:
        disj = m.exchanger_exists[hot, cold, stg]
        disj.conventional = Disjunct()
        if not use_cafaro_approximation:
            disj.conventional.exchanger_area_cost = Constraint(
                expr=m.exchanger_area_cost[stg, hot, cold] *
                1E-3 >= m.exchanger_area_cost_factor[hot, cold] * 1E-3 *
                m.exchanger_area[stg, hot, cold]**m.area_cost_exponent)
        else:
            disj.conventional.exchanger_area_cost = Constraint(
                expr=m.exchanger_area_cost[stg, hot, cold] *
                1E-3 >= m.exchanger_area_cost_factor[hot, cold] * 1E-3 *
                m.cafaro_k *
                log(m.cafaro_b * m.exchanger_area[stg, hot, cold] + 1))
        m.BigM[disj.conventional.exchanger_area_cost] = 100

        disj.conventional.exchanger_fixed_cost = Constraint(
            expr=m.exchanger_fixed_cost[
                stg, hot, cold] == m.exchanger_fixed_unit_cost[hot, cold])

        @disj.conventional.Constraint(m.possible_sizes)
        def no_modules(_, size):
            return m.module_size_active[hot, cold, stg, size] == 0

        # Area requirement
        disj.conventional.exchanger_required_area = Constraint(
            expr=m.exchanger_area[stg, hot, cold] * m.U[hot, cold] *
            m.LMTD[hot, cold, stg] >= m.heat_exchanged[hot, cold, stg])
        m.BigM[disj.conventional.exchanger_required_area] = 5000

        disj.modular = Disjunct()
        disj.modular.choose_one_config = Constraint(expr=sum(
            m.module_size_active[hot, cold, stg, size]
            for size in m.possible_sizes) == 1)
        disj.modular.exchanger_area_cost = Constraint(
            expr=m.exchanger_area_cost[stg, hot, cold] * 1E-3 == sum(
                m.modular_size_cost[hot, cold, size] * 1E-3 *
                m.module_size_active[hot, cold, stg, size]
                for size in m.possible_sizes))
        disj.modular.exchanger_fixed_cost = Constraint(
            expr=m.exchanger_fixed_cost[stg, hot, cold] == sum(
                m.modular_fixed_cost[hot, cold, size] * 1E-3 *
                m.module_size_active[hot, cold, stg, size]
                for size in m.possible_sizes))

        disj.modular.discretize_area = Constraint(
            expr=m.exchanger_area[stg, hot, cold] == sum(
                area * m.module_size_active[hot, cold, stg, area]
                for area in m.possible_sizes))

        disj.modular.discretized_LMTD = Constraint(
            expr=m.LMTD[hot, cold, stg] == sum(m.LMTD_discretize[hot, cold,
                                                                 stg, size]
                                               for size in m.possible_sizes))

        @disj.modular.Constraint(m.possible_sizes)
        def discretized_LMTD_LB(disj, size):
            return (m.LMTD[hot, cold, stg].lb *
                    m.module_size_active[hot, cold, stg, size]
                    ) <= m.LMTD_discretize[hot, cold, stg, size]

        @disj.modular.Constraint(m.possible_sizes)
        def discretized_LMTD_UB(disj, size):
            return m.LMTD_discretize[hot, cold, stg, size] <= (
                m.LMTD[hot, cold, stg].ub *
                m.module_size_active[hot, cold, stg, size])

        disj.modular.exchanger_required_area = Constraint(
            expr=m.U[hot, cold] *
            sum(area * m.LMTD_discretize[hot, cold, stg, area]
                for area in m.possible_sizes) >= m.heat_exchanged[hot, cold,
                                                                  stg])

        disj.modular_or_not = Disjunction(
            expr=[disj.modular, disj.conventional])

    return m
Ejemplo n.º 28
0
    def test_construct_implicit_disjuncts(self):
        m = ConcreteModel()
        m.x = Var()
        m.y = Var()
        m.d = Disjunction(expr=[m.x <= 0, m.y >= 1])
        self.assertEqual(len(m.component_map(Disjunction)), 1)
        self.assertEqual(len(m.component_map(Disjunct)), 1)

        implicit_disjuncts = list(iterkeys(m.component_map(Disjunct)))
        self.assertEqual(implicit_disjuncts[0][:2], "d_")
        disjuncts = m.d.disjuncts
        self.assertEqual(len(disjuncts), 2)
        self.assertIs(disjuncts[0].parent_block(), m)
        self.assertIs(disjuncts[0].constraint[1].body, m.x)
        self.assertIs(disjuncts[1].parent_block(), m)
        self.assertIs(disjuncts[1].constraint[1].body, m.y)

        # Test that the implicit disjuncts get a unique name
        m.add_component('e_disjuncts', Var())
        m.e = Disjunction(expr=[m.y <= 0, m.x >= 1])
        self.assertEqual(len(m.component_map(Disjunction)), 2)
        self.assertEqual(len(m.component_map(Disjunct)), 2)
        implicit_disjuncts = list(iterkeys(m.component_map(Disjunct)))
        self.assertEqual(implicit_disjuncts[1][:12], "e_disjuncts_")
        disjuncts = m.e.disjuncts
        self.assertEqual(len(disjuncts), 2)
        self.assertIs(disjuncts[0].parent_block(), m)
        self.assertIs(disjuncts[0].constraint[1].body, m.y)
        self.assertIs(disjuncts[1].parent_block(), m)
        self.assertIs(disjuncts[1].constraint[1].body, m.x)
        self.assertEqual(len(disjuncts[0].parent_component().name), 13)
        self.assertEqual(disjuncts[0].name[:12], "e_disjuncts_")

        # Test that the implicit disjuncts can be lists/tuples/generators
        def _gen():
            yield m.y <= 4
            yield m.x >= 5

        m.f = Disjunction(expr=[[m.y <= 0, m.x >= 1], (
            m.y <= 2,
            m.x >= 3), _gen()])
        self.assertEqual(len(m.component_map(Disjunction)), 3)
        self.assertEqual(len(m.component_map(Disjunct)), 3)
        implicit_disjuncts = list(iterkeys(m.component_map(Disjunct)))
        self.assertEqual(implicit_disjuncts[2][:12], "f_disjuncts")
        disjuncts = m.f.disjuncts
        self.assertEqual(len(disjuncts), 3)
        self.assertIs(disjuncts[0].parent_block(), m)
        self.assertIs(disjuncts[0].constraint[1].body, m.y)
        self.assertEqual(disjuncts[0].constraint[1].upper, 0)
        self.assertIs(disjuncts[0].constraint[2].body, m.x)
        self.assertEqual(disjuncts[0].constraint[2].lower, 1)

        self.assertIs(disjuncts[1].parent_block(), m)
        self.assertIs(disjuncts[1].constraint[1].body, m.y)
        self.assertEqual(disjuncts[1].constraint[1].upper, 2)
        self.assertIs(disjuncts[1].constraint[2].body, m.x)
        self.assertEqual(disjuncts[1].constraint[2].lower, 3)

        self.assertIs(disjuncts[2].parent_block(), m)
        self.assertIs(disjuncts[2].constraint[1].body, m.y)
        self.assertEqual(disjuncts[2].constraint[1].upper, 4)
        self.assertIs(disjuncts[2].constraint[2].body, m.x)
        self.assertEqual(disjuncts[2].constraint[2].lower, 5)

        self.assertEqual(len(disjuncts[0].parent_component().name), 11)
        self.assertEqual(disjuncts[0].name, "f_disjuncts[0]")
Ejemplo n.º 29
0
def build_nonexclusive_model():
    m = ConcreteModel()
    m.streams = RangeSet(25)
    m.x = Var(m.streams, bounds=(0, 50), initialize=5)

    m.stage1_split = Constraint(expr=m.x[1] == m.x[2] + m.x[4])
    m.unit1 = Disjunction(expr=[
        [
            # Unit 1
            m.x[2] == exp(m.x[3]) - 1,
        ],
        [
            # No Unit 1
            m.x[2] == 0, m.x[3] == 0
        ]
    ])
    m.unit2 = Disjunction(expr=[
        [
            # Unit 2
            m.x[5] == log(m.x[4] + 1),
        ],
        [
            # No Unit 2
            m.x[4] == 0, m.x[5] == 0
        ]
    ])
    m.stage1_mix = Constraint(expr=m.x[3] + m.x[5] == m.x[6])
    m.stage2_split = Constraint(expr=m.x[6] == sum(m.x[i] for i in (7, 9, 11, 13)))
    m.unit3 = Disjunction(expr=[
        [
            # Unit 3
            m.x[8] == 2 * log(m.x[7]) + 3,
            m.x[7] >= 0.2,
        ],
        [
            # No Unit 3
            m.x[7] == 0, m.x[8] == 0
        ]
    ])
    m.unit4 = Disjunction(expr=[
        [
            # Unit 4
            m.x[10] == 1.8 * log(m.x[9] + 4),
        ],
        [
            # No Unit 4
            m.x[9] == 0, m.x[10] == 0
        ]
    ])
    m.unit5 = Disjunction(expr=[
        [
            # Unit 5
            m.x[12] == 1.2 * log(m.x[11]) + 2,
            m.x[11] >= 0.001,
        ],
        [
            # No Unit 5
            m.x[11] == 0, m.x[12] == 0
        ]
    ])
    m.unit6 = Disjunction(expr=[
        [
            # Unit 6
            m.x[15] == sqrt(m.x[14] - 3) * m.x[23] + 1,
            m.x[14] >= 5, m.x[14] <= 20,
        ],
        [
            # No Unit 6
            m.x[14] == 0, m.x[15] == 0
        ]
    ])
    m.stage2_special_mix = Constraint(expr=m.x[14] == m.x[13] + m.x[23])
    m.stage2_mix = Constraint(expr=sum(m.x[i] for i in (8, 10, 12, 15)) == m.x[16])
    m.stage3_split = Constraint(expr=m.x[16] == sum(m.x[i] for i in (17, 19, 21)))
    m.unit7 = Disjunction(expr=[
        [
            # Unit 7
            m.x[18] == m.x[17] * 0.9,
        ],
        [
            # No Unit 7
            m.x[17] == 0, m.x[18] == 0
        ]
    ])
    m.unit8 = Disjunction(expr=[
        [
            # Unit 8
            m.x[20] == log(m.x[19] ** 1.5) + 2,
            m.x[19] >= 1,
        ],
        [
            # No Unit 8
            m.x[19] == 0, m.x[20] == 0
        ]
    ])
    m.unit9 = Disjunction(expr=[
        [
            # Unit 9
            m.x[22] == log(m.x[21] + sqrt(m.x[21])) + 1,
            m.x[21] >= 4,
        ],
        [
            # No Unit 9
            m.x[21] == 0, m.x[22] == 0
        ]
    ])
    m.stage3_special_split = Constraint(expr=m.x[22] == m.x[23] + m.x[24])
    m.stage3_mix = Constraint(expr=m.x[25] == sum(m.x[i] for i in (18, 20, 24)))

    m.obj = Objective(expr=-10 * m.x[25] + m.x[1])

    return m
Ejemplo n.º 30
0
def build_model():
    """
    Base Model

    Optimal solution:
    Select units 1, 3, 8
    Objective value -36.62
    """
    m = ConcreteModel()
    m.streams = RangeSet(25)
    m.x = Var(m.streams, bounds=(0, 50), initialize=5)

    m.stage1_split = Constraint(expr=m.x[1] == m.x[2] + m.x[4])
    m.first_stage = Disjunction(expr=[
        [
            # Unit 1
            m.x[2] == exp(m.x[3]) - 1,
            m.x[4] == 0, m.x[5] == 0
        ],
        [
            # Unit 2
            m.x[5] == log(m.x[4] + 1),
            m.x[2] == 0, m.x[3] == 0
        ]
    ])
    m.stage1_mix = Constraint(expr=m.x[3] + m.x[5] == m.x[6])
    m.stage2_split = Constraint(expr=m.x[6] == sum(m.x[i] for i in (7, 9, 11, 13)))
    m.second_stage = Disjunction(expr=[
        [
            # Unit 3
            m.x[8] == 2 * log(m.x[7]) + 3,
            m.x[7] >= 0.2,
        ] + [m.x[i] == 0 for i in (9, 10, 11, 12, 14, 15)],
        [
            # Unit 4
            m.x[10] == 1.8 * log(m.x[9] + 4),
        ] + [m.x[i] == 0 for i in (7, 8, 11, 12, 14, 15)],
        [
            # Unit 5
            m.x[12] == 1.2 * log(m.x[11]) + 2,
            m.x[11] >= 0.001,
        ] + [m.x[i] == 0 for i in (7, 8, 9, 10, 14, 15)],
        [
            # Unit 6
            m.x[15] == sqrt(m.x[14] - 3) * m.x[23] + 1,
            m.x[14] >= 5, m.x[14] <= 20,
        ] + [m.x[i] == 0 for i in (7, 8, 9, 10, 11, 12)]
    ])
    m.stage2_special_mix = Constraint(expr=m.x[14] == m.x[13] + m.x[23])
    m.stage2_mix = Constraint(expr=sum(m.x[i] for i in (8, 10, 12, 15)) == m.x[16])
    m.stage3_split = Constraint(expr=m.x[16] == sum(m.x[i] for i in (17, 19, 21)))
    m.third_stage = Disjunction(expr=[
        [
            # Unit 7
            m.x[18] == m.x[17] * 0.9,
        ] + [m.x[i] == 0 for i in (19, 20, 21, 22)],
        [
            # Unit 8
            m.x[20] == log(m.x[19] ** 1.5) + 2,
            m.x[19] >= 1,
        ] + [m.x[i] == 0 for i in (17, 18, 21, 22)],
        [
            # Unit 9
            m.x[22] == log(m.x[21] + sqrt(m.x[21])) + 1,
            m.x[21] >= 4,
        ] + [m.x[i] == 0 for i in (17, 18, 19, 20)]
    ])
    m.stage3_special_split = Constraint(expr=m.x[22] == m.x[23] + m.x[24])
    m.stage3_mix = Constraint(expr=m.x[25] == sum(m.x[i] for i in (18, 20, 24)))

    m.obj = Objective(expr=-10 * m.x[25] + m.x[1])

    return m