def CreateAbstractScenarioTreeModel():
    from pyomo.core import (AbstractModel, Set, Param, Boolean)

    model = AbstractModel()

    # all set/parameter values are strings, representing the
    # names of various entities/variables.

    model.Stages = Set(ordered=True)
    model.Nodes = Set(ordered=True)

    model.NodeStage = Param(model.Nodes, within=model.Stages, mutable=True)
    model.Children = Set(model.Nodes,
                         within=model.Nodes,
                         initialize=[],
                         ordered=True)
    model.ConditionalProbability = Param(model.Nodes, mutable=True)

    model.Scenarios = Set(ordered=True)
    model.ScenarioLeafNode = Param(model.Scenarios,
                                   within=model.Nodes,
                                   mutable=True)

    model.StageVariables = Set(model.Stages, initialize=[], ordered=True)

    model.NodeVariables = Set(model.Nodes, initialize=[], ordered=True)

    model.StageCost = Param(model.Stages, mutable=True)
    # DEPRECATED
    model.StageCostVariable = Param(model.Stages, mutable=True)

    # it is often the case that a subset of the stage variables are strictly "derived"
    # variables, in that their values are computable once the values of other variables
    # in that stage are known. it generally useful to know which variables these are,
    # as it is unnecessary to post non-anticipativity constraints for these variables.
    # further, attempting to force non-anticipativity - either implicitly or explicitly -
    # on these variables can cause issues with decomposition algorithms.
    model.StageDerivedVariables = Set(model.Stages,
                                      initialize=[],
                                      ordered=True)
    model.NodeDerivedVariables = Set(model.Nodes, initialize=[], ordered=True)

    # scenario data can be populated in one of two ways. the first is "scenario-based",
    # in which a single .dat file contains all of the data for each scenario. the .dat
    # file prefix must correspond to the scenario name. the second is "node-based",
    # in which a single .dat file contains only the data for each node in the scenario
    # tree. the node-based method is more compact, but the scenario-based method is
    # often more natural when parameter data is generated via simulation. the default
    # is scenario-based.
    model.ScenarioBasedData = Param(within=Boolean, default=True, mutable=True)

    # do we bundle, and if so, how?
    model.Bundling = Param(within=Boolean, default=False, mutable=True)

    # bundle names
    model.Bundles = Set(ordered=True)
    model.BundleScenarios = Set(model.Bundles, ordered=True)

    return model
Ejemplo n.º 2
0
    def create_abstract_model(self):
        """Build the model <b>object</b>."""
        if not self.built:

            def jk_init(m):
                return [(j, k) for j in m.J for k in m.K[j]]

            model = AbstractModel()
            model.J = Set()
            model.K = Set(model.J)
            model.JK = Set(initialize=jk_init, dimen=None)
            model.y_pred = Param()
            model.epsilon = Param()
            model.max_cost = Var()
            model.w = Param(model.J)
            model.a = Param(model.JK)
            model.c = Param(model.JK)
            model.u = Var(model.JK, within=Binary)

            # Make sure only one action is on at a time.
            def c1Rule(m, j):
                return sum([m.u[j, k] for k in m.K[j]]) == 1

            # 2.b: Action sets must flip the prediction of a linear classifier.
            def c2Rule(m):
                return sum((m.u[j, k] * m.a[j, k] * m.w[j])
                           for j, k in m.JK) >= -m.y_pred

            # instantiate max cost
            def maxcost_rule(m, j, k):
                return m.max_cost >= (m.u[j, k] * m.c[j, k])

            # Set up objective for total sum.
            def obj_rule_percentile(m):
                return sum(m.u[j, k] * m.c[j, k] for j, k in m.JK)

            # Set up objective for max cost.
            def obj_rule_max(m):
                return sum(m.epsilon * m.u[j, k] * m.c[j, k]
                           for j, k in m.JK) + (1 - m.epsilon) * m.max_cost

            ## set up objective function.
            if self.mip_cost_type == "max":
                model.g = Objective(rule=obj_rule_max, sense=minimize)
                model.c3 = Constraint(model.JK, rule=maxcost_rule)
            else:
                model.g = Objective(rule=obj_rule_percentile, sense=minimize)

            ##
            model.c1 = Constraint(model.J, rule=c1Rule)
            model.c2 = Constraint(rule=c2Rule)
            self.model = model
            self.built = True

        return self.model
Ejemplo n.º 3
0
 def _create_model(self, ctype, **kwds):
     self.model = ConcreteModel()
     self.model.x = Var()
     self.model.IDX = Set(initialize=sorted(range(1000000)))
     self.model.del_component('test_component')
     self.model.test_component = \
         ctype(self.model.IDX, **kwds)
Ejemplo n.º 4
0
    def _create(self, group=None):
        """ Creates set, variables, constraints for all flow object with
        a attribute flow of type class:`.DiscreteFlow`.

        Parameters
        ----------
        group : list
            List of oemof.solph.DiscreteFlow objects for which
            the constraints are build.
        """
        if group is None:
            return None

        m = self.parent_block()
        # ########################## SETS #####################################
        self.DISCRETE_FLOWS = Set(initialize=[(g[0], g[1]) for g in group])

        self.discrete_flow = Var(self.DISCRETE_FLOWS,
                                 m.TIMESTEPS,
                                 within=NonNegativeIntegers)

        def _discrete_flow_rule(block, i, o, t):
            """Force flow variable to discrete (NonNegativeInteger) values.
            """
            expr = (self.discrete_flow[i, o, t] == m.flow[i, o, t])
            return expr

        self.integer_flow = Constraint(self.DISCRETE_FLOWS,
                                       m.TIMESTEPS,
                                       rule=_discrete_flow_rule)
Ejemplo n.º 5
0
    def test_indexedvar_noindextemplate(self):
        st_model = CreateConcreteTwoStageScenarioTreeModel(1)
        st_model.StageVariables['Stage1'].add("x")
        st_model.StageDerivedVariables['Stage1'].add("y")
        st_model.NodeVariables['RootNode'].add("z")
        st_model.NodeDerivedVariables['RootNode'].add("q")
        st_model.StageCost['Stage1'] = "FirstStageCost"
        st_model.StageCost['Stage2'] = "SecondStageCost"

        scenario_tree = ScenarioTree(scenariotreeinstance=st_model)
        self.assertEqual(len(scenario_tree.stages), 2)
        self.assertEqual(len(scenario_tree.nodes), 2)
        self.assertEqual(len(scenario_tree.scenarios), 1)

        model = ConcreteModel()
        model.s = Set(initialize=[1, 2, 3])
        model.x = Var(model.s)
        model.y = Var(model.s)
        model.z = Var(model.s)
        model.q = Var(model.s)
        model.FirstStageCost = Expression(expr=0.0)
        model.SecondStageCost = Expression(expr=0.0)
        model.obj = Objective(expr=0.0)

        scenario_tree.linkInInstances({'Scenario1': model})

        root = scenario_tree.findRootNode()
        self.assertEqual(len(root._variable_ids), 12)
        self.assertEqual(len(root._standard_variable_ids), 6)
        self.assertEqual(len(root._derived_variable_ids), 6)
        for name in ("x", "y", "z", "q"):
            for index in model.s:
                self.assertEqual((name, index) in root._name_index_to_id, True)
Ejemplo n.º 6
0
def create_nodal_ph_parameters(scenario_tree):

    for stage in scenario_tree._stages[:-1]:

        for tree_node in stage._tree_nodes:

            new_nodal_index_set_name = "PHINDEX_" + str(tree_node._name)
            new_xbar_parameter_name = "PHXBAR_" + str(tree_node._name)
            new_blend_parameter_name = "PHBLEND_" + str(tree_node._name)

            # only create nodal index sets for non-derived variables.
            new_nodal_index_set = Set(name=new_nodal_index_set_name,
                                      initialize=list(
                                          tree_node._standard_variable_ids))

            for scenario in tree_node._scenarios:
                instance = scenario._instance

                # avoid the warnings generated by adding Set to
                # multiple components, and learn to live with the fact
                # that these Params will point to some arbitrary
                # instance as their "parent" in the end
                new_nodal_index_set._parent = None

                # Add the shared parameter to the instance
                instance.add_component(new_nodal_index_set_name,
                                       new_nodal_index_set)

            ### dlw Jan 2014 nochecking=True, mutable=True)
            new_xbar_parameter = Param(new_nodal_index_set,
                                       name=new_xbar_parameter_name,
                                       default=0.0,
                                       mutable=True)
            ### dlw Jan 2014 nochecking=True, mutable=True)
            new_blend_parameter = Param(new_nodal_index_set,
                                        name=new_blend_parameter_name,
                                        within=Binary,
                                        default=False,
                                        mutable=True)

            for scenario in tree_node._scenarios:
                instance = scenario._instance

                # avoid the warnings generated by adding Param to
                # multiple components, and learn to live with the fact
                # that these Params will point to some arbitrary
                # instance as their "parent" in the end
                new_xbar_parameter._parent = None
                new_blend_parameter._parent = None

                # Add the shared parameter to the instance
                instance.add_component(new_xbar_parameter_name,
                                       new_xbar_parameter)
                instance.add_component(new_blend_parameter_name,
                                       new_blend_parameter)

            new_xbar_parameter.store_values(0.0)
            tree_node._xbars.update(dict.fromkeys(tree_node._xbars, 0.0))
            new_blend_parameter.store_values(1)
            tree_node._blend.update(dict.fromkeys(tree_node._blend, 1))
Ejemplo n.º 7
0
def makeTwoTermDisj_IndexedConstraints_BoundedVars():
    # same concept as above, but bounded variables
    m = ConcreteModel()
    m.s = Set(initialize=[1, 2])
    m.lbs = Param(m.s, initialize={1: 2, 2: 4})
    m.ubs = Param(m.s, initialize={1: 7, 2: 6})

    def bounds_rule(m, s):
        return (m.lbs[s], m.ubs[s])

    m.a = Var(m.s, bounds=bounds_rule)

    def d_rule(disjunct, flag):
        m = disjunct.model()

        def true_rule(d, s):
            return m.a[s] == 0

        def false_rule(d, s):
            return m.a[s] >= 5

        if flag:
            disjunct.c = Constraint(m.s, rule=true_rule)
        else:
            disjunct.c = Constraint(m.s, rule=false_rule)

    m.disjunct = Disjunct([0, 1], rule=d_rule)
    m.disjunction = Disjunction(expr=[m.disjunct[0], m.disjunct[1]])
    return m
Ejemplo n.º 8
0
    def _generate_model(self):
        self.model = ConcreteModel()
        model = self.model
        model._name = self.description

        model.s = Set(initialize=[1,2])
        model.x = Var()
        model.y = Var()
        model.z = Var(bounds=(0,None))

        model.obj = Objective(model.s,
                              rule=inactive_index_LP_obj_rule)
        model.OBJ = Objective(expr=model.x+model.y)
        model.obj[1].deactivate()
        model.OBJ.deactivate()
        model.c1 = ConstraintList()
        model.c1.add(model.x<=1)   # index=1
        model.c1.add(model.x>=-1)  # index=2
        model.c1.add(model.y<=1)   # index=3
        model.c1.add(model.y>=-1)  # index=4
        model.c1[1].deactivate()
        model.c1[4].deactivate()
        model.c2 = Constraint(model.s,
                              rule=inactive_index_LP_c2_rule)

        model.b = Block()
        model.b.c = Constraint(expr=model.z >= 2)
        model.B = Block(model.s)
        model.B[1].c = Constraint(expr=model.z >= 3)
        model.B[2].c = Constraint(expr=model.z >= 1)

        model.b.deactivate()
        model.B.deactivate()
        model.B[2].activate()
Ejemplo n.º 9
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.º 10
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.º 11
0
    def test_construct(self):
        model = AbstractModel()
        model.a = Set(initialize=[1, 2, 3])
        model.A = Param(initialize=1)
        model.B = Param(model.a)
        model.x = Var(initialize=1, within=Reals, dense=False)
        model.y = Var(model.a, initialize=1, within=Reals, dense=False)
        model.obj = Objective(rule=lambda model: model.x + model.y[1])
        model.obj2 = Objective(model.a,
                               rule=lambda model, i: i + model.x + model.y[1])
        model.con = Constraint(rule=rule1)
        model.con2 = Constraint(model.a, rule=rule2)
        instance = model.create_instance()
        expr = instance.x + 1

        OUTPUT = open(currdir + "/display.out", "w")
        display(instance, ostream=OUTPUT)
        display(instance.obj, ostream=OUTPUT)
        display(instance.x, ostream=OUTPUT)
        display(instance.con, ostream=OUTPUT)
        OUTPUT.write(expr.to_string())
        model = AbstractModel()
        instance = model.create_instance()
        display(instance, ostream=OUTPUT)
        OUTPUT.close()
        try:
            display(None)
            self.fail("test_construct - expected TypeError")
        except TypeError:
            pass
        self.assertFileEqualsBaseline(currdir + "/display.out",
                                      currdir + "/display.txt")
Ejemplo n.º 12
0
    def test_construct2(self):
        model = AbstractModel()
        model.a = Set(initialize=[1,2,3])
        model.A = Param(initialize=1)
        model.B = Param(model.a)
        model.x = Var(initialize=1, within=Reals, dense=True)
        model.y = Var(model.a, initialize=1, within=Reals, dense=True)
        model.obj = Objective(rule=lambda model: model.x+model.y[1])
        model.obj2 = Objective(model.a,rule=lambda model, i: i+model.x+model.y[1])
        model.con = Constraint(rule=rule1)
        model.con2 = Constraint(model.a, rule=rule2)
        instance = model.create_instance()
        expr = instance.x + 1

        OUTPUT = open(join(currdir, "display2.out"), "w")
        display(instance,ostream=OUTPUT)
        display(instance.obj,ostream=OUTPUT)
        display(instance.x,ostream=OUTPUT)
        display(instance.con,ostream=OUTPUT)
        OUTPUT.write(expr.to_string())
        model = AbstractModel()
        instance = model.create_instance()
        display(instance,ostream=OUTPUT)
        OUTPUT.close()
        try:
            display(None)
            self.fail("test_construct - expected TypeError")
        except TypeError:
            pass
        _out, _txt = join(currdir, "display2.out"), join(currdir, "display2.txt")
        self.assertTrue(cmp(_out, _txt),
                        msg="Files %s and %s differ" % (_out, _txt))
Ejemplo n.º 13
0
def makeTwoTermDisj_IndexedConstraints_BoundedVars():
    """Single two-term disjunction with IndexedConstraints on both disjuncts. 
    """
    m = ConcreteModel()
    m.s = Set(initialize=[1, 2])
    m.lbs = Param(m.s, initialize={1: 2, 2: 4})
    m.ubs = Param(m.s, initialize={1: 7, 2: 6})

    def bounds_rule(m, s):
        return (m.lbs[s], m.ubs[s])

    m.a = Var(m.s, bounds=bounds_rule)

    def d_rule(disjunct, flag):
        m = disjunct.model()

        def true_rule(d, s):
            return m.a[s] == 0

        def false_rule(d, s):
            return m.a[s] >= 5

        if flag:
            disjunct.c = Constraint(m.s, rule=true_rule)
        else:
            disjunct.c = Constraint(m.s, rule=false_rule)

    m.disjunct = Disjunct([0, 1], rule=d_rule)
    m.disjunction = Disjunction(expr=[m.disjunct[0], m.disjunct[1]])
    return m
Ejemplo n.º 14
0
def EXTERNAL_initialize_for_admm(manager, scenario):
    if manager.get_option("verbose"):
        print("Initializing scenario %s for admm algorithm" % (scenario.name))
    admm_block = Block(concrete=True)
    assert not hasattr(scenario._instance, ".admm")
    scenario._instance.add_component(".admm", admm_block)

    # Augment the objective with lagrangian and penalty terms
    # and weight the original objective by the scenario probability.
    # The langrangian and penalty terms will be computed after
    # the parameters are created.
    user_cost_expression = scenario._instance_cost_expression
    admm_block.cost_expression = Expression(initialize=\
        scenario.probability * user_cost_expression)
    admm_block.lagrangian_expression = Expression(initialize=0.0)
    admm_block.penalty_expression = Expression(initialize=0.0)
    # these are used in the objective, they can be toggled
    # between the expression above or something else (e.g., 0.0)
    admm_block.cost_term = Expression(initialize=admm_block.cost_expression)
    admm_block.lagrangian_term = Expression(
        initialize=admm_block.lagrangian_expression)
    admm_block.penalty_term = Expression(
        initialize=admm_block.penalty_expression)
    objective_direction = 1
    if manager.objective_sense == maximize:
        objective_direction = -1
    scenario._instance_objective.expr = \
        admm_block.cost_term + \
        admm_block.lagrangian_term * objective_direction + \
        admm_block.penalty_term * objective_direction

    # add objective parameters to admm block
    for tree_node in scenario.node_list[:-1]:
        assert not tree_node.is_leaf_node()
        node_block = Block(concrete=True)
        admm_block.add_component(tree_node.name, node_block)
        node_block.node_index_set = Set(ordered=True,
                                        initialize=sorted(
                                            tree_node._standard_variable_ids))
        node_block.z = Param(node_block.node_index_set,
                             initialize=0.0,
                             mutable=True)
        node_block.y = Param(node_block.node_index_set,
                             initialize=0.0,
                             mutable=True)
        node_block.rho = Param(node_block.node_index_set,
                               initialize=0.0,
                               mutable=True)

        for id_ in node_block.node_index_set:
            varname, index = tree_node._variable_ids[id_]
            var = scenario._instance.find_component(varname)[index]
            admm_block.lagrangian_expression.expr += \
                node_block.y[id_] * (var - node_block.z[id_])
            admm_block.penalty_expression.expr += \
                (node_block.rho[id_] / 2.0) * (var - node_block.z[id_])**2

    # The objective has changed so flag this if necessary.
    if manager.preprocessor is not None:
        manager.preprocessor.objective_updated[scenario.name] = True
Ejemplo n.º 15
0
def makeAnyIndexedDisjunctionOfDisjunctDatas():
    """An IndexedDisjunction indexed by Any, with two two-term DisjunctionDatas
    build from DisjunctDatas. Identical mathematically to 
    makeDisjunctionOfDisjunctDatas.

    Used to test that the right things happen for a case where soemone
    implements an algorithm which iteratively generates disjuncts and 
    retransforms"""
    m = ConcreteModel()
    m.x = Var(bounds=(-100, 100))

    m.obj = Objective(expr=m.x)

    m.idx = Set(initialize=[1, 2])
    m.firstTerm = Disjunct(m.idx)
    m.firstTerm[1].cons = Constraint(expr=m.x == 0)
    m.firstTerm[2].cons = Constraint(expr=m.x == 2)
    m.secondTerm = Disjunct(m.idx)
    m.secondTerm[1].cons = Constraint(expr=m.x >= 2)
    m.secondTerm[2].cons = Constraint(expr=m.x >= 3)

    m.disjunction = Disjunction(Any)
    m.disjunction[1] = [m.firstTerm[1], m.secondTerm[1]]
    m.disjunction[2] = [m.firstTerm[2], m.secondTerm[2]]
    return m
Ejemplo n.º 16
0
def makeTwoTermDisj_IndexedConstraints():
    """Single two-term disjunction with IndexedConstraints on both disjuncts.  
    Does not bound the variables, so cannot be transformed by hull at all and 
    requires specifying m values in bigm.
    """
    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.º 17
0
def makeTwoTermIndexedDisjunction():
    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.º 18
0
def makeTwoTermMultiIndexedDisjunction():
    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.º 19
0
 def __init__(self, **kwargs):
     """Constructor"""
     args = (Set(), )
     self._nconditions = 0
     Complementarity.__init__(self, *args, **kwargs)
     # disable the implicit rule; construct will exhaust the
     # user-provided rule, and then subsequent attempts to add a CC
     # will bypass the rule
     self._rule = None
Ejemplo n.º 20
0
 def _get_block_model(self):
     model = ConcreteModel()
     model.s = Set(initialize=[1, 2])
     b = Block(concrete=True)
     b.s = Set(initialize=[1, 2])
     b.x = Var()
     b.X = Var(model.s)
     model.b1 = b.clone()
     model.b2 = b.clone()
     model.b3 = b.clone()
     model.b4 = b.clone()
     model.B1 = Block(model.s, rule=lambda _, i: b.clone())
     model.B2 = Block(model.s, rule=lambda _, i: b.clone())
     model.B3 = Block(model.s, rule=lambda _, i: b.clone())
     model.B4 = Block(model.s, rule=lambda _, i: b.clone())
     model.FirstStageCost = Expression(expr=0.0)
     model.SecondStageCost = Expression(expr=0.0)
     model.obj = Objective(expr=0.0)
     return model
Ejemplo n.º 21
0
    def _create(self, group=None):
        """
        Parameters
        ----------
        group : list
            List containing storage objects.
            e.g. groups=[storage1, storage2,..]
        """
        m = self.parent_block()

        if group is None:
            return None

        I = {n: [i for i in n.inputs][0] for n in group}
        O = {n: [o for o in n.outputs][0] for n in group}

        self.STORAGES = Set(initialize=[n for n in group])

        def _storage_capacity_bound_rule(block, n, t):
            """Rule definition for bounds of capacity variable of storage n
            in timestep t
            """
            bounds = (n.nominal_capacity * n.capacity_min[t],
                      n.nominal_capacity * n.capacity_max[t])
            return bounds

        self.capacity = Var(self.STORAGES,
                            m.TIMESTEPS,
                            bounds=_storage_capacity_bound_rule)

        # set the initial capacity of the storage
        for n in group:
            if n.initial_capacity is not None:
                self.capacity[n, m.timesteps[-1]] = (n.initial_capacity *
                                                     n.nominal_capacity)
                self.capacity[n, m.timesteps[-1]].fix()

        # storage balance constraint
        def _storage_balance_rule(block, n, t):
            """Rule definition for the storage balance of every storage n and
            timestep t
            """
            expr = 0
            expr += block.capacity[n, t]
            expr += -block.capacity[n, m.previous_timesteps[t]] * (
                1 - n.capacity_loss[t])
            expr += (-m.flow[I[n], n, t] *
                     n.inflow_conversion_factor[t]) * m.timeincrement[t]
            expr += (m.flow[n, O[n], t] /
                     n.outflow_conversion_factor[t]) * m.timeincrement[t]
            return expr == 0

        self.balance = Constraint(self.STORAGES,
                                  m.TIMESTEPS,
                                  rule=_storage_balance_rule)
Ejemplo n.º 22
0
    def _add_transformation_block(self, instance):
        # make a transformation block on instance to put transformed disjuncts
        # on
        transBlockName = unique_component_name(instance,
                                               '_pyomo_gdp_bigm_relaxation')
        transBlock = Block()
        instance.add_component(transBlockName, transBlock)
        transBlock.relaxedDisjuncts = Block(NonNegativeIntegers)
        transBlock.lbub = Set(initialize=['lb', 'ub'])

        return transBlock
Ejemplo n.º 23
0
def _process_bilinear_constraints(block, v1, v2, var_values, bilinear_constrs):
    # TODO check that the appropriate variable bounds exist.
    if not (v2.has_lb() and v2.has_ub()):
        logger.warning(
            textwrap.dedent("""\
            Attempting to transform bilinear term {v1} * {v2} using effectively
            discrete variable {v1}, but {v2} is missing a lower or upper bound:
            ({v2lb}, {v2ub}).
            """.format(v1=v1, v2=v2, v2lb=v2.lb, v2ub=v2.ub)).strip())
        return False
    blk = Block()
    unique_name = unique_component_name(
        block, ("%s_%s_bilinear" % (v1.local_name, v2.local_name)).replace(
            '[', '').replace(']', ''))
    block._induced_linearity_info.add_component(unique_name, blk)
    # TODO think about not using floats as indices in a set
    blk.valid_values = Set(initialize=sorted(var_values))
    blk.x_active = Var(blk.valid_values, domain=Binary, initialize=1)
    blk.v_increment = Var(blk.valid_values,
                          domain=v2.domain,
                          bounds=(v2.lb, v2.ub),
                          initialize=v2.value)
    blk.v_defn = Constraint(expr=v2 == summation(blk.v_increment))

    @blk.Constraint(blk.valid_values)
    def v_lb(blk, val):
        return v2.lb * blk.x_active[val] <= blk.v_increment[val]

    @blk.Constraint(blk.valid_values)
    def v_ub(blk, val):
        return blk.v_increment[val] <= v2.ub * blk.x_active[val]

    blk.select_one_value = Constraint(expr=summation(blk.x_active) == 1)
    # Categorize as case 1 or case 2
    for bilinear_constr in bilinear_constrs:
        # repn = generate_standard_repn(bilinear_constr.body)

        # Case 1: no other variables besides bilinear term in constraint. v1
        # (effectively discrete variable) is positive.
        # if (len(repn.quadratic_vars) == 1 and len(repn.linear_vars) == 0
        #         and repn.nonlinear_expr is None):
        #     _reformulate_case_1(v1, v2, discrete_constr, bilinear_constr)

        # NOTE: Case 1 is left unimplemented for now, because it involves some
        # messier logic with respect to how the transformation needs to happen.

        # Case 2: this is everything else, but do we want to have a special
        # case if there are nonlinear expressions involved with the constraint?
        pass
        _reformulate_case_2(blk, v1, v2, bilinear_constr)
    pass
Ejemplo n.º 24
0
def makeTwoTermIndexedDisjunction_BoundedVars():
    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.º 25
0
    def add_cut(self, first=False):
        self._iter += 1
        model = self._model

        self._wprod[self._iter] = self._compute_weight_weight_inner_product()
        if first is True:
            self._alphas[self._iter] = -(
                self._compute_objective_term() +
                (self._ph._rho / 2.0) * self._wprod[self._iter])
        else:
            self._alphas[self._iter] = -(self._compute_objective_term(
            )) + self._compute_xbar_weight_inner_product()

        if self._solved is True:
            if self._compute_convergence() is True:
                return True

        model.del_component('cuts')
        model.cuts = Set(initialize=sorted(self._alphas.keys()))
        model.del_component('beta')
        model.beta = Var(model.cuts, within=NonNegativeReals)
        model.del_component('beta_sum_one')
        model.beta_sum_one = Constraint(expr=sum_product(model.beta) == 1)
        model.del_component('obj')
        model.obj = Objective(expr=sum(self._alphas[i] * model.beta[i]
                                       for i in model.cuts))

        self._wbars[self._iter] = {}
        for stage in self._ph._scenario_tree._stages[:
                                                     -1]:  # all blended stages
            for tree_node in stage._tree_nodes:
                self._wbars[self._iter][tree_node._name] = copy.deepcopy(
                    tree_node._wbars)
                block = getattr(model, tree_node._name)

                def _c_rule(block, i):
                    lhs = sum(model.beta[k] * self._wbars[k][tree_node._name][
                        block.id_to_var[i][0]][block.id_to_var[i][1]]
                              for k in model.beta.index_set())
                    if not isinstance(lhs, ExpressionBase):
                        return Constraint.Skip
                    return lhs == 0

                block.del_component('con')
                block.con = Constraint(block.var_index, rule=_c_rule)
        return False
Ejemplo n.º 26
0
def makeDisjunctionsOnIndexedBlock():
    """Two disjunctions (one indexed an one not), each on a separate 
    BlockData of an IndexedBlock of length 2
    """
    m = ConcreteModel()
    m.s = Set(initialize=[1, 2])
    m.a = Var(m.s, bounds=(0, 70))

    @m.Disjunct(m.s, [0, 1])
    def disjunct1(disjunct, s, flag):
        m = disjunct.model()
        if not flag:
            disjunct.c = Constraint(expr=m.a[s] == 0)
        else:
            disjunct.c = Constraint(expr=m.a[s] >= 7)

    def disjunction1_rule(m, s):
        return [m.disjunct1[s, flag] for flag in [0, 1]]

    m.disjunction1 = Disjunction(m.s, rule=disjunction1_rule)

    m.b = Block([0, 1])
    m.b[0].x = Var(bounds=(-2, 2))

    def disjunct2_rule(disjunct, flag):
        if not flag:
            disjunct.c = Constraint(expr=m.b[0].x <= 0)
        else:
            disjunct.c = Constraint(expr=m.b[0].x >= 0)

    m.b[0].disjunct = Disjunct([0, 1], rule=disjunct2_rule)

    def disjunction(b, i):
        return [b.disjunct[0], b.disjunct[1]]

    m.b[0].disjunction = Disjunction([0], rule=disjunction)

    m.b[1].y = Var(bounds=(-3, 3))
    m.b[1].disjunct0 = Disjunct()
    m.b[1].disjunct0.c = Constraint(expr=m.b[1].y <= 0)
    m.b[1].disjunct1 = Disjunct()
    m.b[1].disjunct1.c = Constraint(expr=m.b[1].y >= 0)
    m.b[1].disjunction = Disjunction(expr=[m.b[1].disjunct0, m.b[1].disjunct1])
    return m
Ejemplo n.º 27
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.º 28
0
    def _add_transformation_block(self, instance):
        # make a transformation block on instance where we will store
        # transformed components
        transBlockName = unique_component_name(
            instance, '_pyomo_gdp_hull_reformulation')
        transBlock = Block()
        instance.add_component(transBlockName, transBlock)
        transBlock.relaxedDisjuncts = Block(NonNegativeIntegers)
        transBlock.lbub = Set(initialize=['lb', 'ub', 'eq'])
        # We will store all of the disaggregation constraints for any
        # Disjunctions we transform onto this block here.
        transBlock.disaggregationConstraints = Constraint(
            NonNegativeIntegers, Any)

        # This will map from srcVar to a map of srcDisjunction to the
        # disaggregation constraint corresponding to srcDisjunction
        transBlock._disaggregationConstraintMap = ComponentMap()

        return transBlock
Ejemplo n.º 29
0
    def test_indexedvar_noindextemplate(self):
        st_model = CreateConcreteTwoStageScenarioTreeModel(1)
        st_model.StageVariables['Stage1'].add("x")
        st_model.StageDerivedVariables['Stage1'].add("y")
        st_model.NodeVariables['RootNode'].add("z")
        st_model.NodeDerivedVariables['RootNode'].add("q")
        st_model.StageCost['Stage1'] = "FirstStageCost"
        st_model.StageCost['Stage2'] = "SecondStageCost"

        scenario_tree = ScenarioTree(scenariotreeinstance=st_model)
        self.assertEqual(len(scenario_tree.stages), 2)
        self.assertEqual(len(scenario_tree.nodes), 2)
        self.assertEqual(len(scenario_tree.scenarios), 1)

        model = ConcreteModel()
        model.s = Set(initialize=[1, 2, 3])
        model.x = Var(model.s)
        model.y = Var(model.s)
        model.z = Var(model.s)
        model.q = Var(model.s)
        model.FirstStageCost = Expression(expr=0.0)
        model.SecondStageCost = Expression(expr=0.0)
        model.obj = Objective(expr=0.0)

        root = scenario_tree.findRootNode()
        root_nonant_names = _get_names(_get_nonant_list(model, root))
        root_derived_nonant_names = _get_names(
            _get_derived_nonant_list(model, root))
        assert len(root_nonant_names) == 6
        assert len(root_derived_nonant_names) == 6

        for name in ("x", "z"):
            indexed_var = model.find_component(name)
            for index in model.s:
                var = indexed_var[index]
                assert var.name in root_nonant_names
        for name in ("y", "q"):
            indexed_var = model.find_component(name)
            for index in model.s:
                var = indexed_var[index]
                assert var.name in root_derived_nonant_names
Ejemplo n.º 30
0
def makeDisjunctionOfDisjunctDatas():
    """Two SimpleDisjunctions, where each are disjunctions of DisjunctDatas.
    This adds nothing to makeTwoSimpleDisjunctions but exists for convenience
    because it has the same mathematical meaning as 
    makeAnyIndexedDisjunctionOfDisjunctDatas
    """
    m = ConcreteModel()
    m.x = Var(bounds=(-100, 100))

    m.obj = Objective(expr=m.x)

    m.idx = Set(initialize=[1, 2])
    m.firstTerm = Disjunct(m.idx)
    m.firstTerm[1].cons = Constraint(expr=m.x == 0)
    m.firstTerm[2].cons = Constraint(expr=m.x == 2)
    m.secondTerm = Disjunct(m.idx)
    m.secondTerm[1].cons = Constraint(expr=m.x >= 2)
    m.secondTerm[2].cons = Constraint(expr=m.x >= 3)

    m.disjunction = Disjunction(expr=[m.firstTerm[1], m.secondTerm[1]])
    m.disjunction2 = Disjunction(expr=[m.firstTerm[2], m.secondTerm[2]])
    return m